Skip to content

Commit

Permalink
Add sanity check; fix monkeypatch fixture name; try not using editabl…
Browse files Browse the repository at this point in the history
…e install in CI
  • Loading branch information
Sachaa-Thanasius committed Sep 10, 2024
1 parent 42f9fdf commit f685c02
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ jobs:

- name: Install project and test dependencies
run: |
python -m pip install -e .[test]
python -m pip install .[test]
- name: Run tests on ${{ matrix.python-version }}
run: |
Expand Down
37 changes: 31 additions & 6 deletions src/defer_imports/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,10 +311,10 @@ def check_source_for_defer_usage(data: _tp.Union[_tp.ReadableBuffer, str]) -> tu
def check_ast_for_defer_usage(data: ast.AST) -> tuple[str, bool]:
"""Check if the given AST uses "with defer_imports.until_use". Also assume "utf-8" is the the encoding."""

encoding = "utf-8"
uses_defer = any(
isinstance(node, ast.With) and DeferredInstrumenter.check_With_for_defer_usage(node) for node in ast.walk(data)
)
encoding = "utf-8"
return encoding, uses_defer


Expand Down Expand Up @@ -561,6 +561,34 @@ def _resolve(self) -> None:
namespace[key] = module


# TODO: Keep sanity_check, calc___package__, and resolve_name in sync with the corresponding CPython code in supported
# CPython versions.


def sanity_check(name: str, package: _tp.Optional[str], level: int) -> None:
"""Verify arguments are "sane".
Slightly modified version of importlib._bootstrap._sanity_check.
"""

if not isinstance(name, str): # pyright: ignore [reportUnnecessaryIsInstance]
msg = f"module name must be str, not {type(name)}"
raise TypeError(msg)
if level < 0:
msg = "level must be >= 0"
raise ValueError(msg)
if level > 0:
if not isinstance(package, str):
msg = "__package__ not set to a string"
raise TypeError(msg)
if not package:
msg = "attempted relative import with no known parent package"
raise ImportError(msg)
if not name and level == 0:
msg = "Empty module name"
raise ValueError(msg)


def calc___package__(globals: _tp.MutableMapping[str, _tp.Any]) -> _tp.Optional[str]:
"""Calculate what __package__ should be.
Expand All @@ -573,7 +601,6 @@ def calc___package__(globals: _tp.MutableMapping[str, _tp.Any]) -> _tp.Optional[
package: str | None = globals.get("__package__")
spec: ModuleSpec | None = globals.get("__spec__")

# TODO: Keep the warnings in sync with supported CPython versions.
if package is not None:
if spec is not None and package != spec.parent:
category = DeprecationWarning if sys.version_info >= (3, 12) else ImportWarning
Expand Down Expand Up @@ -624,10 +651,10 @@ def deferred___import__( # noqa: ANN202

fromlist = fromlist or ()

package = calc___package__(locals)
sanity_check(name, package, level)
# Resolve the names of relative imports.
if level > 0:
package = calc___package__(locals)
# TODO: Use a version of importlib._bootstrap._sanity_check before resolve_name?
name = resolve_name(name, package, level) # pyright: ignore [reportArgumentType]
level = 0

Expand All @@ -642,8 +669,6 @@ def deferred___import__( # noqa: ANN202
pass
else:
# Nest submodule proxies as needed.
# TODO: Is there a better way to do this or maybe a better place for it? Modifying a member of the
# passed-in locals isn't ideal.
for limit, attr_name in enumerate(name_parts[1:], start=2):
if attr_name not in vars(parent):
nested_proxy = DeferredImportProxy(".".join(name_parts[:limit]), globals, locals, (), level)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_deferred.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def temp_cache_module(name: str, module: ModuleType):


@pytest.fixture(autouse=True)
def no_requests(monkeypatch: pytest.MonkeyPatch):
def better_key_repr(monkeypatch: pytest.MonkeyPatch):
"""Replace defer_imports._core.DeferredImportKey.__repr__ with a more verbose version for all tests."""

def _verbose_repr(self) -> str: # pyright: ignore # noqa: ANN001
Expand Down

0 comments on commit f685c02

Please sign in to comment.