:rtype:
specifies that this is the type of the returned object.
Therefore, when I create the object obj
in the following snippet I receive a warning from the IDE that cls is not callable
, since the IDE expects that cls
is object
of type SomeAbstractClass
, and I want SomeAbstractClass
itself.
The IDE is right, since this is the default behaviour. But how can I specify that I am returning a class, not an instance of a class?
Specifying type
instead of SomeAbstractClass
helps a bit, but that's not a solution, since no further introspection is available.
def class_selector(data):
"""
:rtype: SomeAbstractClass
:return: Return some class based on given parameters
"""
return get_from.get(data.name)
cls = class_selector(data)
obj = cls(data.more_data)
Meanwhile I have solved this by adding """:type: SomeAbstractClass"""
after object creating, but this does not cancel the warning and it's a dirty solution.
By the way, I am talking about Python 2.x.
As for 2020, the only solution that is working properly - using python3 annotations:
Which in general is totally acceptable for 2020
Attaching a screenshot to demonstrate the correct behavior.
Basically, def factory(name) -> type[SomeAbstractClass]:
or def factory(name) -> "type[SomeAbstractClass]":
(for cases when can't import the name) works totally fine.
Still could not come up with a solution for older Python versions (i.e avoiding the use of annotations). But it's not a deal-breaker in 2020
And same code as text, if anyone wants to copy-paste to test alternative approaches
class SomeAbstractClass:
property_by_class = 1
def __init__(self):
self.property_by_object = 1
def factory(name) -> type[SomeAbstractClass]:
hide_it = dict()
class ActualClassImpl(SomeAbstractClass):
pass
hide_it.__setitem__(name, ActualClassImpl)
return hide_it.__getitem__(name)
if __name__ == '__main__':
a = factory('testclass')
by_class_should_be_ok = a.property_by_class
by_object_should_hint_error = a.property_by_object
just_like_none_existing_property_hints = a.property_by_object_bad
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With