Search code examples
pythonpython-2.7python-attrs

Is it possible to self-reference type in Python attr


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.


Solution

  • 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:

    • You cannot use 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.
    • If a_dict is optional as per validator, you also need to declare it optional using type annotations by wrapping it in an Optional[].