From 88096aca2300fee8d1d0babdb505e1cf50cbea17 Mon Sep 17 00:00:00 2001 From: David Hotham Date: Fri, 4 Aug 2023 14:44:47 +0100 Subject: [PATCH] Misc fixes (#8253) * typo * unnecessary special case * tighten typechecking * mypy 1.4 * handle ast.Str deprecation * keyring 24.0.0 * use requests.utils.atomic_open directly poetry is already using requests, and the docstring for requests.utils indicates that "this module provides utility functions ... that are also useful for external consumption". ie there's no reason copy the code, just use it. --- poetry.lock | 70 ++++++++++---------- pyproject.toml | 2 +- src/poetry/console/commands/group_command.py | 2 +- src/poetry/installation/executor.py | 2 +- src/poetry/json/__init__.py | 5 +- src/poetry/mixology/version_solver.py | 5 +- src/poetry/packages/locker.py | 5 +- src/poetry/repositories/pypi_repository.py | 2 +- src/poetry/utils/helpers.py | 21 +----- src/poetry/utils/setup_reader.py | 42 +++++++----- tests/conftest.py | 2 +- 11 files changed, 72 insertions(+), 86 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1d9584494d8..1b7e44645bd 100644 --- a/poetry.lock +++ b/poetry.lock @@ -683,13 +683,13 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "keyring" -version = "23.13.1" +version = "24.2.0" description = "Store and access your passwords safely." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "keyring-23.13.1-py3-none-any.whl", hash = "sha256:771ed2a91909389ed6148631de678f82ddc73737d85a927f382a8a1b157898cd"}, - {file = "keyring-23.13.1.tar.gz", hash = "sha256:ba2e15a9b35e21908d0aaf4e0a47acc52d6ae33444df0da2b49d41a46ef6d678"}, + {file = "keyring-24.2.0-py3-none-any.whl", hash = "sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6"}, + {file = "keyring-24.2.0.tar.gz", hash = "sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509"}, ] [package.dependencies] @@ -702,8 +702,8 @@ SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} [package.extras] completion = ["shtab"] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [[package]] name = "more-itertools" @@ -790,43 +790,43 @@ files = [ [[package]] name = "mypy" -version = "1.3.0" +version = "1.4.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.7" files = [ - {file = "mypy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eb485cea53f4f5284e5baf92902cd0088b24984f4209e25981cc359d64448d"}, - {file = "mypy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c99c3ecf223cf2952638da9cd82793d8f3c0c5fa8b6ae2b2d9ed1e1ff51ba85"}, - {file = "mypy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:550a8b3a19bb6589679a7c3c31f64312e7ff482a816c96e0cecec9ad3a7564dd"}, - {file = "mypy-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cbc07246253b9e3d7d74c9ff948cd0fd7a71afcc2b77c7f0a59c26e9395cb152"}, - {file = "mypy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:a22435632710a4fcf8acf86cbd0d69f68ac389a3892cb23fbad176d1cddaf228"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e33bb8b2613614a33dff70565f4c803f889ebd2f859466e42b46e1df76018dd"}, - {file = "mypy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d23370d2a6b7a71dc65d1266f9a34e4cde9e8e21511322415db4b26f46f6b8c"}, - {file = "mypy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658fe7b674769a0770d4b26cb4d6f005e88a442fe82446f020be8e5f5efb2fae"}, - {file = "mypy-1.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d29e324cdda61daaec2336c42512e59c7c375340bd202efa1fe0f7b8f8ca"}, - {file = "mypy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:d0b6c62206e04061e27009481cb0ec966f7d6172b5b936f3ead3d74f29fe3dcf"}, - {file = "mypy-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:76ec771e2342f1b558c36d49900dfe81d140361dd0d2df6cd71b3db1be155409"}, - {file = "mypy-1.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc95f8386314272bbc817026f8ce8f4f0d2ef7ae44f947c4664efac9adec929"}, - {file = "mypy-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:faff86aa10c1aa4a10e1a301de160f3d8fc8703b88c7e98de46b531ff1276a9a"}, - {file = "mypy-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8c5979d0deb27e0f4479bee18ea0f83732a893e81b78e62e2dda3e7e518c92ee"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c5d2cc54175bab47011b09688b418db71403aefad07cbcd62d44010543fc143f"}, - {file = "mypy-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87df44954c31d86df96c8bd6e80dfcd773473e877ac6176a8e29898bfb3501cb"}, - {file = "mypy-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:473117e310febe632ddf10e745a355714e771ffe534f06db40702775056614c4"}, - {file = "mypy-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:74bc9b6e0e79808bf8678d7678b2ae3736ea72d56eede3820bd3849823e7f305"}, - {file = "mypy-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:44797d031a41516fcf5cbfa652265bb994e53e51994c1bd649ffcd0c3a7eccbf"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ddae0f39ca146972ff6bb4399f3b2943884a774b8771ea0a8f50e971f5ea5ba8"}, - {file = "mypy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c4c42c60a8103ead4c1c060ac3cdd3ff01e18fddce6f1016e08939647a0e703"}, - {file = "mypy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e86c2c6852f62f8f2b24cb7a613ebe8e0c7dc1402c61d36a609174f63e0ff017"}, - {file = "mypy-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f9dca1e257d4cc129517779226753dbefb4f2266c4eaad610fc15c6a7e14283e"}, - {file = "mypy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:95d8d31a7713510685b05fbb18d6ac287a56c8f6554d88c19e73f724a445448a"}, - {file = "mypy-1.3.0-py3-none-any.whl", hash = "sha256:a8763e72d5d9574d45ce5881962bc8e9046bf7b375b0abf031f3e6811732a897"}, - {file = "mypy-1.3.0.tar.gz", hash = "sha256:e1f4d16e296f5135624b34e8fb741eb0eadedca90862405b1f1fde2040b9bd11"}, + {file = "mypy-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:566e72b0cd6598503e48ea610e0052d1b8168e60a46e0bfd34b3acf2d57f96a8"}, + {file = "mypy-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca637024ca67ab24a7fd6f65d280572c3794665eaf5edcc7e90a866544076878"}, + {file = "mypy-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dde1d180cd84f0624c5dcaaa89c89775550a675aff96b5848de78fb11adabcd"}, + {file = "mypy-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c4d8e89aa7de683e2056a581ce63c46a0c41e31bd2b6d34144e2c80f5ea53dc"}, + {file = "mypy-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:bfdca17c36ae01a21274a3c387a63aa1aafe72bff976522886869ef131b937f1"}, + {file = "mypy-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7549fbf655e5825d787bbc9ecf6028731973f78088fbca3a1f4145c39ef09462"}, + {file = "mypy-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98324ec3ecf12296e6422939e54763faedbfcc502ea4a4c38502082711867258"}, + {file = "mypy-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141dedfdbfe8a04142881ff30ce6e6653c9685b354876b12e4fe6c78598b45e2"}, + {file = "mypy-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8207b7105829eca6f3d774f64a904190bb2231de91b8b186d21ffd98005f14a7"}, + {file = "mypy-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:16f0db5b641ba159eff72cff08edc3875f2b62b2fa2bc24f68c1e7a4e8232d01"}, + {file = "mypy-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:470c969bb3f9a9efcedbadcd19a74ffb34a25f8e6b0e02dae7c0e71f8372f97b"}, + {file = "mypy-1.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5952d2d18b79f7dc25e62e014fe5a23eb1a3d2bc66318df8988a01b1a037c5b"}, + {file = "mypy-1.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:190b6bab0302cec4e9e6767d3eb66085aef2a1cc98fe04936d8a42ed2ba77bb7"}, + {file = "mypy-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9d40652cc4fe33871ad3338581dca3297ff5f2213d0df345bcfbde5162abf0c9"}, + {file = "mypy-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01fd2e9f85622d981fd9063bfaef1aed6e336eaacca00892cd2d82801ab7c042"}, + {file = "mypy-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2460a58faeea905aeb1b9b36f5065f2dc9a9c6e4c992a6499a2360c6c74ceca3"}, + {file = "mypy-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2746d69a8196698146a3dbe29104f9eb6a2a4d8a27878d92169a6c0b74435b6"}, + {file = "mypy-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae704dcfaa180ff7c4cfbad23e74321a2b774f92ca77fd94ce1049175a21c97f"}, + {file = "mypy-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:43d24f6437925ce50139a310a64b2ab048cb2d3694c84c71c3f2a1626d8101dc"}, + {file = "mypy-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c482e1246726616088532b5e964e39765b6d1520791348e6c9dc3af25b233828"}, + {file = "mypy-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43b592511672017f5b1a483527fd2684347fdffc041c9ef53428c8dc530f79a3"}, + {file = "mypy-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34a9239d5b3502c17f07fd7c0b2ae6b7dd7d7f6af35fbb5072c6208e76295816"}, + {file = "mypy-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5703097c4936bbb9e9bce41478c8d08edd2865e177dc4c52be759f81ee4dd26c"}, + {file = "mypy-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e02d700ec8d9b1859790c0475df4e4092c7bf3272a4fd2c9f33d87fac4427b8f"}, + {file = "mypy-1.4.1-py3-none-any.whl", hash = "sha256:45d32cec14e7b97af848bddd97d85ea4f0db4d5a149ed9676caa4eb2f7402bb4"}, + {file = "mypy-1.4.1.tar.gz", hash = "sha256:9bbcd9ab8ea1f2e1c8031c21445b511442cc45c89951e49bbf852cbb70755b1b"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=3.10" +typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] @@ -1662,4 +1662,4 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "2.0" python-versions = "^3.8" -content-hash = "05ea5cbcfebb28782eccca523686f8bd970cbfb8c8ab0c1f5b13689174f875df" +content-hash = "32ec1d1a5741248581cecdf2bac8f04bc23fba8b8e6de9fe72cadfd873528af9" diff --git a/pyproject.toml b/pyproject.toml index 4776b608705..4632af7ccb2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,7 @@ importlib-metadata = { version = ">=4.4", python = "<3.10" } installer = "^0.7.0" # jsonschema 4.18 uses Rust-based libraries which causes issues when building from source jsonschema = ">=4.10.0,<4.18.0" -keyring = "^23.9.0" +keyring = "^24.0.0" # packaging uses calver, so version is unclamped packaging = ">=20.4" pexpect = "^4.7.0" diff --git a/src/poetry/console/commands/group_command.py b/src/poetry/console/commands/group_command.py index 88b9a1ce39a..c080dc1e5e1 100644 --- a/src/poetry/console/commands/group_command.py +++ b/src/poetry/console/commands/group_command.py @@ -113,7 +113,7 @@ def project_with_activated_groups_only(self) -> ProjectPackage: def _validate_group_options(self, group_options: dict[str, set[str]]) -> None: """ - Raises en error if it detects that a group is not part of pyproject.toml + Raises an error if it detects that a group is not part of pyproject.toml """ invalid_options = defaultdict(set) for opt, groups in group_options.items(): diff --git a/src/poetry/installation/executor.py b/src/poetry/installation/executor.py index 33bc924dfc0..4103da299f0 100644 --- a/src/poetry/installation/executor.py +++ b/src/poetry/installation/executor.py @@ -16,6 +16,7 @@ from cleo.io.null_io import NullIO from poetry.core.packages.utils.link import Link +from requests.utils import atomic_open from poetry.installation.chef import Chef from poetry.installation.chef import ChefBuildError @@ -29,7 +30,6 @@ from poetry.utils.authenticator import Authenticator from poetry.utils.cache import ArtifactCache from poetry.utils.env import EnvCommandError -from poetry.utils.helpers import atomic_open from poetry.utils.helpers import get_file_hash from poetry.utils.helpers import pluralize from poetry.utils.helpers import remove_directory diff --git a/src/poetry/json/__init__.py b/src/poetry/json/__init__.py index 3cabdcf69e4..06ee0102d86 100644 --- a/src/poetry/json/__init__.py +++ b/src/poetry/json/__init__.py @@ -22,10 +22,7 @@ def validate_object(obj: dict[str, Any]) -> list[str]: schema = json.loads(schema_file.read_text(encoding="utf-8")) validator = jsonschema.Draft7Validator(schema) - validation_errors = sorted( - validator.iter_errors(obj), - key=lambda e: e.path, # type: ignore[no-any-return] - ) + validation_errors = sorted(validator.iter_errors(obj), key=lambda e: e.path) errors = [] diff --git a/src/poetry/mixology/version_solver.py b/src/poetry/mixology/version_solver.py index e3c122838d1..b97a4ebed04 100644 --- a/src/poetry/mixology/version_solver.py +++ b/src/poetry/mixology/version_solver.py @@ -474,10 +474,7 @@ def _get_min(dependency: Dependency) -> tuple[bool, int, int]: preference = Preference.DEFAULT return is_specific_marker, preference, num_packages - if len(unsatisfied) == 1: - dependency = unsatisfied[0] - else: - dependency = min(*unsatisfied, key=_get_min) + dependency = min(unsatisfied, key=_get_min) locked = self._provider.get_locked(dependency) if locked is None: diff --git a/src/poetry/packages/locker.py b/src/poetry/packages/locker.py index 69adb802ef6..2031194d492 100644 --- a/src/poetry/packages/locker.py +++ b/src/poetry/packages/locker.py @@ -436,10 +436,7 @@ def _dump_package(self, package: Package) -> dict[str, Any]: "description": package.description or "", "optional": package.optional, "python-versions": package.python_versions, - "files": sorted( - package.files, - key=lambda x: x["file"], # type: ignore[no-any-return] - ), + "files": sorted(package.files, key=lambda x: x["file"]), } if dependencies: diff --git a/src/poetry/repositories/pypi_repository.py b/src/poetry/repositories/pypi_repository.py index 73e8e3eb6b1..cf63e3c37bd 100644 --- a/src/poetry/repositories/pypi_repository.py +++ b/src/poetry/repositories/pypi_repository.py @@ -98,7 +98,7 @@ def _find_packages( return [Package(name, version, yanked=yanked) for version, yanked in versions] - def _get_package_info(self, name: str) -> dict[str, Any]: + def _get_package_info(self, name: NormalizedName) -> dict[str, Any]: headers = {"Accept": "application/vnd.pypi.simple.v1+json"} info = self._get(f"simple/{name}/", headers=headers) if info is None: diff --git a/src/poetry/utils/helpers.py b/src/poetry/utils/helpers.py index ab2f369aa6e..fb14e819079 100644 --- a/src/poetry/utils/helpers.py +++ b/src/poetry/utils/helpers.py @@ -14,13 +14,14 @@ from typing import TYPE_CHECKING from typing import Any +from requests.utils import atomic_open + from poetry.utils.constants import REQUESTS_TIMEOUT if TYPE_CHECKING: from collections.abc import Callable from collections.abc import Iterator - from io import BufferedWriter from poetry.core.packages.package import Package from requests import Session @@ -38,24 +39,6 @@ def directory(path: Path) -> Iterator[Path]: os.chdir(cwd) -@contextmanager -def atomic_open(filename: str | os.PathLike[str]) -> Iterator[BufferedWriter]: - """ - write a file to the disk in an atomic fashion - - Taken from requests.utils - (https://github.com/psf/requests/blob/7104ad4b135daab0ed19d8e41bd469874702342b/requests/utils.py#L296) - """ - tmp_descriptor, tmp_name = tempfile.mkstemp(dir=os.path.dirname(filename)) - try: - with os.fdopen(tmp_descriptor, "wb") as tmp_handler: - yield tmp_handler - os.replace(tmp_name, filename) - except BaseException: - os.remove(tmp_name) - raise - - def _on_rm_error(func: Callable[[str], None], path: str, exc_info: Exception) -> None: if not os.path.exists(path): return diff --git a/src/poetry/utils/setup_reader.py b/src/poetry/utils/setup_reader.py index 53cd5e9e68e..921768722ac 100644 --- a/src/poetry/utils/setup_reader.py +++ b/src/poetry/utils/setup_reader.py @@ -214,15 +214,15 @@ def _find_install_requires(self, call: ast.Call, body: list[ast.stmt]) -> list[s if isinstance(value, ast.List): for el in value.elts: - if isinstance(el, ast.Str): - install_requires.append(el.s) + if isinstance(el, ast.Constant) and isinstance(el.value, str): + install_requires.append(el.value) elif isinstance(value, ast.Name): variable = self._find_variable_in_body(body, value.id) if variable is not None and isinstance(variable, ast.List): for el in variable.elts: - if isinstance(el, ast.Str): - install_requires.append(el.s) + if isinstance(el, ast.Constant) and isinstance(el.value, str): + install_requires.append(el.value) return install_requires @@ -259,15 +259,17 @@ def _find_extras_require( if isinstance(value, ast.Dict): val: ast.expr | None for key, val in zip(value.keys, value.values): - if not isinstance(key, ast.Str): + if not isinstance(key, ast.Constant) or not isinstance(key.value, str): continue if isinstance(val, ast.Name): val = self._find_variable_in_body(body, val.id) if isinstance(val, ast.List): - extras_require[key.s] = [ - e.s for e in val.elts if isinstance(e, ast.Str) + extras_require[key.value] = [ + e.value + for e in val.elts + if isinstance(e, ast.Constant) and isinstance(e.value, str) ] elif isinstance(value, ast.Name): variable = self._find_variable_in_body(body, value.id) @@ -276,15 +278,17 @@ def _find_extras_require( return extras_require for key, val in zip(variable.keys, variable.values): - if not isinstance(key, ast.Str): + if not isinstance(key, ast.Constant) or not isinstance(key.value, str): continue if isinstance(val, ast.Name): val = self._find_variable_in_body(body, val.id) if isinstance(val, ast.List): - extras_require[key.s] = [ - e.s for e in val.elts if isinstance(e, ast.Str) + extras_require[key.value] = [ + e.value + for e in val.elts + if isinstance(e, ast.Constant) and isinstance(e.value, str) ] return extras_require @@ -318,13 +322,17 @@ def _find_single_string( if value is None: return None - if isinstance(value, ast.Str): - return value.s + if isinstance(value, ast.Constant) and isinstance(value.value, str): + return value.value elif isinstance(value, ast.Name): variable = self._find_variable_in_body(body, value.id) - if variable is not None and isinstance(variable, ast.Str): - return variable.s + if ( + variable is not None + and isinstance(variable, ast.Constant) + and isinstance(variable.value, str) + ): + return variable.value return None @@ -360,7 +368,11 @@ def _find_variable_in_body( def _find_in_dict(self, dict_: ast.Dict, name: str) -> ast.expr | None: for key, val in zip(dict_.keys, dict_.values): - if isinstance(key, ast.Str) and key.s == name: + if ( + isinstance(key, ast.Constant) + and isinstance(key.value, str) + and key.value == name + ): return val return None diff --git a/tests/conftest.py b/tests/conftest.py index c8d840309ac..8733082ca75 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -122,7 +122,7 @@ def dummy_keyring() -> DummyBackend: def with_simple_keyring(dummy_keyring: DummyBackend) -> None: import keyring - keyring.set_keyring(dummy_keyring) # type: ignore[no-untyped-call] + keyring.set_keyring(dummy_keyring) @pytest.fixture()