From 2442f7209d52de0f499749725ce7cc324c3bd14b Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 20 Dec 2024 13:46:28 +0100 Subject: [PATCH 1/3] Lazily load cli with module __getattr__ --- spacy/__init__.py | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/spacy/__init__.py b/spacy/__init__.py index 1a18ad0d580..95dea266881 100644 --- a/spacy/__init__.py +++ b/spacy/__init__.py @@ -5,24 +5,41 @@ # set library-specific custom warning handling before doing anything else from .errors import setup_default_warnings -setup_default_warnings() # noqa: E402 +setup_default_warnings() # These are imported as part of the API -from thinc.api import Config, prefer_gpu, require_cpu, require_gpu # noqa: F401 +from thinc.api import Config, prefer_gpu, require_cpu, require_gpu -from . import pipeline # noqa: F401 -from . import util -from .about import __version__ # noqa: F401 -from .cli.info import info # noqa: F401 +from . import pipeline, util +from .about import __version__ from .errors import Errors -from .glossary import explain # noqa: F401 +from .glossary import explain from .language import Language -from .util import logger, registry # noqa: F401 +from .util import logger, registry from .vocab import Vocab if sys.maxunicode == 65535: raise SystemError(Errors.E130) +__all__ = [ + "__version__", + "blank", + "Config", + "Errors", + "explain", + "info", + "Language", + "load", + "logger", + "pipeline", + "prefer_gpu", + "registry", + "require_cpu", + "require_gpu", + "util", + "Vocab", +] + def load( name: Union[str, Path], @@ -77,3 +94,12 @@ def blank( # We should accept both dot notation and nested dict here for consistency config = util.dot_to_dict(config) return LangClass.from_config(config, vocab=vocab, meta=meta) + +def __getattr__(name): + if name == "info": + from .cli.info import info + return info + if name == "cli": + from . import cli + return cli + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") From b5bcd164ee2ff6ce68d370a3dcc99f2661f2c23d Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 20 Dec 2024 14:14:06 +0100 Subject: [PATCH 2/3] Fix and add test --- spacy/__init__.py | 9 ++++++--- spacy/tests/test_misc.py | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/spacy/__init__.py b/spacy/__init__.py index 95dea266881..39032b331a0 100644 --- a/spacy/__init__.py +++ b/spacy/__init__.py @@ -95,11 +95,14 @@ def blank( config = util.dot_to_dict(config) return LangClass.from_config(config, vocab=vocab, meta=meta) + def __getattr__(name): + if name == "cli": + import importlib + + return importlib.import_module("." + name, __name__) if name == "info": from .cli.info import info + return info - if name == "cli": - from . import cli - return cli raise AttributeError(f"module {__name__!r} has no attribute {name!r}") diff --git a/spacy/tests/test_misc.py b/spacy/tests/test_misc.py index d2a41ff0fed..eec444c18cd 100644 --- a/spacy/tests/test_misc.py +++ b/spacy/tests/test_misc.py @@ -495,3 +495,27 @@ def test_find_available_port(): with pytest.warns(UserWarning, match="already in use"): found_port = find_available_port(port, host, auto_select=True) assert found_port == port + 1, "Didn't find next port" + + +def test_lazy_load_cli(): + import subprocess + import sys + from textwrap import dedent + + subprocess.run( + [ + sys.executable, + "-c", + dedent( + """\ + import sys + import spacy + assert "spacy" in sys.modules + assert "spacy.cli" not in sys.modules + spacy.cli + assert "spacy.cli" in sys.modules + """ + ), + ], + check=True, + ) From 5b92fd30e2dd8b85209cbd048a9764a588b6fa0a Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Fri, 20 Dec 2024 14:19:06 +0100 Subject: [PATCH 3/3] Fix indentation --- spacy/tests/test_misc.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spacy/tests/test_misc.py b/spacy/tests/test_misc.py index eec444c18cd..7520fd83d0b 100644 --- a/spacy/tests/test_misc.py +++ b/spacy/tests/test_misc.py @@ -508,13 +508,13 @@ def test_lazy_load_cli(): "-c", dedent( """\ - import sys - import spacy - assert "spacy" in sys.modules - assert "spacy.cli" not in sys.modules - spacy.cli - assert "spacy.cli" in sys.modules - """ + import sys + import spacy + assert "spacy" in sys.modules + assert "spacy.cli" not in sys.modules + spacy.cli + assert "spacy.cli" in sys.modules + """ ), ], check=True,