Skip to content

Commit

Permalink
Add a new preferred-dir traitlet
Browse files Browse the repository at this point in the history
  • Loading branch information
goanpeca committed Jul 7, 2021
1 parent 6dffef4 commit 9a641a3
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 4 deletions.
41 changes: 37 additions & 4 deletions jupyter_server/serverapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ def start(self):
'certfile': 'ServerApp.certfile',
'client-ca': 'ServerApp.client_ca',
'notebook-dir': 'ServerApp.root_dir',
'preferred-dir': 'ServerApp.preferred_dir',
'browser': 'ServerApp.browser',
'pylab': 'ServerApp.pylab',
'gateway-url': 'GatewayClient.url',
Expand Down Expand Up @@ -1138,22 +1139,54 @@ def _default_root_dir(self):
else:
return py3compat.getcwd()

@validate('root_dir')
def _root_dir_validate(self, proposal):
value = proposal['value']
def _normalize_root_or_preferred_dir(self, value):
# Strip any trailing slashes
# *except* if it's root
_, path = os.path.splitdrive(value)
if path == os.sep:
return value

value = value.rstrip(os.sep)
if not os.path.isabs(value):
# If we receive a non-absolute path, make it absolute.
value = os.path.abspath(value)

return value

@validate('root_dir')
def _root_dir_validate(self, proposal):
value = self._normalize_root_or_preferred_dir(proposal['value'])
if not os.path.isdir(value):
raise TraitError(trans.gettext("No such notebook dir: '%r'") % value)

return value

preferred_dir = Unicode(config=True,
help=_("Prefered starting directory to use for notebooks and kernels.")
)

@default('preferred_dir')
def _default_prefered_dir(self):
return self.root_dir

@validate('preferred_dir')
def _preferred_dir_validate(self, proposal):
value = self._normalize_root_or_preferred_dir(proposal['value'])
if not os.path.isdir(value):
raise TraitError(trans.gettext("No such preferred dir: '%r'") % value)

# preferred_dir must be equal or a subdir of root_dir
if not value.startswith(self.root_dir):
raise TraitError(trans.gettext("preferred_dir must be equal or a subdir of root_dir: '%r'") % value)

return value

@observe('root_dir')
def _update_root_dir(self, change):
if not self.preferred_dir.startswith(change['new']):
self.log.warning(_("Value of preferred_dir updated to use value of root_dir"))
self.preferred_dir = change['new']

@observe('server_extensions')
def _update_server_extensions(self, change):
self.log.warning(_("server_extensions is deprecated, use jpserver_extensions"))
Expand Down Expand Up @@ -1204,7 +1237,6 @@ def _update_server_extensions(self, change):
"""))

def parse_command_line(self, argv=None):

super(ServerApp, self).parse_command_line(argv)

if self.extra_args:
Expand All @@ -1222,6 +1254,7 @@ def parse_command_line(self, argv=None):
c.ServerApp.root_dir = f
elif os.path.isfile(f):
c.ServerApp.file_to_run = f

self.update_config(c)

def init_configurables(self):
Expand Down
89 changes: 89 additions & 0 deletions tests/test_serverapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,92 @@ def test_list_running_servers(serverapp, app):
servers = list(list_running_servers(serverapp.runtime_dir))
assert len(servers) >= 1


# Preferred dir tests
# ----------------------------------------------------------------------------
def test_valid_preferred_dir(tmp_path, configurable_serverapp):
path = str(tmp_path)
app = configurable_serverapp(root_dir=path, preferred_dir=path)
assert app.root_dir == path
assert app.preferred_dir == path
assert app.root_dir == app.preferred_dir


def test_valid_preferred_dir_is_root_subdir(tmp_path, configurable_serverapp):
path = str(tmp_path)
path_subdir = str(tmp_path / 'subdir')
os.makedirs(path_subdir, exist_ok=True)
app = configurable_serverapp(root_dir=path, preferred_dir=path_subdir)
assert app.root_dir == path
assert app.preferred_dir == path_subdir
assert app.preferred_dir.startswith(app.root_dir)


def test_valid_preferred_dir_does_not_exist(tmp_path, configurable_serverapp):
path = str(tmp_path)
path_subdir = str(tmp_path / 'subdir')
with pytest.raises(TraitError) as error:
app = configurable_serverapp(root_dir=path, preferred_dir=path_subdir)

assert "No such preferred dir:" in str(error)


def test_invalid_preferred_dir_does_not_exist(tmp_path, configurable_serverapp):
path = str(tmp_path)
path_subdir = str(tmp_path / 'subdir')
with pytest.raises(TraitError) as error:
app = configurable_serverapp(root_dir=path, preferred_dir=path_subdir)

assert "No such preferred dir:" in str(error)


def test_invalid_preferred_dir_does_not_exist_set(tmp_path, configurable_serverapp):
path = str(tmp_path)
path_subdir = str(tmp_path / 'subdir')

app = configurable_serverapp(root_dir=path)
with pytest.raises(TraitError) as error:
app.preferred_dir = path_subdir

assert "No such preferred dir:" in str(error)


def test_invalid_preferred_dir_not_root_subdir(tmp_path, configurable_serverapp):
path = str(tmp_path / 'subdir')
os.makedirs(path, exist_ok=True)
not_subdir_path = str(tmp_path)

with pytest.raises(TraitError) as error:
app = configurable_serverapp(root_dir=path, preferred_dir=not_subdir_path)

assert "preferred_dir must be equal or a subdir of root_dir:" in str(error)


def test_invalid_preferred_dir_not_root_subdir_set(tmp_path, configurable_serverapp):
path = str(tmp_path / 'subdir')
os.makedirs(path, exist_ok=True)
not_subdir_path = str(tmp_path)

app = configurable_serverapp(root_dir=path)
with pytest.raises(TraitError) as error:
app.preferred_dir = not_subdir_path

assert "preferred_dir must be equal or a subdir of root_dir:" in str(error)


def test_observed_root_dir_updates_preferred_dir(tmp_path, configurable_serverapp):
path = str(tmp_path)
new_path = str(tmp_path / 'subdir')
os.makedirs(new_path, exist_ok=True)

app = configurable_serverapp(root_dir=path, preferred_dir=path)
app.root_dir = new_path
assert app.preferred_dir == new_path


def test_observed_root_dir_does_not_update_preferred_dir(tmp_path, configurable_serverapp):
path = str(tmp_path)
new_path = str(tmp_path.parent)
app = configurable_serverapp(root_dir=path, preferred_dir=path)
app.root_dir = new_path
assert app.preferred_dir == path

0 comments on commit 9a641a3

Please sign in to comment.