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

Add (and fix) round_trip_tests_for_MyST_markdown #1345

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

mwouts
Copy link
Owner

@mwouts mwouts commented Mar 8, 2025

This PR will eventually close #1317 and #759

Copy link

github-actions bot commented Mar 8, 2025

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/mwouts/jupytext.git@round_trip_tests_for_myst_markdown

(this requires nodejs, see more at Developing Jupytext)

Copy link

codecov bot commented Mar 8, 2025

Codecov Report

Attention: Patch coverage is 95.00000% with 1 line in your changes missing coverage. Please review.

Project coverage is 97.03%. Comparing base (0bda545) to head (67c7181).

Files with missing lines Patch % Lines
src/jupytext/myst.py 93.75% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1345      +/-   ##
==========================================
+ Coverage   96.84%   97.03%   +0.19%     
==========================================
  Files          32       32              
  Lines        4906     4924      +18     
==========================================
+ Hits         4751     4778      +27     
+ Misses        155      146       -9     
Flag Coverage Δ
external 73.43% <50.00%> (?)
functional 86.95% <95.00%> (?)
integration 78.35% <25.00%> (?)
unit 65.85% <75.00%> (?)

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.

if (
is_myst_available()
and ext in myst_extensions()
and matches_mystnb(text, ext, requires_meta=False)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous setting requires_meta=True was the cause of the unstable round trips observed at #789 (comment)

if default_lexer is None:
language = metadata.get("kernelspec", {}).get(
"language"
) or metadata.get("jupytext", {}).get("main_language")
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notebooks constructed from minimalist MyST notebooks don't have any explicit metadata. When reading the MyST notebooks we will now parse the lexer and identify the notebook language from them.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to jupytext.default_lexer which unlike the above will work for all languages

@@ -348,6 +370,16 @@ def _flush_markdown(start_line, token, md_metadata):

if add_source_map:
notebook.metadata["source_map"] = source_map

if "kernelspec" not in notebook.metadata:
for language, count in languages.most_common(1):
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@choldgraf @chrisjsewell we don't expect multiple languages or lexers in the same notebook right? Would you prefer to raise if we observe multiple languages to avoid the risk of using a different language than the one intended?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to default_lexer equal to first non null lexer. There will be a warning if the lexers are not unique.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the near term, I don't think anyone is making use of the language feature for anything beyond syntax highlighting. And, there is current precedent for notebook frontends like JupyterLab to pass that information down to the kernel. There are multi-language kernels like SOS, but they patch the frontend to inject the context about which language is being executed, so they're fairly bespoke.

Given this situation, I'd be inclined to state that MyST notebooks are for-now single language, and raise an error. We can unwind this in future if we need. As far as the MyST-MD engine goes, I think we'd like for language to be optional for the cell, meaning that it should be possible to define it exclusively in the metadata / kernelspec.

I'd also be inclined to say that it is possible to interrogate the on-disk kernelspec for the language, but that introduces an "on-my-system" dependency that I don't think jupytext currently wants to do.

@mwouts mwouts force-pushed the round_trip_tests_for_myst_markdown branch from acfe47d to 67c7181 Compare March 9, 2025 20:38
@mwouts
Copy link
Owner Author

mwouts commented Mar 11, 2025

@choldgraf @chrisjsewell can you confirm you're fine with this change? In a nutshell I am adding a jupytext.default_lexer metadata to store the lexer seen in text notebooks, and I changed requires_meta=False to better identify MyST notebooks when they don't have a header. Thanks!

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.

jupytext --to md:myst *.md should be idempotent
2 participants