Skip to content

Commit

Permalink
Move the jupytext-config helpers to a subpackage, and add tests (#1167)
Browse files Browse the repository at this point in the history
* Move the jupytext-config helpers to a subpackage and add tests
* Use settings_file rather than settings_path
* Simplify LabConfig and increase the coverage
* Locate the config using jupyter_core.paths.jupyter_config_dir()
  • Loading branch information
mwouts authored Nov 27, 2023
1 parent c37d9c2 commit 405617f
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 130 deletions.
119 changes: 0 additions & 119 deletions src/jupytext/labconfig.py

This file was deleted.

2 changes: 1 addition & 1 deletion src/jupytext_config/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import sys

from jupytext.jupytext_config import main
from .jupytext_config import main

if __name__ == "__main__":
sys.exit(main())
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

import sys
from argparse import ArgumentParser
from pathlib import Path

import jupyter_core.paths as jupyter_core_paths

from .labconfig import LabConfig

Expand All @@ -23,20 +26,15 @@ def main(self, args):
"""
return 0 if all goes well
"""
print(
f"{self.__class__.__name__}: redefine main() to implement this subcommand"
)
return 1
raise NotImplementedError() # pragma: no cover


class ListDefaultViewer(SubCommand):
def __init__(self):
super().__init__(
"list-default-viewer", "Display current settings in labconfig/"
)
super().__init__("list-default-viewer", "Display current settings in labconfig")

def main(self, args):
LabConfig().read().list_default_viewer()
LabConfig(settings_file=args.settings_file).read().list_default_viewer()
return 0

def fill_parser(self, subparser):
Expand All @@ -48,7 +46,9 @@ def __init__(self):
super().__init__("set-default-viewer", "Set default viewers for JupyterLab")

def main(self, args):
LabConfig().read().set_default_viewers(args.doctype).write()
LabConfig(settings_file=args.settings_file).read().set_default_viewers(
args.doctype
).write()
return 0

def fill_parser(self, subparser):
Expand All @@ -65,7 +65,9 @@ def __init__(self):
super().__init__("unset-default-viewer", "Unset default viewers for JupyterLab")

def main(self, args):
LabConfig().read().unset_default_viewers(args.doctype).write()
LabConfig(settings_file=args.settings_file).read().unset_default_viewers(
args.doctype
).write()
return 0

def fill_parser(self, subparser):
Expand All @@ -87,6 +89,12 @@ def fill_parser(self, subparser):

def main():
parser = ArgumentParser()
parser.add_argument(
"--settings-file",
default=Path(jupyter_core_paths.jupyter_config_dir())
/ "labconfig"
/ "default_setting_overrides.json",
)
subparsers = parser.add_subparsers(required=True)
for subcommand in SUBCOMMANDS:
subparser = subparsers.add_parser(subcommand.name, help=subcommand.help)
Expand Down
86 changes: 86 additions & 0 deletions src/jupytext_config/labconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
helper to inspect / initialize jupyterlab labconfig settings
that are required to open jupytext notebooks in jupyterlab by default
when these settings are not present, a double click on a jupytext
notebook will cause jupyterlab to open it in an editor, i.e. as a text file
"""

import json
import logging
from pathlib import Path


class LabConfig:
DOCTYPES = [
"python",
"markdown",
"myst",
"r-markdown",
"quarto",
"julia",
"r",
]

def __init__(self, *, settings_file, logger=None):
self.settings_file = Path(settings_file)
self.logger = logger or logging.getLogger(__name__)
self.config = {}

def read(self):
"""
read the labconfig settings file
"""
if self.settings_file.exists():
with self.settings_file.open() as fid:
self.config = json.load(fid)
else:
self.logger.info(f"Could not read from {self.settings_file} (not found)")

return self

def get_viewers(self):
return self.config.setdefault(
"@jupyterlab/docmanager-extension:plugin", {}
).setdefault("defaultViewers", {})

def list_default_viewer(self):
"""
list the current labconfig settings
"""
self.logger.debug(
f"Current @jupyterlab/docmanager-extension:plugin in {self.settings_file}"
)
for key, value in self.get_viewers().items():
print(f"{key}: {value}")

def set_default_viewers(self, doctypes=None):
if not doctypes:
doctypes = self.DOCTYPES
for doctype in doctypes:
self.set_default_viewer(doctype)
return self

def set_default_viewer(self, doctype):
viewers = self.get_viewers()
if doctype not in viewers:
viewers[doctype] = "Jupytext Notebook"

def unset_default_viewers(self, doctypes=None):
if not doctypes:
doctypes = self.DOCTYPES
for doctype in doctypes:
self.unset_default_viewer(doctype)
return self

def unset_default_viewer(self, doctype):
viewers = self.get_viewers()
if doctype in viewers:
del viewers[doctype]

def write(self):
"""
write the labconfig settings file
"""
self.settings_file.parent.mkdir(parents=True, exist_ok=True)
with self.settings_file.open("w") as fid:
json.dump(self.config, fid, indent=2)
30 changes: 30 additions & 0 deletions tests/integration/jupytext_config/test_jupytext_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from jupytext.cli import system


def test_jupytext_config_cli(tmp_path):
settings_file = tmp_path / "default_setting_overrides.json"
system("jupytext-config", "-h")
system(
"jupytext-config",
"--settings-file",
str(settings_file),
"set-default-viewer",
"python",
"markdown",
)
assert "python" in (settings_file).read_text()
assert "markdown" in system(
"jupytext-config", "--settings-file", settings_file, "list-default-viewer"
)
system(
"jupytext-config",
"--settings-file",
str(settings_file),
"unset-default-viewer",
"markdown",
)
list_viewers = system(
"jupytext-config", "--settings-file", settings_file, "list-default-viewer"
)
assert "python" in list_viewers
assert "markdown" not in list_viewers
55 changes: 55 additions & 0 deletions tests/unit/test_labconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import json

import pytest

from jupytext_config.labconfig import LabConfig


@pytest.fixture()
def sample_viewer_config():
return {
"@jupyterlab/docmanager-extension:plugin": {
"defaultViewers": {
"markdown": "Jupytext Notebook",
"myst": "Jupytext Notebook",
"r-markdown": "Jupytext Notebook",
"quarto": "Jupytext Notebook",
"julia": "Jupytext Notebook",
"python": "Jupytext Notebook",
"r": "Jupytext Notebook",
}
}
}


@pytest.fixture()
def sample_empty_viewer_config():
return {"@jupyterlab/docmanager-extension:plugin": {"defaultViewers": {}}}


@pytest.fixture()
def settings_file(tmp_path):
return tmp_path / "default_setting_overrides.json"


def test_read_config(settings_file, sample_viewer_config):
(settings_file).write_text(json.dumps(sample_viewer_config))
labconfig = LabConfig(settings_file=settings_file).read()
assert labconfig.config == sample_viewer_config


def test_set_unset_default_viewers(
settings_file, sample_viewer_config, sample_empty_viewer_config
):
labconfig = LabConfig(settings_file=settings_file)
labconfig.set_default_viewers()
assert labconfig.config == sample_viewer_config
labconfig.unset_default_viewers()
assert labconfig.config == sample_empty_viewer_config


def test_write_config(settings_file, sample_viewer_config):
labconfig = LabConfig(settings_file=settings_file)
labconfig.set_default_viewers()
labconfig.write()
assert json.loads(settings_file.read_text()) == sample_viewer_config

0 comments on commit 405617f

Please sign in to comment.