Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust imports to ensure wildcard imports are prohibited #32

Merged
merged 3 commits into from
Oct 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/32.packaging.rst
14 changes: 8 additions & 6 deletions src/propcache/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,30 @@

from typing import TYPE_CHECKING, List

_PUBLIC_API = ("cached_property", "under_cached_property")

__version__ = "0.2.0.dev0"
__all__ = ()

# Imports have moved to `propcache.api` in 0.2.0+.
# This module is now a facade for the API.
if TYPE_CHECKING:
from .api import cached_property, under_cached_property

__all__ = ("cached_property", "under_cached_property")
from .api import cached_property as cached_property # noqa: F401
from .api import under_cached_property as under_cached_property # noqa: F401


def _import_facade(attr: str) -> object:
"""Import the public API from the `api` module."""
if attr in __all__:
if attr in _PUBLIC_API:
from . import api # pylint: disable=import-outside-toplevel

return getattr(api, attr)
raise AttributeError(f"module 'propcache' has no attribute '{attr}'")
raise AttributeError(f"module '{__package__}' has no attribute '{attr}'")


def _dir_facade() -> List[str]:
"""Include the public API in the module's dir() output."""
return [*__all__, *globals().keys()]
return [*_PUBLIC_API, *globals().keys()]


__getattr__ = _import_facade
Expand Down
18 changes: 8 additions & 10 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,9 @@ def test_api_at_top_level():
"prop_name",
("cached_property", "under_cached_property"),
)
@pytest.mark.parametrize(
"api_list", (dir(propcache), propcache.__all__), ids=("dir", "__all__")
)
def test_public_api_is_in_inspectable_object_lists(prop_name, api_list):
"""Verify the public API is discoverable programmatically.

This checks for presence of known public decorators module's
``__all__`` and ``dir()``.
"""
assert prop_name in api_list
def test_public_api_is_discoverable_in_dir(prop_name: str):
"""Verify the public API is discoverable programmatically."""
assert prop_name in dir(propcache)


def test_importing_invalid_attr_raises():
Expand All @@ -43,3 +36,8 @@ def test_import_error_invalid_attr():
# and may vary between Python versions.
with pytest.raises(ImportError):
from propcache import invalid_attr # noqa: F401


def test_no_wildcard_imports():
"""Verify wildcard imports are prohibited."""
assert not propcache.__all__
bdraco marked this conversation as resolved.
Show resolved Hide resolved
Loading