Type of a returned class
Question:
I do this:
def get_an_x():
class X:
foo = 1
bar = 'Hello'
baz = None
return X
get_an_x
returns a class X
, which serves as a plain structure.
What is the type of this class X
? Doing def get_an_x() -> type: ...
(that what type(X)
returns) will not work, then PyCharms’s type checker does not detect the attributes of X
. Annotating the attributes with ClassVar[...]
also does not help.
I have seen this answer, but doing def get_an_x() -> type[X]: ...
does not work, because I define the class inside the function, and it is not seen from outside.
Note Creating the class in the function is up to 30 times slower than creating an instance of a class defined outside the function. Probably it also uses more ram, but have not tested. Only do this if you want to create global namespaces. Don’t do this when you create many such structures, for example one for each line parsed from a file.
Answers:
The issue is, every time you call foo
, it returns a different class. If it had a base class, you could annotate it with typing.Type[Base]
, to at least show the base’s attributes. But in your situation I’d suggest you to either let your IDE figure it out without annotations, or to annotate it as typing.Type
.
One more option you have is creating a protocol, if you know the exact attribute set in advance, and using it for the annotation
Protocol, suggested by abel1502, seems to do what I want:
from typing import Protocol
class X(Protocol):
foo: str
bar: int
baz: None
def get_an_x() -> X:
class x:
foo = 'the answer'
bar = 42
baz = None
return x
Now PyCharms type checker detects wrong types and non-existing or unknown attributes:
# These are ok
x: X = get_an_x()
foo: str = x.foo
bar: int = x.bar
baz: None = x.baz
# These are type errors
unknown = x.unknownattribute
wrong_type: int = x.foo
wrong_x: str = get_an_x()
def get_a_wrong_x() -> X:
class x:
foox = 'the answer'
bar = '42'
return x
I do this:
def get_an_x():
class X:
foo = 1
bar = 'Hello'
baz = None
return X
get_an_x
returns a class X
, which serves as a plain structure.
What is the type of this class X
? Doing def get_an_x() -> type: ...
(that what type(X)
returns) will not work, then PyCharms’s type checker does not detect the attributes of X
. Annotating the attributes with ClassVar[...]
also does not help.
I have seen this answer, but doing def get_an_x() -> type[X]: ...
does not work, because I define the class inside the function, and it is not seen from outside.
Note Creating the class in the function is up to 30 times slower than creating an instance of a class defined outside the function. Probably it also uses more ram, but have not tested. Only do this if you want to create global namespaces. Don’t do this when you create many such structures, for example one for each line parsed from a file.
The issue is, every time you call foo
, it returns a different class. If it had a base class, you could annotate it with typing.Type[Base]
, to at least show the base’s attributes. But in your situation I’d suggest you to either let your IDE figure it out without annotations, or to annotate it as typing.Type
.
One more option you have is creating a protocol, if you know the exact attribute set in advance, and using it for the annotation
Protocol, suggested by abel1502, seems to do what I want:
from typing import Protocol
class X(Protocol):
foo: str
bar: int
baz: None
def get_an_x() -> X:
class x:
foo = 'the answer'
bar = 42
baz = None
return x
Now PyCharms type checker detects wrong types and non-existing or unknown attributes:
# These are ok
x: X = get_an_x()
foo: str = x.foo
bar: int = x.bar
baz: None = x.baz
# These are type errors
unknown = x.unknownattribute
wrong_type: int = x.foo
wrong_x: str = get_an_x()
def get_a_wrong_x() -> X:
class x:
foox = 'the answer'
bar = '42'
return x