[Python-checkins] peps: Add NewType() to PEP 484.
guido.van.rossum
python-checkins at python.org
Wed Jun 1 21:02:44 EDT 2016
https://hg.python.org/peps/rev/64f152d66b72
changeset: 6345:64f152d66b72
user: Guido van Rossum <guido at python.org>
date: Wed Jun 01 18:02:33 2016 -0700
summary:
Add NewType() to PEP 484.
files:
pep-0484.txt | 65 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/pep-0484.txt b/pep-0484.txt
--- a/pep-0484.txt
+++ b/pep-0484.txt
@@ -1173,6 +1173,68 @@
in expressions, while type comments only apply to assignments.
+NewType helper function
+-----------------------
+
+There are also situations where a programmer might want to avoid logical
+errors by creating simple classes. For example::
+
+ class UserId(int):
+ pass
+
+ get_by_user_id(user_id: UserId):
+ ...
+
+However, this approach introduces a runtime overhead. To avoid this,
+``typing.py`` provides a helper function ``NewType`` that creates
+simple unique types with almost zero runtime overhead. For a static type
+checker ``Derived = NewType('Derived', Base)`` is roughly equivalent
+to a definition::
+
+class Derived(Base):
+ def __init__(self, _x: Base) -> None:
+ ...
+
+While at runtime, ``NewType('Derived', Base)`` returns a dummy function
+that simply returns its argument. Type checkers require explicit casts
+from ``int`` where ``UserId`` is expected, while implicitly casting
+from ``UserId`` where ``int`` is expected. Examples::
+
+ UserId = NewType('UserId', int)
+
+ def name_by_id(user_id: UserId) -> str:
+ ...
+
+ UserId('user') # Fails type check
+
+ name_by_id(42) # Fails type check
+ name_by_id(UserId(42)) # OK
+
+ num = UserId(5) + 1 # type: int
+
+``NewType`` accepts only one argument that shoud be a proper class,
+i.e., not a type construct like ``Union``, etc. The function returned
+by ``NewType`` accepts only one argument; this is equivalent to supporting
+only one constructor accepting an instance of the base class (see above).
+Example::
+
+ class PacketId:
+ def __init__(self, major: int, minor: int) -> None:
+ self._major = major
+ self._minor = minor
+
+ TcpPacketId = NewType('TcpPacketId', PacketId)
+
+ packet = PacketId(100, 100)
+ tcp_packet = TcpPacketId(packet) # OK
+
+ tcp_packet = TcpPacketId(127, 0) # Fails in type checker and at runtime
+
+Both ``isinstance`` and ``issubclass``, as well as subclassing will fail
+for ``NewType('Derived', Base)`` since function objects don't support
+these operations.
+
+
Stub Files
==========
@@ -1562,6 +1624,9 @@
This is useful to declare the types of the fields of a named tuple
type.
+* NewType, used to create unique types with little runtime overhead
+ ``UserId = NewType('UserId', int)``
+
* cast(), described earlier
* @no_type_check, a decorator to disable type checking per class or
--
Repository URL: https://hg.python.org/peps
More information about the Python-checkins
mailing list