From 30af2029a0c847410f6df573196854be143b8e8b Mon Sep 17 00:00:00 2001 From: Andy Maloney <60523020+ndmlny-qs@users.noreply.github.com> Date: Thu, 3 Aug 2023 13:29:58 -0500 Subject: [PATCH] env var for extra_template_basedirs This commit add the following three items. - Updates the method `_default_extra_template_basedirs` in the module `templateexporter.py` to search for a new environment variable called `NBCONVERT_EXTRA_TEMPLATE_BASEDIRS`. This environment variable will be added to the basedirs list if it is found, and it exists. - Updates the tests to ensure if the new environment variable exists then it is included in the `TemplateExporter.template_paths`. - Adds a context manager method that modifies the `os.environ` dictionary. Closes #2026 --- nbconvert/exporters/templateexporter.py | 8 ++++- .../exporters/tests/test_templateexporter.py | 33 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/nbconvert/exporters/templateexporter.py b/nbconvert/exporters/templateexporter.py index 982b21e7b..65ea8873e 100644 --- a/nbconvert/exporters/templateexporter.py +++ b/nbconvert/exporters/templateexporter.py @@ -260,7 +260,13 @@ def _raw_template_changed(self, change): @default("extra_template_basedirs") def _default_extra_template_basedirs(self): - return [os.getcwd()] + basedirs = [os.getcwd()] + env = os.environ + if "NBCONVERT_EXTRA_TEMPLATE_BASEDIR" in env: + extra_template_path = env["NBCONVERT_EXTRA_TEMPLATE_BASEDIR"] + if os.path.exists(extra_template_path): + basedirs.append(extra_template_path) + return basedirs # Extension that the template files use. template_extension = Unicode().tag(config=True, affects_environment=True) diff --git a/nbconvert/exporters/tests/test_templateexporter.py b/nbconvert/exporters/tests/test_templateexporter.py index 88b4e86ac..80e75e5d5 100644 --- a/nbconvert/exporters/tests/test_templateexporter.py +++ b/nbconvert/exporters/tests/test_templateexporter.py @@ -8,6 +8,7 @@ import json import os from concurrent.futures import ProcessPoolExecutor +from contextlib import contextmanager from tempfile import TemporaryDirectory from unittest.mock import patch @@ -32,6 +33,20 @@ """ +@contextmanager +def temp_environ(**env): + for key, value in env.items(): + if value is None: + os.environ.pop(key, None) + else: + os.environ[key] = value + try: + yield + finally: + for key, _ in env.items(): + os.environ.pop(key, None) + + class SampleExporter(TemplateExporter): """ Exports a Python code file. @@ -268,6 +283,24 @@ def test_absolute_template_dir(self): assert exporter.template_name == template assert os.path.join(td, template) in exporter.template_paths + def test_env_var_template_dir(self): + with TemporaryDirectory() as td: + template = "env-var" + template_file = os.path.join(td, template, "index.py.j2") + template_dir = os.path.dirname(template_file) + os.mkdir(template_dir) + test_output = "env-var!" + with open(template_file, "w") as f: + f.write(test_output) + with temp_environ(NBCONVERT_EXTRA_TEMPLATE_BASEDIRS=template_dir): + config = Config() + config.TemplateExporter.template_name = template + config.TemplateExporter.extra_template_basedirs = [td, template_dir] + exporter = self._make_exporter(config=config) + assert exporter.template.filename == template_file + assert exporter.template_name == template + assert template_dir in exporter.template_paths + def test_local_template_dir(self): with TemporaryDirectory() as td, _contextlib_chdir.chdir(td): # noqa with patch("os.getcwd", return_value=os.path.abspath(td)):