python / typeshed

Collection of library stubs for Python, with static types
Other
4.3k stars 1.73k forks source link

How do I add a type hint for __metaclass_ ABCMeta? #12515

Closed papadeltasierra closed 1 month ago

papadeltasierra commented 1 month ago

I'm trying to fixup this type hint:

class FilterExpr:
    __metaclass__: ABCMeta
    @abstractmethod
    def eval(self, route): ..

but am getting this error from the tests:

error: stone.cli_helpers.FilterExpr.__metaclass__ variable differs from runtime type builtins.type
Stub: in file /home/pds/git/typeshed/stubs/stone/stone/cli_helpers.pyi:45
abc.ABCMeta
Runtime: in file /usr/lib/python3.10/abc.py:92
def (name, bases, namespace, **kwargs)

This has exhausted my limited knowledge of abstract classes - anyone able to help me out? Thanks.

AlexWaygood commented 1 month ago

Hard to say without more context, but __metaclass__: ABCMeta means "the value of the __metaclass__ variable is an instance of ABCMeta". That's probably not what you want? __metaclass__ is probably set to a subclass of ABCMeta rather than an instance of ABCMeta -- so you probably want __metaclass__: type[ABCMeta] or __metaclass__ = ABCMeta rather than __metaclass__: ABCMeta.

Again, though, it's hard to say without more context about what exactly you're trying to add stubs for here. And the question is a bit strange to begin with, since the __metaclass__ attribute does nothing in Python 3 (it was only a valid way of specifying a metaclass in Python 2).

JelleZijlstra commented 1 month ago

Possibly what you actually want to write is class FilterExpr(metaclass=ABCMeta):.

papadeltasierra commented 1 month ago

Thanks @AlexWaygood and (again) @JelleZijlstra . Will give this a try tonight. As to the Py2 stuff, the package I'm trying to create stubs for is not mine (it's actually Dropbox's stone package as a prelude to Dropbox's dropbox-sdk-python) and this __metaclass__... stuff comes from there.

papadeltasierra commented 1 month ago

__metaclass__: type[ABCMeta] was the magic bullet - thanks.

JelleZijlstra commented 1 month ago

I'd probably omit this attribute from the stub, actually; it looks like a Python 2 remnant that wasn't cleaned up, not an intentionally exposed attribute.