diff --git a/pyproject.toml b/pyproject.toml index 819895fa8f6cf7f6a4a4adbfbe1e6b1d0e7ca972..6e245635cdb31a26b7b061b96ddbed5611907f5f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,6 +113,8 @@ lines-after-imports = 2 python_version = "3.8" ignore_missing_imports = true warn_unused_ignores = true +# TODO: enable this at some point +# check_untyped_defs = true [tool.typos.default] extend-ignore-re = [ diff --git a/pytools/__init__.py b/pytools/__init__.py index 08c3ed1adf549055fb839bb0050c9331c3734668..af4b0fd82d0f62de5ed2c26115b0fce03c1246cc 100644 --- a/pytools/__init__.py +++ b/pytools/__init__.py @@ -32,6 +32,7 @@ import sys from functools import reduce, wraps from sys import intern from typing import ( + TYPE_CHECKING, Any, Callable, ClassVar, @@ -52,15 +53,21 @@ from typing import ( ) -try: - from typing import Concatenate, SupportsIndex -except ImportError: - from typing_extensions import Concatenate, SupportsIndex +if TYPE_CHECKING: + # NOTE: mypy seems to be confused by the `try.. except` below when called with + # python -m mypy --python-version 3.8 ... + # see https://github.com/python/mypy/issues/14220 + from typing_extensions import Concatenate, ParamSpec, SupportsIndex +else: + try: + from typing import Concatenate, SupportsIndex + except ImportError: + from typing_extensions import Concatenate, SupportsIndex -try: - from typing import ParamSpec -except ImportError: - from typing_extensions import ParamSpec # type: ignore[assignment] + try: + from typing import ParamSpec + except ImportError: + from typing_extensions import ParamSpec # type: ignore[assignment] # These are deprecated and will go away in 2022. diff --git a/pytools/convergence.py b/pytools/convergence.py index aa85c2014f9dfd5367a10d45bfca8f377a0ea295..4ad5d9219bae5822f4ff931977c13f513de85d6f 100644 --- a/pytools/convergence.py +++ b/pytools/convergence.py @@ -75,7 +75,7 @@ class EOCRecorder: gliding_mean = size data_points = size - gliding_mean + 1 - result = np.zeros((data_points, 2), float) + result: np.ndarray = np.zeros((data_points, 2), float) for i in range(data_points): result[i, 0], result[i, 1] = estimate_order_of_convergence( abscissae[i:i+gliding_mean], errors[i:i+gliding_mean]) diff --git a/pytools/graph.py b/pytools/graph.py index f500805997a8f5593b96f8a699a8fa2cdf3610a1..91f2bffa7a2096d10a46d76b7dbacd22f0b57a4c 100644 --- a/pytools/graph.py +++ b/pytools/graph.py @@ -66,6 +66,7 @@ Type Variables Used from dataclasses import dataclass from typing import ( + TYPE_CHECKING, Any, Callable, Collection, @@ -83,10 +84,16 @@ from typing import ( ) -try: - from typing import TypeAlias -except ImportError: +if TYPE_CHECKING: + # NOTE: mypy seems to be confused by the `try.. except` below when called with + # python -m mypy --python-version 3.8 ... + # see https://github.com/python/mypy/issues/14220 from typing_extensions import TypeAlias +else: + try: + from typing import TypeAlias + except ImportError: + from typing_extensions import TypeAlias NodeT = TypeVar("NodeT", bound=Hashable) diff --git a/pytools/persistent_dict.py b/pytools/persistent_dict.py index bd86a0c5c4f370ff682f7da4f198ecd816b3f729..8ba7074f8673a1114c1ce5b25a67faf7e26d7a32 100644 --- a/pytools/persistent_dict.py +++ b/pytools/persistent_dict.py @@ -77,6 +77,10 @@ else: logger = logging.getLogger(__name__) +# NOTE: not always available so they get hardcoded here +SQLITE_BUSY = getattr(sqlite3, "SQLITE_BUSY", 5) +SQLITE_CONSTRAINT_PRIMARYKEY = getattr(sqlite3, "SQLITE_CONSTRAINT_PRIMARYKEY", 1555) + __doc__ = """ Persistent Hashing and Persistent Dictionaries ============================================== @@ -574,7 +578,7 @@ class _PersistentDictBase(Mapping[K, V]): except sqlite3.OperationalError as e: # If the database is busy, retry if (hasattr(e, "sqlite_errorcode") - and not e.sqlite_errorcode == sqlite3.SQLITE_BUSY): + and e.sqlite_errorcode != SQLITE_BUSY): raise if n % 20 == 0: warn(f"PersistentDict: database '{self.filename}' busy, {n} " @@ -721,7 +725,7 @@ class WriteOncePersistentDict(_PersistentDictBase[K, V]): self._exec_sql("INSERT INTO dict VALUES (?, ?)", (keyhash, v)) except sqlite3.IntegrityError as e: if hasattr(e, "sqlite_errorcode"): - if e.sqlite_errorcode == sqlite3.SQLITE_CONSTRAINT_PRIMARYKEY: + if e.sqlite_errorcode == SQLITE_CONSTRAINT_PRIMARYKEY: raise ReadOnlyEntryError("WriteOncePersistentDict, " "tried overwriting key") from e else: diff --git a/pytools/test/test_pytools.py b/pytools/test/test_pytools.py index 07b59a9ce1b2996ee94d791630ac8bb04aaacbdf..c6f6fda482b6a9b4070760b6eb668190e839a9c2 100644 --- a/pytools/test/test_pytools.py +++ b/pytools/test/test_pytools.py @@ -497,7 +497,7 @@ def test_obj_array_vectorize(c=1): # }}} -def test_tag(): +def test_tag() -> None: from pytools.tag import ( NonUniqueTagError, Tag, @@ -552,7 +552,7 @@ def test_tag(): # a subclass of Tag with pytest.raises(TypeError): check_tag_uniqueness(frozenset(( - "I am not a tag", best_in_show_ribbon, + "I am not a tag", best_in_show_ribbon, # type: ignore[arg-type] blue_ribbon, red_ribbon))) # Test that instantiation succeeds if there are multiple instances @@ -583,7 +583,7 @@ def test_tag(): # Test that tagged() fails if tags are not a FrozenSet of Tags with pytest.raises(TypeError): - t1.tagged(tags=frozenset((1,))) + t1.tagged(tags=frozenset((1,))) # type: ignore[arg-type] # Test without_tags() function t4 = t2.without_tags(red_ribbon)