Skip to content
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

Move the jupytext-config helpers to a subpackage, and add tests #1167

Merged
merged 4 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading