Skip to content

Commit

Permalink
Merge branch 'main' into requiremnts
Browse files Browse the repository at this point in the history
  • Loading branch information
Borda authored Mar 1, 2023
2 parents a9ad4e6 + 21341e9 commit aece1a6
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 17 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/release-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ jobs:
run: ls -lh dist/

- name: Upload to release
if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release'
uses: AButler/upload-release-assets@v2.0
with:
files: 'dist/*'
Expand All @@ -65,7 +64,7 @@ jobs:

delay-publish:
needs: build-package
if: startsWith(github.event.ref, 'refs/tags')
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
runs-on: ubuntu-latest
steps:
- name: Delay ⏰ releasing
Expand Down Expand Up @@ -93,7 +92,6 @@ jobs:

# We do this, since failures on test.pypi aren't that bad
- name: Publish to Test PyPI
if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release'
uses: pypa/gh-action-pypi-publish@v1.6.4
with:
user: __token__
Expand All @@ -102,7 +100,6 @@ jobs:
verbose: true

- name: Publish distribution 📦 to PyPI
if: startsWith(github.event.ref, 'refs/tags') || github.event_name == 'release'
uses: pypa/gh-action-pypi-publish@v1.6.4
with:
user: __token__
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ repos:
- "flake8-docstrings"

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.249
rev: v0.0.253
hooks:
- id: ruff
args: ["--fix"]
19 changes: 17 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- CI: guardian as parametrization closure ([#111](https://github.com/Lightning-AI/utilities/pull/111))
-


### Changed

- CI: allow specify typing extra ([#110](https://github.com/Lightning-AI/utilities/pull/110))
-


### Fixed

-


## [0.7.1] - 2023-02-23

### Added

- CI: guardian as parametrization closure ([#111](https://github.com/Lightning-AI/utilities/pull/111))

### Changed

- CI: allow specify typing extra ([#110](https://github.com/Lightning-AI/utilities/pull/110))

### Fixed

- More resilient `RequirementCache` that checks for module import-ability ([#112](https://github.com/Lightning-AI/utilities/pull/112))


## [0.7.0] - 2023-02-20

### Added
Expand Down
40 changes: 30 additions & 10 deletions src/lightning_utilities/core/imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,28 +84,48 @@ def compare_version(package: str, op: Callable, version: str, use_base_version:


class RequirementCache:
"""Boolean-like class for check of requirement with extras and version specifiers.
"""Boolean-like class to check for requirement and module availability.
Args:
requirement: The requirement to check, version specifiers are allowed.
module: The optional module to try to import if the requirement check fails.
>>> RequirementCache("torch>=0.1")
Requirement 'torch>=0.1' met
>>> bool(RequirementCache("torch>=0.1"))
True
>>> bool(RequirementCache("torch>100.0"))
False
>>> RequirementCache("torch")
Requirement 'torch' met
>>> bool(RequirementCache("torch"))
True
>>> bool(RequirementCache("unknown_package"))
False
"""

def __init__(self, requirement: str) -> None:
def __init__(self, requirement: str, module: Optional[str] = None) -> None:
self.requirement = requirement
self.module = module

def _check_requirement(self) -> None:
if not hasattr(self, "available"):
try:
pkg_resources.require(self.requirement)
self.available = True
self.message = f"Requirement {self.requirement!r} met"
except Exception as ex:
self.available = False
self.message = f"{ex.__class__.__name__}: {ex}. HINT: Try running `pip install -U {self.requirement!r}`"
if hasattr(self, "available"):
return
try:
# first try the pkg_resources requirement
pkg_resources.require(self.requirement)
self.available = True
self.message = f"Requirement {self.requirement!r} met"
except Exception as ex:
self.available = False
self.message = f"{ex.__class__.__name__}: {ex}. HINT: Try running `pip install -U {self.requirement!r}`"
requirement_contains_version_specifier = any(c in self.requirement for c in "=<>")
if not requirement_contains_version_specifier or self.module is not None:
module = self.requirement if self.module is None else self.module
# sometimes `pkg_resources.require()` fails but the module is importable
self.available = module_available(module)
if self.available:
self.message = f"Module {module!r} available"

def __bool__(self) -> bool:
"""Format as bool."""
Expand Down
11 changes: 11 additions & 0 deletions tests/unittests/core/test_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,17 @@ def test_requirement_cache():
assert not RequirementCache(f"pytest<{pytest.__version__}")
assert "pip install -U '-'" in str(RequirementCache("-"))

# invalid requirement is skipped by valid module
assert RequirementCache(f"pytest<{pytest.__version__}", "pytest")

cache = RequirementCache("this_module_is_not_installed")
assert not cache
assert "pip install -U 'this_module_is_not_installed" in str(cache)

cache = RequirementCache("this_module_is_not_installed", "this_also_is_not")
assert not cache
assert "pip install -U 'this_module_is_not_installed" in str(cache)


def test_module_available_cache():
assert ModuleAvailableCache("pytest")
Expand Down

0 comments on commit aece1a6

Please sign in to comment.