Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Description
Bug report
Bug description:
Code like the following:
importreprlibclassarray:def__repr__(self):return"not array.array!"reprlib.repr(array())
raises
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/jpivarski/mambaforge/lib/python3.10/reprlib.py", line 52, in repr return self.repr1(x, self.maxlevel) File "/home/jpivarski/mambaforge/lib/python3.10/reprlib.py", line 60, in repr1 return getattr(self, 'repr_' + typename)(x, level) File "/home/jpivarski/mambaforge/lib/python3.10/reprlib.py", line 86, in repr_array header = "array('%s', [" % x.typecodeAttributeError: 'array' object has no attribute 'typecode'because reprlib usestype(x).__name__ to infer thatx has typearray.array, rather than my user-defined class:
Lines 62 to 70 incf34b77
| defrepr1(self,x,level): | |
| typename=type(x).__name__ | |
| if' 'intypename: | |
| parts=typename.split() | |
| typename='_'.join(parts) | |
| ifhasattr(self,'repr_'+typename): | |
| returngetattr(self,'repr_'+typename)(x,level) | |
| else: | |
| returnself.repr_instance(x,level) |
Perhaps there's good reason to check the__name__ string instead ofisinstance(x, array.array), to avoid unnecessarily importing thearray module for start-up time or for minimizing clutter in thesys.modules. However, this test should check both the__name__ string and the__module__ string.
This affects any user-defined classes with the following names:
- tuple
- list
- array
- set
- frozenset
- deque
- dict
- str
- int
- instance
Some of these, admittedly, would be bad names for user-defined classes, but others are more reasonable, such asarray anddeque.1
Since these methods are publicly available on classreprlib.Repr, the method names can't change, but the lookup could be replaced using a dict like
classRepr:_lookup= { ("builtins","tuple"):repr_tuple, ("builtins","list"):repr_list, ("array","array"):repr_array, ("builtins","set"):repr_set, ("builtins","frozenset"):repr_frozenset, ("collections","deque"):repr_deque, ("builtins","dict"):repr_dict, ("builtins","str"):repr_str, ("builtins","int"):repr_int, }
I encountered this in pytest. My error output contained
x = <[ValueError('the truth value of an array whose length is not 1 is ambiguous; use ak.any() or ak.all()') raised in repr()] array object at 0x779b54763700>y = array([1, 2, 3])or
x = <[AttributeError("'array' object has no attribute 'typecode'") raised in repr()] array object at 0x728278bacd60>y = array([1, 2, 3])for reasons that had nothing to do with the actual error, and thearray.__repr__ code itself is error-free. (pytest overrides reprlib to provide a SafeRepr.)
Thanks!
CPython versions tested on:
3.10
Operating systems tested on:
Linux
Linked PRs
- gh-113570: reprlib.repr does not use builtin __repr__ for reshadowed builtins #113577
- [3.13] gh-113570: reprlib.repr does not use builtin __repr__ for reshadowed builtins (GH-113577) #125654
- [3.12] gh-113570: reprlib.repr does not use builtin __repr__ for reshadowed builtins (GH-113577) #125655
Footnotes
In my case, I want the
raggedlibrary to provide aragged.arraybecause it reads like English that way. I also don't want to change the__name__of my class to differ from its actual name. In particular, theArray API specification uses "array" as a type name.↩