[Python-Dev] Adding Type[C] to PEP 484 (original) (raw)
Guido van Rossum guido at python.org
Fri May 13 15:31:04 EDT 2016
- Previous message (by thread): [Python-Dev] File system path PEP, 3rd draft
- Next message (by thread): [Python-Dev] Adding Type[C] to PEP 484
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I've got another proposed update to PEP 484 ready. There was previously some discussion on python-ideas (Bcc'ed for closure) and quite a bit on the typing issue tracker: https://github.com/python/typing/issues/107
I've worked all that into a patch for PEP 484: https://github.com/python/typing/pull/218
Once we're okay with that I will work on getting the implementation ready in time for Python 3.5.2.
Here's the added text:
Meta-types
A meta-type can be used to indicate a value that is itself a class
object that is a subclass of a given class. It is spelled as
Type[C]
where C
is a class. To clarify: while C
(when
used as an annotation) refers to instances of class C
, Type[C]
refers to subclasses of C
. (This is a similar distinction as
between object
and type
.)
For example, suppose we have the following classes::
class User: ... # Abstract base for User classes class BasicUser(User): ... class ProUser(User): ... class TeamUser(User): ...
And suppose we have a function that creates an instance of one of these classes if you pass it a class object::
def new_user(user_class): user = user_class() # (Here we could write the user object to a database) return user
Without Type[]
the best we could do to annotate new_user()
would be::
def new_user(user_class: type) -> User: ...
However using Type[]
and a type variable with an upper bound we
can do much better::
U = TypeVar('U', bound=User) def new_user(user_class: Type[U]) -> U: ...
Now when we call new_user()
with a specific subclass of User
a
type checker will infer the correct type of the result::
joe = new_user(BasicUser) # Inferred type is BasicUser
At runtime the value corresponding to Type[C]
must be an actual
class object that's a subtype of C
, not a special form. IOW, in
the above example calling e.g. new_user(Union[BasicUser, ProUser])
is not allowed.
There are some concerns with this feature: for example when
new_user()
calls user_class()
this implies that all subclasses
of User
must support this in their constructor signature. However
this is not unique to Type[]
: class methods have similar concerns.
A type checker ought to flag violations of such assumptions, but by
default constructor calls that match the constructor signature in the
indicated base class (User
in the example above) should be
allowed. A program containing a complex or extensible class hierarchy
might also handle this by using a factory class method.
Plain Type
without brackets is equivalent to using type
(the
root of Python's metaclass hierarchy). This equivalence also
motivates the name, Type
, as opposed to alternatives like
Class
or SubType
, which were proposed while this feature was
under discussion; this is similar to the relationship between
e.g. List
and list
.
-- --Guido van Rossum (python.org/~guido) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20160513/74558d17/attachment.html>
- Previous message (by thread): [Python-Dev] File system path PEP, 3rd draft
- Next message (by thread): [Python-Dev] Adding Type[C] to PEP 484
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]