Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the differences between Set, FrozenSet, MutableSet and AbstractSet in python typing module?

I am trying to annotate my code with types but I am a little confused when it comes to sets. I read some points in PEP 484:

Note: Dict , List , Set and FrozenSet are mainly useful for annotating return values. For arguments, prefer the abstract collection types defined below, e.g. Mapping , Sequence or AbstractSet .

and

Set, renamed to AbstractSet . This name change was required because Set in the typing module means set() with generics.

but this does not help.

My first question is: what are the commonalities and differences between Set, FrozenSet, MutableSet and AbstractSet?

My second question is: why if I try

from collections import FrozenSet

I get

ImportError: cannot import name 'FrozenSet'

?

I am using Python 3.4 and I have installed mypy-lang via pip.

like image 348
marcotama Avatar asked Mar 10 '16 03:03

marcotama


2 Answers

Be careful with annotations and typing. The ideas discussed in 484 are brand new, and implemented in the typing module. That module is only available in Python3.5 (the latest typing is also available from pip for both Py2 and Py3).

https://docs.python.org/3/library/typing.html

That note that you quoted is from a section in 484 that starts:

To open the usage of static type checking to Python 3.5 as well as older versions, a uniform namespace is required. For this purpose, a new module in the standard library is introduced called typing .

The things that the note lists are annotation types, not actual object classes (builtin or from collections). Don't confuse the two.

Note that Dict , List , Set and FrozenSet are all capitalized, where as the functions (and type names) are dict, list, set, frozenset. In other words to make a dictionary you use dict() or {}, not Dict.

Annotations are new to 3.0 (not in 2.n at all). In a regular interpreter all they do is populate the function's __annotations__ dictionary. There's nothing in the interpreter that uses or requires annotations.

http://mypy-lang.org/ describes itself as an experiemental typing checker. You need to look at it's documentation to see how compatible it is with 484 etc.

https://docs.python.org/3/library/collections.abc.html#module-collections.abc has some abstract definitions, which I believe typing uses. I've never used these. They are mainly for people developing new classes of objects, not 'regular' users.

The typing tag for this question is probably not a good idea. It doesn't have many followers, and is too generic. It does not refer to this Python module.

Search for [python] 484 for other SO questions dealing with this style of annotations.

https://github.com/python/typing - the typing development repository.

In this repository, there is a FrozenSet definition in the python2/typing.py file (the python2 backport), but not in src/typing.py. I'm not sure of the significance of that.

like image 181
hpaulj Avatar answered Oct 13 '22 09:10

hpaulj


Two years late to the party, but anyway...

You can think of AbstractSet and MutableSet as like an interface in Java or an abstract base class in Python. Python's builtin set() and frozenset() are one implementation, but someone could create another implementation that doesn't use the builtins at all.

FrozenSet and Set, on the other hand, represent the types of the concrete built in classes frozenset and set.

For example, the "interface" types don't have union methods, while the concrete types do. So:

def merge(a: Set[str], b: Iterable[str]) -> Set[str]:
    return a.union(b)

will type check just fine, but if you change the type of a to AbstractSet, mypy says:

typetest.py:7: error: "AbstractSet[str]" has no attribute "union"

like image 38
Martin C. Martin Avatar answered Oct 13 '22 10:10

Martin C. Martin