cookiecutter.environment   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 6
eloc 26
dl 0
loc 66
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A ExtensionLoaderMixin._read_extensions() 0 12 3
A StrictEnvironment.__init__() 0 6 1
A ExtensionLoaderMixin.__init__() 0 24 2
1
"""Jinja2 environment and extensions loading."""
2
from jinja2 import Environment, StrictUndefined
3
4
from cookiecutter.exceptions import UnknownExtension
5
6
7
class ExtensionLoaderMixin:
8
    """Mixin providing sane loading of extensions specified in a given context.
9
10
    The context is being extracted from the keyword arguments before calling
11
    the next parent class in line of the child.
12
    """
13
14
    def __init__(self, **kwargs):
15
        """Initialize the Jinja2 Environment object while loading extensions.
16
17
        Does the following:
18
19
        1. Establishes default_extensions (currently just a Time feature)
20
        2. Reads extensions set in the cookiecutter.json _extensions key.
21
        3. Attempts to load the extensions. Provides useful error if fails.
22
        """
23
        context = kwargs.pop('context', {})
24
25
        default_extensions = [
26
            'cookiecutter.extensions.JsonifyExtension',
27
            'cookiecutter.extensions.RandomStringExtension',
28
            'cookiecutter.extensions.SlugifyExtension',
29
            'cookiecutter.extensions.UUIDExtension',
30
            'jinja2_time.TimeExtension',
31
        ]
32
        extensions = default_extensions + self._read_extensions(context)
33
34
        try:
35
            super().__init__(extensions=extensions, **kwargs)
36
        except ImportError as err:
37
            raise UnknownExtension(f'Unable to load extension: {err}') from err
38
39
    def _read_extensions(self, context):
40
        """Return list of extensions as str to be passed on to the Jinja2 env.
41
42
        If context does not contain the relevant info, return an empty
43
        list instead.
44
        """
45
        try:
46
            extensions = context['cookiecutter']['_extensions']
47
        except KeyError:
48
            return []
49
        else:
50
            return [str(ext) for ext in extensions]
51
52
53
class StrictEnvironment(ExtensionLoaderMixin, Environment):
54
    """Create strict Jinja2 environment.
55
56
    Jinja2 environment will raise error on undefined variable in template-
57
    rendering context.
58
    """
59
60
    def __init__(self, **kwargs):
61
        """Set the standard Cookiecutter StrictEnvironment.
62
63
        Also loading extensions defined in cookiecutter.json's _extensions key.
64
        """
65
        super().__init__(undefined=StrictUndefined, **kwargs)
66