Skip to content

fix(extensions): ensure trusted/safe templates extensions are seen during update or copy with --vcs-ref#2557

Open
noirbizarre wants to merge 1 commit intocopier-org:masterfrom
noirbizarre:fix/sys-template-path
Open

fix(extensions): ensure trusted/safe templates extensions are seen during update or copy with --vcs-ref#2557
noirbizarre wants to merge 1 commit intocopier-org:masterfrom
noirbizarre:fix/sys-template-path

Conversation

@noirbizarre
Copy link
Contributor

Hello 👋🏼

This PR fix a regression on template extensions.
When a template provides some extensions, they are not on sys.path anymore when:

  • using copy with --vcs-ref
  • using update

It fails with the following error (for a extensions package in the template directory)

Copier could not load some Jinja extensions:
No module named 'extensions'
Make sure to install these extensions alongside copier itself.

I can't say precisely in what version it broke, but it was working on Copier 9.3, 9.4 (I think it worked in 9.10) and not anymore since 9.12.

This PR fix this by explicitely adding the template path to sys.path when the template is trusted.

@codecov
Copy link

codecov bot commented Mar 17, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.27%. Comparing base (ba15e57) to head (296faa6).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2557      +/-   ##
==========================================
+ Coverage   97.25%   97.27%   +0.01%     
==========================================
  Files          58       58              
  Lines        6751     6782      +31     
==========================================
+ Hits         6566     6597      +31     
  Misses        185      185              
Flag Coverage Δ
unittests 97.27% <100.00%> (+0.01%) ⬆️

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.

@noirbizarre noirbizarre force-pushed the fix/sys-template-path branch from 0476c29 to b3f5747 Compare March 17, 2026 13:24
@noirbizarre noirbizarre force-pushed the fix/sys-template-path branch from b3f5747 to 296faa6 Compare March 17, 2026 13:48
@sisp
Copy link
Member

sisp commented Mar 17, 2026

Are you sure this ever worked without copier-template-extensions? I've checked out the v9.4.1 tag, added your fixture and tests, and ran those tests – they're failing for me:

FAILED tests/test_jinja2_extensions.py::test_extension_on_update - copier.errors.ExtensionNotFoundError: Copier could not load some Jinja extensions:
FAILED tests/test_jinja2_extensions.py::test_extension_from_copy_with_vcs_ref - copier.errors.ExtensionNotFoundError: Copier could not load some Jinja extensions:

This is an excerpt of the stack trace:

    @cached_property
    def jinja_env(self) -> SandboxedEnvironment:
        """Return a pre-configured Jinja environment.
    
        Respects template settings.
        """
        paths = [str(self.template.local_abspath)]
        loader = FileSystemLoader(paths)
        default_extensions = [
            "jinja2_ansible_filters.AnsibleCoreFiltersExtension",
        ]
        extensions = default_extensions + list(self.template.jinja_extensions)
        # We want to minimize the risk of hidden malware in the templates
        # so we use the SandboxedEnvironment instead of the regular one.
        # Of course we still have the post-copy tasks to worry about, but at least
        # they are more visible to the final user.
        try:
            env = SandboxedEnvironment(
                loader=loader, extensions=extensions, **self.template.envops
            )
        except ModuleNotFoundError as error:
>           raise ExtensionNotFoundError(
                f"Copier could not load some Jinja extensions:\n{error}\n"
                "Make sure to install these extensions alongside Copier itself.\n"
                "See the docs at https://copier.readthedocs.io/en/latest/configuring/#jinja_extensions"
            )
E           copier.errors.ExtensionNotFoundError: Copier could not load some Jinja extensions:
E           No module named 'extensions'
E           Make sure to install these extensions alongside Copier itself.
E           See the docs at https://copier.readthedocs.io/en/latest/configuring/#jinja_extensions

@noirbizarre
Copy link
Contributor Author

noirbizarre commented Mar 18, 2026

You're right, it only works with copier-template-extensions and in my case, it doesn't support imports (which is what triggered my error, that I solved by duplicating into the loaded extension module).

I'll close the PR unless you are interested in this feature (I would be truly interested into supporting template-local imports, it would simplify a lot of things)

@sisp
Copy link
Member

sisp commented Mar 18, 2026

I think that template-local extension loading using file paths is preferable over module names in the search path for better clarity. This is what copier-template-extensions is doing. I agree that loading template-local extensions is a rather common use case which may deserve first-class support by Copier. This has been discussed before (#1756), a few more points to consider were raised there. I'm curious what you think.

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.

2 participants