Skip to content

Commit bd2c17e

Browse files
shadeMeadrianeboyd
andauthored
Warn about reloading dependencies after downloading models (#13081)
* Update the "Missing factory" error message This accounts for model installations that took place during the current Python session. * Add a note about Jupyter notebooks * Move error to `spacy.cli.download` Add extra message for Jupyter sessions * Add additional note for interactive sessions * Remove note about `spacy-transformers` from error message * `isort` * Improve checks for colab (also helps displacy) * Update warning messages * Improve flow for multiple checks --------- Co-authored-by: Adriane Boyd <[email protected]>
1 parent 513bbd5 commit bd2c17e

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

spacy/cli/download.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@
77

88
from .. import about
99
from ..errors import OLD_MODEL_SHORTCUTS
10-
from ..util import get_minor_version, is_package, is_prerelease_version, run_command
10+
from ..util import (
11+
get_minor_version,
12+
is_in_interactive,
13+
is_in_jupyter,
14+
is_package,
15+
is_prerelease_version,
16+
run_command,
17+
)
1118
from ._util import SDIST_SUFFIX, WHEEL_SUFFIX, Arg, Opt, app
1219

1320

@@ -77,6 +84,27 @@ def download(
7784
"Download and installation successful",
7885
f"You can now load the package via spacy.load('{model_name}')",
7986
)
87+
if is_in_jupyter():
88+
reload_deps_msg = (
89+
"If you are in a Jupyter or Colab notebook, you may need to "
90+
"restart Python in order to load all the package's dependencies. "
91+
"You can do this by selecting the 'Restart kernel' or 'Restart "
92+
"runtime' option."
93+
)
94+
msg.warn(
95+
"Restart to reload dependencies",
96+
reload_deps_msg,
97+
)
98+
elif is_in_interactive():
99+
reload_deps_msg = (
100+
"If you are in an interactive Python session, you may need to "
101+
"exit and restart Python to load all the package's dependencies. "
102+
"You can exit with Ctrl-D (or Ctrl-Z and Enter on Windows)."
103+
)
104+
msg.warn(
105+
"Restart to reload dependencies",
106+
reload_deps_msg,
107+
)
80108

81109

82110
def get_model_filename(model_name: str, version: str, sdist: bool = False) -> str:

spacy/errors.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ class Errors(metaclass=ErrorsWithCodes):
227227
E002 = ("Can't find factory for '{name}' for language {lang} ({lang_code}). "
228228
"This usually happens when spaCy calls `nlp.{method}` with a custom "
229229
"component name that's not registered on the current language class. "
230-
"If you're using a Transformer, make sure to install 'spacy-transformers'. "
231230
"If you're using a custom component, make sure you've added the "
232231
"decorator `@Language.component` (for function components) or "
233232
"`@Language.factory` (for class components).\n\nAvailable "

spacy/util.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,20 +1077,38 @@ def force_remove(rmfunc, path, ex):
10771077

10781078

10791079
def is_in_jupyter() -> bool:
1080-
"""Check if user is running spaCy from a Jupyter notebook by detecting the
1081-
IPython kernel. Mainly used for the displaCy visualizer.
1082-
RETURNS (bool): True if in Jupyter, False if not.
1080+
"""Check if user is running spaCy from a Jupyter or Colab notebook by
1081+
detecting the IPython kernel. Mainly used for the displaCy visualizer.
1082+
RETURNS (bool): True if in Jupyter/Colab, False if not.
10831083
"""
10841084
# https://stackoverflow.com/a/39662359/6400719
1085+
# https://stackoverflow.com/questions/15411967
10851086
try:
1086-
shell = get_ipython().__class__.__name__ # type: ignore[name-defined]
1087-
if shell == "ZMQInteractiveShell":
1087+
if get_ipython().__class__.__name__ == "ZMQInteractiveShell": # type: ignore[name-defined]
10881088
return True # Jupyter notebook or qtconsole
1089+
if get_ipython().__class__.__module__ == "google.colab._shell": # type: ignore[name-defined]
1090+
return True # Colab notebook
10891091
except NameError:
1090-
return False # Probably standard Python interpreter
1092+
pass # Probably standard Python interpreter
1093+
# additional check for Colab
1094+
try:
1095+
import google.colab
1096+
1097+
return True # Colab notebook
1098+
except ImportError:
1099+
pass
10911100
return False
10921101

10931102

1103+
def is_in_interactive() -> bool:
1104+
"""Check if user is running spaCy from an interactive Python
1105+
shell. Will return True in Jupyter notebooks too.
1106+
RETURNS (bool): True if in interactive mode, False if not.
1107+
"""
1108+
# https://stackoverflow.com/questions/2356399/tell-if-python-is-in-interactive-mode
1109+
return hasattr(sys, "ps1") or hasattr(sys, "ps2")
1110+
1111+
10941112
def get_object_name(obj: Any) -> str:
10951113
"""Get a human-readable name of a Python object, e.g. a pipeline component.
10961114

0 commit comments

Comments
 (0)