From 86b6c4bbb67f9eaaf55f09f548d184af5001a496 Mon Sep 17 00:00:00 2001 From: Matt Davis Date: Mon, 3 Aug 2020 17:31:32 -0700 Subject: [PATCH] fix collection package root location under pytest >=6.0.0 (#70963) --- .../ansible-test-pytest-cap-revert.yml | 2 + .../fragments/pytest-collections-fix.yml | 2 + .../plugins/ansible_pytest_collections.py | 37 +++++++++++++++---- .../_data/requirements/constraints.txt | 1 - 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/ansible-test-pytest-cap-revert.yml create mode 100644 changelogs/fragments/pytest-collections-fix.yml diff --git a/changelogs/fragments/ansible-test-pytest-cap-revert.yml b/changelogs/fragments/ansible-test-pytest-cap-revert.yml new file mode 100644 index 00000000000..e64d8c81dc7 --- /dev/null +++ b/changelogs/fragments/ansible-test-pytest-cap-revert.yml @@ -0,0 +1,2 @@ +minor_changes: + - ansible-test - Remove ``pytest < 6.0.0`` constraint for managed installations on Python 3.x now that pytest 6 is supported. diff --git a/changelogs/fragments/pytest-collections-fix.yml b/changelogs/fragments/pytest-collections-fix.yml new file mode 100644 index 00000000000..c01e0dfa82a --- /dev/null +++ b/changelogs/fragments/pytest-collections-fix.yml @@ -0,0 +1,2 @@ +bugfixes: + - ansible-test units - fixed collection location code to work under pytest >= 6.0.0 diff --git a/test/lib/ansible_test/_data/pytest/plugins/ansible_pytest_collections.py b/test/lib/ansible_test/_data/pytest/plugins/ansible_pytest_collections.py index f1dc3f85434..67c69f15df0 100644 --- a/test/lib/ansible_test/_data/pytest/plugins/ansible_pytest_collections.py +++ b/test/lib/ansible_test/_data/pytest/plugins/ansible_pytest_collections.py @@ -3,12 +3,23 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type import os -import sys # set by ansible-test to a single directory, rather than a list of directories as supported by Ansible itself ANSIBLE_COLLECTIONS_PATH = os.path.join(os.environ['ANSIBLE_COLLECTIONS_PATH'], 'ansible_collections') +# this monkeypatch to _pytest.pathlib.resolve_package_path fixes PEP420 resolution for collections in pytest >= 6.0.0 +# NB: this code should never run under py2 +def collection_resolve_package_path(path): + """Configure the Python package path so that pytest can find our collections.""" + for parent in path.parents: + if str(parent) == ANSIBLE_COLLECTIONS_PATH: + return parent + + raise Exception('File "%s" not found in collection path "%s".' % (path, ANSIBLE_COLLECTIONS_PATH)) + + +# this monkeypatch to py.path.local.LocalPath.pypkgpath fixes PEP420 resolution for collections in pytest < 6.0.0 def collection_pypkgpath(self): """Configure the Python package path so that pytest can find our collections.""" for parent in self.parts(reverse=True): @@ -26,19 +37,31 @@ def pytest_configure(): except AttributeError: pytest_configure.executed = True + # noinspection PyProtectedMember from ansible.utils.collection_loader._collection_finder import _AnsibleCollectionFinder # allow unit tests to import code from collections + # noinspection PyProtectedMember _AnsibleCollectionFinder(paths=[os.path.dirname(ANSIBLE_COLLECTIONS_PATH)])._install() # pylint: disable=protected-access - # noinspection PyProtectedMember - import py._path.local + try: + # noinspection PyProtectedMember + from _pytest import pathlib as _pytest_pathlib + except ImportError: + _pytest_pathlib = None - # force collections unit tests to be loaded with the ansible_collections namespace - # original idea from https://stackoverflow.com/questions/50174130/how-do-i-pytest-a-project-using-pep-420-namespace-packages/50175552#50175552 - # noinspection PyProtectedMember - py._path.local.LocalPath.pypkgpath = collection_pypkgpath # pylint: disable=protected-access + if hasattr(_pytest_pathlib, 'resolve_package_path'): + _pytest_pathlib.resolve_package_path = collection_resolve_package_path + else: + # looks like pytest <= 6.0.0, use the old hack against py.path + # noinspection PyProtectedMember + import py._path.local + + # force collections unit tests to be loaded with the ansible_collections namespace + # original idea from https://stackoverflow.com/questions/50174130/how-do-i-pytest-a-project-using-pep-420-namespace-packages/50175552#50175552 + # noinspection PyProtectedMember + py._path.local.LocalPath.pypkgpath = collection_pypkgpath # pylint: disable=protected-access pytest_configure() diff --git a/test/lib/ansible_test/_data/requirements/constraints.txt b/test/lib/ansible_test/_data/requirements/constraints.txt index a5bd7df5831..b02bcf76289 100644 --- a/test/lib/ansible_test/_data/requirements/constraints.txt +++ b/test/lib/ansible_test/_data/requirements/constraints.txt @@ -17,7 +17,6 @@ idna < 2.6, >= 2.5 # linode requires idna < 2.9, >= 2.5, requests requires idna paramiko < 2.4.0 ; python_version < '2.7' # paramiko 2.4.0 drops support for python 2.6 pytest < 3.3.0 ; python_version < '2.7' # pytest 3.3.0 drops support for python 2.6 pytest < 5.0.0 ; python_version == '2.7' # pytest 5.0.0 and later will no longer support python 2.7 -pytest < 6.0.0 ; python_version > '2.7' # pytest 6.0.0 and later have issues with relative imports (further investigation required) pytest-forked < 1.0.2 ; python_version < '2.7' # pytest-forked 1.0.2 and later require python 2.7 or later pytest-forked >= 1.0.2 ; python_version >= '2.7' # pytest-forked before 1.0.2 does not work with pytest 4.2.0+ (which requires python 2.7+) ntlm-auth >= 1.3.0 # message encryption support using cryptography