From 1c08e1aa7db07061078d2c1bae341597739c5f0c Mon Sep 17 00:00:00 2001 From: Matthias Diener Date: Mon, 1 Apr 2024 14:37:21 -0500 Subject: [PATCH 1/2] type-annotate Record --- pytools/__init__.py | 32 +++++++++++++++----------------- pytools/datatable.py | 3 +-- run-mypy.sh | 4 ++-- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/pytools/__init__.py b/pytools/__init__.py index 0f452a80..62fc22e9 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -35,7 +35,7 @@ import sys from functools import reduce, wraps from sys import intern -from typing import ( +from typing import (cast, Any, Callable, ClassVar, Dict, Generic, Hashable, Iterable, Iterator, List, Mapping, Optional, Sequence, Set, Tuple, Type, TypeVar, Union) @@ -413,7 +413,8 @@ class RecordWithoutPickling: __slots__: ClassVar[List[str]] = [] fields: ClassVar[Set[str]] - def __init__(self, valuedict=None, exclude=None, **kwargs): + def __init__(self, valuedict: Optional[Dict[str, Any]] = None, + exclude: Optional[List[str]] = None, **kwargs: Any) -> None: assert self.__class__ is not Record if exclude is None: @@ -432,7 +433,7 @@ def __init__(self, valuedict=None, exclude=None, **kwargs): fields.add(key) setattr(self, key, value) - def get_copy_kwargs(self, **kwargs): + def get_copy_kwargs(self, **kwargs: Any) -> Dict[str, Any]: for f in self.__class__.fields: if f not in kwargs: try: @@ -441,17 +442,17 @@ def get_copy_kwargs(self, **kwargs): pass return kwargs - def copy(self, **kwargs): + def copy(self, **kwargs: Any) -> "RecordWithoutPickling": return self.__class__(**self.get_copy_kwargs(**kwargs)) - def __repr__(self): + def __repr__(self) -> str: return "{}({})".format( self.__class__.__name__, ", ".join(f"{fld}={getattr(self, fld)!r}" for fld in self.__class__.fields if hasattr(self, fld))) - def register_fields(self, new_fields): + def register_fields(self, new_fields: Set[str]) -> None: try: fields = self.__class__.fields except AttributeError: @@ -459,7 +460,7 @@ def register_fields(self, new_fields): fields.update(new_fields) - def __getattr__(self, name): + def __getattr__(self, name: str) -> Any: # This method is implemented to avoid pylint 'no-member' errors for # attribute access. raise AttributeError( @@ -470,13 +471,13 @@ def __getattr__(self, name): class Record(RecordWithoutPickling): __slots__: ClassVar[List[str]] = [] - def __getstate__(self): + def __getstate__(self) -> Dict[str, Any]: return { key: getattr(self, key) for key in self.__class__.fields if hasattr(self, key)} - def __setstate__(self, valuedict): + def __setstate__(self, valuedict: Dict[str, Any]) -> None: try: fields = self.__class__.fields except AttributeError: @@ -486,30 +487,27 @@ def __setstate__(self, valuedict): fields.add(key) setattr(self, key, value) - def __eq__(self, other): + def __eq__(self, other: object) -> bool: if self is other: return True return (self.__class__ == other.__class__ and self.__getstate__() == other.__getstate__()) - def __ne__(self, other): - return not self.__eq__(other) - class ImmutableRecordWithoutPickling(RecordWithoutPickling): """Hashable record. Does not explicitly enforce immutability.""" - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: RecordWithoutPickling.__init__(self, *args, **kwargs) - self._cached_hash = None + self._cached_hash: Optional[int] = None - def __hash__(self): + def __hash__(self) -> int: # This attribute may vanish during pickling. if getattr(self, "_cached_hash", None) is None: self._cached_hash = hash( (type(self),) + tuple(getattr(self, field) for field in self.__class__.fields)) - return self._cached_hash + return cast(int, self._cached_hash) class ImmutableRecord(ImmutableRecordWithoutPickling, Record): diff --git a/pytools/datatable.py b/pytools/datatable.py index 4fcb03e6..2f36e220 100644 --- a/pytools/datatable.py +++ b/pytools/datatable.py @@ -11,8 +11,7 @@ """ -# type-ignore-reason: Record is untyped -class Row(Record): # type: ignore[misc] +class Row(Record): pass diff --git a/run-mypy.sh b/run-mypy.sh index 39055a8c..cb7227d0 100755 --- a/run-mypy.sh +++ b/run-mypy.sh @@ -2,6 +2,6 @@ set -ex -mypy --show-error-codes pytools +mypy pytools -mypy --strict --follow-imports=skip pytools/datatable.py +mypy --strict pytools/datatable.py From 48991829b53f90b4ba3e86cc2a03100b970e1c24 Mon Sep 17 00:00:00 2001 From: Matthias Diener Date: Mon, 1 Apr 2024 14:37:21 -0500 Subject: [PATCH 2/2] type-annotate Record --- pytools/__init__.py | 4 ++-- run-mypy.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pytools/__init__.py b/pytools/__init__.py index 62fc22e9..1487595f 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -35,9 +35,9 @@ import sys from functools import reduce, wraps from sys import intern -from typing import (cast, +from typing import ( Any, Callable, ClassVar, Dict, Generic, Hashable, Iterable, Iterator, List, - Mapping, Optional, Sequence, Set, Tuple, Type, TypeVar, Union) + Mapping, Optional, Sequence, Set, Tuple, Type, TypeVar, Union, cast) try: diff --git a/run-mypy.sh b/run-mypy.sh index cb7227d0..2115e48c 100755 --- a/run-mypy.sh +++ b/run-mypy.sh @@ -4,4 +4,4 @@ set -ex mypy pytools -mypy --strict pytools/datatable.py +mypy --strict --follow-imports=skip pytools/datatable.py