Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regression: Stub generator no longer generates __members__ for enum class #12717

Closed
bluenote10 opened this issue May 2, 2022 · 0 comments · Fixed by #12828
Closed

Regression: Stub generator no longer generates __members__ for enum class #12717

bluenote10 opened this issue May 2, 2022 · 0 comments · Fixed by #12828
Labels
bug mypy got something wrong topic-enum topic-stubgen

Comments

@bluenote10
Copy link
Contributor

bluenote10 commented May 2, 2022

Bug Report

In mypy version 0.942, the stub generator used to create __members__ fields like:

class MyEnum:
    __members__: ClassVar[dict] = ...  # read-only

In our case, MyEnum is a C++ enum class exposed to Python via pybind11. The type annotation seemed to be correct, because at runtime, __members__ does exist.

In mypy version 0.950 the __members__ field is no longer annotated, which means that existing value code no longer type checks properly.

To Reproduce

  • Create a temporary venv:
$ mkdir some_temporary_folder
$ cd some_temporary_folder
$ virtualenv ./tmp_venv -p /usr/bin/python3.8
$ . ./tmp_venv/bin/activate
$ pip install -U pip setuptools
$ pip install mypy==0.950 pybind11==2.9.0
  • Create a file native_enum_test.cpp with content:
#include <cstddef>
#include <memory>
#include <pybind11/pybind11.h>

namespace py = pybind11;

enum class MyEnum { FOO, BAR };

PYBIND11_MODULE(native_enum_test, module) {
  pybind11::enum_<MyEnum>(module, "MyEnum", pybind11::arithmetic())
      .value("FOO", MyEnum::FOO)
      .value("BAR", MyEnum::BAR);
}
  • Compile via:
$ c++ -O3 -Wall -shared -std=c++17 -fPIC $(python3 -m pybind11 --includes) native_enum_test.cpp -o native_enum_test.so
  • Run the stub generator:
$ stubgen -p native_enum_test

Expected Behavior

As far as I can see, __members__ should be generated by the stub generator.

Check against the previous mypy version: pip install mypy==0.942 and re-running the stub generator produces:

Generator output mypy 0.942
from typing import ClassVar

class MyEnum:
    __doc__: ClassVar[str] = ...  # read-only
    __members__: ClassVar[dict] = ...  # read-only
    BAR: ClassVar[MyEnum] = ...
    FOO: ClassVar[MyEnum] = ...
    __entries: ClassVar[dict] = ...
    def __init__(self, value: int) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __getstate__(self) -> int: ...
    def __gt__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...
    def __index__(self) -> int: ...
    def __int__(self) -> int: ...
    def __le__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __setstate__(self, state: int) -> None: ...
    @property
    def name(self) -> str: ...
    @property
    def value(self) -> int: ...

Actual Behavior

__members__ is missing in the stub generator output.

Generator output mypy 0.950
from typing import ClassVar

class MyEnum:
    BAR: ClassVar[MyEnum] = ...
    FOO: ClassVar[MyEnum] = ...
    __entries: ClassVar[dict] = ...
    def __init__(self, value: int) -> None: ...
    def __eq__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __getstate__(self) -> int: ...
    def __gt__(self, other: object) -> bool: ...
    def __hash__(self) -> int: ...
    def __index__(self) -> int: ...
    def __int__(self) -> int: ...
    def __le__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __setstate__(self, state: int) -> None: ...
    @property
    def name(self) -> str: ...
    @property
    def value(self) -> int: ...

Your Environment

  • Mypy version used: 0.950
  • Mypy command-line flags: not relevant, this is about the stub generator
  • Mypy configuration options from mypy.ini (and other config files): not relevant, this is about the stub generator
  • Python version used: 3.8.10
  • Operating system and version: Ubuntu 20.04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-enum topic-stubgen
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants