Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

reprlib (used by pytest) infers builtin types based on class__name__ #113570

Closed
Labels
3.12only security fixes3.13bugs and security fixes3.14bugs and security fixestype-bugAn unexpected behavior, bug, or error
@jpivarski

Description

@jpivarski

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:

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

Footnotes

  1. In my case, I want theragged library to provide aragged.array because 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.12only security fixes3.13bugs and security fixes3.14bugs and security fixestype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp