Skip to content

Conversation

@krassowski
Copy link
Contributor

This fixes #398 by using higher precedence pattern matching to restore original icons for files which are now declared by the server's content manager as notebooks.

The file types which default to a notebook factory (.Rmd, .qmd, .mnb and other myst extensions) have now an orange border box indicator which makes them look more like the notebook icon. I think this is a nice idea but happy to drop it (I initially added that for debugging purposes).

Before After this PR
image image
Details
After this PR Without jupytext
image image

@github-actions
Copy link

Thank you for making this pull request.

Did you know? You can try it on Binder: Binder:lab or Binder:notebook.

Also, the version of Jupytext developed in this PR can be installed with pip:

HATCH_BUILD_HOOKS_ENABLE=true pip install git+https://github.com/krassowski/jupytext.git@add-back-default-icons

(this requires nodejs, see more at Developing Jupytext)

@mwouts
Copy link
Owner

mwouts commented Jan 20, 2026

Hi @krassowski , thank you for the PR, it's very nice of you to make this finally happen ! I do like the extra red square (and I am impressed at how many extensions you have tested!!)

Can you explain what it means for a file types to default to a notebook factory ? Does it depend on the user configuration, and if so, can a user get that little box for e.g. a Python script if they decide to open .py files with the notebook viewer by default ? Thanks !

@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.92%. Comparing base (1eb46dc) to head (9a46189).
⚠️ Report is 1 commits behind head on main.

❌ Your project status has failed because the head coverage (93.94%) is below the target coverage (96.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1482      +/-   ##
==========================================
- Coverage   96.45%   93.92%   -2.53%     
==========================================
  Files          30       30              
  Lines        5298     5298              
==========================================
- Hits         5110     4976     -134     
- Misses        188      322     +134     
Flag Coverage Δ
external ?
functional ?
integration ?
unit ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@krassowski
Copy link
Contributor Author

Does it depend on the user configuration, and if so, can a user get that little box for e.g. a Python script if they decide to open .py files with the notebook viewer by default ?

No, currently it does not so it would always be these pre-defined file types that are registered here.

@krassowski krassowski marked this pull request as ready for review January 21, 2026 12:33
@mwouts
Copy link
Owner

mwouts commented Jan 21, 2026

No, currently it does not so it would always be these pre-defined file types that are registered here.

I see, thanks for the link. I will give a try at the PR over the week-end, sounds great - I might have to update the documentation as I list the notebook icon on text notebook as one way to check that Jupytext's content manager has been activated, but that's really not a concern 😄

@mahendrapaipuri any thoughts on this ?

@mwouts mwouts force-pushed the add-back-default-icons branch from 909c723 to 0ec4fda Compare January 25, 2026 17:18
@mahendrapaipuri
Copy link
Collaborator

@mwouts This is a great addition. Cheers @krassowski for proposing this!

@mwouts
Copy link
Owner

mwouts commented Jan 25, 2026

@mwouts This is a great addition. Cheers @krassowski for proposing this!

Thank you @mahendrapaipuri for giving your go! I am trying to build this locally, but unlike the CI I run into errors. I have tried this:

HATCH_BUILD_HOOKS_ENABLE=true pixi run hatch build

which failed with

Unknown build hook: jupyter-builder (...)

──────────────────────────────────────────────────────────────── sdist ─────────────────────────────────────────────────────────────────
Processing README.md to generate build/README_with_absolute_links.md with absolute links
Generated build/README_with_absolute_links.md with absolute links
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/__main__.py", line 6, in <module>
    sys.exit(hatchling())
             ^^^^^^^^^^^
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/cli/__init__.py", line 26, in hatchling
    command(**kwargs)
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/cli/build/__init__.py", line 82, in build_impl
    for artifact in builder.build(
                    ^^^^^^^^^^^^^^
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py", line 118, in build
    configured_build_hooks = self.get_build_hooks(directory)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py", line 388, in get_build_hooks
    raise UnknownPluginError(message)
hatchling.plugin.exceptions.UnknownPluginError: Unknown build hook: jupyter-builder

and also

pixi shell
HATCH_BUILD_HOOKS_ENABLE=true pip install -e .[dev]

which failed with

Error: Cannot find module 'at-least-node' (...)

Obtaining file:///home/marc/GitHub/jupytext
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build editable ... done
  Installing backend dependencies ... done
  Preparing editable metadata (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Preparing editable metadata (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [93 lines of output]
      INFO:hatch_jupyter_builder.utils:Running jupyter-builder
      INFO:hatch_jupyter_builder.utils:Building with hatch_jupyter_builder.npm_builder
      INFO:hatch_jupyter_builder.utils:With kwargs: {'path': 'jupyterlab', 'build_cmd': 'build', 'npm': ['jlpm'], 'source_dir': 'jupyterlab/packages', 'build_dir': 'jupyterlab/jupyterlab_jupytext/labextension'}
      INFO:hatch_jupyter_builder.utils:Installing build dependencies with npm.  This may take a while...
      INFO:hatch_jupyter_builder.utils:> /tmp/pip-build-env-usqunc3_/overlay/bin/jlpm install
      ➤ YN0000: ┌ Resolution step
      ➤ YN0002: │ @jupyterlab/galata@npm:5.5.2 doesn't provide react (pd4688), requested by @jupyterlab/settingregistry
      ➤ YN0002: │ @jupyterlab/services@npm:7.5.2 doesn't provide react (p92ef2), requested by @jupyterlab/settingregistry
      ➤ YN0002: │ @nrwl/devkit@npm:16.10.0 doesn't provide nx (p048f2), requested by @nx/devkit
      ➤ YN0060: │ jupyterlab-jupytext-extensions@workspace:. provides stylelint (p02a34) with version 16.26.1, which doesn't satisfy what stylelint-config-prettier requests
      ➤ YN0002: │ jupyterlab-jupytext@workspace:packages/jupyterlab-jupytext-extension doesn't provide react (p136f5), requested by @jupyterlab/settingregistry
      ➤ YN0002: │ jupyterlab-rise@npm:0.43.1 doesn't provide react (p4ffce), requested by @jupyterlab/settingregistry
      ➤ YN0000: │ Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code
      ➤ YN0000: └ Completed in 0s 274ms
      ➤ YN0000: ┌ Fetch step
      ➤ YN0013: │ typescript@patch:typescript@npm%3A5.9.3#~builtin<compat/typescript>::version=5.9.3&hash=85af82 can't be found in the cache and will be fetched from the disk
      ➤ YN0000: └ Completed in 0s 500ms
      ➤ YN0000: ┌ Link step
      ➤ YN0000: └ Completed in 0s 440ms
      ➤ YN0000: Done with warnings in 1s 297ms
      INFO:hatch_jupyter_builder.utils:> /tmp/pip-build-env-usqunc3_/overlay/bin/jlpm run build
      node:internal/modules/cjs/loader:1423
        throw err;
        ^
      
      Error: Cannot find module 'at-least-node'
      Require stack:
      - /home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/mkdirs/make-dir.js
      - /home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/mkdirs/index.js
      - /home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/copy-sync/copy-sync.js
      - /home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/copy-sync/index.js
      - /home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/index.js
      - /home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/dist/index.js
      - /home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/dist/cli.js
          at Module._resolveFilename (node:internal/modules/cjs/loader:1420:15)
          at defaultResolveImpl (node:internal/modules/cjs/loader:1058:19)
          at resolveForCJSWithHooks (node:internal/modules/cjs/loader:1063:22)
          at Module._load (node:internal/modules/cjs/loader:1226:37)
          at TracingChannel.traceSync (node:diagnostics_channel:328:14)
          at wrapModuleLoad (node:internal/modules/cjs/loader:244:24)
          at Module.require (node:internal/modules/cjs/loader:1503:12)
          at require (node:internal/modules/helpers:152:16)
          at Object.<anonymous> (/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/mkdirs/make-dir.js:9:21)
          at Module._compile (node:internal/modules/cjs/loader:1760:14) {
        code: 'MODULE_NOT_FOUND',
        requireStack: [
          '/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/mkdirs/make-dir.js',
          '/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/mkdirs/index.js',
          '/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/copy-sync/copy-sync.js',
          '/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/copy-sync/index.js',
          '/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/node_modules/fs-extra/lib/index.js',
          '/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/dist/index.js',
          '/home/marc/GitHub/jupytext/jupyterlab/node_modules/lerna/dist/cli.js'
        ]
      }
      
      Node.js v24.9.0
      Processing README.md to generate build/README_with_absolute_links.md with absolute links
      Generated build/README_with_absolute_links.md with absolute links
      Traceback (most recent call last):
        File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 195, in prepare_metadata_for_build_editable
          hook = backend.prepare_metadata_for_build_editable
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      AttributeError: module 'hatchling.build' has no attribute 'prepare_metadata_for_build_editable'
      
      During handling of the above exception, another exception occurred:
      
      Traceback (most recent call last):
        File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 389, in <module>
          main()
        File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 373, in main
          json_out["return_val"] = hook(**hook_input["kwargs"])
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 204, in prepare_metadata_for_build_editable
          whl_basename = build_hook(metadata_directory, config_settings)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/tmp/pip-build-env-usqunc3_/overlay/lib/python3.12/site-packages/hatchling/build.py", line 83, in build_editable
          return os.path.basename(next(builder.build(directory=wheel_directory, versions=["editable"])))
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/tmp/pip-build-env-usqunc3_/overlay/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py", line 149, in build
          build_hook.initialize(version, build_data)
        File "/tmp/pip-build-env-usqunc3_/overlay/lib/python3.12/site-packages/hatch_jupyter_builder/plugin.py", line 94, in initialize
          raise e
        File "/tmp/pip-build-env-usqunc3_/overlay/lib/python3.12/site-packages/hatch_jupyter_builder/plugin.py", line 89, in initialize
          build_func(self.target_name, version, **build_kwargs)
        File "/tmp/pip-build-env-usqunc3_/overlay/lib/python3.12/site-packages/hatch_jupyter_builder/utils.py", line 117, in npm_builder
          run([*npm_cmd, "run", build_cmd], cwd=str(abs_path))
        File "/tmp/pip-build-env-usqunc3_/overlay/lib/python3.12/site-packages/hatch_jupyter_builder/utils.py", line 231, in run
          return subprocess.check_call(cmd, **kwargs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/subprocess.py", line 413, in check_call
          raise CalledProcessError(retcode, cmd)
      subprocess.CalledProcessError: Command '['/tmp/pip-build-env-usqunc3_/overlay/bin/jlpm', 'run', 'build']' returned non-zero exit status 1.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

note: This is an issue with the package mentioned above, not pip.
hint: See above for details.

Do you have a clue on how to address these? Isn't it odd that the build CI passed? The only difference that I see is that my pixi is 0.61.0 while the CI has 0.59.0.

@mahendrapaipuri
Copy link
Collaborator

@mwouts I could build the package and run pip install -e . as well. Maybe clean your pixi envs and start from scratch?

──────────────────────────────────────────────────────────────── sdist ─────────────────────────────────────────────────────────────────
Processing README.md to generate build/README_with_absolute_links.md with absolute links
Generated build/README_with_absolute_links.md with absolute links
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/__main__.py", line 6, in <module>
    sys.exit(hatchling())
             ^^^^^^^^^^^
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/cli/__init__.py", line 26, in hatchling
    command(**kwargs)
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/cli/build/__init__.py", line 82, in build_impl
    for artifact in builder.build(
                    ^^^^^^^^^^^^^^
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py", line 118, in build
    configured_build_hooks = self.get_build_hooks(directory)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/marc/GitHub/jupytext/.pixi/envs/default/lib/python3.12/site-packages/hatchling/builders/plugin/interface.py", line 388, in get_build_hooks
    raise UnknownPluginError(message)
hatchling.plugin.exceptions.UnknownPluginError: Unknown build hook: jupyter-builder

This error is what we fixed in the last PR. So, it is strange you are getting it again!

@mwouts
Copy link
Owner

mwouts commented Jan 25, 2026

This error is what we fixed in the last PR. So, it is strange yu are getting it again!

Thanks @mahendrapaipuri for the confirmation ! The issue went away once I ran rm -rf jupyterlab/node_modules/.

@mwouts mwouts merged commit 4895de7 into mwouts:main Jan 25, 2026
35 of 36 checks passed
@mwouts
Copy link
Owner

mwouts commented Jan 25, 2026

Tested locally, works well! Thank you again @krassowski . I will prepare a release later on today.

@krassowski
Copy link
Contributor Author

Thank you!

@mwouts
Copy link
Owner

mwouts commented Jan 25, 2026

Thank you!

My pleasure, thank you @krassowski for making the PR!

On another topic, I would like to see what we could do about Jupytext+JupyterLite, would you have recommendations for #1225 ?

@martinRenou
Copy link
Contributor

Hello there! Looking at the code, I fail to understand exactly why, but it seems this PR may be responsible for breaking icons for extensions like JupyterGIS: See our jupyterlite deployment (which includes the jupytext labextension in it): https://jupytergis.readthedocs.io/en/latest/lite/lab

Pinning jupytext fixes it: geojupyter/jupytergis#1092

@krassowski
Copy link
Contributor Author

It looks like this needs a change in JupyterLab, I opened jupyterlab/jupyterlab#18397 to track it.

@mwouts
Copy link
Owner

mwouts commented Jan 28, 2026

Thank you @martinRenou for reporting the issue, and @krassowski for the follow-up. Let me know if you need anything from my part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refrain from changing file type icons

4 participants