From e816acffddf9d984bac131224b0eb0f6a3e1c9fc Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Mon, 1 May 2023 15:50:50 +0100 Subject: [PATCH] Avoid unnecessary forward refs in class definitions (#10124) --- stdlib/enum.pyi | 56 +++++------ stdlib/multiprocessing/synchronize.pyi | 20 ++-- stdlib/sqlite3/dbapi2.pyi | 5 +- .../SQLAlchemy/sqlalchemy/sql/annotation.pyi | 20 ++-- stubs/setuptools/pkg_resources/__init__.pyi | 96 +++++++++---------- 5 files changed, 98 insertions(+), 99 deletions(-) diff --git a/stdlib/enum.pyi b/stdlib/enum.pyi index 5a39c456b..383c336ed 100644 --- a/stdlib/enum.pyi +++ b/stdlib/enum.pyi @@ -208,13 +208,6 @@ def unique(enumeration: _EnumerationT) -> _EnumerationT: ... _auto_null: Any -# subclassing IntFlag so it picks up all implemented base functions, best modeling behavior of enum.auto() -class auto(IntFlag): - _value_: Any - @_magic_enum_attr - def value(self) -> Any: ... - def __new__(cls) -> Self: ... - class Flag(Enum): _name_: str | None # type: ignore[assignment] _value_: int @@ -235,27 +228,6 @@ class Flag(Enum): __rand__ = __and__ __rxor__ = __xor__ -if sys.version_info >= (3, 11): - # The body of the class is the same, but the base classes are different. - class IntFlag(int, ReprEnum, Flag, boundary=KEEP): # type: ignore[misc] # complaints about incompatible bases - def __new__(cls, value: int) -> Self: ... - def __or__(self, other: int) -> Self: ... - def __and__(self, other: int) -> Self: ... - def __xor__(self, other: int) -> Self: ... - __ror__ = __or__ - __rand__ = __and__ - __rxor__ = __xor__ - -else: - class IntFlag(int, Flag): # type: ignore[misc] # complaints about incompatible bases - def __new__(cls, value: int) -> Self: ... - def __or__(self, other: int) -> Self: ... - def __and__(self, other: int) -> Self: ... - def __xor__(self, other: int) -> Self: ... - __ror__ = __or__ - __rand__ = __and__ - __rxor__ = __xor__ - if sys.version_info >= (3, 11): class StrEnum(str, ReprEnum): def __new__(cls, value: str) -> Self: ... @@ -289,3 +261,31 @@ if sys.version_info >= (3, 11): def global_enum(cls: _EnumerationT, update_str: bool = False) -> _EnumerationT: ... def global_enum_repr(self: Enum) -> str: ... def global_flag_repr(self: Flag) -> str: ... + +if sys.version_info >= (3, 11): + # The body of the class is the same, but the base classes are different. + class IntFlag(int, ReprEnum, Flag, boundary=KEEP): # type: ignore[misc] # complaints about incompatible bases + def __new__(cls, value: int) -> Self: ... + def __or__(self, other: int) -> Self: ... + def __and__(self, other: int) -> Self: ... + def __xor__(self, other: int) -> Self: ... + __ror__ = __or__ + __rand__ = __and__ + __rxor__ = __xor__ + +else: + class IntFlag(int, Flag): # type: ignore[misc] # complaints about incompatible bases + def __new__(cls, value: int) -> Self: ... + def __or__(self, other: int) -> Self: ... + def __and__(self, other: int) -> Self: ... + def __xor__(self, other: int) -> Self: ... + __ror__ = __or__ + __rand__ = __and__ + __rxor__ = __xor__ + +# subclassing IntFlag so it picks up all implemented base functions, best modeling behavior of enum.auto() +class auto(IntFlag): + _value_: Any + @_magic_enum_attr + def value(self) -> Any: ... + def __new__(cls) -> Self: ... diff --git a/stdlib/multiprocessing/synchronize.pyi b/stdlib/multiprocessing/synchronize.pyi index 6c2e18954..a4e36cfa0 100644 --- a/stdlib/multiprocessing/synchronize.pyi +++ b/stdlib/multiprocessing/synchronize.pyi @@ -14,9 +14,6 @@ class Barrier(threading.Barrier): self, parties: int, action: Callable[[], object] | None = None, timeout: float | None = None, *ctx: BaseContext ) -> None: ... -class BoundedSemaphore(Semaphore): - def __init__(self, value: int = 1, *, ctx: BaseContext) -> None: ... - class Condition(AbstractContextManager[bool]): def __init__(self, lock: _LockLike | None = None, *, ctx: BaseContext) -> None: ... def notify(self, n: int = 1) -> None: ... @@ -36,6 +33,14 @@ class Event: def clear(self) -> None: ... def wait(self, timeout: float | None = None) -> bool: ... +# Not part of public API +class SemLock(AbstractContextManager[bool]): + def acquire(self, block: bool = ..., timeout: float | None = ...) -> bool: ... + def release(self) -> None: ... + def __exit__( + self, __exc_type: type[BaseException] | None, __exc_val: BaseException | None, __exc_tb: TracebackType | None + ) -> None: ... + class Lock(SemLock): def __init__(self, *, ctx: BaseContext) -> None: ... @@ -45,10 +50,5 @@ class RLock(SemLock): class Semaphore(SemLock): def __init__(self, value: int = 1, *, ctx: BaseContext) -> None: ... -# Not part of public API -class SemLock(AbstractContextManager[bool]): - def acquire(self, block: bool = ..., timeout: float | None = ...) -> bool: ... - def release(self) -> None: ... - def __exit__( - self, __exc_type: type[BaseException] | None, __exc_val: BaseException | None, __exc_tb: TracebackType | None - ) -> None: ... +class BoundedSemaphore(Semaphore): + def __init__(self, value: int = 1, *, ctx: BaseContext) -> None: ... diff --git a/stdlib/sqlite3/dbapi2.pyi b/stdlib/sqlite3/dbapi2.pyi index 372c7e3f4..24974f787 100644 --- a/stdlib/sqlite3/dbapi2.pyi +++ b/stdlib/sqlite3/dbapi2.pyi @@ -390,14 +390,13 @@ class Cursor(Iterator[Any]): def __iter__(self) -> Self: ... def __next__(self) -> Any: ... -class DataError(DatabaseError): ... -class DatabaseError(Error): ... - class Error(Exception): if sys.version_info >= (3, 11): sqlite_errorcode: int sqlite_errorname: str +class DatabaseError(Error): ... +class DataError(DatabaseError): ... class IntegrityError(DatabaseError): ... class InterfaceError(Error): ... class InternalError(DatabaseError): ... diff --git a/stubs/SQLAlchemy/sqlalchemy/sql/annotation.pyi b/stubs/SQLAlchemy/sqlalchemy/sql/annotation.pyi index cb5717f07..38c963023 100644 --- a/stubs/SQLAlchemy/sqlalchemy/sql/annotation.pyi +++ b/stubs/SQLAlchemy/sqlalchemy/sql/annotation.pyi @@ -118,9 +118,15 @@ annotated_classes: dict[Incomplete, Incomplete] # Everything below is dynamically generated at runtime -class AnnotatedAlias(AnnotatedAliasedReturnsRows, Alias): ... +class AnnotatedFromClause(_SelectableAnnotatedFromClause, FromClause): ... class AnnotatedAliasedReturnsRows(AnnotatedFromClause, AliasedReturnsRows): ... +class AnnotatedAlias(AnnotatedAliasedReturnsRows, Alias): ... +class AnnotatedColumnElement(_ElementsAnnotatedColumnElement, ColumnElement[_T]): ... +class AnnotatedFunctionElement(AnnotatedColumnElement[_T], FunctionElement): ... # type: ignore[misc] +class AnnotatedFunction(AnnotatedFunctionElement[_T], Function): ... # type: ignore[misc] +class AnnotatedGenericFunction(AnnotatedFunction[_T], GenericFunction): ... # type: ignore[misc] class AnnotatedAnsiFunction(AnnotatedGenericFunction[_T], AnsiFunction): ... # type: ignore[misc] +class AnnotatedUnaryExpression(AnnotatedColumnElement[_T], UnaryExpression): ... class AnnotatedAsBoolean(AnnotatedUnaryExpression[_T], AsBoolean): ... class AnnotatedBinaryExpression(AnnotatedColumnElement[_T], BinaryExpression): ... class AnnotatedBindParameter(AnnotatedColumnElement[_T], BindParameter[_T]): ... @@ -131,25 +137,20 @@ class AnnotatedCast(AnnotatedColumnElement[_T], Cast): ... class AnnotatedClauseList(Annotated, ClauseList): ... class AnnotatedCollationClause(AnnotatedColumnElement[_T], CollationClause): ... class AnnotatedCollectionAggregate(AnnotatedUnaryExpression[_T], CollectionAggregate): ... -class AnnotatedColumn(AnnotatedColumnClause[_T], Column): ... +class AnnotatedNamedColumn(AnnotatedColumnElement[_T], NamedColumn): ... class AnnotatedColumnClause(AnnotatedNamedColumn[_T], ColumnClause): ... -class AnnotatedColumnElement(_ElementsAnnotatedColumnElement, ColumnElement[_T]): ... +class AnnotatedColumn(AnnotatedColumnClause[_T], Column): ... class AnnotatedExists(AnnotatedUnaryExpression[_T], Exists): ... class AnnotatedExtract(AnnotatedColumnElement[_T], Extract): ... class AnnotatedFalse_(AnnotatedColumnElement[_T], False_): ... -class AnnotatedFromClause(_SelectableAnnotatedFromClause, FromClause): ... class AnnotatedFromGrouping(AnnotatedFromClause, FromGrouping): ... -class AnnotatedFunction(AnnotatedFunctionElement[_T], Function): ... # type: ignore[misc] class AnnotatedFunctionAsBinary(AnnotatedBinaryExpression[_T], FunctionAsBinary): ... -class AnnotatedFunctionElement(AnnotatedColumnElement[_T], FunctionElement): ... # type: ignore[misc] class AnnotatedFunctionFilter(AnnotatedColumnElement[_T], FunctionFilter): ... -class AnnotatedGenericFunction(AnnotatedFunction[_T], GenericFunction): ... # type: ignore[misc] class AnnotatedGrouping(AnnotatedColumnElement[_T], Grouping): ... class AnnotatedIndexExpression(AnnotatedBinaryExpression[_T], IndexExpression): ... class AnnotatedJoin(AnnotatedFromClause, Join): ... class AnnotatedLabel(AnnotatedColumnElement[_T], Label): ... class AnnotatedLateral(AnnotatedAliasedReturnsRows, Lateral): ... -class AnnotatedNamedColumn(AnnotatedColumnElement[_T], NamedColumn): ... class AnnotatedNull(AnnotatedColumnElement[_T], Null): ... class AnnotatedOrderedSetAgg(AnnotatedGenericFunction[_T], OrderedSetAgg): ... # type: ignore[misc] class AnnotatedOver(AnnotatedColumnElement[_T], Over): ... @@ -158,15 +159,14 @@ class AnnotatedScalarFunctionColumn(AnnotatedNamedColumn[_T], ScalarFunctionColu class AnnotatedScalarSelect(AnnotatedGrouping[_T], ScalarSelect): ... class AnnotatedSlice(AnnotatedColumnElement[_T], Slice): ... class AnnotatedSubquery(AnnotatedAliasedReturnsRows, Subquery): ... -class AnnotatedTable(AnnotatedTableClause, Table): ... class AnnotatedTableClause(AnnotatedFromClause, TableClause): ... +class AnnotatedTable(AnnotatedTableClause, Table): ... class AnnotatedTableSample(AnnotatedAliasedReturnsRows, TableSample): ... class AnnotatedTableValuedAlias(AnnotatedAlias, TableValuedAlias): ... class AnnotatedTableValuedColumn(AnnotatedNamedColumn[_T], TableValuedColumn): ... class AnnotatedTrue_(AnnotatedColumnElement[_T], True_): ... class AnnotatedTuple(AnnotatedColumnElement[_T], Tuple): ... class AnnotatedTypeCoerce(AnnotatedColumnElement[_T], TypeCoerce): ... -class AnnotatedUnaryExpression(AnnotatedColumnElement[_T], UnaryExpression): ... class AnnotatedValues(AnnotatedFromClause, Values): ... class AnnotatedWithinGroup(AnnotatedColumnElement[_T], WithinGroup): ... class Annotated_CompileLabel(AnnotatedColumnElement[_T], _CompileLabel): ... diff --git a/stubs/setuptools/pkg_resources/__init__.pyi b/stubs/setuptools/pkg_resources/__init__.pyi index df0fa6aca..2188c0078 100644 --- a/stubs/setuptools/pkg_resources/__init__.pyi +++ b/stubs/setuptools/pkg_resources/__init__.pyi @@ -73,10 +73,6 @@ class Environment: def obtain(self, requirement: Requirement, installer: Callable[[Requirement], _T]) -> _T: ... def scan(self, search_path: Sequence[str] | None = None) -> None: ... -class DistInfoDistribution(Distribution): - PKG_INFO: ClassVar[Literal["METADATA"]] - EQEQ: ClassVar[Pattern[str]] - def parse_requirements(strs: str | Iterable[str]) -> Generator[Requirement, None, None]: ... class Requirement: @@ -133,50 +129,6 @@ def get_distribution(dist: _D) -> _D: ... @overload def get_distribution(dist: _PkgReqType) -> Distribution: ... -class Distribution(NullProvider, IResourceProvider, IMetadataProvider): - PKG_INFO: ClassVar[str] - location: str - project_name: str - @property - def key(self) -> str: ... - @property - def extras(self) -> list[str]: ... - @property - def version(self) -> str: ... - @property - def parsed_version(self) -> tuple[str, ...]: ... - py_version: str - platform: str | None - precedence: int - def __init__( - self, - location: str | None = None, - metadata: _MetadataType = None, - project_name: str | None = None, - version: str | None = None, - py_version: str = ..., - platform: str | None = None, - precedence: int = 3, - ) -> None: ... - @classmethod - def from_location( - cls, location: str, basename: str, metadata: _MetadataType = None, **kw: str | None | int - ) -> Distribution: ... - @classmethod - def from_filename(cls, filename: str, metadata: _MetadataType = None, **kw: str | None | int) -> Distribution: ... - def activate(self, path: list[str] | None = None) -> None: ... - def as_requirement(self) -> Requirement: ... - def requires(self, extras: tuple[str, ...] = ()) -> list[Requirement]: ... - def clone(self, **kw: str | int | None) -> Requirement: ... - def egg_name(self) -> str: ... # type: ignore[override] # supertype's egg_name is a variable, not a method - def __cmp__(self, other: Any) -> bool: ... - def get_entry_info(self, group: str, name: str) -> EntryPoint | None: ... - @overload - def get_entry_map(self) -> dict[str, dict[str, EntryPoint]]: ... - @overload - def get_entry_map(self, group: str) -> dict[str, EntryPoint]: ... - def load_entry_point(self, group: str, name: str) -> Any: ... - EGG_DIST: int BINARY_DIST: int SOURCE_DIST: int @@ -276,6 +228,54 @@ class NullProvider: def metadata_listdir(self, name: str) -> list[str]: ... def run_script(self, script_name: str, namespace: dict[str, Any]) -> None: ... +class Distribution(NullProvider, IResourceProvider, IMetadataProvider): + PKG_INFO: ClassVar[str] + location: str + project_name: str + @property + def key(self) -> str: ... + @property + def extras(self) -> list[str]: ... + @property + def version(self) -> str: ... + @property + def parsed_version(self) -> tuple[str, ...]: ... + py_version: str + platform: str | None + precedence: int + def __init__( + self, + location: str | None = None, + metadata: _MetadataType = None, + project_name: str | None = None, + version: str | None = None, + py_version: str = ..., + platform: str | None = None, + precedence: int = 3, + ) -> None: ... + @classmethod + def from_location( + cls, location: str, basename: str, metadata: _MetadataType = None, **kw: str | None | int + ) -> Distribution: ... + @classmethod + def from_filename(cls, filename: str, metadata: _MetadataType = None, **kw: str | None | int) -> Distribution: ... + def activate(self, path: list[str] | None = None) -> None: ... + def as_requirement(self) -> Requirement: ... + def requires(self, extras: tuple[str, ...] = ()) -> list[Requirement]: ... + def clone(self, **kw: str | int | None) -> Requirement: ... + def egg_name(self) -> str: ... # type: ignore[override] # supertype's egg_name is a variable, not a method + def __cmp__(self, other: Any) -> bool: ... + def get_entry_info(self, group: str, name: str) -> EntryPoint | None: ... + @overload + def get_entry_map(self) -> dict[str, dict[str, EntryPoint]]: ... + @overload + def get_entry_map(self, group: str) -> dict[str, EntryPoint]: ... + def load_entry_point(self, group: str, name: str) -> Any: ... + +class DistInfoDistribution(Distribution): + PKG_INFO: ClassVar[Literal["METADATA"]] + EQEQ: ClassVar[Pattern[str]] + class EggProvider(NullProvider): egg_root: str