summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ansible/galaxy/collection/__init__.py2
-rw-r--r--lib/ansible/galaxy/collection/concrete_artifact_manager.py36
-rw-r--r--lib/ansible/galaxy/collection/gpg.py2
-rw-r--r--lib/ansible/galaxy/dependency_resolution/providers.py6
-rw-r--r--test/lib/ansible_test/_data/requirements/sanity.mypy.in3
-rw-r--r--test/lib/ansible_test/_data/requirements/sanity.mypy.txt12
-rw-r--r--test/lib/ansible_test/_internal/commands/sanity/mypy.py19
-rw-r--r--test/sanity/ignore.txt1
8 files changed, 47 insertions, 34 deletions
diff --git a/lib/ansible/galaxy/collection/__init__.py b/lib/ansible/galaxy/collection/__init__.py
index f76fcc3e75..0e53339eef 100644
--- a/lib/ansible/galaxy/collection/__init__.py
+++ b/lib/ansible/galaxy/collection/__init__.py
@@ -156,7 +156,7 @@ class CollectionVerifyResult:
def verify_local_collection(local_collection, remote_collection, artifacts_manager):
- # type: (Candidate, Candidate | None, ConcreteArtifactsManager) -> CollectionVerifyResult
+ # type: (Candidate, t.Optional[Candidate], ConcreteArtifactsManager) -> CollectionVerifyResult
"""Verify integrity of the locally installed collection.
:param local_collection: Collection being checked.
diff --git a/lib/ansible/galaxy/collection/concrete_artifact_manager.py b/lib/ansible/galaxy/collection/concrete_artifact_manager.py
index b63cf8fec1..fe1159d893 100644
--- a/lib/ansible/galaxy/collection/concrete_artifact_manager.py
+++ b/lib/ansible/galaxy/collection/concrete_artifact_manager.py
@@ -88,7 +88,7 @@ class ConcreteArtifactsManager:
return self._ignore_signature_errors
def get_galaxy_artifact_source_info(self, collection):
- # type: (Candidate) -> dict[str, str | list[dict[str, str]]]
+ # type: (Candidate) -> dict[str, t.Union[str, list[dict[str, str]]]]
server = collection.src.api_server
try:
@@ -112,7 +112,7 @@ class ConcreteArtifactsManager:
}
def get_galaxy_artifact_path(self, collection):
- # type: (Candidate | Requirement) -> bytes
+ # type: (t.Union[Candidate, Requirement]) -> bytes
"""Given a Galaxy-stored collection, return a cached path.
If it's not yet on disk, this method downloads the artifact first.
@@ -172,7 +172,7 @@ class ConcreteArtifactsManager:
return b_artifact_path
def get_artifact_path(self, collection):
- # type: (Candidate | Requirement) -> bytes
+ # type: (t.Union[Candidate, Requirement]) -> bytes
"""Given a concrete collection pointer, return a cached path.
If it's not yet on disk, this method downloads the artifact first.
@@ -237,15 +237,15 @@ class ConcreteArtifactsManager:
return b_artifact_path
def _get_direct_collection_namespace(self, collection):
- # type: (Candidate) -> str | None
+ # type: (Candidate) -> t.Optional[str]
return self.get_direct_collection_meta(collection)['namespace'] # type: ignore[return-value]
def _get_direct_collection_name(self, collection):
- # type: (Candidate) -> str | None
+ # type: (Candidate) -> t.Optional[str]
return self.get_direct_collection_meta(collection)['name'] # type: ignore[return-value]
def get_direct_collection_fqcn(self, collection):
- # type: (Candidate) -> str | None
+ # type: (Candidate) -> t.Optional[str]
"""Extract FQCN from the given on-disk collection artifact.
If the collection is virtual, ``None`` is returned instead
@@ -261,12 +261,12 @@ class ConcreteArtifactsManager:
))
def get_direct_collection_version(self, collection):
- # type: (Candidate | Requirement) -> str
+ # type: (t.Union[Candidate, Requirement]) -> str
"""Extract version from the given on-disk collection artifact."""
return self.get_direct_collection_meta(collection)['version'] # type: ignore[return-value]
def get_direct_collection_dependencies(self, collection):
- # type: (Candidate | Requirement) -> dict[str, str]
+ # type: (t.Union[Candidate, Requirement]) -> dict[str, str]
"""Extract deps from the given on-disk collection artifact."""
collection_dependencies = self.get_direct_collection_meta(collection)['dependencies']
if collection_dependencies is None:
@@ -274,7 +274,7 @@ class ConcreteArtifactsManager:
return collection_dependencies # type: ignore[return-value]
def get_direct_collection_meta(self, collection):
- # type: (Candidate | Requirement) -> dict[str, str | dict[str, str] | list[str] | None]
+ # type: (t.Union[Candidate, Requirement]) -> dict[str, t.Union[str, dict[str, str], list[str], None]]
"""Extract meta from the given on-disk collection artifact."""
try: # FIXME: use unique collection identifier as a cache key?
return self._artifact_meta_cache[collection.src]
@@ -447,7 +447,7 @@ def _extract_collection_from_git(repo_url, coll_ver, b_path):
# FIXME: use random subdirs while preserving the file names
def _download_file(url, b_path, expected_hash, validate_certs, token=None, timeout=60):
- # type: (str, bytes, str | None, bool, GalaxyToken, int) -> bytes
+ # type: (str, bytes, t.Optional[str], bool, GalaxyToken, int) -> bytes
# ^ NOTE: used in download and verify_collections ^
b_tarball_name = to_bytes(
url.rsplit('/', 1)[1], errors='surrogate_or_strict',
@@ -503,14 +503,14 @@ def _consume_file(read_from, write_to=None):
def _normalize_galaxy_yml_manifest(
- galaxy_yml, # type: dict[str, str | list[str] | dict[str, str] | None]
+ galaxy_yml, # type: dict[str, t.Union[str, list[str], dict[str, str], None]]
b_galaxy_yml_path, # type: bytes
):
- # type: (...) -> dict[str, str | list[str] | dict[str, str] | None]
+ # type: (...) -> dict[str, t.Union[str, list[str], dict[str, str], None]]
galaxy_yml_schema = (
get_collections_galaxy_meta_info()
) # type: list[dict[str, t.Any]] # FIXME: <--
- # FIXME: 👆maybe precise type: list[dict[str, bool | str | list[str]]]
+ # FIXME: 👆maybe precise type: list[dict[str, t.Union[bool, str, list[str]]]]
mandatory_keys = set()
string_keys = set() # type: set[str]
@@ -570,7 +570,7 @@ def _normalize_galaxy_yml_manifest(
def _get_meta_from_dir(
b_path, # type: bytes
-): # type: (...) -> dict[str, str | list[str] | dict[str, str] | None]
+): # type: (...) -> dict[str, t.Union[str, list[str], dict[str, str], None]]
try:
return _get_meta_from_installed_dir(b_path)
except LookupError:
@@ -579,7 +579,7 @@ def _get_meta_from_dir(
def _get_meta_from_src_dir(
b_path, # type: bytes
-): # type: (...) -> dict[str, str | list[str] | dict[str, str] | None]
+): # type: (...) -> dict[str, t.Union[str, list[str], dict[str, str], None]]
galaxy_yml = os.path.join(b_path, _GALAXY_YAML)
if not os.path.isfile(galaxy_yml):
raise LookupError(
@@ -641,7 +641,7 @@ def _get_json_from_installed_dir(
def _get_meta_from_installed_dir(
b_path, # type: bytes
-): # type: (...) -> dict[str, str | list[str] | dict[str, str] | None]
+): # type: (...) -> dict[str, t.Union[str, list[str], dict[str, str], None]]
manifest = _get_json_from_installed_dir(b_path, MANIFEST_FILENAME)
collection_info = manifest['collection_info']
@@ -662,7 +662,7 @@ def _get_meta_from_installed_dir(
def _get_meta_from_tar(
b_path, # type: bytes
-): # type: (...) -> dict[str, str | list[str] | dict[str, str] | None]
+): # type: (...) -> dict[str, t.Union[str, list[str], dict[str, str], None]]
if not tarfile.is_tarfile(b_path):
raise AnsibleError(
"Collection artifact at '{path!s}' is not a valid tar file.".
@@ -710,7 +710,7 @@ def _tarfile_extract(
tar, # type: tarfile.TarFile
member, # type: tarfile.TarInfo
):
- # type: (...) -> t.Iterator[tuple[tarfile.TarInfo, t.IO[bytes] | None]]
+ # type: (...) -> t.Iterator[tuple[tarfile.TarInfo, t.Optional[t.IO[bytes]]]]
tar_obj = tar.extractfile(member)
try:
yield member, tar_obj
diff --git a/lib/ansible/galaxy/collection/gpg.py b/lib/ansible/galaxy/collection/gpg.py
index f684de162b..8641f0d7f7 100644
--- a/lib/ansible/galaxy/collection/gpg.py
+++ b/lib/ansible/galaxy/collection/gpg.py
@@ -25,7 +25,7 @@ IS_PY310_PLUS = sys.version_info[:2] >= (3, 10)
frozen_dataclass = partial(dataclass, frozen=True, **({'slots': True} if IS_PY310_PLUS else {}))
-def get_signature_from_source(source, display=None): # type: (str, Display | None) -> str
+def get_signature_from_source(source, display=None): # type: (str, t.Optional[Display]) -> str
if display is not None:
display.vvvv(f"Using signature at {source}")
try:
diff --git a/lib/ansible/galaxy/dependency_resolution/providers.py b/lib/ansible/galaxy/dependency_resolution/providers.py
index 08aeb2074c..9d82513c26 100644
--- a/lib/ansible/galaxy/dependency_resolution/providers.py
+++ b/lib/ansible/galaxy/dependency_resolution/providers.py
@@ -155,7 +155,7 @@ class CollectionDependencyProvider(AbstractProvider):
return False
def identify(self, requirement_or_candidate):
- # type: (Candidate | Requirement) -> str
+ # type: (t.Union[Candidate, Requirement]) -> str
"""Given requirement or candidate, return an identifier for it.
This is used to identify a requirement or candidate, e.g.
@@ -168,10 +168,10 @@ class CollectionDependencyProvider(AbstractProvider):
def get_preference(
self, # type: CollectionDependencyProvider
- resolution, # type: Candidate | None
+ resolution, # type: t.Optional[Candidate]
candidates, # type: list[Candidate]
information, # type: list[t.NamedTuple]
- ): # type: (...) -> float | int
+ ): # type: (...) -> t.Union[float, int]
"""Return sort key function return value for given requirement.
This result should be based on preference that is defined as
diff --git a/test/lib/ansible_test/_data/requirements/sanity.mypy.in b/test/lib/ansible_test/_data/requirements/sanity.mypy.in
index b7b8229794..890caf30f4 100644
--- a/test/lib/ansible_test/_data/requirements/sanity.mypy.in
+++ b/test/lib/ansible_test/_data/requirements/sanity.mypy.in
@@ -2,8 +2,9 @@ mypy[python2]
packaging # type stubs not published separately
types-backports
types-jinja2
-types-paramiko
+types-paramiko < 2.8.14 # newer versions drop support for Python 2.7
types-pyyaml < 6 # PyYAML 6+ stubs do not support Python 2.7
+types-cryptography < 3.3.16 # newer versions drop support for Python 2.7
types-requests
types-setuptools
types-toml
diff --git a/test/lib/ansible_test/_data/requirements/sanity.mypy.txt b/test/lib/ansible_test/_data/requirements/sanity.mypy.txt
index d4baf5630d..e448c9074e 100644
--- a/test/lib/ansible_test/_data/requirements/sanity.mypy.txt
+++ b/test/lib/ansible_test/_data/requirements/sanity.mypy.txt
@@ -1,10 +1,10 @@
# edit "sanity.mypy.in" and generate with: hacking/update-sanity-requirements.py --test mypy
-mypy==0.931
+mypy==0.950
mypy-extensions==0.4.3
packaging==21.2
pyparsing==2.4.7
tomli==2.0.1
-typed-ast==1.5.2
+typed-ast==1.5.3
types-backports==0.1.3
types-cryptography==3.3.15
types-enum34==1.1.8
@@ -13,8 +13,8 @@ types-Jinja2==2.11.9
types-MarkupSafe==1.1.10
types-paramiko==2.8.13
types-PyYAML==5.4.12
-types-requests==2.27.10
-types-setuptools==57.4.9
-types-toml==0.10.4
-types-urllib3==1.26.9
+types-requests==2.27.25
+types-setuptools==57.4.14
+types-toml==0.10.6
+types-urllib3==1.26.14
typing-extensions==3.10.0.2
diff --git a/test/lib/ansible_test/_internal/commands/sanity/mypy.py b/test/lib/ansible_test/_internal/commands/sanity/mypy.py
index 5b83aa8b9f..fe664ddc9f 100644
--- a/test/lib/ansible_test/_internal/commands/sanity/mypy.py
+++ b/test/lib/ansible_test/_internal/commands/sanity/mypy.py
@@ -90,11 +90,22 @@ class MypyTest(SanityMultipleVersion):
display.warning(f'Skipping sanity test "{self.name}" due to missing virtual environment support on Python {args.controller_python.version}.')
return SanitySkipped(self.name, python.version)
+ # Temporary hack to make Python 3.8 a remote-only Python version since we'll be dropping controller support for it soon.
+ # This avoids having to change annotations or add ignores for issues that are specific to that version.
+
+ change_version = '3.8'
+
+ if change_version not in CONTROLLER_PYTHON_VERSIONS or change_version in REMOTE_ONLY_PYTHON_VERSIONS:
+ raise Exception(f'Remove this hack now that Python {change_version} is not supported by the controller.')
+
+ controller_python_versions = tuple(version for version in CONTROLLER_PYTHON_VERSIONS if version != change_version)
+ remote_only_python_versions = REMOTE_ONLY_PYTHON_VERSIONS + (change_version,)
+
contexts = (
- MyPyContext('ansible-test', ['test/lib/ansible_test/_util/target/sanity/import/'], CONTROLLER_PYTHON_VERSIONS),
- MyPyContext('ansible-test', ['test/lib/ansible_test/_internal/'], CONTROLLER_PYTHON_VERSIONS),
- MyPyContext('ansible-core', ['lib/ansible/'], CONTROLLER_PYTHON_VERSIONS),
- MyPyContext('modules', ['lib/ansible/modules/', 'lib/ansible/module_utils/'], REMOTE_ONLY_PYTHON_VERSIONS),
+ MyPyContext('ansible-test', ['test/lib/ansible_test/_util/target/sanity/import/'], controller_python_versions),
+ MyPyContext('ansible-test', ['test/lib/ansible_test/_internal/'], controller_python_versions),
+ MyPyContext('ansible-core', ['lib/ansible/'], controller_python_versions),
+ MyPyContext('modules', ['lib/ansible/modules/', 'lib/ansible/module_utils/'], remote_only_python_versions),
)
unfiltered_messages = [] # type: t.List[SanityMessage]
diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt
index 6129674e12..16763b3599 100644
--- a/test/sanity/ignore.txt
+++ b/test/sanity/ignore.txt
@@ -286,6 +286,7 @@ lib/ansible/module_utils/six/__init__.py mypy-2.7:assignment # vendored code
lib/ansible/module_utils/six/__init__.py mypy-3.5:assignment # vendored code
lib/ansible/module_utils/six/__init__.py mypy-3.6:assignment # vendored code
lib/ansible/module_utils/six/__init__.py mypy-3.7:assignment # vendored code
+lib/ansible/module_utils/six/__init__.py mypy-3.8:assignment # vendored code
lib/ansible/module_utils/six/__init__.py mypy-2.7:misc # vendored code
lib/ansible/module_utils/six/__init__.py mypy-3.5:misc # vendored code
lib/ansible/module_utils/six/__init__.py mypy-3.6:misc # vendored code