Repository: malthe/chameleon

Issue:
PageTemplateLoader constructor no longer accepts default_extension as a positional argument in v4.5.0
As in the title, it looks like adding type annotations messed it up. In version 4.2.0, it worked fine. Providing it as a keyword silences an exception, but I'm not sure if it works as intended then as my code currently uses full file names (so I'm dropping this argument from my invocations anyway).

Hints from issue comments:
@malthe: See https://github.com/malthe/chameleon/releases/tag/4.5.1.

Solution patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index d5ce22f..fc53d86 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -3,7 +3,9 @@ Changes
 
 In next release ...
 
--
+- Fix a regression where `default_extension` was no longer permitted
+  as a positional argument to `PageTemplateLoader`.
+  (`#411 <https://github.com/malthe/chameleon/issues/411>`_)
 
 4.5.0 (2024-01-18)
 ------------------
diff --git a/src/chameleon/zpt/loader.py b/src/chameleon/zpt/loader.py
index a07e4ea..0182535 100644
--- a/src/chameleon/zpt/loader.py
+++ b/src/chameleon/zpt/loader.py
@@ -28,6 +28,7 @@ class TemplateLoader(BaseLoader):
     def __init__(
         self,
         search_path: Sequence[str] | str | None = None,
+        default_extension: str | None = None,
         *,
         formats: _FormatsMapping | None = None,
         **kwargs: Any
@@ -36,7 +37,7 @@ class TemplateLoader(BaseLoader):
         if formats is not None:
             self.formats = formats
 
-        super().__init__(search_path, **kwargs)
+        super().__init__(search_path, default_extension, **kwargs)
 
     @overload  # type: ignore[override]
     def load(


Test patch:
diff --git a/src/chameleon/tests/test_loader.py b/src/chameleon/tests/test_loader.py
index 8a23fc0..a3bfa4f 100644
--- a/src/chameleon/tests/test_loader.py
+++ b/src/chameleon/tests/test_loader.py
@@ -7,9 +7,9 @@ from pathlib import Path
 
 
 class LoadTests:
-    def _makeOne(self, search_path=None, **kwargs):
+    def _makeOne(self, *args, **kwargs):
         klass = self._getTargetClass()
-        return klass(search_path, **kwargs)
+        return klass(*args, **kwargs)
 
     def _getTargetClass(self):
         from chameleon.loader import TemplateLoader
@@ -24,6 +24,15 @@ class LoadTests:
             result.filename,
             os.path.join(here, 'hello_world.pt'))
 
+    def test_load_relative_default_extension(self):
+        import os
+        here = os.path.join(os.path.dirname(__file__), "inputs")
+        loader = self._makeOne([here], ".pt")
+        result = self._load(loader, 'hello_world')
+        self.assertEqual(
+            result.filename,
+            os.path.join(here, 'hello_world.pt'))
+
     def test_consecutive_loads(self):
         import os
         here = os.path.join(os.path.dirname(__file__), "inputs")
@@ -140,6 +149,15 @@ class LoadPageTests(unittest.TestCase, LoadTests):
         return loader.load(spec, template.PageTemplateFile)
 
 
+class ZPTLoadPageTests(unittest.TestCase, LoadTests):
+    def _getTargetClass(self):
+        from chameleon.zpt.loader import TemplateLoader
+        return TemplateLoader
+
+    def _load(self, loader, spec):
+        return loader.load(spec)
+
+
 class ModuleLoadTests(unittest.TestCase):
     def _makeOne(self, *args, **kwargs):
         from chameleon.loader import ModuleLoader