Skip to content

ClassLabel.str2int and int2str do not validate the elements of an iterable #8481

Description

@shashvat-singham

Describe the bug

ClassLabel.str2int and ClassLabel.int2str both validate the container they're given, but never the elements inside it. Two of the resulting cases fail silently and return wrong labels rather than raising.

str2int accepts ints and hands them straight back, so a column of integer labels round-trips through a "string to int" call untouched instead of being rejected:

>>> from datasets import ClassLabel
>>> cl = ClassLabel(names=["neg", "pos"])
>>> cl.str2int([1])
[1]
>>> cl.str2int([5])     # not even a valid class id
[5]

int2str truncates floats through int(v), so a float silently resolves to a label:

>>> cl.int2str([1.7])
['pos']

The remaining two are loud but misleading. A nested string still produces the cryptic TypeError that #8416 is fixing at the top level:

>>> cl.int2str(["1"])
TypeError: '<=' not supported between instances of 'int' and 'str'

and bytes gets iterated into its byte values:

>>> cl.int2str(b"1")
ValueError: Invalid integer class label 49    # 49 is ord("1")

Cause

Both methods guard only the argument itself:

if not isinstance(values, int) and not isinstance(values, Iterable):
    raise ValueError(...)

after which int2str does if not 0 <= v < self.num_classes (which is what raises the TypeError on a str element, and what a float passes) and str2int's loop only checks membership for values it recognises as strings, letting anything else fall through to the return.

#8416 tightens the top-level check for str, which fixes int2str("1") but not int2str(["1"]), and doesn't address the two silent cases at all.

Expected behavior

Every element is validated, so all four raise a ValueError naming the offending value — in particular str2int([1]) and int2str([1.7]) should not return a result.

str2int([1]) returning [1] is the one I'd flag as most worth fixing: it's silent, and it means a mistakenly-already-encoded label column survives a str2int call looking like it was encoded correctly.

Environment info

  • datasets 4.5.1.dev0 (main @ 48b7ee7)
  • Python 3.11.9, Windows

I'm happy to open a PR adding per-element validation to both methods if you'd like it — it would want coordinating with #8416 since they touch the same guard.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions