0

I have found several posts on how to "hide" a package and simulate an ImportError with pytest, however, I haven't succeeded in my case and I am looking for some help:

Here is the content of an __about__.py file that I want to test with pytest.

"""Get the metadata from the package or from setup.py."""
try:
    import importlib
    metadata = importlib.metadata
except ImportError:
    import importlib_metadata as metadata

try:
    data = metadata.metadata("mypackage")
    __version__ = data["Version"]
    __author__ = data["Author"]
    __name__ = data["Name"]
except metadata.PackageNotFoundError:
    # The repo of the package is accessible to python to get at least the version
    import re
    from pathlib import Path

    try:
        from nested_grid_plotter import __file__ as loc

        with open(Path(loc).parent.joinpath("../setup.py"), "r") as f:
            data = f.read()
    except FileNotFoundError:
        data = ""

    def version_parser(v):
        """Parse the version from the setup file."""
        version_pattern = (
            r"""(version\s*=\s*)["|'](\d+(=?\.(\d+(=?\.(\d+)*)*)*)*)["|']"""
        )
        regex_matcher = re.compile(version_pattern).search(v)
        if regex_matcher is None:
            return "unknwon"
        return regex_matcher.group(2)

    try:
        __version__ = version_parser(data)
    except Exception:
        __version__ = "unknown"
    __author__ = "unknown"
    __name__ = "unknown"

Here is the __init__.py at the root of the package:

from .__about__ import __version__, __name__, __author__

And here is the tests that I have come up with until now. However, I am not able to hide importlib.

"""Test the file __about__.py."""

import pytest
import sys


class PackageDiscarder:
    def __init__(self):
        self.pkgnames = []

    def find_spec(self, fullname, path, target=None):
        if fullname in self.pkgnames:
            raise ImportError()


@pytest.fixture
def no_requests():
    sys.modules.pop("importlib", None)
    d = PackageDiscarder()
    d.pkgnames.append("importlib")
    sys.meta_path.insert(0, d)
    yield
    sys.meta_path.remove(d)


@pytest.fixture(autouse=True)
def cleanup_imports():
    yield
    sys.modules.pop("mypackage", None)


def test_requests_available():
    import mypackage

    assert mypackage.__version__ != "unknwon"


@pytest.mark.usefixtures("no_requests")
def test_requests_missing():
    import mypackage

    assert mypackage.__version__ != "unknwon"

Here is the coverage report:

Name                               Stmts   Miss  Cover   Missing
----------------------------------------------------------------
mypackage/__about__.py                31     10    68%   5-6, 10-12, 23-24, 33, 38-39
----------------------------------------------------------------
TOTAL                                 31     10    68%
Antoine Collet
  • 154
  • 1
  • 10

0 Answers0