Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining python type hints for list of a weakref object

I haven't found how to give type hints indication when using weakrefs.

from typing import List
import weakref
class MyObject:
    def __init(self, foo)
        self.foo = foo
o1 = MyObject(1)
o2 = MyObject(2)
my_list: List[weakref] = [weakref.ref(o1), weakref.ref(o2)]

Is there a way to say that my_list is a list of weakref to MyObject, something like:

my_list: List[Weakref[MyObject]] = [weakref.ref(o1), weakref.ref(o2)]

?

like image 721
beesleep Avatar asked Sep 27 '18 01:09

beesleep


People also ask

How do you write a class hint in Python?

In a type hint, if we specify a type (class), then we mark the variable as containing an instance of that type. To specify that a variable instead contains a type, we need to use type[Cls] (or the old syntax typing. Type ).

Does Python 3.6 support type hints?

This module supports type hints as specified by PEP 484 and PEP 526. The most fundamental support consists of the types Any , Union , Tuple , Callable , TypeVar , and Generic . For full specification please see PEP 484. For a simplified introduction to type hints see PEP 483.

How do you write a tuple hint in Python?

To specify a variable-length tuple of homogeneous type, use literal ellipsis, e.g. Tuple[int, ...] . A plain Tuple is equivalent to Tuple[Any, ...] , and in turn to tuple .

What is Weakref object in Python?

The weakref module allows the Python programmer to create weak references to objects. In the following, the term referent means the object which is referred to by a weak reference.


1 Answers

We can find this information by consulting typeshed, a repository of type hints for the standard library and some popular 3rd party modules.

Specifically, if we look at the stubs for the weakref module, we can see that it re-exports ref from the _weakref module. And from there, we see that ref is defined to be equivalent to the ReferenceType class, which is defined to be generic (and is also re-exported from weakref).

Putting these pieces together, we can give your my_list variable a type hint that looks like this:

from __future__ import annotations
from typing import List
from weakref import ref, ReferenceType

# ...snip...

my_list: List[ReferenceType[MyObject]] = [...]

Somewhat interestingly, it's also ok to do this:

from __future__ import annotations
from typing import List
from weakref import ref

# ...snip...

my_list: List[ref[MyObject]] = [...]

Basically, ref is also an alias to ReferenceType so we can use both types interchangeably.

I would personally use ReferenceType, but that's mostly because I'm just so used to types starting with capital letters. (Or, if that type hint starts getting too verbose, I'd maybe define a custom type alias Ref = ReferenceType).

Note that the from __future__ import annotations line is available only on Python 3.7+. If you're using an older version of Python, you'll need to make your type hints be strings manually:

from typing import List
from weakref import ref

# ...snip...

my_list: "List[ReferenceType[MyObject]]" = [...]

# Or:

my_list: List["ReferenceType[MyObject]"] = [...]
like image 192
Michael0x2a Avatar answered Sep 19 '22 07:09

Michael0x2a