-
Notifications
You must be signed in to change notification settings - Fork 5k
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
Disable nbextension in first location found #2725
Closed
Closed
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
cfe8a23
Disable nbextension in first location found
takluyver 5eca411
Add options for explicitly disabling extension in user or sys.prefix …
takluyver e6a7fe6
Add searching behaviour to 'jupyter nbextension uninstall'
takluyver a17f384
Fold ToggleNBExtensionApp into EnableNBExtensionApp, other fixes
takluyver 1127c6e
Fix usage string
takluyver File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ | |
from urlparse import urlparse | ||
from urllib import urlretrieve | ||
|
||
from jupyter_core.application import JupyterApp | ||
from jupyter_core.paths import ( | ||
jupyter_data_dir, jupyter_config_path, jupyter_path, | ||
SYSTEM_JUPYTER_PATH, ENV_JUPYTER_PATH, | ||
|
@@ -29,6 +30,7 @@ | |
from ipython_genutils.tempdir import TemporaryDirectory | ||
from ._version import __version__ | ||
|
||
from tornado.log import LogFormatter | ||
from traitlets.config.manager import BaseJSONConfigManager | ||
from traitlets.utils.importstring import import_item | ||
|
||
|
@@ -241,10 +243,7 @@ def uninstall_nbextension(dest, require=None, user=False, sys_prefix=False, pref | |
---------- | ||
|
||
dest : str | ||
path to file, directory, zip or tarball archive, or URL to install | ||
name the nbextension is installed to. For example, if destination is 'foo', then | ||
the source file will be installed to 'nbextensions/foo', regardless of the source name. | ||
This cannot be specified if an archive is given as the source. | ||
Name of the installed nbextension file or folder. | ||
require : str [optional] | ||
require.js path used to load the extension. | ||
If specified, frontend config loading extension will be removed. | ||
|
@@ -278,6 +277,25 @@ def uninstall_nbextension(dest, require=None, user=False, sys_prefix=False, pref | |
for section in NBCONFIG_SECTIONS: | ||
cm.update(section, {"load_extensions": {require: None}}) | ||
|
||
def _find_uninstall_nbextension(filename, logger=None): | ||
"""Remove nbextension files from the first location they are found. | ||
|
||
Returns True if files were removed, False otherwise. | ||
""" | ||
filename = cast_unicode_py2(filename) | ||
for nbext in jupyter_path('nbextensions'): | ||
path = pjoin(nbext, filename) | ||
if os.path.lexists(path): | ||
if logger: | ||
logger.info("Removing: %s" % path) | ||
if os.path.isdir(path) and not os.path.islink(path): | ||
shutil.rmtree(path) | ||
else: | ||
os.remove(path) | ||
return True | ||
|
||
return False | ||
|
||
|
||
def uninstall_nbextension_python(module, | ||
user=False, sys_prefix=False, prefix=None, nbextensions_dir=None, | ||
|
@@ -419,6 +437,22 @@ def disable_nbextension(section, require, user=True, sys_prefix=False, | |
user=user, sys_prefix=sys_prefix, | ||
logger=logger) | ||
|
||
def _find_disable_nbextension(section, require, logger=None): | ||
"""Disable an nbextension from the first config location where it is enabled. | ||
|
||
Returns True if it changed any config, False otherwise. | ||
""" | ||
for config_dir in jupyter_config_path(): | ||
cm = BaseJSONConfigManager(config_dir=os.path.join(config_dir, 'nbconfig')) | ||
d = cm.get(section) | ||
if d.get('load_extensions', {}).get(require, None): | ||
if logger: | ||
logger.info("Disabling %s extension in %s", require, config_dir) | ||
cm.update(section, {'load_extensions': {require: None}}) | ||
return True | ||
|
||
return False | ||
|
||
|
||
def enable_nbextension_python(module, user=True, sys_prefix=False, | ||
logger=None): | ||
|
@@ -712,37 +746,56 @@ def _config_file_name_default(self): | |
"""The default config file name.""" | ||
return 'jupyter_notebook_config' | ||
|
||
def uninstall_extensions(self): | ||
"""Uninstall some nbextensions""" | ||
def uninstall_extension(self): | ||
"""Uninstall an nbextension from a specific location""" | ||
kwargs = { | ||
'user': self.user, | ||
'sys_prefix': self.sys_prefix, | ||
'prefix': self.prefix, | ||
'nbextensions_dir': self.nbextensions_dir, | ||
'logger': self.log | ||
} | ||
|
||
arg_count = 1 | ||
if len(self.extra_args) > arg_count: | ||
raise ValueError("only one nbextension allowed at a time. Call multiple times to uninstall multiple extensions.") | ||
if len(self.extra_args) < arg_count: | ||
raise ValueError("not enough arguments") | ||
|
||
|
||
if self.python: | ||
uninstall_nbextension_python(self.extra_args[0], **kwargs) | ||
else: | ||
if self.require: | ||
kwargs['require'] = self.require | ||
uninstall_nbextension(self.extra_args[0], **kwargs) | ||
|
||
def find_uninstall_extension(self): | ||
"""Uninstall an nbextension from an unspecified location""" | ||
name = self.extra_args[0] | ||
if self.python: | ||
_, nbexts = _get_nbextension_metadata(name) | ||
changed = False | ||
for nbext in nbexts: | ||
if _find_uninstall_nbextension(nbext, logger=self.log): | ||
changed = True | ||
|
||
else: | ||
changed = _find_uninstall_nbextension(name, logger=self.log) | ||
|
||
if not changed: | ||
print("No installed extension %r found." % name) | ||
|
||
if self.require: | ||
for section in NBCONFIG_SECTIONS: | ||
_find_disable_nbextension(section, self.require, logger=self.log) | ||
|
||
def start(self): | ||
if not self.extra_args: | ||
sys.exit('Please specify an nbextension to uninstall') | ||
else: | ||
elif len(self.extra_args) > 1: | ||
sys.exit("Only one nbextension allowed at a time. " | ||
"Call multiple times to uninstall multiple extensions.") | ||
elif self.user or self.sys_prefix or self.prefix or self.nbextensions_dir: | ||
try: | ||
self.uninstall_extensions() | ||
self.uninstall_extension() | ||
except ArgumentConflict as e: | ||
sys.exit(str(e)) | ||
else: | ||
self.find_uninstall_extension() | ||
|
||
|
||
class ToggleNBExtensionApp(BaseExtensionApp): | ||
|
@@ -822,7 +875,7 @@ class EnableNBExtensionApp(ToggleNBExtensionApp): | |
_toggle_value = True | ||
|
||
|
||
class DisableNBExtensionApp(ToggleNBExtensionApp): | ||
class DisableNBExtensionApp(JupyterApp): | ||
"""An App that disables nbextensions""" | ||
name = "jupyter nbextension disable" | ||
description = """ | ||
|
@@ -831,7 +884,60 @@ class DisableNBExtensionApp(ToggleNBExtensionApp): | |
Usage | ||
jupyter nbextension disable [--system|--sys-prefix] | ||
""" | ||
_toggle_value = None | ||
version = __version__ | ||
flags = { | ||
"py" : ({"DisableNBExtensionApp" : {"python" : True}}, | ||
"Disable an extension from a Python package name"), | ||
"user": ({"DisableNBExtensionApp" : {"user": True}}, | ||
"Explicitly disable in user config"), | ||
"sys-prefix": ({"DisableNBExtensionApp": {"sys_prefix": True}}, | ||
"Explicitly disable in sys.prefix config") | ||
} | ||
flags['python'] = flags['py'] | ||
aliases = {'section': 'DisableNBExtensionApp.section'} | ||
|
||
user = Bool(False, config=True, help="Explicitly disable in user config") | ||
sys_prefix = Bool(False, config=True, | ||
help="Explicitly disable in sys.prefix config") | ||
|
||
python = Bool(False, config=True, help="Install from a Python package") | ||
|
||
section = Unicode('notebook', config=True, | ||
help="""Which config section to disable the extension in.""" | ||
) | ||
|
||
def start(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could we get away with only overriding start, instead of losing the ToggleNBExtensionApp inheritance? |
||
name = self.extra_args[0] | ||
|
||
disable_func = disable_nbextension_python if self.python \ | ||
else disable_nbextension | ||
if self.user: | ||
return disable_func(self.section, name, user=True, logger=self.log) | ||
if self.sys_prefix: | ||
return disable_func(self.section, name, sys_prefix=True, | ||
logger=self.log) | ||
|
||
# Default behaviour: find and remove config enabling an extension. | ||
if self.python: | ||
_, nbexts = _get_nbextension_metadata(name) | ||
changed = False | ||
for nbext in nbexts: | ||
if _find_disable_nbextension(self.section, nbext, | ||
logger=self.log): | ||
changed = True | ||
|
||
else: | ||
changed = _find_disable_nbextension(self.section, name, | ||
logger=self.log) | ||
|
||
if not changed: | ||
print("No config found enabling", name) | ||
|
||
_log_formatter_cls = LogFormatter | ||
|
||
def _log_format_default(self): | ||
"""A default format for messages""" | ||
return "%(message)s" | ||
|
||
|
||
class ListNBExtensionsApp(BaseExtensionApp): | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍