Skip to content

Commit

Permalink
Merged latest main.
Browse files Browse the repository at this point in the history
  • Loading branch information
erictraut committed Feb 11, 2024
2 parents b09bd65 + 12eb6c6 commit ca65a3d
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 11 deletions.
10 changes: 10 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: monthly
groups:
actions:
patterns:
- "*"
4 changes: 2 additions & 2 deletions .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3.9
- name: Install dependencies
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Python 3
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: 3
cache: "pip"
Expand Down
2 changes: 1 addition & 1 deletion conformance/results/pyre/directives_no_type_check.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
conformant = "Unsupported"
conformant = "Pass"
notes = """
Does not honor @no_type_check decorator.
"""
Expand Down
2 changes: 1 addition & 1 deletion conformance/results/pyright/directives_no_type_check.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
conformant = "Partial"
conformant = "Pass"
notes = """
Does not honor `@no_type_check` class decorator.
"""
Expand Down
2 changes: 1 addition & 1 deletion conformance/results/pytype/directives_no_type_check.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
conformant = "Unsupported"
conformant = "Pass"
notes = """
Does not honor @no_type_check decorator.
"""
Expand Down
14 changes: 10 additions & 4 deletions docs/spec/directives.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,16 @@ This approach may also be useful to handle import cycles.
``@no_type_check``
------------------

To mark portions of the program that should not be covered by type
hinting, you can use the ``@typing.no_type_check`` decorator on a class or function.
Functions with this decorator should be treated as having
no annotations.
The ``@typing.no_type_check`` decorator may be supported by type checkers
for functions and classes.

If a type checker supports the ``no_type_check`` decorator for functions, it
should suppress all type errors for the ``def`` statement and its body including
any nested functions or classes. It should also ignore all parameter
and return type annotations and treat the function as if it were unannotated.

The behavior for the ``no_type_check`` decorator when applied to a class is
left undefined by the typing spec at this time.

Version and platform checking
-----------------------------
Expand Down
2 changes: 2 additions & 0 deletions docs/spec/generics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1754,6 +1754,8 @@ overloads for each possible rank is, of course, a rather cumbersome
solution. However, it's the best we can do without additional type
manipulation mechanisms.)

.. _`self`:

``Self``
--------

Expand Down
1 change: 1 addition & 0 deletions docs/spec/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Specification for the Python type system
dataclasses
typeddict
tuples
namedtuples
narrowing
directives
distributing
Expand Down
148 changes: 148 additions & 0 deletions docs/spec/namedtuples.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
Named Tuples
============

As with tuples, named tuple classes require some special behaviors for type
checking.


Defining Named Tuples
---------------------

A named tuple class can be defined using a class syntax or a factory function
call.

Type checkers should support the class syntax::

class Point(NamedTuple):
x: int
y: int
units: str = "meters"

Regardless of whether the class syntax or factory function call is used to define
a named tuple, type checkers should synthesize a ``__new__`` method based on
the named tuple fields. This mirrors the runtime behavior. In the example
above, the synthesized ``__new__`` method would look like the following::

def __new__(cls, x: int, y: int, units: str = "meters") -> Self:
...

The runtime implementation of ``NamedTuple`` enforces that fields with default
values must come after fields without default values. Type checkers should
likewise enforce this restriction::

class Location(NamedTuple):
altitude: float = 0.0
latitude: float # Type error (previous field has a default value)
longitude: float

A named tuple class can be subclassed, but any fields added by the subclass
are not considered part of the named tuple type. Type checkers should enforce
that these newly-added fields do not conflict with the named tuple fields
in the base class::

class PointWithName(Point):
name: str # OK
x: int # Type error (invalid override of named tuple field)

In Python 3.11 and newer, the class syntax supports generic named tuple classes.
Type checkers should support this::

class Property[T](NamedTuple):
name: str
value: T

reveal_type(Property("height", 3.4)) # Revealed type is Property[float]

``NamedTuple`` does not support multiple inheritance. Type checkers should
enforce this limitation::

class Unit(NamedTuple, object): # Type error
name: str

The factory function call supports two variants: ``collections.namedtuple`` and
``typing.NamedTuple``. The latter provides a way to specify the types
of the fields in the tuple whereas the former does not. The ``namedtuple``
form allows fields to be specified as a tuple or list of strings or a single
string with fields separated by whitespace or commas. The ``NamedTuple``
functional form accepts an iterable of ``(name, type)`` pairs.
For the ``namedtuple`` form, all fields are assumed to be of type ``Any``.

A type checker may support the factory function call in its various forms::

Point1 = namedtuple('Point1', ['x', 'y'])
Point2 = namedtuple('Point2', ('x', 'y'))
Point3 = namedtuple('Point3', 'x y')
Point4 = namedtuple('Point4', 'x, y')

Point5 = NamedTuple('Point5', [('x', int), ('y', int)])
Point6 = NamedTuple('Point6', (('x', int), ('y', int)))

At runtime, the ``namedtuple`` function disallows field names that are
illegal Python identifiers and either raises an exception or replaces these
fields with a parameter name of the form ``_N``. The behavior depends on
the value of the ``rename`` argument. Type checkers may replicate this
behavior statically::

NT1 = namedtuple("NT1", ["a", "a"]) # Type error (duplicate field name)
NT2 = namedtuple("NT2", ["abc", "def"], rename=False) # Type error (illegal field name)

NT3 = namedtuple("NT3", ["abc", "def"], rename=True) # OK
NT3(abc="", _1="") # OK

The ``namedtuple`` function also supports a ``defaults`` keyword argument that
specifies default values for the fields. Type checkers may support this::

NT4 = namedtuple("NT4", "a b c", defaults=(1, 2))
NT4() # Type error (too few arguments)
NT4(1) # OK


Named Tuple Usage
-----------------

The fields within a named tuple instance can be accessed by name using an
attribute access (``.``) operator. Type checkers should support this::

p = Point(1, 2)
assert_type(p.x, int)
assert_type(p.units, str)

Like normal tuples, elements of a named tuple can also be accessed by index,
and type checkers should support this::

assert_type(p[0], int)
assert_type(p[2], str)

Type checkers should enforce that named tuple fields cannot be overwritten
or deleted::

p.x = 3 # Type error
p[0] = 3 # Type error
del p.x # Type error
del p[0] # Type error

Like regular tuples, named tuples can be unpacked. Type checkers should understand
this::

x, y, units = p
assert_type(x, int)
assert_type(units, str)

x, y = p # Type error (too few values to unpack)


Type Compatibility Rules
------------------------

A named tuple is a subtype of a ``tuple`` with a known length and parameterized
by types corresponding to the named tuple's individual field types::

p = Point(x=1, y=2, units="inches")
v1: tuple[int, int, str] = p # OK
v2: tuple[Any, ...] = p # OK
v3: tuple[int, int] = p # Type error (too few elements)
v4: tuple[int, str, str] = p # Type error (incompatible element type)

As with normal tuples, named tuples are covariant in their type parameters::

v5: tuple[float, float, str] = p # OK
4 changes: 4 additions & 0 deletions docs/spec/narrowing.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
.. _`type-narrowing`:

Type narrowing
==============

Type checkers should narrow the types of expressions in
certain contexts. This behavior is currently largely unspecified.

.. _`typeguard`:

TypeGuard
---------

Expand Down
2 changes: 2 additions & 0 deletions docs/spec/protocol.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _protocols:

Protocols
---------

Expand Down

0 comments on commit ca65a3d

Please sign in to comment.