Skip to content

The TestProtocol enum does weird stuff in __str__, accessing other enum members via self #8318

@hroncok

Description

@hroncok

Hello. We are testing Python packages in Fedora with Python 3.10 to see what breaks. Packages using meson fail with:

Found ninja-1.10.2 at /usr/bin/ninja
  File "/usr/lib/python3.10/site-packages/mesonbuild/mesonmain.py", line 140, in run
    return options.run_func(options)
  File "/usr/lib/python3.10/site-packages/mesonbuild/msetup.py", line 253, in run
    app.generate()
  File "/usr/lib/python3.10/site-packages/mesonbuild/msetup.py", line 161, in generate
    self._generate(env)
  File "/usr/lib/python3.10/site-packages/mesonbuild/msetup.py", line 235, in _generate
    mintro.generate_introspection_file(b, intr.backend)
  File "/usr/lib/python3.10/site-packages/mesonbuild/mintro.py", line 470, in generate_introspection_file
    intro_info += [(key, val.func())]
  File "/usr/lib/python3.10/site-packages/mesonbuild/mintro.py", line 77, in <lambda>
    ('tests', IntroCommand('List all unit tests', func=lambda: list_tests(testdata))),
  File "/usr/lib/python3.10/site-packages/mesonbuild/mintro.py", line 342, in list_tests
    return get_test_list(testdata)
  File "/usr/lib/python3.10/site-packages/mesonbuild/mintro.py", line 336, in get_test_list
    to['protocol'] = str(t.protocol)
  File "/usr/lib/python3.10/site-packages/mesonbuild/backend/backends.py", line 59, in __str__
    if self is self.EXITCODE:
  File "/usr/lib64/python3.10/enum.py", line 146, in __get__
    raise AttributeError(
AttributeError: TestProtocol: no attribute 'EXITCODE'

This comes from:

class TestProtocol(enum.Enum):
EXITCODE = 0
TAP = 1
GTEST = 2
RUST = 3
@classmethod
def from_str(cls, string: str) -> 'TestProtocol':
if string == 'exitcode':
return cls.EXITCODE
elif string == 'tap':
return cls.TAP
elif string == 'gtest':
return cls.GTEST
elif string == 'rust':
return cls.RUST
raise MesonException('unknown test format {}'.format(string))
def __str__(self) -> str:
if self is self.EXITCODE:
return 'exitcode'
elif self is self.GTEST:
return 'gtest'
elif self is self.RUST:
return 'rust'
return 'tap'

The __str__ method accesses other enum members via self.<name>.

I've reported this as a regression to Python, because it used to work prior to 3.10.0a5 and no longer does. It seems however, that the author of enum doesn't think this is a proper API, and while they agree to keep it working in Python 3.10, they might end up adding a deprecation warning. https://bugs.python.org/issue43162

Possibly, the method could be simplified to:

     def __str__(self) -> str: 
         return self.name.lower()

?

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