From 7f563ff927917aa112a67b116ee3588c92d5b09f Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Wed, 5 Jan 2022 08:51:11 +0000 Subject: [PATCH 1/2] `_typeshed.structseq`: Use `Final` instead of `ClassVar` As discussed in https://github.com/python/typeshed/pull/6816, for some `structseq` classes these attributes are writeable `ClassVar`s, but for other classes, they're read-only `ClassVar`s. Either way, however, it's probably a bad idea to be modifying these attributes, so it makes sense to simply annotate them with `Final` rather than `ClassVar`. Note that [PEP 591](https://www.python.org/dev/peps/pep-0591/) specifically states: > Type checkers should infer a final attribute that is initialized in a class body as being a class variable. Variables should not be annotated with both ClassVar and Final. As such, annotating these attributes as `Final[ClassVar[int]]` would be neither necessary nor possible. --- stdlib/_typeshed/__init__.pyi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/stdlib/_typeshed/__init__.pyi b/stdlib/_typeshed/__init__.pyi index a7f8c5147103..7650a9f62630 100644 --- a/stdlib/_typeshed/__init__.pyi +++ b/stdlib/_typeshed/__init__.pyi @@ -7,8 +7,8 @@ import ctypes import mmap import sys from os import PathLike -from typing import AbstractSet, Any, Awaitable, ClassVar, Container, Generic, Iterable, Protocol, Type, TypeVar, Union -from typing_extensions import Literal, final +from typing import AbstractSet, Any, Awaitable, Container, Generic, Iterable, Protocol, Type, TypeVar, Union +from typing_extensions import Literal, Final, final _KT = TypeVar("_KT") _KT_co = TypeVar("_KT_co", covariant=True) @@ -206,9 +206,9 @@ else: # See discussion at #6546 & #6560 # `structseq` classes are unsubclassable, so are all decorated with `@final`. class structseq(Generic[_T_co]): - n_fields: ClassVar[int] - n_unnamed_fields: ClassVar[int] - n_sequence_fields: ClassVar[int] + n_fields: Final[int] + n_unnamed_fields: Final[int] + n_sequence_fields: Final[int] # The first parameter will generally only take an iterable of a specific length. # E.g. `os.uname_result` takes any iterable of length exactly 5. # From 11b24fed07703501ac6a2faa50e17408c622f847 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 5 Jan 2022 08:52:34 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/_typeshed/__init__.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/_typeshed/__init__.pyi b/stdlib/_typeshed/__init__.pyi index 7650a9f62630..c52f3e0dad57 100644 --- a/stdlib/_typeshed/__init__.pyi +++ b/stdlib/_typeshed/__init__.pyi @@ -8,7 +8,7 @@ import mmap import sys from os import PathLike from typing import AbstractSet, Any, Awaitable, Container, Generic, Iterable, Protocol, Type, TypeVar, Union -from typing_extensions import Literal, Final, final +from typing_extensions import Final, Literal, final _KT = TypeVar("_KT") _KT_co = TypeVar("_KT_co", covariant=True)