From 25a29c3b2d477e8135eebeed0bfddd7081a91066 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Wed, 15 Jun 2022 15:53:39 +0100 Subject: [PATCH 1/8] Feat: allow any value for expr --- myst_nb/core/execute/inline.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/myst_nb/core/execute/inline.py b/myst_nb/core/execute/inline.py index c1b3b12a..cecf6ab8 100644 --- a/myst_nb/core/execute/inline.py +++ b/myst_nb/core/execute/inline.py @@ -151,8 +151,6 @@ def code_cell_outputs( return cell.get("execution_count", None), cell.get("outputs", []) def eval_variable(self, name: str) -> list[NotebookNode]: - if not EVAL_NAME_REGEX.match(name): - raise EvalNameError(name) return self._client.eval_expression(name) From a1eff009db5ee6112fd125bc95ff41eed8b4015c Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Wed, 15 Jun 2022 16:07:17 +0100 Subject: [PATCH 2/8] Chore: remove unused identifier --- myst_nb/core/execute/base.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/myst_nb/core/execute/base.py b/myst_nb/core/execute/base.py index edcfd03d..702a235e 100644 --- a/myst_nb/core/execute/base.py +++ b/myst_nb/core/execute/base.py @@ -39,9 +39,6 @@ class EvalNameError(Exception): """An exception for if an evaluation variable name is invalid.""" -EVAL_NAME_REGEX = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$") - - class NotebookClientBase: """A base client for interacting with Jupyter notebooks. From b37e5502b33bdc14c32121beb25d014142eea23e Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Wed, 15 Jun 2022 16:52:25 +0100 Subject: [PATCH 3/8] Fix: missed some existing definitions --- myst_nb/core/execute/base.py | 5 ----- myst_nb/core/execute/inline.py | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/myst_nb/core/execute/base.py b/myst_nb/core/execute/base.py index 702a235e..3a3d2ba7 100644 --- a/myst_nb/core/execute/base.py +++ b/myst_nb/core/execute/base.py @@ -2,7 +2,6 @@ from __future__ import annotations from pathlib import Path -import re from typing import Any from nbformat import NotebookNode @@ -35,10 +34,6 @@ class ExecutionError(Exception): """An exception for failed execution and `execution_raise_on_error` is true.""" -class EvalNameError(Exception): - """An exception for if an evaluation variable name is invalid.""" - - class NotebookClientBase: """A base client for interacting with Jupyter notebooks. diff --git a/myst_nb/core/execute/inline.py b/myst_nb/core/execute/inline.py index cecf6ab8..79761eb3 100644 --- a/myst_nb/core/execute/inline.py +++ b/myst_nb/core/execute/inline.py @@ -22,7 +22,7 @@ from myst_nb.ext.glue import extract_glue_data_cell -from .base import EVAL_NAME_REGEX, EvalNameError, ExecutionError, NotebookClientBase +from .base import ExecutionError, NotebookClientBase class NotebookClientInline(NotebookClientBase): From 5e866bbb528d2b970fd0d9012a210f7f60d92004 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Wed, 15 Jun 2022 16:54:27 +0100 Subject: [PATCH 4/8] Fix: remove last references to eval name --- myst_nb/ext/eval/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/myst_nb/ext/eval/__init__.py b/myst_nb/ext/eval/__init__.py index 3b565c74..3f10ae42 100644 --- a/myst_nb/ext/eval/__init__.py +++ b/myst_nb/ext/eval/__init__.py @@ -7,7 +7,6 @@ from docutils import nodes from docutils.parsers.rst import directives as spec -from myst_nb.core.execute.base import EvalNameError from myst_nb.core.render import NbElementRenderer from myst_nb.core.variables import ( RetrievalError, @@ -42,8 +41,6 @@ def retrieve_eval_data(document: nodes.document, key: str) -> list[VariableOutpu outputs = element.renderer.nb_client.eval_variable(key) except NotImplementedError: raise RetrievalError("This document does not have a running kernel") - except EvalNameError: - raise RetrievalError(f"The variable {key!r} is not a valid name") except Exception as exc: raise RetrievalError(f"variable evaluation error: {exc}") if not outputs: From a40abebdfa913935ae50231a3829e7cb63d98381 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 27 Feb 2023 15:53:02 +0000 Subject: [PATCH 5/8] feat: add config setting for name regex --- myst_nb/core/config.py | 8 ++++++++ myst_nb/core/execute/base.py | 4 ++++ myst_nb/core/execute/inline.py | 4 +++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/myst_nb/core/config.py b/myst_nb/core/config.py index d90e85ab..d3b11080 100644 --- a/myst_nb/core/config.py +++ b/myst_nb/core/config.py @@ -188,6 +188,14 @@ def __post_init__(self): "sections": (Section.global_lvl, Section.execute), }, ) + eval_name_regex: str = dc.field( + default=r"^[a-zA-Z_][a-zA-Z0-9_]*$", + metadata={ + "validator": instance_of(str), + "help": "Regex that matches permitted values of eval expressions", + "sections": (Section.global_lvl, Section.file_lvl, Section.execute), + }, + ) execution_mode: Literal["off", "force", "auto", "cache", "inline"] = dc.field( default="auto", metadata={ diff --git a/myst_nb/core/execute/base.py b/myst_nb/core/execute/base.py index 3a3d2ba7..befb6d29 100644 --- a/myst_nb/core/execute/base.py +++ b/myst_nb/core/execute/base.py @@ -34,6 +34,10 @@ class ExecutionError(Exception): """An exception for failed execution and `execution_raise_on_error` is true.""" +class EvalNameError(Exception): + """An exception for if an evaluation variable name is invalid.""" + + class NotebookClientBase: """A base client for interacting with Jupyter notebooks. diff --git a/myst_nb/core/execute/inline.py b/myst_nb/core/execute/inline.py index 79761eb3..26d6f2ac 100644 --- a/myst_nb/core/execute/inline.py +++ b/myst_nb/core/execute/inline.py @@ -22,7 +22,7 @@ from myst_nb.ext.glue import extract_glue_data_cell -from .base import ExecutionError, NotebookClientBase +from .base import EvalNameError, ExecutionError, NotebookClientBase class NotebookClientInline(NotebookClientBase): @@ -151,6 +151,8 @@ def code_cell_outputs( return cell.get("execution_count", None), cell.get("outputs", []) def eval_variable(self, name: str) -> list[NotebookNode]: + if not re.match(self.nb_config.eval_name_regex, name): + raise EvalNameError(name) return self._client.eval_expression(name) From e8f8f4a0b699598edcc701e3635fe0570b9fb865 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Mon, 27 Feb 2023 15:58:37 +0000 Subject: [PATCH 6/8] fix: add import --- myst_nb/core/execute/inline.py | 1 + 1 file changed, 1 insertion(+) diff --git a/myst_nb/core/execute/inline.py b/myst_nb/core/execute/inline.py index 26d6f2ac..4c716cbf 100644 --- a/myst_nb/core/execute/inline.py +++ b/myst_nb/core/execute/inline.py @@ -3,6 +3,7 @@ import asyncio from datetime import datetime +import re import shutil from tempfile import mkdtemp import time From 0bb7bc891a2db7d482ad1d373cc4b8519a337ac5 Mon Sep 17 00:00:00 2001 From: Angus Hollands Date: Fri, 23 Jun 2023 12:10:33 +0100 Subject: [PATCH 7/8] feat: improve error message --- myst_nb/ext/eval/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/myst_nb/ext/eval/__init__.py b/myst_nb/ext/eval/__init__.py index 3f10ae42..29cf3f3a 100644 --- a/myst_nb/ext/eval/__init__.py +++ b/myst_nb/ext/eval/__init__.py @@ -7,6 +7,7 @@ from docutils import nodes from docutils.parsers.rst import directives as spec +from myst_nb.core.execute.base import EvalNameError from myst_nb.core.render import NbElementRenderer from myst_nb.core.variables import ( RetrievalError, @@ -41,10 +42,12 @@ def retrieve_eval_data(document: nodes.document, key: str) -> list[VariableOutpu outputs = element.renderer.nb_client.eval_variable(key) except NotImplementedError: raise RetrievalError("This document does not have a running kernel") + except EvalNameError: + raise RetrievalError(f"The expression {key!r} is not valid according to the configured pattern") except Exception as exc: raise RetrievalError(f"variable evaluation error: {exc}") if not outputs: - raise RetrievalError(f"variable {key!r} does not return any outputs") + raise RetrievalError(f"expression {key!r} does not return any outputs") # the returned outputs could be one of the following: # https://nbformat.readthedocs.io/en/latest/format_description.html#code-cell-outputs From 56adeb9e90de91030abdd3db93faab9af9f58b5e Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:10:58 +0000 Subject: [PATCH 8/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- myst_nb/ext/eval/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/myst_nb/ext/eval/__init__.py b/myst_nb/ext/eval/__init__.py index 29cf3f3a..52c04cd2 100644 --- a/myst_nb/ext/eval/__init__.py +++ b/myst_nb/ext/eval/__init__.py @@ -43,7 +43,9 @@ def retrieve_eval_data(document: nodes.document, key: str) -> list[VariableOutpu except NotImplementedError: raise RetrievalError("This document does not have a running kernel") except EvalNameError: - raise RetrievalError(f"The expression {key!r} is not valid according to the configured pattern") + raise RetrievalError( + f"The expression {key!r} is not valid according to the configured pattern" + ) except Exception as exc: raise RetrievalError(f"variable evaluation error: {exc}") if not outputs: