Skip to content

jinjarope

Class info

Classes

Name Children Inherits
BlockNotFoundError
jinjarope.environment
Exception for not-found template blocks.
    ChoiceLoader
    jinjarope.loaders
    A loader which combines multiple other loaders.
      DictLoader
      jinjarope.loaders
      A loader to load static content from a path->template-str mapping.
        EnvConfig
        jinjarope.envconfig
        A class representing the config of an Environment.
          Environment
          jinjarope.environment
          An enhanced Jinja environment.
          FileSystemLoader
          jinjarope.loaders
          A loader to load templates from the file system.
            FsSpecFileSystemLoader
            jinjarope.fsspecloaders
            A jinja loader for fsspec filesystems.
              FsSpecProtocolPathLoader
              jinjarope.fsspecloaders
              A jinja loader for fsspec filesystems.
                FunctionLoader
                jinjarope.loaders
                A loader for loading templates from a function.
                  JinjaFile
                  jinjarope.jinjafile
                  A file defining filters / tests.
                    JinjaItem
                    jinjarope.jinjafile
                    An item representing a filter / test.
                      LoaderMixin
                      jinjarope.loaders
                      Loader mixin which allows to OR loaders into a choice loader.
                      LoaderRegistry
                      jinjarope.loaderregistry
                      Registry which caches and builds jinja loaders.
                        ModuleLoader
                        jinjarope.loaders
                        This loader loads templates from precompiled templates.
                          NestedDictLoader
                          jinjarope.configloaders
                          A jinja loader for loading templates from nested dicts.
                          PackageLoader
                          jinjarope.loaders
                          A loader for loading templates from a package.
                            PrefixLoader
                            jinjarope.loaders
                            A loader for prefixing other loaders.
                              RewriteLoader
                              jinjarope.rewriteloader
                              A loader which modifies templates based on a callable.
                                TemplateFileLoader
                                jinjarope.configloaders
                                A jinja loader for loading templates from config files.

                                  🛈 DocStrings

                                  BlockNotFoundError

                                  Bases: Exception

                                  Exception for not-found template blocks.

                                  Source code in src/jinjarope/environment.py
                                  633
                                  634
                                  635
                                  636
                                  637
                                  638
                                  639
                                  640
                                  641
                                  642
                                  643
                                  644
                                  645
                                  646
                                  647
                                  648
                                  class BlockNotFoundError(Exception):
                                      """Exception for not-found template blocks."""
                                  
                                      def __init__(
                                          self,
                                          block_name: str,
                                          template_name: str,
                                          message: str | None = None,
                                      ):
                                          """Initialize the exception."""
                                          self.block_name = block_name
                                          self.template_name = template_name
                                          super().__init__(
                                              message
                                              or f"Block {self.block_name!r} not found in template {self.template_name!r}",
                                          )
                                  

                                  __init__

                                  __init__(block_name: str, template_name: str, message: str | None = None)
                                  

                                  Initialize the exception.

                                  Source code in src/jinjarope/environment.py
                                  636
                                  637
                                  638
                                  639
                                  640
                                  641
                                  642
                                  643
                                  644
                                  645
                                  646
                                  647
                                  648
                                  def __init__(
                                      self,
                                      block_name: str,
                                      template_name: str,
                                      message: str | None = None,
                                  ):
                                      """Initialize the exception."""
                                      self.block_name = block_name
                                      self.template_name = template_name
                                      super().__init__(
                                          message
                                          or f"Block {self.block_name!r} not found in template {self.template_name!r}",
                                      )
                                  

                                  ChoiceLoader

                                  Bases: LoaderMixin, ChoiceLoader

                                  A loader which combines multiple other loaders.

                                  Source code in src/jinjarope/loaders.py
                                  186
                                  187
                                  188
                                  189
                                  190
                                  191
                                  192
                                  193
                                  194
                                  195
                                  196
                                  197
                                  198
                                  199
                                  200
                                  201
                                  202
                                  203
                                  204
                                  class ChoiceLoader(LoaderMixin, jinja2.ChoiceLoader):
                                      """A loader which combines multiple other loaders."""
                                  
                                      ID = "choice"
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, loaders=self.loaders)
                                  
                                      def __bool__(self):
                                          return len(self.loaders) > 0
                                  
                                      def __eq__(self, other):
                                          return type(self) is type(other) and self.loaders == other.loaders
                                  
                                      def __hash__(self):
                                          return hash(tuple(self.loaders))
                                  
                                      def __iter__(self):
                                          return iter(self.loaders)
                                  

                                  DictLoader

                                  Bases: LoaderMixin, DictLoader

                                  A loader to load static content from a path->template-str mapping.

                                  Source code in src/jinjarope/loaders.py
                                  207
                                  208
                                  209
                                  210
                                  211
                                  212
                                  213
                                  214
                                  215
                                  216
                                  217
                                  218
                                  219
                                  220
                                  221
                                  222
                                  223
                                  224
                                  225
                                  226
                                  class DictLoader(LoaderMixin, jinja2.DictLoader):
                                      """A loader to load static content from a path->template-str mapping."""
                                  
                                      ID = "dict"
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, mapping=self.mapping)
                                  
                                      def __add__(self, other: dict[str, str] | jinja2.DictLoader) -> DictLoader:
                                          if isinstance(other, jinja2.DictLoader):
                                              mapping = {**self.mapping, **other.mapping}
                                          else:
                                              mapping = {**self.mapping, **other}
                                          return DictLoader(mapping)
                                  
                                      def __eq__(self, other):
                                          return type(self) is type(other) and self.mapping == other.mapping
                                  
                                      def __hash__(self):
                                          return hash(tuple(sorted(self.mapping.items())))
                                  

                                  EnvConfig dataclass

                                  A class representing the config of an Environment.

                                  Does not include loaders, filters, tests, globals.

                                  Source code in src/jinjarope/envconfig.py
                                  11
                                  12
                                  13
                                  14
                                  15
                                  16
                                  17
                                  18
                                  19
                                  20
                                  21
                                  22
                                  23
                                  24
                                  25
                                  26
                                  27
                                  28
                                  29
                                  30
                                  31
                                  32
                                  33
                                  34
                                  35
                                  36
                                  37
                                  38
                                  39
                                  40
                                  41
                                  42
                                  43
                                  44
                                  45
                                  46
                                  47
                                  48
                                  49
                                  50
                                  51
                                  52
                                  53
                                  54
                                  55
                                  56
                                  57
                                  58
                                  59
                                  60
                                  61
                                  62
                                  63
                                  64
                                  @dataclasses.dataclass(unsafe_hash=True)
                                  class EnvConfig:
                                      """A class representing the config of an Environment.
                                  
                                      Does not include loaders, filters, tests, globals.
                                      """
                                  
                                      block_start_string: str = "{%"
                                      """The string marking the beginning of a block. Defaults to '{%'."""
                                      block_end_string: str = "%}"
                                      """The string marking the end of a block. Defaults to '%}'."""
                                      variable_start_string: str = r"{{"
                                      """The string marking the end of a print statement. Defaults to '}}'."""
                                      variable_end_string: str = r"}}"
                                      """The string marking the end of a print statement. Defaults to '}}'."""
                                      comment_start_string: str = "{#"
                                      """The string marking the beginning of a comment. Defaults to '{#'."""
                                      comment_end_string: str = "#}"
                                      """The string marking the end of a comment. Defaults to '#}'."""
                                      line_statement_prefix: str | None = None
                                      """If given and a string, this will be used as prefix for line based statements."""
                                      line_comment_prefix: str | None = None
                                      """If given and a string, this will be used as prefix for line based comments."""
                                      trim_blocks: bool = True
                                      """Remove first newline after a block (not variable tag!). Defaults to False."""
                                      lstrip_blocks: bool = False
                                      """Strip leading spaces / tabs from start of a line to a block. Defaults to False."""
                                      newline_sequence: Literal["\n", "\r\n", "\r"] = "\n"
                                      r"""The sequence that starts a newline. ('\r', '\n' or '\r\n'. Defaults to '\n' """
                                      keep_trailing_newline: bool = False
                                      """Preserve the trailing newline when rendering templates. The default is False.
                                  
                                      The default causes a single newline, if present,
                                      to be stripped from the end of the template.
                                      """
                                      loader: jinja2.BaseLoader | None = None
                                      """The template loader."""
                                      undefined: type[jinja2.Undefined] = jinja2.StrictUndefined
                                      """The undefined object determining the "Undefined" behavior."""
                                      extensions: list[str] = dataclasses.field(
                                          default_factory=list,
                                      )
                                      """A list of jinja2 extentions."""
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, **self.as_dict())
                                  
                                      def as_dict(self) -> dict[str, Any]:
                                          """Return dataclass as a dict, filtering all None-values."""
                                          return {
                                              field.name: v
                                              for field in dataclasses.fields(self)
                                              if (v := getattr(self, field.name)) is not None
                                          }
                                  

                                  block_end_string class-attribute instance-attribute

                                  block_end_string: str = '%}'
                                  

                                  The string marking the end of a block. Defaults to '%}'.

                                  block_start_string class-attribute instance-attribute

                                  block_start_string: str = '{%'
                                  

                                  The string marking the beginning of a block. Defaults to '{%'.

                                  comment_end_string class-attribute instance-attribute

                                  comment_end_string: str = '#}'
                                  

                                  The string marking the end of a comment. Defaults to '#}'.

                                  comment_start_string class-attribute instance-attribute

                                  comment_start_string: str = '{#'
                                  

                                  The string marking the beginning of a comment. Defaults to '{#'.

                                  extensions class-attribute instance-attribute

                                  extensions: list[str] = field(default_factory=list)
                                  

                                  A list of jinja2 extentions.

                                  keep_trailing_newline class-attribute instance-attribute

                                  keep_trailing_newline: bool = False
                                  

                                  Preserve the trailing newline when rendering templates. The default is False.

                                  The default causes a single newline, if present, to be stripped from the end of the template.

                                  line_comment_prefix class-attribute instance-attribute

                                  line_comment_prefix: str | None = None
                                  

                                  If given and a string, this will be used as prefix for line based comments.

                                  line_statement_prefix class-attribute instance-attribute

                                  line_statement_prefix: str | None = None
                                  

                                  If given and a string, this will be used as prefix for line based statements.

                                  loader class-attribute instance-attribute

                                  loader: BaseLoader | None = None
                                  

                                  The template loader.

                                  lstrip_blocks class-attribute instance-attribute

                                  lstrip_blocks: bool = False
                                  

                                  Strip leading spaces / tabs from start of a line to a block. Defaults to False.

                                  newline_sequence class-attribute instance-attribute

                                  newline_sequence: Literal['\n', '\r\n', '\r'] = '\n'
                                  

                                  The sequence that starts a newline. ('\r', '\n' or '\r\n'. Defaults to '\n'

                                  trim_blocks class-attribute instance-attribute

                                  trim_blocks: bool = True
                                  

                                  Remove first newline after a block (not variable tag!). Defaults to False.

                                  undefined class-attribute instance-attribute

                                  The undefined object determining the "Undefined" behavior.

                                  variable_end_string class-attribute instance-attribute

                                  variable_end_string: str = '}}'
                                  

                                  The string marking the end of a print statement. Defaults to '}}'.

                                  variable_start_string class-attribute instance-attribute

                                  variable_start_string: str = '{{'
                                  

                                  The string marking the end of a print statement. Defaults to '}}'.

                                  as_dict

                                  as_dict() -> dict[str, Any]
                                  

                                  Return dataclass as a dict, filtering all None-values.

                                  Source code in src/jinjarope/envconfig.py
                                  58
                                  59
                                  60
                                  61
                                  62
                                  63
                                  64
                                  def as_dict(self) -> dict[str, Any]:
                                      """Return dataclass as a dict, filtering all None-values."""
                                      return {
                                          field.name: v
                                          for field in dataclasses.fields(self)
                                          if (v := getattr(self, field.name)) is not None
                                      }
                                  

                                  Environment

                                  Bases: Environment

                                  An enhanced Jinja environment.

                                  This class extends the Jinja2 environment with functionality for loading Jinja files, managing undefined variables, and providing helper functions for rendering templates.

                                  Source code in src/jinjarope/environment.py
                                   41
                                   42
                                   43
                                   44
                                   45
                                   46
                                   47
                                   48
                                   49
                                   50
                                   51
                                   52
                                   53
                                   54
                                   55
                                   56
                                   57
                                   58
                                   59
                                   60
                                   61
                                   62
                                   63
                                   64
                                   65
                                   66
                                   67
                                   68
                                   69
                                   70
                                   71
                                   72
                                   73
                                   74
                                   75
                                   76
                                   77
                                   78
                                   79
                                   80
                                   81
                                   82
                                   83
                                   84
                                   85
                                   86
                                   87
                                   88
                                   89
                                   90
                                   91
                                   92
                                   93
                                   94
                                   95
                                   96
                                   97
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  114
                                  115
                                  116
                                  117
                                  118
                                  119
                                  120
                                  121
                                  122
                                  123
                                  124
                                  125
                                  126
                                  127
                                  128
                                  129
                                  130
                                  131
                                  132
                                  133
                                  134
                                  135
                                  136
                                  137
                                  138
                                  139
                                  140
                                  141
                                  142
                                  143
                                  144
                                  145
                                  146
                                  147
                                  148
                                  149
                                  150
                                  151
                                  152
                                  153
                                  154
                                  155
                                  156
                                  157
                                  158
                                  159
                                  160
                                  161
                                  162
                                  163
                                  164
                                  165
                                  166
                                  167
                                  168
                                  169
                                  170
                                  171
                                  172
                                  173
                                  174
                                  175
                                  176
                                  177
                                  178
                                  179
                                  180
                                  181
                                  182
                                  183
                                  184
                                  185
                                  186
                                  187
                                  188
                                  189
                                  190
                                  191
                                  192
                                  193
                                  194
                                  195
                                  196
                                  197
                                  198
                                  199
                                  200
                                  201
                                  202
                                  203
                                  204
                                  205
                                  206
                                  207
                                  208
                                  209
                                  210
                                  211
                                  212
                                  213
                                  214
                                  215
                                  216
                                  217
                                  218
                                  219
                                  220
                                  221
                                  222
                                  223
                                  224
                                  225
                                  226
                                  227
                                  228
                                  229
                                  230
                                  231
                                  232
                                  233
                                  234
                                  235
                                  236
                                  237
                                  238
                                  239
                                  240
                                  241
                                  242
                                  243
                                  244
                                  245
                                  246
                                  247
                                  248
                                  249
                                  250
                                  251
                                  252
                                  253
                                  254
                                  255
                                  256
                                  257
                                  258
                                  259
                                  260
                                  261
                                  262
                                  263
                                  264
                                  265
                                  266
                                  267
                                  268
                                  269
                                  270
                                  271
                                  272
                                  273
                                  274
                                  275
                                  276
                                  277
                                  278
                                  279
                                  280
                                  281
                                  282
                                  283
                                  284
                                  285
                                  286
                                  287
                                  288
                                  289
                                  290
                                  291
                                  292
                                  293
                                  294
                                  295
                                  296
                                  297
                                  298
                                  299
                                  300
                                  301
                                  302
                                  303
                                  304
                                  305
                                  306
                                  307
                                  308
                                  309
                                  310
                                  311
                                  312
                                  313
                                  314
                                  315
                                  316
                                  317
                                  318
                                  319
                                  320
                                  321
                                  322
                                  323
                                  324
                                  325
                                  326
                                  327
                                  328
                                  329
                                  330
                                  331
                                  332
                                  333
                                  334
                                  335
                                  336
                                  337
                                  338
                                  339
                                  340
                                  341
                                  342
                                  343
                                  344
                                  345
                                  346
                                  347
                                  348
                                  349
                                  350
                                  351
                                  352
                                  353
                                  354
                                  355
                                  356
                                  357
                                  358
                                  359
                                  360
                                  361
                                  362
                                  363
                                  364
                                  365
                                  366
                                  367
                                  368
                                  369
                                  370
                                  371
                                  372
                                  373
                                  374
                                  375
                                  376
                                  377
                                  378
                                  379
                                  380
                                  381
                                  382
                                  383
                                  384
                                  385
                                  386
                                  387
                                  388
                                  389
                                  390
                                  391
                                  392
                                  393
                                  394
                                  395
                                  396
                                  397
                                  398
                                  399
                                  400
                                  401
                                  402
                                  403
                                  404
                                  405
                                  406
                                  407
                                  408
                                  409
                                  410
                                  411
                                  412
                                  413
                                  414
                                  415
                                  416
                                  417
                                  418
                                  419
                                  420
                                  421
                                  422
                                  423
                                  424
                                  425
                                  426
                                  427
                                  428
                                  429
                                  430
                                  431
                                  432
                                  433
                                  434
                                  435
                                  436
                                  437
                                  438
                                  439
                                  440
                                  441
                                  442
                                  443
                                  444
                                  445
                                  446
                                  447
                                  448
                                  449
                                  450
                                  451
                                  452
                                  453
                                  454
                                  455
                                  456
                                  457
                                  458
                                  459
                                  460
                                  461
                                  462
                                  463
                                  464
                                  465
                                  466
                                  467
                                  468
                                  469
                                  470
                                  471
                                  472
                                  473
                                  474
                                  475
                                  476
                                  477
                                  478
                                  479
                                  480
                                  481
                                  482
                                  483
                                  484
                                  485
                                  486
                                  487
                                  488
                                  489
                                  490
                                  491
                                  492
                                  493
                                  494
                                  495
                                  496
                                  497
                                  498
                                  499
                                  500
                                  501
                                  502
                                  503
                                  504
                                  505
                                  506
                                  507
                                  508
                                  509
                                  510
                                  511
                                  512
                                  513
                                  514
                                  515
                                  516
                                  517
                                  518
                                  519
                                  520
                                  521
                                  522
                                  523
                                  524
                                  525
                                  526
                                  527
                                  528
                                  529
                                  530
                                  531
                                  532
                                  533
                                  534
                                  535
                                  536
                                  537
                                  538
                                  539
                                  540
                                  541
                                  542
                                  543
                                  544
                                  545
                                  546
                                  547
                                  548
                                  549
                                  550
                                  551
                                  552
                                  553
                                  554
                                  555
                                  556
                                  557
                                  558
                                  559
                                  560
                                  561
                                  562
                                  563
                                  564
                                  565
                                  566
                                  567
                                  568
                                  569
                                  570
                                  571
                                  572
                                  573
                                  574
                                  575
                                  576
                                  577
                                  578
                                  579
                                  580
                                  581
                                  582
                                  583
                                  584
                                  585
                                  586
                                  587
                                  588
                                  589
                                  590
                                  591
                                  592
                                  593
                                  594
                                  595
                                  596
                                  597
                                  598
                                  599
                                  600
                                  601
                                  602
                                  603
                                  604
                                  605
                                  606
                                  607
                                  608
                                  609
                                  610
                                  611
                                  612
                                  613
                                  614
                                  615
                                  616
                                  617
                                  618
                                  619
                                  620
                                  621
                                  622
                                  623
                                  624
                                  625
                                  626
                                  627
                                  628
                                  629
                                  630
                                  class Environment(jinja2.Environment):
                                      """An enhanced Jinja environment.
                                  
                                      This class extends the Jinja2 environment with functionality for
                                      loading Jinja files, managing undefined variables, and providing
                                      helper functions for rendering templates.
                                      """
                                  
                                      def __init__(
                                          self,
                                          *,
                                          undefined: undefined_.UndefinedStr | type[jinja2.Undefined] = "strict",
                                          trim_blocks: bool = True,
                                          cache_size: int = -1,
                                          auto_reload: bool = False,
                                          loader: (
                                              jinja2.BaseLoader | list[jinja2.BaseLoader] | dict | list[dict] | None
                                          ) = None,
                                          **kwargs: Any,
                                      ):
                                          """Constructor.
                                  
                                          This constructor initializes the environment with custom
                                          configuration and loads default filters, tests, functions and
                                          globals. It also registers the custom ``render_template``,
                                          ``render_string``, ``render_file`` and ``evaluate`` functions
                                          as filters.
                                  
                                          !!! info "Changes from Jinja2"
                                              The ``trim_blocks`` parameter is set to ``True`` by default,
                                              and the ``cache_size`` is set to ``-1``, which disables
                                              automatic cache cleanup.
                                  
                                          Args:
                                              undefined: Handling of "Undefined" errors
                                              trim_blocks: Whitespace handling
                                              cache_size: Amount of templates to cache
                                              auto_reload: Whether to check templates for changes on loading
                                              loader: Loader to use (Also accepts a JSON representation of loaders)
                                              kwargs: Keyword arguments passed to parent
                                          """
                                          self.cache_code = True
                                          self.context_class = Context
                                          if isinstance(undefined, str):
                                              undefined = undefined_.UNDEFINED_BEHAVIOR[undefined]
                                          kwargs = dict(
                                              undefined=undefined,
                                              trim_blocks=trim_blocks,
                                              auto_reload=auto_reload,
                                              cache_size=cache_size,
                                              loader=loaders.from_json(loader),
                                              **kwargs,
                                          )
                                          self._extra_files: set[str] = set()
                                          self._extra_paths: set[str] = set()
                                          super().__init__(**kwargs)
                                  
                                          # Update namespaces
                                          folder = pathlib.Path(__file__).parent / "resources"
                                          self.load_jinja_file(folder / "filters.toml")
                                          self.load_jinja_file(folder / "tests.toml")
                                          self.load_jinja_file(folder / "functions.toml")
                                          self.load_jinja_file(folder / "humanize_filters.toml")
                                          self.load_jinja_file(folder / "llm_filters.toml")
                                          self.globals.update(envglobals.ENV_GLOBALS)
                                          for fn in utils.entry_points(group="jinjarope.environment").values():
                                              fn(self)
                                          self.filters["render_template"] = self.render_template
                                          self.filters["render_string"] = self.render_string
                                          self.filters["render_file"] = self.render_file
                                          self.filters["evaluate"] = self.evaluate
                                          self.globals["filters"] = self.filters
                                          self.globals["tests"] = self.tests
                                          self.tests["template"] = lambda template_name: template_name in self
                                          self.template_cache: weakref.WeakValueDictionary[
                                              str | jinja2.nodes.Template,
                                              CodeType | str | None,
                                          ] = weakref.WeakValueDictionary()
                                          self.add_extension("jinja2.ext.loopcontrols")
                                          self.add_extension("jinja2.ext.do")
                                  
                                      def __repr__(self):
                                          cfg = self.get_config()
                                          return utils.get_repr(self, **utils.get_dataclass_nondefault_values(cfg))
                                  
                                      def __contains__(self, template: str | os.PathLike[str]) -> bool:
                                          """Check whether given template path exists.
                                  
                                          Args:
                                              template: The template path to check
                                  
                                          Returns:
                                              True if the template exists, False otherwise.
                                          """
                                          return pathlib.Path(template).as_posix() in self.list_templates()
                                  
                                      def __getitem__(self, val: str) -> jinja2.Template:
                                          """Return a template by path.
                                  
                                          Args:
                                              val: The template path
                                  
                                          Returns:
                                              The template object for the given path.
                                          """
                                          return self.get_template(val)
                                  
                                      def install_translations(self, locale: str, dirs: Sequence[str | os.PathLike[str]]):
                                          """Install translations for the environment.
                                  
                                          This function installs translations for the given locale
                                          using the provided directory paths. It uses the
                                          `jinjarope.localization` module to manage translations.
                                  
                                          Args:
                                              locale: The locale to install translations for
                                              dirs: A sequence of directory paths containing translation files
                                          """
                                          from jinjarope import localization
                                  
                                          localization.install_translations(self, locale, dirs)
                                  
                                      def set_undefined(self, value: undefined_.UndefinedStr | type[jinja2.Undefined]):
                                          """Set the undefined behaviour for the environment.
                                  
                                          Args:
                                              value: The new undefined behaviour
                                          """
                                          new = undefined_.UNDEFINED_BEHAVIOR[value] if isinstance(value, str) else value
                                          self.undefined = new
                                  
                                      def load_jinja_file(
                                          self,
                                          path: str | os.PathLike[str],
                                          scope_prefix: str = "",
                                          load_filters: bool = True,
                                          load_tests: bool = True,
                                          load_functions: bool = True,
                                          load_config: bool = True,
                                          load_loader: bool = True,
                                      ):
                                          """Load the content of a JinjaFile and add it to the environment.
                                  
                                          This function reads a JinjaFile and adds its filters, tests,
                                          functions, and configuration to the current environment.
                                  
                                          Args:
                                              path: The path to the JinjaFile
                                              scope_prefix: Optional prefix to add to all tests / filters / functions
                                              load_filters: Whether to load filters from the JinjaFile
                                              load_tests: Whether to load tests from the JinjaFile
                                              load_functions: Whether to load functions from the JinjaFile
                                              load_config: Whether to load the environment config from the JinjaFile
                                              load_loader: Whether to load the Loader from the JinjaFile
                                          """
                                          file = jinjafile.JinjaFile(path)
                                          if load_filters:
                                              dct = {f"{scope_prefix}{k}": v for k, v in file.filters_dict.items()}
                                              self.filters.update(dct)
                                          if load_tests:
                                              dct = {f"{scope_prefix}{k}": v for k, v in file.tests_dict.items()}
                                              self.tests.update(dct)
                                          if load_functions:
                                              dct = {f"{scope_prefix}{k}": v for k, v in file.functions_dict.items()}
                                              self.globals.update(dct)
                                          if load_config:
                                              self.block_start_string = file.envconfig.block_start_string
                                              self.block_end_string = file.envconfig.block_end_string
                                              self.variable_start_string = file.envconfig.variable_start_string
                                              self.variable_end_string = file.envconfig.variable_end_string
                                              self.comment_start_string = file.envconfig.comment_start_string
                                              self.comment_end_string = file.envconfig.comment_end_string
                                              self.line_statement_prefix = file.envconfig.line_statement_prefix
                                              self.line_comment_prefix = file.envconfig.line_comment_prefix
                                              self.trim_blocks = file.envconfig.trim_blocks
                                              self.lstrip_blocks = file.envconfig.lstrip_blocks
                                              self.newline_sequence = file.envconfig.newline_sequence
                                              self.keep_trailing_newline = file.envconfig.keep_trailing_newline
                                              for ext in file.envconfig.extensions or []:
                                                  self.add_extension(ext)
                                          if load_loader and (loader := file.loader):
                                              self._add_loader(loader)
                                  
                                      @overload
                                      def compile(  # type: ignore
                                          self,
                                          source: str | jinja2.nodes.Template,
                                          name: str | None = None,
                                          filename: str | None = None,
                                          raw: Literal[False] = False,
                                          defer_init: bool = False,
                                      ) -> CodeType: ...
                                  
                                      @overload
                                      def compile(
                                          self,
                                          source: str | jinja2.nodes.Template,
                                          name: str | None = None,
                                          filename: str | None = None,
                                          raw: Literal[True] = ...,
                                          defer_init: bool = False,
                                      ) -> str: ...
                                  
                                      def compile(
                                          self,
                                          source: str | jinja2.nodes.Template,
                                          name: str | None = None,
                                          filename: str | None = None,
                                          raw: bool = False,
                                          defer_init: bool = False,
                                      ) -> CodeType | str:
                                          """Compile the template.
                                  
                                          This function compiles the given template source. If any of the
                                          keyword arguments are set to a non-default value, the compiled code
                                          is not cached. Otherwise, the compilation result is cached using the
                                          ``source`` as key. This behavior can be overwritten by setting
                                          ``self.cache_code`` to ``False``.
                                  
                                          !!! info "Changes from Jinja2"
                                              The default behavior of the ``compile`` method has been modified
                                              to cache the compiled code unless any keyword arguments are
                                              provided.
                                  
                                          Args:
                                              source: The template source
                                              name: The name of the template
                                              filename: The filename of the template
                                              raw: Whether to compile the template as raw
                                              defer_init: Whether to defer initialization
                                  
                                          Returns:
                                              The compiled template code.
                                          """
                                          if (
                                              not self.cache_code
                                              or name is not None
                                              or filename is not None
                                              or raw is not False
                                              or defer_init is not False
                                          ):
                                              # If there are any non-default keywords args, we do
                                              # not cache.
                                              return super().compile(  # type: ignore[no-any-return,call-overload]
                                                  source,
                                                  name,
                                                  filename,
                                                  raw,
                                                  defer_init,
                                              )
                                  
                                          if (cached := self.template_cache.get(source)) is None:
                                              cached = self.template_cache[source] = super().compile(source)
                                  
                                          return cached
                                  
                                      def inherit_from(self, env: jinja2.Environment):
                                          """Inherit complete configuration from another environment.
                                  
                                          This function copies all settings and configuration from another
                                          environment to the current one. This effectively allows
                                          inheritance of environment settings.
                                  
                                          Args:
                                              env: The environment to inherit settings from
                                          """
                                          self.__dict__.update(env.__dict__)
                                          self.linked_to = env
                                          self.overlayed = True
                                  
                                      def add_template(self, file: str | os.PathLike[str]):
                                          """Add a new template during runtime.
                                  
                                          This function adds a new template to the environment during
                                          runtime by creating a new DictLoader and injecting it into the
                                          existing loaders. This allows rendering templates that were not
                                          defined when the environment was initialized.
                                  
                                          !!! info "Use case"
                                              This function is particularly useful for situations where a
                                              template needs to be rendered dynamically, such as when
                                              rendering templates within other templates.
                                  
                                          Args:
                                              file: File to add as a template
                                          """
                                          # we keep track of already added extra files to not add things multiple times.
                                          file = str(file)
                                          if file in self._extra_files:
                                              return
                                          self._extra_files.add(file)
                                          content = envglobals.load_file_cached(file)
                                          new_loader = loaders.DictLoader({file: content})
                                          self._add_loader(new_loader)
                                  
                                      def add_template_path(self, *path: str | os.PathLike[str]):
                                          """Add a new template path during runtime.
                                  
                                          This function adds a new template path to the environment
                                          during runtime by appending a new FileSystemLoader to the
                                          existing loaders. This allows the environment to find templates
                                          in additional locations.
                                  
                                          Args:
                                              path: Template search path(s) to add
                                          """
                                          for p in path:
                                              if p in self._extra_paths:
                                                  return
                                              self._extra_paths.add(str(p))
                                              new_loader = loaders.FileSystemLoader(p)
                                              self._add_loader(new_loader)
                                  
                                      def _add_loader(
                                          self,
                                          new_loader: jinja2.BaseLoader | dict[str, str] | str | os.PathLike[str],
                                      ):
                                          """Add a new loader to the current environment."""
                                          match new_loader:
                                              case dict():
                                                  new_loader = loaders.DictLoader(new_loader)
                                              case str() | os.PathLike():
                                                  new_loader = loaders.FileSystemLoader(new_loader)
                                          match self.loader:
                                              case jinja2.ChoiceLoader():
                                                  self.loader.loaders = [new_loader, *self.loader.loaders]
                                              case None:
                                                  self.loader = new_loader
                                              case _:
                                                  self.loader = loaders.ChoiceLoader(loaders=[new_loader, self.loader])
                                  
                                      def render_condition(
                                          self,
                                          string: str,
                                          variables: dict[str, Any] | None = None,
                                          **kwargs: Any,
                                      ) -> bool:
                                          """Render a template condition.
                                  
                                          This function renders a template string and evaluates its
                                          result as a boolean. It returns True if the result is truthy
                                          (not None, False, or an empty string), otherwise False.
                                  
                                          Args:
                                              string: String to evaluate for True-ishness
                                              variables: Extra variables for the rendering
                                              kwargs: Further extra variables for rendering
                                  
                                          Returns:
                                              True if the rendered string is truthy, False otherwise.
                                          """
                                          result = self.render_string(string=string, variables=variables, **kwargs)
                                          return result not in ["None", "False", ""]
                                  
                                      def render_string(
                                          self,
                                          string: str,
                                          variables: dict[str, Any] | None = None,
                                          **kwargs: Any,
                                      ) -> str:
                                          """Render a template string.
                                  
                                          This function renders the given template string using the
                                          current environment's configuration and globals.
                                  
                                          Args:
                                              string: String to render
                                              variables: Extra variables for the rendering
                                              kwargs: Further extra variables for rendering
                                  
                                          Returns:
                                              The rendered string.
                                          """
                                          variables = (variables or {}) | kwargs
                                          cls = self.template_class
                                          try:
                                              template = cls.from_code(self, self.compile(string), self.globals, None)
                                          except TemplateSyntaxError as e:
                                              msg = f"Error when evaluating \n{string}\n (extra globals: {variables})"
                                              raise SyntaxError(msg) from e
                                          return template.render(**variables)
                                  
                                      def render_file(
                                          self,
                                          file: str | os.PathLike[str],
                                          variables: dict[str, Any] | None = None,
                                          **kwargs: Any,
                                      ) -> str:
                                          """Helper to directly render a template from filesystem.
                                  
                                          This function renders a template file directly from the
                                          filesystem using the current environment's configuration and
                                          globals.
                                  
                                          !!! info
                                              The file content is cached, which is generally acceptable
                                              for common use cases.
                                  
                                          Args:
                                              file: Template file to load
                                              variables: Extra variables for the rendering
                                              kwargs: Further extra variables for rendering
                                  
                                          Returns:
                                              The rendered string.
                                          """
                                          content = envglobals.load_file_cached(str(file))
                                          return self.render_string(content, variables, **kwargs)
                                  
                                      def render_template(
                                          self,
                                          template_name: str,
                                          variables: dict[str, Any] | None = None,
                                          block_name: str | None = None,
                                          parent_template: str | None = None,
                                          **kwargs: Any,
                                      ) -> str:
                                          """Render a loaded template (or a block of a template).
                                  
                                          This function renders a loaded template or a specific block from
                                          a template. It allows for the inclusion of parent templates and
                                          provides the flexibility to render individual blocks.
                                  
                                          Args:
                                              template_name: Template name
                                              variables: Extra variables for rendering
                                              block_name: Render specific block from the template
                                              parent_template: The name of the parent template importing this template
                                              kwargs: Further extra variables for rendering
                                  
                                          Returns:
                                              The rendered string.
                                  
                                          Raises:
                                              BlockNotFoundError: If the specified block is not found in the
                                              template.
                                          """
                                          variables = (variables or {}) | kwargs
                                          template = self.get_template(template_name, parent=parent_template)
                                          if not block_name:
                                              return template.render(**variables)
                                          try:
                                              block_render_func = template.blocks[block_name]
                                          except KeyError:
                                              raise BlockNotFoundError(block_name, template_name) from KeyError
                                  
                                          ctx = template.new_context(variables)
                                          return self.concat(block_render_func(ctx))  # type: ignore
                                          # except Exception:
                                          #     self.handle_exception()
                                  
                                      @contextlib.contextmanager
                                      def with_globals(self, **kwargs: Any):
                                          """Context manager to temporarily set globals for the environment.
                                  
                                          This context manager allows temporarily overriding the environment's
                                          globals with the provided values. Any changes made within the context
                                          manager are reverted upon exiting the context.
                                  
                                          Args:
                                              kwargs: Globals to set
                                          """
                                          temp = self.globals.copy()
                                          self.globals.update(kwargs)
                                          yield
                                          self.globals = temp
                                  
                                      def setup_loader(
                                          self,
                                          dir_paths: list[str] | None = None,
                                          module_paths: list[str] | None = None,
                                          static: dict[str, str] | None = None,
                                          fsspec_paths: bool = True,
                                      ):
                                          """Set the loader for the environment.
                                  
                                          This function sets the loader for the environment based on
                                          the provided parameters. It uses the ``jinjarope.get_loader``
                                          function to create a suitable loader.
                                  
                                          Args:
                                              dir_paths: List of directory paths to search for templates
                                              module_paths: List of module paths to search for templates
                                              static: Dictionary of static files to include in the loader
                                              fsspec_paths: Whether to use fsspec paths for loading
                                          """
                                          self.loader = jinjarope.get_loader(
                                              dir_paths=dir_paths,
                                              module_paths=module_paths,
                                              static=static,
                                              fsspec_paths=fsspec_paths,
                                          )
                                  
                                      def evaluate(
                                          self,
                                          code: str,
                                          context: dict[str, Any] | None = None,
                                      ) -> str:
                                          """Evaluate python code and return the caught stdout + return value of last line.
                                  
                                          This function executes Python code within the environment's
                                          globals. It captures the standard output generated during
                                          execution and returns the combined result as a string.
                                  
                                          Args:
                                              code: The code to execute
                                              context: Globals for the execution environment
                                  
                                          Returns:
                                              The combined standard output and return value of the last
                                              line of code.
                                          """
                                          now = time.time()
                                          logger.debug("Evaluating code:\n%s", code)
                                          tree = ast.parse(code)
                                          eval_expr = ast.Expression(tree.body[-1].value)  # type: ignore
                                          # exec_expr = ast.Module(tree.body[:-1])  # type: ignore
                                          exec_expr = ast.parse("")
                                          exec_expr.body = tree.body[:-1]
                                          compiled = compile(exec_expr, "file", "exec")
                                          buffer = io.StringIO()
                                          with contextlib.redirect_stdout(buffer):
                                              exec(compiled, self.globals)
                                              val = eval(compile(eval_expr, "file", "eval"), self.globals)
                                          logger.debug("Code evaluation took %s seconds.", time.time() - now)
                                          # result = mk.MkContainer([buffer.getvalue(), val])
                                          return val or ""
                                  
                                      def get_config(self) -> envconfig.EnvConfig:
                                          """All environment settings as a dict (not included: undefined and loaders).
                                  
                                          This function returns a dictionary representation of all
                                          environment settings, excluding undefined and loaders.
                                  
                                          Returns:
                                              A dictionary containing the environment configuration.
                                          """
                                          exts = [
                                              k
                                              for k in self.extensions
                                              if k
                                              not in ["jinja2.ext.LoopControlExtension", "jinja2.ext.ExprStmtExtension"]
                                          ]
                                          return envconfig.EnvConfig(
                                              block_start_string=self.block_start_string,
                                              block_end_string=self.block_end_string,
                                              variable_start_string=self.variable_start_string,
                                              variable_end_string=self.variable_end_string,
                                              comment_start_string=self.comment_start_string,
                                              comment_end_string=self.comment_end_string,
                                              line_statement_prefix=self.line_statement_prefix,
                                              line_comment_prefix=self.line_comment_prefix,
                                              trim_blocks=self.trim_blocks,
                                              lstrip_blocks=self.lstrip_blocks,
                                              newline_sequence=self.newline_sequence,
                                              keep_trailing_newline=self.keep_trailing_newline,
                                              loader=self.loader,
                                              undefined=self.undefined,
                                              extensions=exts,
                                          )
                                  
                                      def make_globals(
                                          self,
                                          d: MutableMapping[str, Any] | None,
                                      ) -> MutableMapping[str, Any]:
                                          """Make the globals map for a template.
                                  
                                          This function creates a globals map for a template, where
                                          template-specific globals overlay the environment's global
                                          variables.
                                  
                                          !!! info
                                              Avoid modifying any globals after a template is loaded.
                                  
                                          Args:
                                              d: Dict of template-specific globals
                                  
                                          Returns:
                                              A ChainMap containing the template globals.
                                          """
                                          if d is None:
                                              d = {}
                                  
                                          import collections
                                  
                                          class GlobalsMap(collections.ChainMap):
                                              def __repr__(self):
                                                  return f"GlobalsMap<{len(self)} keys>"
                                  
                                          return GlobalsMap(d, self.globals)
                                  

                                  __contains__

                                  __contains__(template: str | PathLike[str]) -> bool
                                  

                                  Check whether given template path exists.

                                  Parameters:

                                  Name Type Description Default
                                  template str | PathLike[str]

                                  The template path to check

                                  required

                                  Returns:

                                  Type Description
                                  bool

                                  True if the template exists, False otherwise.

                                  Source code in src/jinjarope/environment.py
                                  126
                                  127
                                  128
                                  129
                                  130
                                  131
                                  132
                                  133
                                  134
                                  135
                                  def __contains__(self, template: str | os.PathLike[str]) -> bool:
                                      """Check whether given template path exists.
                                  
                                      Args:
                                          template: The template path to check
                                  
                                      Returns:
                                          True if the template exists, False otherwise.
                                      """
                                      return pathlib.Path(template).as_posix() in self.list_templates()
                                  

                                  __getitem__

                                  __getitem__(val: str) -> Template
                                  

                                  Return a template by path.

                                  Parameters:

                                  Name Type Description Default
                                  val str

                                  The template path

                                  required

                                  Returns:

                                  Type Description
                                  Template

                                  The template object for the given path.

                                  Source code in src/jinjarope/environment.py
                                  137
                                  138
                                  139
                                  140
                                  141
                                  142
                                  143
                                  144
                                  145
                                  146
                                  def __getitem__(self, val: str) -> jinja2.Template:
                                      """Return a template by path.
                                  
                                      Args:
                                          val: The template path
                                  
                                      Returns:
                                          The template object for the given path.
                                      """
                                      return self.get_template(val)
                                  

                                  __init__

                                  __init__(
                                      *,
                                      undefined: UndefinedStr | type[Undefined] = "strict",
                                      trim_blocks: bool = True,
                                      cache_size: int = -1,
                                      auto_reload: bool = False,
                                      loader: BaseLoader | list[BaseLoader] | dict | list[dict] | None = None,
                                      **kwargs: Any
                                  )
                                  

                                  Constructor.

                                  This constructor initializes the environment with custom configuration and loads default filters, tests, functions and globals. It also registers the custom render_template, render_string, render_file and evaluate functions as filters.

                                  Changes from Jinja2

                                  The trim_blocks parameter is set to True by default, and the cache_size is set to -1, which disables automatic cache cleanup.

                                  Parameters:

                                  Name Type Description Default
                                  undefined UndefinedStr | type[Undefined]

                                  Handling of "Undefined" errors

                                  'strict'
                                  trim_blocks bool

                                  Whitespace handling

                                  True
                                  cache_size int

                                  Amount of templates to cache

                                  -1
                                  auto_reload bool

                                  Whether to check templates for changes on loading

                                  False
                                  loader BaseLoader | list[BaseLoader] | dict | list[dict] | None

                                  Loader to use (Also accepts a JSON representation of loaders)

                                  None
                                  kwargs Any

                                  Keyword arguments passed to parent

                                  {}
                                  Source code in src/jinjarope/environment.py
                                   49
                                   50
                                   51
                                   52
                                   53
                                   54
                                   55
                                   56
                                   57
                                   58
                                   59
                                   60
                                   61
                                   62
                                   63
                                   64
                                   65
                                   66
                                   67
                                   68
                                   69
                                   70
                                   71
                                   72
                                   73
                                   74
                                   75
                                   76
                                   77
                                   78
                                   79
                                   80
                                   81
                                   82
                                   83
                                   84
                                   85
                                   86
                                   87
                                   88
                                   89
                                   90
                                   91
                                   92
                                   93
                                   94
                                   95
                                   96
                                   97
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  114
                                  115
                                  116
                                  117
                                  118
                                  119
                                  120
                                  def __init__(
                                      self,
                                      *,
                                      undefined: undefined_.UndefinedStr | type[jinja2.Undefined] = "strict",
                                      trim_blocks: bool = True,
                                      cache_size: int = -1,
                                      auto_reload: bool = False,
                                      loader: (
                                          jinja2.BaseLoader | list[jinja2.BaseLoader] | dict | list[dict] | None
                                      ) = None,
                                      **kwargs: Any,
                                  ):
                                      """Constructor.
                                  
                                      This constructor initializes the environment with custom
                                      configuration and loads default filters, tests, functions and
                                      globals. It also registers the custom ``render_template``,
                                      ``render_string``, ``render_file`` and ``evaluate`` functions
                                      as filters.
                                  
                                      !!! info "Changes from Jinja2"
                                          The ``trim_blocks`` parameter is set to ``True`` by default,
                                          and the ``cache_size`` is set to ``-1``, which disables
                                          automatic cache cleanup.
                                  
                                      Args:
                                          undefined: Handling of "Undefined" errors
                                          trim_blocks: Whitespace handling
                                          cache_size: Amount of templates to cache
                                          auto_reload: Whether to check templates for changes on loading
                                          loader: Loader to use (Also accepts a JSON representation of loaders)
                                          kwargs: Keyword arguments passed to parent
                                      """
                                      self.cache_code = True
                                      self.context_class = Context
                                      if isinstance(undefined, str):
                                          undefined = undefined_.UNDEFINED_BEHAVIOR[undefined]
                                      kwargs = dict(
                                          undefined=undefined,
                                          trim_blocks=trim_blocks,
                                          auto_reload=auto_reload,
                                          cache_size=cache_size,
                                          loader=loaders.from_json(loader),
                                          **kwargs,
                                      )
                                      self._extra_files: set[str] = set()
                                      self._extra_paths: set[str] = set()
                                      super().__init__(**kwargs)
                                  
                                      # Update namespaces
                                      folder = pathlib.Path(__file__).parent / "resources"
                                      self.load_jinja_file(folder / "filters.toml")
                                      self.load_jinja_file(folder / "tests.toml")
                                      self.load_jinja_file(folder / "functions.toml")
                                      self.load_jinja_file(folder / "humanize_filters.toml")
                                      self.load_jinja_file(folder / "llm_filters.toml")
                                      self.globals.update(envglobals.ENV_GLOBALS)
                                      for fn in utils.entry_points(group="jinjarope.environment").values():
                                          fn(self)
                                      self.filters["render_template"] = self.render_template
                                      self.filters["render_string"] = self.render_string
                                      self.filters["render_file"] = self.render_file
                                      self.filters["evaluate"] = self.evaluate
                                      self.globals["filters"] = self.filters
                                      self.globals["tests"] = self.tests
                                      self.tests["template"] = lambda template_name: template_name in self
                                      self.template_cache: weakref.WeakValueDictionary[
                                          str | jinja2.nodes.Template,
                                          CodeType | str | None,
                                      ] = weakref.WeakValueDictionary()
                                      self.add_extension("jinja2.ext.loopcontrols")
                                      self.add_extension("jinja2.ext.do")
                                  

                                  add_template

                                  add_template(file: str | PathLike[str])
                                  

                                  Add a new template during runtime.

                                  This function adds a new template to the environment during runtime by creating a new DictLoader and injecting it into the existing loaders. This allows rendering templates that were not defined when the environment was initialized.

                                  Use case

                                  This function is particularly useful for situations where a template needs to be rendered dynamically, such as when rendering templates within other templates.

                                  Parameters:

                                  Name Type Description Default
                                  file str | PathLike[str]

                                  File to add as a template

                                  required
                                  Source code in src/jinjarope/environment.py
                                  311
                                  312
                                  313
                                  314
                                  315
                                  316
                                  317
                                  318
                                  319
                                  320
                                  321
                                  322
                                  323
                                  324
                                  325
                                  326
                                  327
                                  328
                                  329
                                  330
                                  331
                                  332
                                  333
                                  334
                                  def add_template(self, file: str | os.PathLike[str]):
                                      """Add a new template during runtime.
                                  
                                      This function adds a new template to the environment during
                                      runtime by creating a new DictLoader and injecting it into the
                                      existing loaders. This allows rendering templates that were not
                                      defined when the environment was initialized.
                                  
                                      !!! info "Use case"
                                          This function is particularly useful for situations where a
                                          template needs to be rendered dynamically, such as when
                                          rendering templates within other templates.
                                  
                                      Args:
                                          file: File to add as a template
                                      """
                                      # we keep track of already added extra files to not add things multiple times.
                                      file = str(file)
                                      if file in self._extra_files:
                                          return
                                      self._extra_files.add(file)
                                      content = envglobals.load_file_cached(file)
                                      new_loader = loaders.DictLoader({file: content})
                                      self._add_loader(new_loader)
                                  

                                  add_template_path

                                  add_template_path(*path: str | PathLike[str])
                                  

                                  Add a new template path during runtime.

                                  This function adds a new template path to the environment during runtime by appending a new FileSystemLoader to the existing loaders. This allows the environment to find templates in additional locations.

                                  Parameters:

                                  Name Type Description Default
                                  path str | PathLike[str]

                                  Template search path(s) to add

                                  ()
                                  Source code in src/jinjarope/environment.py
                                  336
                                  337
                                  338
                                  339
                                  340
                                  341
                                  342
                                  343
                                  344
                                  345
                                  346
                                  347
                                  348
                                  349
                                  350
                                  351
                                  352
                                  def add_template_path(self, *path: str | os.PathLike[str]):
                                      """Add a new template path during runtime.
                                  
                                      This function adds a new template path to the environment
                                      during runtime by appending a new FileSystemLoader to the
                                      existing loaders. This allows the environment to find templates
                                      in additional locations.
                                  
                                      Args:
                                          path: Template search path(s) to add
                                      """
                                      for p in path:
                                          if p in self._extra_paths:
                                              return
                                          self._extra_paths.add(str(p))
                                          new_loader = loaders.FileSystemLoader(p)
                                          self._add_loader(new_loader)
                                  

                                  compile

                                  compile(
                                      source: str | Template,
                                      name: str | None = None,
                                      filename: str | None = None,
                                      raw: Literal[False] = False,
                                      defer_init: bool = False,
                                  ) -> CodeType
                                  
                                  compile(
                                      source: str | Template,
                                      name: str | None = None,
                                      filename: str | None = None,
                                      raw: Literal[True] = ...,
                                      defer_init: bool = False,
                                  ) -> str
                                  
                                  compile(
                                      source: str | Template,
                                      name: str | None = None,
                                      filename: str | None = None,
                                      raw: bool = False,
                                      defer_init: bool = False,
                                  ) -> CodeType | str
                                  

                                  Compile the template.

                                  This function compiles the given template source. If any of the keyword arguments are set to a non-default value, the compiled code is not cached. Otherwise, the compilation result is cached using the source as key. This behavior can be overwritten by setting self.cache_code to False.

                                  Changes from Jinja2

                                  The default behavior of the compile method has been modified to cache the compiled code unless any keyword arguments are provided.

                                  Parameters:

                                  Name Type Description Default
                                  source str | Template

                                  The template source

                                  required
                                  name str | None

                                  The name of the template

                                  None
                                  filename str | None

                                  The filename of the template

                                  None
                                  raw bool

                                  Whether to compile the template as raw

                                  False
                                  defer_init bool

                                  Whether to defer initialization

                                  False

                                  Returns:

                                  Type Description
                                  CodeType | str

                                  The compiled template code.

                                  Source code in src/jinjarope/environment.py
                                  244
                                  245
                                  246
                                  247
                                  248
                                  249
                                  250
                                  251
                                  252
                                  253
                                  254
                                  255
                                  256
                                  257
                                  258
                                  259
                                  260
                                  261
                                  262
                                  263
                                  264
                                  265
                                  266
                                  267
                                  268
                                  269
                                  270
                                  271
                                  272
                                  273
                                  274
                                  275
                                  276
                                  277
                                  278
                                  279
                                  280
                                  281
                                  282
                                  283
                                  284
                                  285
                                  286
                                  287
                                  288
                                  289
                                  290
                                  291
                                  292
                                  293
                                  294
                                  295
                                  def compile(
                                      self,
                                      source: str | jinja2.nodes.Template,
                                      name: str | None = None,
                                      filename: str | None = None,
                                      raw: bool = False,
                                      defer_init: bool = False,
                                  ) -> CodeType | str:
                                      """Compile the template.
                                  
                                      This function compiles the given template source. If any of the
                                      keyword arguments are set to a non-default value, the compiled code
                                      is not cached. Otherwise, the compilation result is cached using the
                                      ``source`` as key. This behavior can be overwritten by setting
                                      ``self.cache_code`` to ``False``.
                                  
                                      !!! info "Changes from Jinja2"
                                          The default behavior of the ``compile`` method has been modified
                                          to cache the compiled code unless any keyword arguments are
                                          provided.
                                  
                                      Args:
                                          source: The template source
                                          name: The name of the template
                                          filename: The filename of the template
                                          raw: Whether to compile the template as raw
                                          defer_init: Whether to defer initialization
                                  
                                      Returns:
                                          The compiled template code.
                                      """
                                      if (
                                          not self.cache_code
                                          or name is not None
                                          or filename is not None
                                          or raw is not False
                                          or defer_init is not False
                                      ):
                                          # If there are any non-default keywords args, we do
                                          # not cache.
                                          return super().compile(  # type: ignore[no-any-return,call-overload]
                                              source,
                                              name,
                                              filename,
                                              raw,
                                              defer_init,
                                          )
                                  
                                      if (cached := self.template_cache.get(source)) is None:
                                          cached = self.template_cache[source] = super().compile(source)
                                  
                                      return cached
                                  

                                  evaluate

                                  evaluate(code: str, context: dict[str, Any] | None = None) -> str
                                  

                                  Evaluate python code and return the caught stdout + return value of last line.

                                  This function executes Python code within the environment's globals. It captures the standard output generated during execution and returns the combined result as a string.

                                  Parameters:

                                  Name Type Description Default
                                  code str

                                  The code to execute

                                  required
                                  context dict[str, Any] | None

                                  Globals for the execution environment

                                  None

                                  Returns:

                                  Type Description
                                  str

                                  The combined standard output and return value of the last

                                  str

                                  line of code.

                                  Source code in src/jinjarope/environment.py
                                  534
                                  535
                                  536
                                  537
                                  538
                                  539
                                  540
                                  541
                                  542
                                  543
                                  544
                                  545
                                  546
                                  547
                                  548
                                  549
                                  550
                                  551
                                  552
                                  553
                                  554
                                  555
                                  556
                                  557
                                  558
                                  559
                                  560
                                  561
                                  562
                                  563
                                  564
                                  565
                                  566
                                  567
                                  def evaluate(
                                      self,
                                      code: str,
                                      context: dict[str, Any] | None = None,
                                  ) -> str:
                                      """Evaluate python code and return the caught stdout + return value of last line.
                                  
                                      This function executes Python code within the environment's
                                      globals. It captures the standard output generated during
                                      execution and returns the combined result as a string.
                                  
                                      Args:
                                          code: The code to execute
                                          context: Globals for the execution environment
                                  
                                      Returns:
                                          The combined standard output and return value of the last
                                          line of code.
                                      """
                                      now = time.time()
                                      logger.debug("Evaluating code:\n%s", code)
                                      tree = ast.parse(code)
                                      eval_expr = ast.Expression(tree.body[-1].value)  # type: ignore
                                      # exec_expr = ast.Module(tree.body[:-1])  # type: ignore
                                      exec_expr = ast.parse("")
                                      exec_expr.body = tree.body[:-1]
                                      compiled = compile(exec_expr, "file", "exec")
                                      buffer = io.StringIO()
                                      with contextlib.redirect_stdout(buffer):
                                          exec(compiled, self.globals)
                                          val = eval(compile(eval_expr, "file", "eval"), self.globals)
                                      logger.debug("Code evaluation took %s seconds.", time.time() - now)
                                      # result = mk.MkContainer([buffer.getvalue(), val])
                                      return val or ""
                                  

                                  get_config

                                  get_config() -> EnvConfig
                                  

                                  All environment settings as a dict (not included: undefined and loaders).

                                  This function returns a dictionary representation of all environment settings, excluding undefined and loaders.

                                  Returns:

                                  Type Description
                                  EnvConfig

                                  A dictionary containing the environment configuration.

                                  Source code in src/jinjarope/environment.py
                                  569
                                  570
                                  571
                                  572
                                  573
                                  574
                                  575
                                  576
                                  577
                                  578
                                  579
                                  580
                                  581
                                  582
                                  583
                                  584
                                  585
                                  586
                                  587
                                  588
                                  589
                                  590
                                  591
                                  592
                                  593
                                  594
                                  595
                                  596
                                  597
                                  598
                                  599
                                  600
                                  def get_config(self) -> envconfig.EnvConfig:
                                      """All environment settings as a dict (not included: undefined and loaders).
                                  
                                      This function returns a dictionary representation of all
                                      environment settings, excluding undefined and loaders.
                                  
                                      Returns:
                                          A dictionary containing the environment configuration.
                                      """
                                      exts = [
                                          k
                                          for k in self.extensions
                                          if k
                                          not in ["jinja2.ext.LoopControlExtension", "jinja2.ext.ExprStmtExtension"]
                                      ]
                                      return envconfig.EnvConfig(
                                          block_start_string=self.block_start_string,
                                          block_end_string=self.block_end_string,
                                          variable_start_string=self.variable_start_string,
                                          variable_end_string=self.variable_end_string,
                                          comment_start_string=self.comment_start_string,
                                          comment_end_string=self.comment_end_string,
                                          line_statement_prefix=self.line_statement_prefix,
                                          line_comment_prefix=self.line_comment_prefix,
                                          trim_blocks=self.trim_blocks,
                                          lstrip_blocks=self.lstrip_blocks,
                                          newline_sequence=self.newline_sequence,
                                          keep_trailing_newline=self.keep_trailing_newline,
                                          loader=self.loader,
                                          undefined=self.undefined,
                                          extensions=exts,
                                      )
                                  

                                  inherit_from

                                  inherit_from(env: Environment)
                                  

                                  Inherit complete configuration from another environment.

                                  This function copies all settings and configuration from another environment to the current one. This effectively allows inheritance of environment settings.

                                  Parameters:

                                  Name Type Description Default
                                  env Environment

                                  The environment to inherit settings from

                                  required
                                  Source code in src/jinjarope/environment.py
                                  297
                                  298
                                  299
                                  300
                                  301
                                  302
                                  303
                                  304
                                  305
                                  306
                                  307
                                  308
                                  309
                                  def inherit_from(self, env: jinja2.Environment):
                                      """Inherit complete configuration from another environment.
                                  
                                      This function copies all settings and configuration from another
                                      environment to the current one. This effectively allows
                                      inheritance of environment settings.
                                  
                                      Args:
                                          env: The environment to inherit settings from
                                      """
                                      self.__dict__.update(env.__dict__)
                                      self.linked_to = env
                                      self.overlayed = True
                                  

                                  install_translations

                                  install_translations(locale: str, dirs: Sequence[str | PathLike[str]])
                                  

                                  Install translations for the environment.

                                  This function installs translations for the given locale using the provided directory paths. It uses the jinjarope.localization module to manage translations.

                                  Parameters:

                                  Name Type Description Default
                                  locale str

                                  The locale to install translations for

                                  required
                                  dirs Sequence[str | PathLike[str]]

                                  A sequence of directory paths containing translation files

                                  required
                                  Source code in src/jinjarope/environment.py
                                  148
                                  149
                                  150
                                  151
                                  152
                                  153
                                  154
                                  155
                                  156
                                  157
                                  158
                                  159
                                  160
                                  161
                                  def install_translations(self, locale: str, dirs: Sequence[str | os.PathLike[str]]):
                                      """Install translations for the environment.
                                  
                                      This function installs translations for the given locale
                                      using the provided directory paths. It uses the
                                      `jinjarope.localization` module to manage translations.
                                  
                                      Args:
                                          locale: The locale to install translations for
                                          dirs: A sequence of directory paths containing translation files
                                      """
                                      from jinjarope import localization
                                  
                                      localization.install_translations(self, locale, dirs)
                                  

                                  load_jinja_file

                                  load_jinja_file(
                                      path: str | PathLike[str],
                                      scope_prefix: str = "",
                                      load_filters: bool = True,
                                      load_tests: bool = True,
                                      load_functions: bool = True,
                                      load_config: bool = True,
                                      load_loader: bool = True,
                                  )
                                  

                                  Load the content of a JinjaFile and add it to the environment.

                                  This function reads a JinjaFile and adds its filters, tests, functions, and configuration to the current environment.

                                  Parameters:

                                  Name Type Description Default
                                  path str | PathLike[str]

                                  The path to the JinjaFile

                                  required
                                  scope_prefix str

                                  Optional prefix to add to all tests / filters / functions

                                  ''
                                  load_filters bool

                                  Whether to load filters from the JinjaFile

                                  True
                                  load_tests bool

                                  Whether to load tests from the JinjaFile

                                  True
                                  load_functions bool

                                  Whether to load functions from the JinjaFile

                                  True
                                  load_config bool

                                  Whether to load the environment config from the JinjaFile

                                  True
                                  load_loader bool

                                  Whether to load the Loader from the JinjaFile

                                  True
                                  Source code in src/jinjarope/environment.py
                                  172
                                  173
                                  174
                                  175
                                  176
                                  177
                                  178
                                  179
                                  180
                                  181
                                  182
                                  183
                                  184
                                  185
                                  186
                                  187
                                  188
                                  189
                                  190
                                  191
                                  192
                                  193
                                  194
                                  195
                                  196
                                  197
                                  198
                                  199
                                  200
                                  201
                                  202
                                  203
                                  204
                                  205
                                  206
                                  207
                                  208
                                  209
                                  210
                                  211
                                  212
                                  213
                                  214
                                  215
                                  216
                                  217
                                  218
                                  219
                                  220
                                  221
                                  222
                                  def load_jinja_file(
                                      self,
                                      path: str | os.PathLike[str],
                                      scope_prefix: str = "",
                                      load_filters: bool = True,
                                      load_tests: bool = True,
                                      load_functions: bool = True,
                                      load_config: bool = True,
                                      load_loader: bool = True,
                                  ):
                                      """Load the content of a JinjaFile and add it to the environment.
                                  
                                      This function reads a JinjaFile and adds its filters, tests,
                                      functions, and configuration to the current environment.
                                  
                                      Args:
                                          path: The path to the JinjaFile
                                          scope_prefix: Optional prefix to add to all tests / filters / functions
                                          load_filters: Whether to load filters from the JinjaFile
                                          load_tests: Whether to load tests from the JinjaFile
                                          load_functions: Whether to load functions from the JinjaFile
                                          load_config: Whether to load the environment config from the JinjaFile
                                          load_loader: Whether to load the Loader from the JinjaFile
                                      """
                                      file = jinjafile.JinjaFile(path)
                                      if load_filters:
                                          dct = {f"{scope_prefix}{k}": v for k, v in file.filters_dict.items()}
                                          self.filters.update(dct)
                                      if load_tests:
                                          dct = {f"{scope_prefix}{k}": v for k, v in file.tests_dict.items()}
                                          self.tests.update(dct)
                                      if load_functions:
                                          dct = {f"{scope_prefix}{k}": v for k, v in file.functions_dict.items()}
                                          self.globals.update(dct)
                                      if load_config:
                                          self.block_start_string = file.envconfig.block_start_string
                                          self.block_end_string = file.envconfig.block_end_string
                                          self.variable_start_string = file.envconfig.variable_start_string
                                          self.variable_end_string = file.envconfig.variable_end_string
                                          self.comment_start_string = file.envconfig.comment_start_string
                                          self.comment_end_string = file.envconfig.comment_end_string
                                          self.line_statement_prefix = file.envconfig.line_statement_prefix
                                          self.line_comment_prefix = file.envconfig.line_comment_prefix
                                          self.trim_blocks = file.envconfig.trim_blocks
                                          self.lstrip_blocks = file.envconfig.lstrip_blocks
                                          self.newline_sequence = file.envconfig.newline_sequence
                                          self.keep_trailing_newline = file.envconfig.keep_trailing_newline
                                          for ext in file.envconfig.extensions or []:
                                              self.add_extension(ext)
                                      if load_loader and (loader := file.loader):
                                          self._add_loader(loader)
                                  

                                  make_globals

                                  make_globals(d: MutableMapping[str, Any] | None) -> MutableMapping[str, Any]
                                  

                                  Make the globals map for a template.

                                  This function creates a globals map for a template, where template-specific globals overlay the environment's global variables.

                                  Info

                                  Avoid modifying any globals after a template is loaded.

                                  Parameters:

                                  Name Type Description Default
                                  d MutableMapping[str, Any] | None

                                  Dict of template-specific globals

                                  required

                                  Returns:

                                  Type Description
                                  MutableMapping[str, Any]

                                  A ChainMap containing the template globals.

                                  Source code in src/jinjarope/environment.py
                                  602
                                  603
                                  604
                                  605
                                  606
                                  607
                                  608
                                  609
                                  610
                                  611
                                  612
                                  613
                                  614
                                  615
                                  616
                                  617
                                  618
                                  619
                                  620
                                  621
                                  622
                                  623
                                  624
                                  625
                                  626
                                  627
                                  628
                                  629
                                  630
                                  def make_globals(
                                      self,
                                      d: MutableMapping[str, Any] | None,
                                  ) -> MutableMapping[str, Any]:
                                      """Make the globals map for a template.
                                  
                                      This function creates a globals map for a template, where
                                      template-specific globals overlay the environment's global
                                      variables.
                                  
                                      !!! info
                                          Avoid modifying any globals after a template is loaded.
                                  
                                      Args:
                                          d: Dict of template-specific globals
                                  
                                      Returns:
                                          A ChainMap containing the template globals.
                                      """
                                      if d is None:
                                          d = {}
                                  
                                      import collections
                                  
                                      class GlobalsMap(collections.ChainMap):
                                          def __repr__(self):
                                              return f"GlobalsMap<{len(self)} keys>"
                                  
                                      return GlobalsMap(d, self.globals)
                                  

                                  render_condition

                                  render_condition(
                                      string: str, variables: dict[str, Any] | None = None, **kwargs: Any
                                  ) -> bool
                                  

                                  Render a template condition.

                                  This function renders a template string and evaluates its result as a boolean. It returns True if the result is truthy (not None, False, or an empty string), otherwise False.

                                  Parameters:

                                  Name Type Description Default
                                  string str

                                  String to evaluate for True-ishness

                                  required
                                  variables dict[str, Any] | None

                                  Extra variables for the rendering

                                  None
                                  kwargs Any

                                  Further extra variables for rendering

                                  {}

                                  Returns:

                                  Type Description
                                  bool

                                  True if the rendered string is truthy, False otherwise.

                                  Source code in src/jinjarope/environment.py
                                  372
                                  373
                                  374
                                  375
                                  376
                                  377
                                  378
                                  379
                                  380
                                  381
                                  382
                                  383
                                  384
                                  385
                                  386
                                  387
                                  388
                                  389
                                  390
                                  391
                                  392
                                  393
                                  def render_condition(
                                      self,
                                      string: str,
                                      variables: dict[str, Any] | None = None,
                                      **kwargs: Any,
                                  ) -> bool:
                                      """Render a template condition.
                                  
                                      This function renders a template string and evaluates its
                                      result as a boolean. It returns True if the result is truthy
                                      (not None, False, or an empty string), otherwise False.
                                  
                                      Args:
                                          string: String to evaluate for True-ishness
                                          variables: Extra variables for the rendering
                                          kwargs: Further extra variables for rendering
                                  
                                      Returns:
                                          True if the rendered string is truthy, False otherwise.
                                      """
                                      result = self.render_string(string=string, variables=variables, **kwargs)
                                      return result not in ["None", "False", ""]
                                  

                                  render_file

                                  render_file(
                                      file: str | PathLike[str], variables: dict[str, Any] | None = None, **kwargs: Any
                                  ) -> str
                                  

                                  Helper to directly render a template from filesystem.

                                  This function renders a template file directly from the filesystem using the current environment's configuration and globals.

                                  Info

                                  The file content is cached, which is generally acceptable for common use cases.

                                  Parameters:

                                  Name Type Description Default
                                  file str | PathLike[str]

                                  Template file to load

                                  required
                                  variables dict[str, Any] | None

                                  Extra variables for the rendering

                                  None
                                  kwargs Any

                                  Further extra variables for rendering

                                  {}

                                  Returns:

                                  Type Description
                                  str

                                  The rendered string.

                                  Source code in src/jinjarope/environment.py
                                  423
                                  424
                                  425
                                  426
                                  427
                                  428
                                  429
                                  430
                                  431
                                  432
                                  433
                                  434
                                  435
                                  436
                                  437
                                  438
                                  439
                                  440
                                  441
                                  442
                                  443
                                  444
                                  445
                                  446
                                  447
                                  448
                                  def render_file(
                                      self,
                                      file: str | os.PathLike[str],
                                      variables: dict[str, Any] | None = None,
                                      **kwargs: Any,
                                  ) -> str:
                                      """Helper to directly render a template from filesystem.
                                  
                                      This function renders a template file directly from the
                                      filesystem using the current environment's configuration and
                                      globals.
                                  
                                      !!! info
                                          The file content is cached, which is generally acceptable
                                          for common use cases.
                                  
                                      Args:
                                          file: Template file to load
                                          variables: Extra variables for the rendering
                                          kwargs: Further extra variables for rendering
                                  
                                      Returns:
                                          The rendered string.
                                      """
                                      content = envglobals.load_file_cached(str(file))
                                      return self.render_string(content, variables, **kwargs)
                                  

                                  render_string

                                  render_string(string: str, variables: dict[str, Any] | None = None, **kwargs: Any) -> str
                                  

                                  Render a template string.

                                  This function renders the given template string using the current environment's configuration and globals.

                                  Parameters:

                                  Name Type Description Default
                                  string str

                                  String to render

                                  required
                                  variables dict[str, Any] | None

                                  Extra variables for the rendering

                                  None
                                  kwargs Any

                                  Further extra variables for rendering

                                  {}

                                  Returns:

                                  Type Description
                                  str

                                  The rendered string.

                                  Source code in src/jinjarope/environment.py
                                  395
                                  396
                                  397
                                  398
                                  399
                                  400
                                  401
                                  402
                                  403
                                  404
                                  405
                                  406
                                  407
                                  408
                                  409
                                  410
                                  411
                                  412
                                  413
                                  414
                                  415
                                  416
                                  417
                                  418
                                  419
                                  420
                                  421
                                  def render_string(
                                      self,
                                      string: str,
                                      variables: dict[str, Any] | None = None,
                                      **kwargs: Any,
                                  ) -> str:
                                      """Render a template string.
                                  
                                      This function renders the given template string using the
                                      current environment's configuration and globals.
                                  
                                      Args:
                                          string: String to render
                                          variables: Extra variables for the rendering
                                          kwargs: Further extra variables for rendering
                                  
                                      Returns:
                                          The rendered string.
                                      """
                                      variables = (variables or {}) | kwargs
                                      cls = self.template_class
                                      try:
                                          template = cls.from_code(self, self.compile(string), self.globals, None)
                                      except TemplateSyntaxError as e:
                                          msg = f"Error when evaluating \n{string}\n (extra globals: {variables})"
                                          raise SyntaxError(msg) from e
                                      return template.render(**variables)
                                  

                                  render_template

                                  render_template(
                                      template_name: str,
                                      variables: dict[str, Any] | None = None,
                                      block_name: str | None = None,
                                      parent_template: str | None = None,
                                      **kwargs: Any
                                  ) -> str
                                  

                                  Render a loaded template (or a block of a template).

                                  This function renders a loaded template or a specific block from a template. It allows for the inclusion of parent templates and provides the flexibility to render individual blocks.

                                  Parameters:

                                  Name Type Description Default
                                  template_name str

                                  Template name

                                  required
                                  variables dict[str, Any] | None

                                  Extra variables for rendering

                                  None
                                  block_name str | None

                                  Render specific block from the template

                                  None
                                  parent_template str | None

                                  The name of the parent template importing this template

                                  None
                                  kwargs Any

                                  Further extra variables for rendering

                                  {}

                                  Returns:

                                  Type Description
                                  str

                                  The rendered string.

                                  Raises:

                                  Type Description
                                  BlockNotFoundError

                                  If the specified block is not found in the

                                  Source code in src/jinjarope/environment.py
                                  450
                                  451
                                  452
                                  453
                                  454
                                  455
                                  456
                                  457
                                  458
                                  459
                                  460
                                  461
                                  462
                                  463
                                  464
                                  465
                                  466
                                  467
                                  468
                                  469
                                  470
                                  471
                                  472
                                  473
                                  474
                                  475
                                  476
                                  477
                                  478
                                  479
                                  480
                                  481
                                  482
                                  483
                                  484
                                  485
                                  486
                                  487
                                  488
                                  def render_template(
                                      self,
                                      template_name: str,
                                      variables: dict[str, Any] | None = None,
                                      block_name: str | None = None,
                                      parent_template: str | None = None,
                                      **kwargs: Any,
                                  ) -> str:
                                      """Render a loaded template (or a block of a template).
                                  
                                      This function renders a loaded template or a specific block from
                                      a template. It allows for the inclusion of parent templates and
                                      provides the flexibility to render individual blocks.
                                  
                                      Args:
                                          template_name: Template name
                                          variables: Extra variables for rendering
                                          block_name: Render specific block from the template
                                          parent_template: The name of the parent template importing this template
                                          kwargs: Further extra variables for rendering
                                  
                                      Returns:
                                          The rendered string.
                                  
                                      Raises:
                                          BlockNotFoundError: If the specified block is not found in the
                                          template.
                                      """
                                      variables = (variables or {}) | kwargs
                                      template = self.get_template(template_name, parent=parent_template)
                                      if not block_name:
                                          return template.render(**variables)
                                      try:
                                          block_render_func = template.blocks[block_name]
                                      except KeyError:
                                          raise BlockNotFoundError(block_name, template_name) from KeyError
                                  
                                      ctx = template.new_context(variables)
                                      return self.concat(block_render_func(ctx))  # type: ignore
                                  

                                  set_undefined

                                  set_undefined(value: UndefinedStr | type[Undefined])
                                  

                                  Set the undefined behaviour for the environment.

                                  Parameters:

                                  Name Type Description Default
                                  value UndefinedStr | type[Undefined]

                                  The new undefined behaviour

                                  required
                                  Source code in src/jinjarope/environment.py
                                  163
                                  164
                                  165
                                  166
                                  167
                                  168
                                  169
                                  170
                                  def set_undefined(self, value: undefined_.UndefinedStr | type[jinja2.Undefined]):
                                      """Set the undefined behaviour for the environment.
                                  
                                      Args:
                                          value: The new undefined behaviour
                                      """
                                      new = undefined_.UNDEFINED_BEHAVIOR[value] if isinstance(value, str) else value
                                      self.undefined = new
                                  

                                  setup_loader

                                  setup_loader(
                                      dir_paths: list[str] | None = None,
                                      module_paths: list[str] | None = None,
                                      static: dict[str, str] | None = None,
                                      fsspec_paths: bool = True,
                                  )
                                  

                                  Set the loader for the environment.

                                  This function sets the loader for the environment based on the provided parameters. It uses the jinjarope.get_loader function to create a suitable loader.

                                  Parameters:

                                  Name Type Description Default
                                  dir_paths list[str] | None

                                  List of directory paths to search for templates

                                  None
                                  module_paths list[str] | None

                                  List of module paths to search for templates

                                  None
                                  static dict[str, str] | None

                                  Dictionary of static files to include in the loader

                                  None
                                  fsspec_paths bool

                                  Whether to use fsspec paths for loading

                                  True
                                  Source code in src/jinjarope/environment.py
                                  508
                                  509
                                  510
                                  511
                                  512
                                  513
                                  514
                                  515
                                  516
                                  517
                                  518
                                  519
                                  520
                                  521
                                  522
                                  523
                                  524
                                  525
                                  526
                                  527
                                  528
                                  529
                                  530
                                  531
                                  532
                                  def setup_loader(
                                      self,
                                      dir_paths: list[str] | None = None,
                                      module_paths: list[str] | None = None,
                                      static: dict[str, str] | None = None,
                                      fsspec_paths: bool = True,
                                  ):
                                      """Set the loader for the environment.
                                  
                                      This function sets the loader for the environment based on
                                      the provided parameters. It uses the ``jinjarope.get_loader``
                                      function to create a suitable loader.
                                  
                                      Args:
                                          dir_paths: List of directory paths to search for templates
                                          module_paths: List of module paths to search for templates
                                          static: Dictionary of static files to include in the loader
                                          fsspec_paths: Whether to use fsspec paths for loading
                                      """
                                      self.loader = jinjarope.get_loader(
                                          dir_paths=dir_paths,
                                          module_paths=module_paths,
                                          static=static,
                                          fsspec_paths=fsspec_paths,
                                      )
                                  

                                  with_globals

                                  with_globals(**kwargs: Any)
                                  

                                  Context manager to temporarily set globals for the environment.

                                  This context manager allows temporarily overriding the environment's globals with the provided values. Any changes made within the context manager are reverted upon exiting the context.

                                  Parameters:

                                  Name Type Description Default
                                  kwargs Any

                                  Globals to set

                                  {}
                                  Source code in src/jinjarope/environment.py
                                  492
                                  493
                                  494
                                  495
                                  496
                                  497
                                  498
                                  499
                                  500
                                  501
                                  502
                                  503
                                  504
                                  505
                                  506
                                  @contextlib.contextmanager
                                  def with_globals(self, **kwargs: Any):
                                      """Context manager to temporarily set globals for the environment.
                                  
                                      This context manager allows temporarily overriding the environment's
                                      globals with the provided values. Any changes made within the context
                                      manager are reverted upon exiting the context.
                                  
                                      Args:
                                          kwargs: Globals to set
                                      """
                                      temp = self.globals.copy()
                                      self.globals.update(kwargs)
                                      yield
                                      self.globals = temp
                                  

                                  FileSystemLoader

                                  Bases: LoaderMixin, FileSystemLoader

                                  A loader to load templates from the file system.

                                  Source code in src/jinjarope/loaders.py
                                  164
                                  165
                                  166
                                  167
                                  168
                                  169
                                  170
                                  171
                                  172
                                  173
                                  174
                                  175
                                  176
                                  177
                                  178
                                  179
                                  180
                                  181
                                  182
                                  183
                                  class FileSystemLoader(LoaderMixin, jinja2.FileSystemLoader):
                                      """A loader to load templates from the file system."""
                                  
                                      ID = "filesystem"
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, searchpath=self.searchpath)
                                  
                                      def __add__(self, other) -> FileSystemLoader:
                                          ls = [other] if isinstance(other, jinja2.FileSystemLoader) else other.serchpath
                                          return FileSystemLoader([*self.searchpath, *ls])
                                  
                                      def __bool__(self):
                                          return len(self.searchpath) > 0
                                  
                                      def __eq__(self, other):
                                          return type(self) is type(other) and self.searchpath == other.searchpath
                                  
                                      def __hash__(self):
                                          return hash(tuple(self.searchpath))
                                  

                                  FsSpecFileSystemLoader

                                  Bases: LoaderMixin, BaseLoader

                                  A jinja loader for fsspec filesystems.

                                  This loader allows to access templates from an fsspec filesystem.

                                  Template paths must be relative to the filesystem root. In order to access templates via protocol path, see FsSpecProtocolPathLoader.

                                  Examples:

                                  # protocol path
                                  loader = FsSpecFileSystemLoader("dir::github://phil65:mknodes@main/docs")
                                  env = Environment(loader=loader)
                                  env.get_template("icons.jinja").render()
                                  
                                  # protocol and storage options
                                  loader = FsSpecFileSystemLoader("github", org="phil65", repo="mknodes")
                                  env = Environment(loader=loader)
                                  env.get_template("docs/icons.jinja").render()
                                  
                                  # fsspec filesystem
                                  fs = fsspec.filesystem("github", org="phil65", repo="mknodes")
                                  loader = FsSpecFileSystemLoader(fs)
                                  env = Environment(loader=loader)
                                  env.get_template("docs/icons.jinja").render()
                                  
                                  Source code in src/jinjarope/fsspecloaders.py
                                   66
                                   67
                                   68
                                   69
                                   70
                                   71
                                   72
                                   73
                                   74
                                   75
                                   76
                                   77
                                   78
                                   79
                                   80
                                   81
                                   82
                                   83
                                   84
                                   85
                                   86
                                   87
                                   88
                                   89
                                   90
                                   91
                                   92
                                   93
                                   94
                                   95
                                   96
                                   97
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  114
                                  115
                                  116
                                  117
                                  118
                                  119
                                  120
                                  121
                                  122
                                  123
                                  124
                                  125
                                  126
                                  127
                                  128
                                  129
                                  130
                                  131
                                  132
                                  133
                                  134
                                  135
                                  136
                                  137
                                  138
                                  139
                                  140
                                  141
                                  142
                                  143
                                  144
                                  145
                                  146
                                  147
                                  148
                                  149
                                  150
                                  151
                                  class FsSpecFileSystemLoader(loaders_.LoaderMixin, jinja2.BaseLoader):
                                      """A jinja loader for fsspec filesystems.
                                  
                                      This loader allows to access templates from an fsspec filesystem.
                                  
                                      Template paths must be relative to the filesystem root.
                                      In order to access templates via protocol path, see `FsSpecProtocolPathLoader`.
                                  
                                      Examples:
                                          ``` py
                                          # protocol path
                                          loader = FsSpecFileSystemLoader("dir::github://phil65:mknodes@main/docs")
                                          env = Environment(loader=loader)
                                          env.get_template("icons.jinja").render()
                                  
                                          # protocol and storage options
                                          loader = FsSpecFileSystemLoader("github", org="phil65", repo="mknodes")
                                          env = Environment(loader=loader)
                                          env.get_template("docs/icons.jinja").render()
                                  
                                          # fsspec filesystem
                                          fs = fsspec.filesystem("github", org="phil65", repo="mknodes")
                                          loader = FsSpecFileSystemLoader(fs)
                                          env = Environment(loader=loader)
                                          env.get_template("docs/icons.jinja").render()
                                          ```
                                  
                                      """
                                  
                                      ID = "fsspec"
                                  
                                      def __init__(self, fs: fsspec.AbstractFileSystem | str, **kwargs: Any):
                                          """Constructor.
                                  
                                          Args:
                                              fs: Either a protocol path string or an fsspec filesystem instance.
                                                  Also supports "::dir" prefix to set the root path.
                                              kwargs: Optional storage options for the filesystem.
                                          """
                                          super().__init__()
                                          match fs:
                                              case str() if "://" in fs:
                                                  self.fs, self.path = fsspec.core.url_to_fs(fs, **kwargs)
                                              case str():
                                                  self.fs, self.path = fsspec.filesystem(fs, **kwargs), ""
                                              case _:
                                                  self.fs, self.path = fs, ""
                                          self.storage_options = kwargs
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, fs=self.fs)
                                  
                                      def __eq__(self, other):
                                          return (
                                              type(self) is type(other)
                                              and self.storage_options == other.storage_options
                                              and self.fs == other.fs
                                              and self.path == other.path
                                          )
                                  
                                      def __hash__(self):
                                          return (
                                              hash(tuple(sorted(self.storage_options.items())))
                                              + hash(self.fs)
                                              + hash(self.path)
                                          )
                                  
                                      def list_templates(self) -> list[str]:
                                          return [
                                              f"{path}{self.fs.sep}{f}" if path else f
                                              for path, _dirs, files in self.fs.walk(self.fs.root_marker)
                                              for f in files
                                          ]
                                  
                                      def get_source(
                                          self,
                                          environment: jinja2.Environment,
                                          template: str,
                                      ) -> tuple[str, str, Callable[[], bool] | None]:
                                          try:
                                              with self.fs.open(template) as file:
                                                  src = file.read().decode()
                                          except FileNotFoundError as e:
                                              raise jinja2.TemplateNotFound(template) from e
                                          path = pathlib.Path(template).as_posix()
                                          return src, path, lambda: True
                                  

                                  __init__

                                  __init__(fs: AbstractFileSystem | str, **kwargs: Any)
                                  

                                  Constructor.

                                  Parameters:

                                  Name Type Description Default
                                  fs AbstractFileSystem | str

                                  Either a protocol path string or an fsspec filesystem instance. Also supports "::dir" prefix to set the root path.

                                  required
                                  kwargs Any

                                  Optional storage options for the filesystem.

                                  {}
                                  Source code in src/jinjarope/fsspecloaders.py
                                   97
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  def __init__(self, fs: fsspec.AbstractFileSystem | str, **kwargs: Any):
                                      """Constructor.
                                  
                                      Args:
                                          fs: Either a protocol path string or an fsspec filesystem instance.
                                              Also supports "::dir" prefix to set the root path.
                                          kwargs: Optional storage options for the filesystem.
                                      """
                                      super().__init__()
                                      match fs:
                                          case str() if "://" in fs:
                                              self.fs, self.path = fsspec.core.url_to_fs(fs, **kwargs)
                                          case str():
                                              self.fs, self.path = fsspec.filesystem(fs, **kwargs), ""
                                          case _:
                                              self.fs, self.path = fs, ""
                                      self.storage_options = kwargs
                                  

                                  FsSpecProtocolPathLoader

                                  Bases: LoaderMixin, BaseLoader

                                  A jinja loader for fsspec filesystems.

                                  This loader allows to access templates from an fsspec protocol path, like "github://phil65:mknodes@main/README.md"

                                  Examples:

                                  loader = FsSpecProtocolPathLoader()
                                  env = Environment(loader=loader)
                                  env.get_template("github://phil65:mknodes@main/docs/icons.jinja").render()
                                  
                                  Source code in src/jinjarope/fsspecloaders.py
                                  17
                                  18
                                  19
                                  20
                                  21
                                  22
                                  23
                                  24
                                  25
                                  26
                                  27
                                  28
                                  29
                                  30
                                  31
                                  32
                                  33
                                  34
                                  35
                                  36
                                  37
                                  38
                                  39
                                  40
                                  41
                                  42
                                  43
                                  44
                                  45
                                  46
                                  47
                                  48
                                  49
                                  50
                                  51
                                  52
                                  53
                                  54
                                  55
                                  56
                                  57
                                  58
                                  59
                                  60
                                  61
                                  62
                                  63
                                  class FsSpecProtocolPathLoader(loaders_.LoaderMixin, jinja2.BaseLoader):
                                      """A jinja loader for fsspec filesystems.
                                  
                                      This loader allows to access templates from an fsspec protocol path,
                                      like "github://phil65:mknodes@main/README.md"
                                  
                                      Examples:
                                          ``` py
                                          loader = FsSpecProtocolPathLoader()
                                          env = Environment(loader=loader)
                                          env.get_template("github://phil65:mknodes@main/docs/icons.jinja").render()
                                          ```
                                      """
                                  
                                      ID = "fsspec_protocol_path"
                                  
                                      def __eq__(self, other: object):
                                          return type(self) is type(other)
                                  
                                      def __hash__(self):
                                          return hash(type(self))
                                  
                                      def get_source(
                                          self,
                                          environment: jinja2.Environment | None,
                                          template: str,
                                      ) -> tuple[str, str, Callable[[], bool] | None]:
                                          try:
                                              src = envglobals.load_file_cached(template)
                                          except FileNotFoundError as e:
                                              raise jinja2.TemplateNotFound(template) from e
                                          path = pathlib.Path(template).as_posix()
                                          return src, path, lambda: True
                                  
                                      def list_templates(self) -> list[str]:
                                          return []
                                  
                                      def __contains__(self, path: str):
                                          try:
                                              self.get_source(None, path)
                                          except jinja2.TemplateNotFound:
                                              return False
                                          else:
                                              return True
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self)
                                  

                                  FunctionLoader

                                  Bases: LoaderMixin, FunctionLoader

                                  A loader for loading templates from a function.

                                  The function takes a template path as parameter and either returns a (text, None, uptodate_fn) tuple or just the text as str.

                                  Source code in src/jinjarope/loaders.py
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  114
                                  class FunctionLoader(LoaderMixin, jinja2.FunctionLoader):
                                      """A loader for loading templates from a function.
                                  
                                      The function takes a template path as parameter and either returns
                                      a (text, None, uptodate_fn) tuple or just the text as str.
                                      """
                                  
                                      ID = "function"
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, self.load_func)
                                  
                                      def __eq__(self, other):
                                          return type(self) is type(other) and self.load_func == other.load_func
                                  
                                      def __hash__(self):
                                          return hash(self.load_func)
                                  

                                  JinjaFile

                                  Bases: dict[str, Any]

                                  A file defining filters / tests.

                                  Source code in src/jinjarope/jinjafile.py
                                   25
                                   26
                                   27
                                   28
                                   29
                                   30
                                   31
                                   32
                                   33
                                   34
                                   35
                                   36
                                   37
                                   38
                                   39
                                   40
                                   41
                                   42
                                   43
                                   44
                                   45
                                   46
                                   47
                                   48
                                   49
                                   50
                                   51
                                   52
                                   53
                                   54
                                   55
                                   56
                                   57
                                   58
                                   59
                                   60
                                   61
                                   62
                                   63
                                   64
                                   65
                                   66
                                   67
                                   68
                                   69
                                   70
                                   71
                                   72
                                   73
                                   74
                                   75
                                   76
                                   77
                                   78
                                   79
                                   80
                                   81
                                   82
                                   83
                                   84
                                   85
                                   86
                                   87
                                   88
                                   89
                                   90
                                   91
                                   92
                                   93
                                   94
                                   95
                                   96
                                   97
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  114
                                  class JinjaFile(dict[str, Any]):
                                      """A file defining filters / tests."""
                                  
                                      def __init__(self, path: str | os.PathLike[str]):
                                          """Instanciate the file.
                                  
                                          Args:
                                              path: Path to the jinja file
                                          """
                                          super().__init__()
                                          text = envglobals.load_file_cached(os.fspath(path))
                                          data = _load(text)
                                          self.update(data)
                                  
                                      @property
                                      def filters(self) -> list[JinjaItem]:
                                          """Return list of filters defined in the file."""
                                          return [
                                              JinjaItem(filter_name, typ="filter", **dct)
                                              for filter_name, dct in self.get("filters", {}).items()
                                              if all(envtests.is_installed(i) for i in dct.get("required_packages", []))
                                          ]
                                  
                                      @property
                                      def tests(self) -> list[JinjaItem]:
                                          """Return list of tests defined in the file."""
                                          return [
                                              JinjaItem(filter_name, typ="test", **dct)
                                              for filter_name, dct in self.get("tests", {}).items()
                                              if all(envtests.is_installed(i) for i in dct.get("required_packages", []))
                                          ]
                                  
                                      @property
                                      def functions(self) -> list[JinjaItem]:
                                          """Return list of functions defined in the file."""
                                          return [
                                              JinjaItem(filter_name, typ="function", **dct)
                                              for filter_name, dct in self.get("functions", {}).items()
                                              if all(envtests.is_installed(i) for i in dct.get("required_packages", []))
                                          ]
                                  
                                      @property
                                      def filters_dict(self) -> dict[str, Callable[..., Any]]:
                                          """Return a dictionary with all filters.
                                  
                                          Can directly get merged into env filters.
                                          """
                                          dct = {}
                                          for f in self.filters:
                                              dct[f.identifier] = f.filter_fn
                                              for alias in f.aliases:
                                                  dct[alias] = f.filter_fn
                                          return dct
                                  
                                      @property
                                      def tests_dict(self) -> dict[str, Callable[..., bool]]:
                                          """Return a dictionary with all filters.
                                  
                                          Can directly get merged into env filters.
                                          """
                                          dct = {}
                                          for f in self.tests:
                                              dct[f.identifier] = f.filter_fn
                                              for alias in f.aliases:
                                                  dct[alias] = f.filter_fn
                                          return dct
                                  
                                      @property
                                      def functions_dict(self) -> dict[str, Callable[..., Any]]:
                                          """Return a dictionary with all filters.
                                  
                                          Can directly get merged into env filters.
                                          """
                                          dct = {}
                                          for f in self.functions:
                                              dct[f.identifier] = f.filter_fn
                                              for alias in f.aliases:
                                                  dct[alias] = f.filter_fn
                                          return dct
                                  
                                      @property
                                      def envconfig(self) -> envconfig.EnvConfig:
                                          """Return the config object defined in this Jinja file."""
                                          cfg = self.get("config", {})
                                          return envconfig.EnvConfig(**cfg, loader=self.loader)
                                  
                                      @property
                                      def loader(self) -> jinja2.BaseLoader | None:
                                          """Return a (composed Choice-) loader defined in this Jinja file."""
                                          return loaders.from_json(self.get("loaders", []))
                                  

                                  envconfig property

                                  envconfig: EnvConfig
                                  

                                  Return the config object defined in this Jinja file.

                                  filters property

                                  filters: list[JinjaItem]
                                  

                                  Return list of filters defined in the file.

                                  filters_dict property

                                  filters_dict: dict[str, Callable[..., Any]]
                                  

                                  Return a dictionary with all filters.

                                  Can directly get merged into env filters.

                                  functions property

                                  functions: list[JinjaItem]
                                  

                                  Return list of functions defined in the file.

                                  functions_dict property

                                  functions_dict: dict[str, Callable[..., Any]]
                                  

                                  Return a dictionary with all filters.

                                  Can directly get merged into env filters.

                                  loader property

                                  loader: BaseLoader | None
                                  

                                  Return a (composed Choice-) loader defined in this Jinja file.

                                  tests property

                                  tests: list[JinjaItem]
                                  

                                  Return list of tests defined in the file.

                                  tests_dict property

                                  tests_dict: dict[str, Callable[..., bool]]
                                  

                                  Return a dictionary with all filters.

                                  Can directly get merged into env filters.

                                  __init__

                                  __init__(path: str | PathLike[str])
                                  

                                  Instanciate the file.

                                  Parameters:

                                  Name Type Description Default
                                  path str | PathLike[str]

                                  Path to the jinja file

                                  required
                                  Source code in src/jinjarope/jinjafile.py
                                  28
                                  29
                                  30
                                  31
                                  32
                                  33
                                  34
                                  35
                                  36
                                  37
                                  def __init__(self, path: str | os.PathLike[str]):
                                      """Instanciate the file.
                                  
                                      Args:
                                          path: Path to the jinja file
                                      """
                                      super().__init__()
                                      text = envglobals.load_file_cached(os.fspath(path))
                                      data = _load(text)
                                      self.update(data)
                                  

                                  JinjaItem dataclass

                                  An item representing a filter / test.

                                  Source code in src/jinjarope/jinjafile.py
                                  117
                                  118
                                  119
                                  120
                                  121
                                  122
                                  123
                                  124
                                  125
                                  126
                                  127
                                  128
                                  129
                                  130
                                  131
                                  132
                                  133
                                  134
                                  135
                                  136
                                  137
                                  138
                                  139
                                  140
                                  141
                                  142
                                  143
                                  144
                                  145
                                  146
                                  147
                                  148
                                  149
                                  150
                                  151
                                  152
                                  153
                                  154
                                  155
                                  156
                                  157
                                  158
                                  159
                                  160
                                  161
                                  162
                                  163
                                  164
                                  165
                                  166
                                  167
                                  168
                                  169
                                  170
                                  171
                                  172
                                  173
                                  174
                                  175
                                  176
                                  177
                                  178
                                  179
                                  180
                                  181
                                  182
                                  183
                                  184
                                  185
                                  186
                                  187
                                  188
                                  189
                                  @dataclasses.dataclass(frozen=True)
                                  class JinjaItem:
                                      """An item representing a filter / test."""
                                  
                                      identifier: str
                                      typ: Literal["filter", "test", "function"]
                                      fn: str
                                      group: str
                                      icon: str | None = None
                                      examples: dict[str, dict[str, str]] = dataclasses.field(default_factory=dict)
                                      description: str | None = None
                                      aliases: list[str] = dataclasses.field(default_factory=list)
                                      required_packages: list[str] = dataclasses.field(default_factory=list)
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, self.identifier)
                                  
                                      @property
                                      def filter_fn(self) -> Callable[..., Any]:
                                          """Return the callable to use as filter / test / function."""
                                          try:
                                              obj = utils.resolve(self.fn)
                                          except AttributeError:
                                              msg = f"Could not import jinja item {self.identifier!r} from {self.fn!r}"
                                              raise ImportError(msg) from AttributeError
                                          if not callable(obj):
                                              msg = "Filter needs correct, importable Path for callable"
                                              raise TypeError(msg)
                                          return obj
                                  
                                      @classmethod
                                      def for_function(
                                          cls,
                                          fn: Callable[..., Any],
                                          typ: Literal["filter", "test", "function"],
                                          group: str = "imported",
                                          **kwargs: Any,
                                      ) -> Self:
                                          """Alternative ctor to construct a JinjaItem based on a callable.
                                  
                                          Args:
                                              fn: Callable to get a JinjaItem for
                                              typ: The item type
                                              group: Group for metadata
                                              kwargs: Additional keyword arguments for JinjaItem ctor
                                          """
                                          return cls(
                                              fn.__name__,
                                              typ=typ,
                                              fn=f"{fn.__module__}.{fn.__name__}",
                                              group=group,
                                              **kwargs,
                                          )
                                  
                                      def apply(self, *args: Any, **kwargs: Any) -> Any:
                                          """Apply the filter function using given arguments and keywords.
                                  
                                          Args:
                                              args: The arguments for the call
                                              kwargs: They keyword arguments for the call
                                          """
                                          return self.filter_fn(*args, **kwargs)
                                  
                                      def resolve_example(self, example_name: str) -> str:
                                          """Render example with given name and return the result.
                                  
                                          Args:
                                              example_name: The example identifier
                                          """
                                          example = self.examples[example_name]
                                          loader = jinjarope.FileSystemLoader("")
                                          env = jinjarope.Environment(loader=loader)
                                          return env.render_string(example["template"])
                                  

                                  filter_fn property

                                  filter_fn: Callable[..., Any]
                                  

                                  Return the callable to use as filter / test / function.

                                  apply

                                  apply(*args: Any, **kwargs: Any) -> Any
                                  

                                  Apply the filter function using given arguments and keywords.

                                  Parameters:

                                  Name Type Description Default
                                  args Any

                                  The arguments for the call

                                  ()
                                  kwargs Any

                                  They keyword arguments for the call

                                  {}
                                  Source code in src/jinjarope/jinjafile.py
                                  171
                                  172
                                  173
                                  174
                                  175
                                  176
                                  177
                                  178
                                  def apply(self, *args: Any, **kwargs: Any) -> Any:
                                      """Apply the filter function using given arguments and keywords.
                                  
                                      Args:
                                          args: The arguments for the call
                                          kwargs: They keyword arguments for the call
                                      """
                                      return self.filter_fn(*args, **kwargs)
                                  

                                  for_function classmethod

                                  for_function(
                                      fn: Callable[..., Any],
                                      typ: Literal["filter", "test", "function"],
                                      group: str = "imported",
                                      **kwargs: Any
                                  ) -> Self
                                  

                                  Alternative ctor to construct a JinjaItem based on a callable.

                                  Parameters:

                                  Name Type Description Default
                                  fn Callable[..., Any]

                                  Callable to get a JinjaItem for

                                  required
                                  typ Literal['filter', 'test', 'function']

                                  The item type

                                  required
                                  group str

                                  Group for metadata

                                  'imported'
                                  kwargs Any

                                  Additional keyword arguments for JinjaItem ctor

                                  {}
                                  Source code in src/jinjarope/jinjafile.py
                                  147
                                  148
                                  149
                                  150
                                  151
                                  152
                                  153
                                  154
                                  155
                                  156
                                  157
                                  158
                                  159
                                  160
                                  161
                                  162
                                  163
                                  164
                                  165
                                  166
                                  167
                                  168
                                  169
                                  @classmethod
                                  def for_function(
                                      cls,
                                      fn: Callable[..., Any],
                                      typ: Literal["filter", "test", "function"],
                                      group: str = "imported",
                                      **kwargs: Any,
                                  ) -> Self:
                                      """Alternative ctor to construct a JinjaItem based on a callable.
                                  
                                      Args:
                                          fn: Callable to get a JinjaItem for
                                          typ: The item type
                                          group: Group for metadata
                                          kwargs: Additional keyword arguments for JinjaItem ctor
                                      """
                                      return cls(
                                          fn.__name__,
                                          typ=typ,
                                          fn=f"{fn.__module__}.{fn.__name__}",
                                          group=group,
                                          **kwargs,
                                      )
                                  

                                  resolve_example

                                  resolve_example(example_name: str) -> str
                                  

                                  Render example with given name and return the result.

                                  Parameters:

                                  Name Type Description Default
                                  example_name str

                                  The example identifier

                                  required
                                  Source code in src/jinjarope/jinjafile.py
                                  180
                                  181
                                  182
                                  183
                                  184
                                  185
                                  186
                                  187
                                  188
                                  189
                                  def resolve_example(self, example_name: str) -> str:
                                      """Render example with given name and return the result.
                                  
                                      Args:
                                          example_name: The example identifier
                                      """
                                      example = self.examples[example_name]
                                      loader = jinjarope.FileSystemLoader("")
                                      env = jinjarope.Environment(loader=loader)
                                      return env.render_string(example["template"])
                                  

                                  ModuleLoader

                                  Bases: LoaderMixin, ModuleLoader

                                  This loader loads templates from precompiled templates.

                                  Templates can be precompiled with :meth:Environment.compile_templates.

                                  Source code in src/jinjarope/loaders.py
                                  76
                                  77
                                  78
                                  79
                                  80
                                  81
                                  82
                                  83
                                  84
                                  85
                                  86
                                  87
                                  88
                                  89
                                  90
                                  91
                                  92
                                  93
                                  94
                                  95
                                  class ModuleLoader(LoaderMixin, jinja2.ModuleLoader):
                                      """This loader loads templates from precompiled templates.
                                  
                                      Templates can be precompiled with :meth:`Environment.compile_templates`.
                                      """
                                  
                                      ID = "module"
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, path=self.module.__path__)
                                  
                                      def __eq__(self, other):
                                          return (
                                              type(self) is type(other)
                                              and self.package_name == other.package_name
                                              and self.module == other.module
                                          )
                                  
                                      def __hash__(self):
                                          return hash(self.package_name) + hash(self.module)
                                  

                                  NestedDictLoader

                                  Bases: LoaderMixin, BaseLoader

                                  A jinja loader for loading templates from nested dicts.

                                  This loader allows to access templates from nested dicts. Can be used to load templates defined with markup like TOML.

                                  Examples:

                                  [example]
                                  template = "{{ something }}"
                                  
                                  content = tomllib.load(toml_file)
                                  loader = NestedDictLoader(content)
                                  env = Environment(loader=loader)
                                  env.get_template("example/template")
                                  

                                  Source code in src/jinjarope/configloaders.py
                                  18
                                  19
                                  20
                                  21
                                  22
                                  23
                                  24
                                  25
                                  26
                                  27
                                  28
                                  29
                                  30
                                  31
                                  32
                                  33
                                  34
                                  35
                                  36
                                  37
                                  38
                                  39
                                  40
                                  41
                                  42
                                  43
                                  44
                                  45
                                  46
                                  47
                                  48
                                  49
                                  50
                                  51
                                  52
                                  53
                                  54
                                  55
                                  56
                                  57
                                  58
                                  59
                                  60
                                  61
                                  62
                                  63
                                  64
                                  65
                                  66
                                  class NestedDictLoader(loaders.LoaderMixin, jinja2.BaseLoader):
                                      """A jinja loader for loading templates from nested dicts.
                                  
                                      This loader allows to access templates from nested dicts.
                                      Can be used to load templates defined with markup like TOML.
                                  
                                      Examples:
                                          ``` toml
                                          [example]
                                          template = "{{ something }}"
                                          ```
                                          ``` py
                                          content = tomllib.load(toml_file)
                                          loader = NestedDictLoader(content)
                                          env = Environment(loader=loader)
                                          env.get_template("example/template")
                                          ```
                                      """
                                  
                                      ID = "nested_dict"
                                  
                                      def __init__(self, mapping: NestedMapping):
                                          """Constructor.
                                  
                                          Args:
                                              mapping: A nested dict containing templates
                                          """
                                          super().__init__()
                                          self._data = mapping
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, mapping=self._data)
                                  
                                      def list_templates(self) -> list[str]:
                                          return list(iterfilters.flatten_dict(self._data).keys())
                                  
                                      def get_source(
                                          self,
                                          environment: jinja2.Environment,
                                          template: str,
                                      ) -> tuple[str, str | None, Callable[[], bool] | None]:
                                          data: Any = self._data
                                          try:
                                              for part in template.split("/"):
                                                  data = data[part]
                                              assert isinstance(data, str)
                                          except (AssertionError, KeyError) as e:
                                              raise jinja2.TemplateNotFound(template) from e
                                          return data, None, lambda: True  # type: ignore[return-value]
                                  

                                  __init__

                                  __init__(mapping: NestedMapping)
                                  

                                  Constructor.

                                  Parameters:

                                  Name Type Description Default
                                  mapping NestedMapping

                                  A nested dict containing templates

                                  required
                                  Source code in src/jinjarope/configloaders.py
                                  39
                                  40
                                  41
                                  42
                                  43
                                  44
                                  45
                                  46
                                  def __init__(self, mapping: NestedMapping):
                                      """Constructor.
                                  
                                      Args:
                                          mapping: A nested dict containing templates
                                      """
                                      super().__init__()
                                      self._data = mapping
                                  

                                  PackageLoader

                                  Bases: LoaderMixin, PackageLoader

                                  A loader for loading templates from a package.

                                  Source code in src/jinjarope/loaders.py
                                  117
                                  118
                                  119
                                  120
                                  121
                                  122
                                  123
                                  124
                                  125
                                  126
                                  127
                                  128
                                  129
                                  130
                                  131
                                  132
                                  133
                                  134
                                  135
                                  136
                                  137
                                  138
                                  139
                                  140
                                  141
                                  142
                                  143
                                  144
                                  145
                                  146
                                  147
                                  148
                                  149
                                  150
                                  151
                                  152
                                  153
                                  154
                                  155
                                  156
                                  157
                                  158
                                  159
                                  160
                                  161
                                  class PackageLoader(LoaderMixin, jinja2.PackageLoader):
                                      """A loader for loading templates from a package."""
                                  
                                      ID = "package"
                                  
                                      def __init__(
                                          self,
                                          package: str | types.ModuleType,
                                          package_path: str | None = None,
                                          encoding: str = "utf-8",
                                      ) -> None:
                                          """Instanciate a PackageLoader.
                                  
                                          Compared to the jinja2 equivalent, this loader also supports
                                          `ModuleType`s and dotted module paths for the `package` argument.
                                  
                                          Args:
                                              package: The python package to create a loader for
                                              package_path: If given, use the given path as the root.
                                              encoding: The encoding to use for loading templates
                                          """
                                          if isinstance(package, types.ModuleType):
                                              package = package.__name__
                                          parts = package.split(".")
                                          path = "/".join(parts[1:])
                                          if package_path:
                                              path = (pathlib.Path(path) / package_path).as_posix()
                                          super().__init__(parts[0], path, encoding)
                                  
                                      def __repr__(self):
                                          return utils.get_repr(
                                              self,
                                              package_name=self.package_name,
                                              package_path=self.package_path,
                                          )
                                  
                                      def __eq__(self, other):
                                          return (
                                              type(self) is type(other)
                                              and self.package_name == other.package_name
                                              and self.package_path == other.package_path
                                          )
                                  
                                      def __hash__(self):
                                          return hash(self.package_name) + hash(self.package_path)
                                  

                                  __init__

                                  __init__(
                                      package: str | ModuleType, package_path: str | None = None, encoding: str = "utf-8"
                                  ) -> None
                                  

                                  Instanciate a PackageLoader.

                                  Compared to the jinja2 equivalent, this loader also supports ModuleTypes and dotted module paths for the package argument.

                                  Parameters:

                                  Name Type Description Default
                                  package str | ModuleType

                                  The python package to create a loader for

                                  required
                                  package_path str | None

                                  If given, use the given path as the root.

                                  None
                                  encoding str

                                  The encoding to use for loading templates

                                  'utf-8'
                                  Source code in src/jinjarope/loaders.py
                                  122
                                  123
                                  124
                                  125
                                  126
                                  127
                                  128
                                  129
                                  130
                                  131
                                  132
                                  133
                                  134
                                  135
                                  136
                                  137
                                  138
                                  139
                                  140
                                  141
                                  142
                                  143
                                  144
                                  def __init__(
                                      self,
                                      package: str | types.ModuleType,
                                      package_path: str | None = None,
                                      encoding: str = "utf-8",
                                  ) -> None:
                                      """Instanciate a PackageLoader.
                                  
                                      Compared to the jinja2 equivalent, this loader also supports
                                      `ModuleType`s and dotted module paths for the `package` argument.
                                  
                                      Args:
                                          package: The python package to create a loader for
                                          package_path: If given, use the given path as the root.
                                          encoding: The encoding to use for loading templates
                                      """
                                      if isinstance(package, types.ModuleType):
                                          package = package.__name__
                                      parts = package.split(".")
                                      path = "/".join(parts[1:])
                                      if package_path:
                                          path = (pathlib.Path(path) / package_path).as_posix()
                                      super().__init__(parts[0], path, encoding)
                                  

                                  PrefixLoader

                                  Bases: LoaderMixin, PrefixLoader

                                  A loader for prefixing other loaders.

                                  Source code in src/jinjarope/loaders.py
                                  55
                                  56
                                  57
                                  58
                                  59
                                  60
                                  61
                                  62
                                  63
                                  64
                                  65
                                  66
                                  67
                                  68
                                  69
                                  70
                                  71
                                  72
                                  73
                                  class PrefixLoader(LoaderMixin, jinja2.PrefixLoader):
                                      """A loader for prefixing other loaders."""
                                  
                                      ID = "prefix"
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, self.mapping)
                                  
                                      def __eq__(self, other):
                                          return type(self) is type(other) and self.mapping == other.mapping
                                  
                                      def __hash__(self):
                                          return hash(tuple(sorted(self.mapping.items())))
                                  
                                      def __bool__(self):
                                          return bool(self.mapping)
                                  
                                      def __iter__(self):
                                          return iter(self.mapping)
                                  

                                  RewriteLoader

                                  Bases: LoaderMixin, BaseLoader

                                  A loader which modifies templates based on a callable.

                                  Can get chained like a PrefixLoader. The path passed to the callable can be used to check whether given template should be modified.

                                  Source code in src/jinjarope/rewriteloader.py
                                  15
                                  16
                                  17
                                  18
                                  19
                                  20
                                  21
                                  22
                                  23
                                  24
                                  25
                                  26
                                  27
                                  28
                                  29
                                  30
                                  31
                                  32
                                  33
                                  34
                                  35
                                  36
                                  37
                                  38
                                  39
                                  40
                                  41
                                  42
                                  43
                                  44
                                  45
                                  46
                                  47
                                  48
                                  49
                                  50
                                  51
                                  52
                                  53
                                  54
                                  55
                                  56
                                  57
                                  58
                                  59
                                  60
                                  61
                                  class RewriteLoader(loaders_.LoaderMixin, jinja2.BaseLoader):
                                      """A loader which modifies templates based on a callable.
                                  
                                      Can get chained like a PrefixLoader.
                                      The path passed to the callable can be used to check whether given template
                                      should be modified.
                                      """
                                  
                                      ID = "rewrite"
                                  
                                      def __init__(self, loader: jinja2.BaseLoader, rewrite_fn: Callable[[str, str], str]):
                                          """Instanciate the RewriteLoader.
                                  
                                          Args:
                                              loader: The loader to rewrite / modify the templates from
                                              rewrite_fn: Callable to modify templates.
                                                          It gets called with two arguments (path and template text)
                                                          and should return a (possibly modified) template text
                                          """
                                          self.loader = loader
                                          self.rewrite_fn = rewrite_fn
                                  
                                      def __repr__(self):
                                          return utils.get_repr(self, self.loader, self.rewrite_fn)
                                  
                                      def __eq__(self, other):
                                          return (
                                              type(self) is type(other)
                                              and self.loader == other.loader
                                              and self.rewrite_fn == other.rewrite_fn
                                          )
                                  
                                      def __hash__(self):
                                          return hash(self.loader) + hash(self.rewrite_fn)
                                  
                                      def get_source(
                                          self,
                                          environment: jinja2.Environment,
                                          template: str,
                                      ) -> tuple[str, str, Callable[[], bool] | None]:
                                          src: str | None
                                          src, filename, uptodate = self.loader.get_source(environment, template)
                                          old_src = src
                                          assert filename is not None
                                          path = pathlib.Path(filename).as_posix()
                                          src = self.rewrite_fn(path, src)
                                          return src or old_src, filename, uptodate
                                  

                                  __init__

                                  __init__(loader: BaseLoader, rewrite_fn: Callable[[str, str], str])
                                  

                                  Instanciate the RewriteLoader.

                                  Parameters:

                                  Name Type Description Default
                                  loader BaseLoader

                                  The loader to rewrite / modify the templates from

                                  required
                                  rewrite_fn Callable[[str, str], str]

                                  Callable to modify templates. It gets called with two arguments (path and template text) and should return a (possibly modified) template text

                                  required
                                  Source code in src/jinjarope/rewriteloader.py
                                  25
                                  26
                                  27
                                  28
                                  29
                                  30
                                  31
                                  32
                                  33
                                  34
                                  35
                                  def __init__(self, loader: jinja2.BaseLoader, rewrite_fn: Callable[[str, str], str]):
                                      """Instanciate the RewriteLoader.
                                  
                                      Args:
                                          loader: The loader to rewrite / modify the templates from
                                          rewrite_fn: Callable to modify templates.
                                                      It gets called with two arguments (path and template text)
                                                      and should return a (possibly modified) template text
                                      """
                                      self.loader = loader
                                      self.rewrite_fn = rewrite_fn
                                  

                                  TemplateFileLoader

                                  Bases: NestedDictLoader

                                  A jinja loader for loading templates from config files.

                                  This loader allows to access templates from config files. Config files often often resemble nested dicts when getting loaded / deserialized.

                                  The loader will load config file from given path and will make it accessible in the same way as the NestedDictLoader. (esp. TOML is well-suited for this)

                                  Config files can be loaded from any fsspec protocol URL.

                                  Examples:

                                  loader = TemplateFileLoader("http://path_to_toml_file.toml")
                                  env = Environment(loader=loader)
                                  env.get_template("example/template")
                                  
                                  loader = TemplateFileLoader("path/to/file.json")
                                  env = Environment(loader=loader)
                                  env.get_template("example/template")
                                  

                                  Source code in src/jinjarope/configloaders.py
                                   69
                                   70
                                   71
                                   72
                                   73
                                   74
                                   75
                                   76
                                   77
                                   78
                                   79
                                   80
                                   81
                                   82
                                   83
                                   84
                                   85
                                   86
                                   87
                                   88
                                   89
                                   90
                                   91
                                   92
                                   93
                                   94
                                   95
                                   96
                                   97
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  114
                                  115
                                  116
                                  117
                                  118
                                  119
                                  120
                                  121
                                  class TemplateFileLoader(NestedDictLoader):
                                      """A jinja loader for loading templates from config files.
                                  
                                      This loader allows to access templates from config files.
                                      Config files often often resemble nested dicts when getting loaded / deserialized.
                                  
                                      The loader will load config file from given path and will make it accessible in the
                                      same way as the `NestedDictLoader`. (esp. TOML is well-suited for this)
                                  
                                      Config files can be loaded from any fsspec protocol URL.
                                  
                                      Examples:
                                          ``` py
                                          loader = TemplateFileLoader("http://path_to_toml_file.toml")
                                          env = Environment(loader=loader)
                                          env.get_template("example/template")
                                          ```
                                          ``` py
                                          loader = TemplateFileLoader("path/to/file.json")
                                          env = Environment(loader=loader)
                                          env.get_template("example/template")
                                          ```
                                      """
                                  
                                      ID = "template_file"
                                  
                                      def __init__(
                                          self,
                                          path: str | os.PathLike[str],
                                          fmt: Literal["toml", "json", "ini", "yaml"] | None = None,
                                          sub_path: tuple[str, ...] | None = None,
                                      ):
                                          """Constructor.
                                  
                                          Args:
                                              path: Path / fsspec protocol URL to the file
                                              fmt: Config file format. If None, try to auto-infer from file extension
                                              sub_path: An optional tuple of keys describing the "dictionary path" inside
                                                        the file
                                          """
                                          self.path = upath.UPath(path)
                                          text = envglobals.load_file_cached(self.path)
                                          file_fmt = fmt if fmt else self.path.suffix.lstrip(".")
                                          assert file_fmt in ["json", "toml", "yaml", "ini"]
                                          mapping = serializefilters.deserialize(text, fmt=file_fmt)  # type: ignore[arg-type]
                                          for part in sub_path or []:
                                              mapping = mapping[part]
                                          super().__init__(mapping=mapping)
                                          self._data = mapping
                                  
                                      def __repr__(self):
                                          path = self.path.as_posix()
                                          return utils.get_repr(self, path=path)
                                  

                                  __init__

                                  __init__(
                                      path: str | PathLike[str],
                                      fmt: Literal["toml", "json", "ini", "yaml"] | None = None,
                                      sub_path: tuple[str, ...] | None = None,
                                  )
                                  

                                  Constructor.

                                  Parameters:

                                  Name Type Description Default
                                  path str | PathLike[str]

                                  Path / fsspec protocol URL to the file

                                  required
                                  fmt Literal['toml', 'json', 'ini', 'yaml'] | None

                                  Config file format. If None, try to auto-infer from file extension

                                  None
                                  sub_path tuple[str, ...] | None

                                  An optional tuple of keys describing the "dictionary path" inside the file

                                  None
                                  Source code in src/jinjarope/configloaders.py
                                   95
                                   96
                                   97
                                   98
                                   99
                                  100
                                  101
                                  102
                                  103
                                  104
                                  105
                                  106
                                  107
                                  108
                                  109
                                  110
                                  111
                                  112
                                  113
                                  114
                                  115
                                  116
                                  117
                                  def __init__(
                                      self,
                                      path: str | os.PathLike[str],
                                      fmt: Literal["toml", "json", "ini", "yaml"] | None = None,
                                      sub_path: tuple[str, ...] | None = None,
                                  ):
                                      """Constructor.
                                  
                                      Args:
                                          path: Path / fsspec protocol URL to the file
                                          fmt: Config file format. If None, try to auto-infer from file extension
                                          sub_path: An optional tuple of keys describing the "dictionary path" inside
                                                    the file
                                      """
                                      self.path = upath.UPath(path)
                                      text = envglobals.load_file_cached(self.path)
                                      file_fmt = fmt if fmt else self.path.suffix.lstrip(".")
                                      assert file_fmt in ["json", "toml", "yaml", "ini"]
                                      mapping = serializefilters.deserialize(text, fmt=file_fmt)  # type: ignore[arg-type]
                                      for part in sub_path or []:
                                          mapping = mapping[part]
                                      super().__init__(mapping=mapping)
                                      self._data = mapping
                                  

                                  get_loader_from_json

                                  get_loader_from_json(dct_or_list: dict | list | None | BaseLoader) -> BaseLoader | None
                                  

                                  Create a loader based on a json representation.

                                  Parameters:

                                  Name Type Description Default
                                  dct_or_list dict | list | None | BaseLoader

                                  A dictionary or list describing loaders.

                                  required
                                  Source code in src/jinjarope/loaders.py
                                  229
                                  230
                                  231
                                  232
                                  233
                                  234
                                  235
                                  236
                                  237
                                  238
                                  239
                                  240
                                  241
                                  242
                                  243
                                  244
                                  245
                                  246
                                  247
                                  248
                                  249
                                  250
                                  251
                                  252
                                  253
                                  254
                                  255
                                  256
                                  257
                                  258
                                  259
                                  260
                                  261
                                  262
                                  263
                                  264
                                  265
                                  266
                                  267
                                  268
                                  269
                                  270
                                  271
                                  272
                                  273
                                  274
                                  275
                                  276
                                  277
                                  278
                                  279
                                  def from_json(
                                      dct_or_list: dict | list | None | jinja2.BaseLoader,
                                  ) -> jinja2.BaseLoader | None:
                                      """Create a loader based on a json representation.
                                  
                                      Args:
                                          dct_or_list: A dictionary or list describing loaders.
                                      """
                                      from jinjarope import fsspecloaders
                                  
                                      if not dct_or_list:
                                          return None
                                      loaders = []
                                      ls = dct_or_list if isinstance(dct_or_list, list) else [dct_or_list]
                                      for item in ls:
                                          match item:
                                              case jinja2.BaseLoader():
                                                  loader = item
                                              case str() if "://" in item:
                                                  loader = fsspecloaders.FsSpecFileSystemLoader(item)
                                              case str():
                                                  loader = FileSystemLoader(item)
                                              case types.ModuleType():
                                                  loader = PackageLoader(item)
                                              case dict():
                                                  dct_copy = item.copy()
                                                  typ = dct_copy.pop("type")
                                                  mapping = dct_copy.pop("mapping", None)
                                                  prefix = dct_copy.pop("prefix", None)
                                                  kls = next(
                                                      kls
                                                      for kls in inspectfilters.list_subclasses(jinja2.BaseLoader)
                                                      if getattr(kls, "ID", None) == typ
                                                  )
                                                  if kls.ID == "prefix":  # type: ignore[attr-defined]
                                                      mapping = {k: from_json(v) for k, v in mapping.items()}
                                                      loader = kls(mapping)  # type: ignore[call-arg]
                                                  elif prefix:
                                                      loader = prefix / kls(**dct_copy)
                                                  else:
                                                      loader = kls(**dct_copy)
                                              case _:
                                                  raise TypeError(item)
                                          loaders.append(loader)
                                      match len(loaders):
                                          case 1:
                                              return loaders[0]
                                          case 0:
                                              return None
                                          case _:
                                              return ChoiceLoader(loaders)