Reputation: 1126
I am looking to do something like this:
@attr.s
class A(object):
a_dict = attr.ib(factory=Dict, type=Dict[str, A], validator=optional(instance_of(Dict)))
It is possible to type it just as type=Dict
but I wonder if you can self-reference like type=Dict[str, cls]
, but it might be limited by possibilities of Python.
Thanks.
Upvotes: 1
Views: 1317
Reputation: 4146
If I interpret is correctly, what you want is this:
from typing import Dict, Optional
import attr
from attr.validators import optional, instance_of
@attr.s
class A(object):
a_dict = attr.ib(
factory=dict,
type=Optional[Dict[str, "A"]],
validator=optional(instance_of(dict))
)
A({"key": A(None)})
And it passes mypy.
Please note:
typing.Dict
for factory
because it's really just for type hints and fails if you try to instantiate it.instance_of
uses isinstance()
internally and while isinstance({}, Dict)
is True, I don't think it's the intended to be used like that.Optional[]
.Upvotes: 1
Reputation: 850
cls
and self
are names given to classes and their instances by convention, when they are passed as arguments to class methods and instance methods respectively. Neither will be defined where you're trying to use them.
What you might be able to do instead, is enforce the type to be a non-object superclass of A, if there is any.
Upvotes: 1
Reputation: 74655
The issue is that class A(object): A
results in NameError: name 'A' is not defined
. What this means is that one can not reference a class by its name during its creation in its defining block.
I think that to get around this in typing, one can use a string instead: type=Dict[str, 'A']
. I remember seeing this as how forward references are made but this might not be right.
Upvotes: 2