I've run into a snippit of code which essentially boils down into this:
classSomeObject(object):
@classmethoddeftest_class_method(cls) ->None:
print('Test class method')
@staticmethoddeftest_static_method() ->None:
print('Test static method')
s=SomeObject()
t=type(s)
# Doesn't typecheckt.test_static_method()
t.test_class_method()The behavior I was expecting was for t to be of type Type[SomeObject] -- instead, it's of type type, due to how type is annotated in Typeshed:
classtype:
__bases__= ... # type: Tuple[type, ...]__name__= ... # type: str__qualname__= ... # type: str__module__= ... # type: str__dict__= ... # type: Dict[str, Any]__mro__= ... # type: Tuple[type, ...]@overloaddef__init__(self, o: object) ->None: ...
@overloaddef__init__(self, name: str, bases: Tuple[type, ...], dict: Dict[str, Any]) ->None: ...
@overloaddef__new__(cls, o: object) ->type: ...
@overloaddef__new__(cls, name: str, bases: Tuple[type, ...], namespace: Dict[str, Any]) ->type: ...
def__call__(self, *args: Any, **kwds: Any) ->Any: ...
def__subclasses__(self) ->List[type]: ...
# Note: the documentation doesn't specify what the return type is, the standard# implementation seems to be returning a list.defmro(self) ->List[type]: ...
I attempted modifying the definition in Typeshed by first changing __new__ to have the signature def __new__(cls, o: _T) -> Type[_T], but that had no effect. I then tried commenting out both __init__s entirely in case mypy was defaulting to looking at those, but that also did nothing. I'm not entirely sure why the change to __new__ isn't working, though it may be related to issue 1020?
I did find a workaround for this particular case by doing:
fromtypingimportcast, Type# ...snip...s=SomeObject()
t2=cast(Type[SomeObject], type(s))
# typecheckst2.test_static_method()
t2.test_class_method()
...but it would be nice if type could be changed so this casting is unnecessary, though I'm not entirely sure how this would be done.
I've run into a snippit of code which essentially boils down into this:
The behavior I was expecting was for
tto be of typeType[SomeObject]-- instead, it's of typetype, due to howtypeis annotated in Typeshed:I attempted modifying the definition in Typeshed by first changing
__new__to have the signaturedef __new__(cls, o: _T) -> Type[_T], but that had no effect. I then tried commenting out both__init__s entirely in case mypy was defaulting to looking at those, but that also did nothing. I'm not entirely sure why the change to__new__isn't working, though it may be related to issue 1020?I did find a workaround for this particular case by doing:
...but it would be nice if
typecould be changed so this casting is unnecessary, though I'm not entirely sure how this would be done.