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.
Describe the bug
ClassLabel.str2intandClassLabel.int2strboth 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.str2intaccepts 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:int2strtruncates floats throughint(v), so a float silently resolves to a label:The remaining two are loud but misleading. A nested string still produces the cryptic
TypeErrorthat #8416 is fixing at the top level:and
bytesgets iterated into its byte values:Cause
Both methods guard only the argument itself:
after which
int2strdoesif not 0 <= v < self.num_classes(which is what raises theTypeErroron a str element, and what a float passes) andstr2int'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 fixesint2str("1")but notint2str(["1"]), and doesn't address the two silent cases at all.Expected behavior
Every element is validated, so all four raise a
ValueErrornaming the offending value — in particularstr2int([1])andint2str([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 astr2intcall looking like it was encoded correctly.Environment info
datasets4.5.1.dev0 (main @ 48b7ee7)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.