diff --git a/.actions/assistant.py b/.actions/assistant.py index c1e2f08c34..ac0f83458e 100644 --- a/.actions/assistant.py +++ b/.actions/assistant.py @@ -22,9 +22,9 @@ from distutils.version import LooseVersion from itertools import chain from os.path import dirname, isfile from pathlib import Path -from typing import Any, Dict, Iterable, Iterator, List, Optional, Sequence, Tuple, Union +from typing import Any, Dict, Iterable, Iterator, List, Optional, Sequence, Tuple -from pkg_resources import Requirement, parse_requirements, yield_lines +from packaging.requirements import Requirement REQUIREMENT_FILES = { "pytorch": ( @@ -80,14 +80,15 @@ class _RequirementWithComment(Requirement): out = str(self) if self.strict: return f"{out} {self.strict_string}" + specs = [(spec.operator, spec.version) for spec in self.specifier] if unfreeze == "major": - for operator, version in self.specs: + for operator, version in specs: if operator in ("<", "<="): major = LooseVersion(version).version[0] # replace upper bound with major version increased by one return out.replace(f"{operator}{version}", f"<{major + 1}.0") elif unfreeze == "all": - for operator, version in self.specs: + for operator, version in specs: if operator in ("<", "<="): # drop upper bound return out.replace(f"{operator}{version},", "") @@ -96,33 +97,25 @@ class _RequirementWithComment(Requirement): return out -def _parse_requirements(strs: Union[str, Iterable[str]]) -> Iterator[_RequirementWithComment]: +def _parse_requirements(lines: Iterable[str]) -> Iterator[_RequirementWithComment]: """Adapted from `pkg_resources.parse_requirements` to include comments. >>> txt = ['# ignored', '', 'this # is an', '--piparg', 'example', 'foo # strict', 'thing', '-r different/file.txt'] >>> [r.adjust('none') for r in _parse_requirements(txt)] ['this', 'example', 'foo # strict', 'thing'] - >>> txt = '\\n'.join(txt) - >>> [r.adjust('none') for r in _parse_requirements(txt)] - ['this', 'example', 'foo # strict', 'thing'] """ - lines = yield_lines(strs) pip_argument = None for line in lines: + line = line.strip() + if not line or line.startswith("#"): + continue # Drop comments -- a hash without a space may be in a URL. if " #" in line: comment_pos = line.find(" #") line, comment = line[:comment_pos], line[comment_pos:] else: comment = "" - # If there is a line continuation, drop it, and append the next line. - if line.endswith("\\"): - line = line[:-2].strip() - try: - line += next(lines) - except StopIteration: - return # If there's a pip argument, save it if line.startswith("--"): pip_argument = line @@ -148,7 +141,7 @@ def load_requirements(path_dir: str, file_name: str = "base.txt", unfreeze: str logging.warning(f"Folder {path_dir} does not have any base requirements.") return [] assert path.exists(), (path_dir, file_name, path) - text = path.read_text() + text = path.read_text().splitlines() return [req.adjust(unfreeze) for req in _parse_requirements(text)] @@ -368,7 +361,7 @@ class AssistantCLI: if not ln_ or ln_.startswith("#"): final.append(line) continue - req = list(parse_requirements(ln_))[0] + req = list(_parse_requirements([ln_]))[0] if req.name not in packages: final.append(line) print(final) diff --git a/.actions/requirements.txt b/.actions/requirements.txt index a19661dbae..4b5cc8d568 100644 --- a/.actions/requirements.txt +++ b/.actions/requirements.txt @@ -1,2 +1,3 @@ jsonargparse >=4.16.0, <4.28.0 requests +packaging diff --git a/pyproject.toml b/pyproject.toml index 4189de8e97..6edd6d1a8f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,6 +16,7 @@ requires = [ "setuptools", "wheel", + "packaging", ] diff --git a/src/lightning/__setup__.py b/src/lightning/__setup__.py index 1e6fec715d..09eab5601f 100644 --- a/src/lightning/__setup__.py +++ b/src/lightning/__setup__.py @@ -5,7 +5,7 @@ from pathlib import Path from types import ModuleType from typing import Any, Dict -from setuptools import find_packages +from setuptools import find_namespace_packages _PROJECT_ROOT = "." _SOURCE_ROOT = os.path.join(_PROJECT_ROOT, "src") @@ -87,7 +87,7 @@ def _setup_args() -> Dict[str, Any]: "url": about.__homepage__, "download_url": "https://github.com/Lightning-AI/lightning", "license": about.__license__, - "packages": find_packages(where="src", include=["lightning", "lightning.*"]), + "packages": find_namespace_packages(where="src", include=["lightning", "lightning.*"]), "package_dir": {"": "src"}, "long_description": long_description, "long_description_content_type": "text/markdown", diff --git a/src/lightning/fabric/__init__.py b/src/lightning/fabric/__init__.py index 26f01aad64..921d3d61e6 100644 --- a/src/lightning/fabric/__init__.py +++ b/src/lightning/fabric/__init__.py @@ -37,9 +37,6 @@ import lightning.fabric._graveyard # noqa: E402, F401 # isort: skip __all__ = ["Fabric", "seed_everything", "is_wrapped"] -# for compatibility with namespace packages -__import__("pkg_resources").declare_namespace(__name__) - if os.environ.get("POSSIBLE_USER_WARNINGS", "").lower() in ("0", "off"): disable_possible_user_warnings() diff --git a/src/lightning/pytorch/__init__.py b/src/lightning/pytorch/__init__.py index b8c89f075d..53e7d5b7c1 100644 --- a/src/lightning/pytorch/__init__.py +++ b/src/lightning/pytorch/__init__.py @@ -33,8 +33,6 @@ import lightning.pytorch._graveyard # noqa: E402, F401 # isort: skip __all__ = ["Trainer", "LightningDataModule", "LightningModule", "Callback", "seed_everything"] -# for compatibility with namespace packages -__import__("pkg_resources").declare_namespace(__name__) LIGHTNING_LOGO: str = """ ####