Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-Chameleon for
openSUSE:Factory checked in at 2024-04-21 20:27:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Chameleon (Old)
and /work/SRC/openSUSE:Factory/.python-Chameleon.new.26366 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Chameleon"
Sun Apr 21 20:27:04 2024 rev:19 rq:1169357 version:4.5.4
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Chameleon/python-Chameleon.changes
2024-03-18 16:46:17.214783135 +0100
+++
/work/SRC/openSUSE:Factory/.python-Chameleon.new.26366/python-Chameleon.changes
2024-04-21 20:28:38.368912058 +0200
@@ -1,0 +2,12 @@
+Sat Apr 20 13:30:44 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 4.5.4:
+ * Fix an issue where $-sign interpolation escaping would not
+ work correctly when more than two such symbols appeared next
+ to each other.
+ * Minor optimization when rendering translations with a static
+ message id (don't need to test if it's non-empty).
+ * Fix a bug where a macro could not be used correctly to render
+ a translation name.
+
+-------------------------------------------------------------------
Old:
----
Chameleon-4.5.2.tar.gz
New:
----
Chameleon-4.5.4.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-Chameleon.spec ++++++
--- /var/tmp/diff_new_pack.dNvNn5/_old 2024-04-21 20:28:39.012935700 +0200
+++ /var/tmp/diff_new_pack.dNvNn5/_new 2024-04-21 20:28:39.016935847 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-Chameleon
-Version: 4.5.2
+Version: 4.5.4
Release: 0
Summary: Fast HTML/XML Template Compiler
License: BSD-3-Clause AND BSD-4-Clause AND Python-2.0 AND ZPL-2.1
++++++ Chameleon-4.5.2.tar.gz -> Chameleon-4.5.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/.github/workflows/main.yml
new/chameleon-4.5.4/.github/workflows/main.yml
--- old/chameleon-4.5.2/.github/workflows/main.yml 2024-01-29
21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/.github/workflows/main.yml 2024-04-08
09:10:10.000000000 +0200
@@ -41,8 +41,9 @@
- ["pypy-3.9", "pypy3"]
- ["3.9", "docs"]
- ["3.9", "coverage"]
- - ["3.12", "mypy"]
-
+ - ["3.12", "mypy"]
+ - ["3.11", "z3c.macro"]
+ - ["3.11", "z3c.pt"]
runs-on: ${{ matrix.os[1] }}
if: github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name !=
github.event.pull_request.base.repo.full_name
name: ${{ matrix.config[1] }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/CHANGES.rst
new/chameleon-4.5.4/CHANGES.rst
--- old/chameleon-4.5.2/CHANGES.rst 2024-01-29 21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/CHANGES.rst 2024-04-08 09:10:10.000000000 +0200
@@ -1,6 +1,24 @@
Changes
=======
+4.5.4 (2024-04-08)
+------------------
+
+- Fix an issue where $-sign interpolation escaping would not work
+ correctly when more than two such symbols appeared next to each
+ other.
+ (`#422 <https://github.com/malthe/chameleon/issues/422>`_)
+
+4.5.3 (2024-04-05)
+------------------
+
+- Minor optimization when rendering translations with a static
+ message id (don't need to test if it's non-empty).
+
+- Fix a bug where a macro could not be used correctly to render a
+ translation name.
+ (`#419 <https://github.com/malthe/chameleon/issues/419>`_)
+
4.5.2 (2024-01-29)
------------------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/README.rst
new/chameleon-4.5.4/README.rst
--- old/chameleon-4.5.2/README.rst 2024-01-29 21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/README.rst 2024-04-08 09:10:10.000000000 +0200
@@ -1,5 +1,10 @@
-Overview
-========
+Chameleon
+=========
+
+.. image:: https://img.shields.io/pypi/pyversions/Chameleon
+ :alt: PyPI - Python Version
+.. image::
https://img.shields.io/github/actions/workflow/status/malthe/chameleon/main.yml
+ :alt: GitHub Actions Workflow Status
Chameleon is an HTML/XML template engine for `Python
<http://www.python.org>`_. It uses the *page templates* language.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/pyproject.toml
new/chameleon-4.5.4/pyproject.toml
--- old/chameleon-4.5.2/pyproject.toml 2024-01-29 21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/pyproject.toml 2024-04-08 09:10:10.000000000 +0200
@@ -7,6 +7,10 @@
# we may want to include tests eventually
exclude = "/tests/"
follow_imports = "silent"
+warn_redundant_casts = true
+warn_unused_configs = true
+warn_unused_ignores = true
+warn_return_any = true
[[tool.mypy.overrides]]
# strict config for fully typed modules and public API
@@ -23,7 +27,9 @@
disallow_untyped_defs = true
disallow_incomplete_defs = true
disallow_untyped_decorators = true
-warn_unused_ignores = true
+no_implicit_reexport = true
+strict_equality = true
+extra_checks = true
[[tool.mypy.overrides]]
module = ["zope.*"]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/setup.cfg
new/chameleon-4.5.4/setup.cfg
--- old/chameleon-4.5.2/setup.cfg 2024-01-29 21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/setup.cfg 2024-04-08 09:10:10.000000000 +0200
@@ -6,9 +6,6 @@
[flake8]
doctests = 1
extend-select = TC1
-# F401 imported but unused
-per-file-ignores =
- src/chameleon/__init__.py: F401
[check-manifest]
ignore =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/setup.py new/chameleon-4.5.4/setup.py
--- old/chameleon-4.5.2/setup.py 2024-01-29 21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/setup.py 2024-04-08 09:10:10.000000000 +0200
@@ -1,4 +1,4 @@
-__version__ = '4.5.2'
+__version__ = '4.5.4'
import os
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/__init__.py
new/chameleon-4.5.4/src/chameleon/__init__.py
--- old/chameleon-4.5.2/src/chameleon/__init__.py 2024-01-29
21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/__init__.py 2024-04-08
09:10:10.000000000 +0200
@@ -4,3 +4,13 @@
from chameleon.zpt.template import PageTemplateFile
from chameleon.zpt.template import PageTextTemplate
from chameleon.zpt.template import PageTextTemplateFile
+
+
+__all__ = (
+ 'TemplateError',
+ 'PageTemplateLoader',
+ 'PageTemplate',
+ 'PageTemplateFile',
+ 'PageTextTemplate',
+ 'PageTextTemplateFile',
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/astutil.py
new/chameleon-4.5.4/src/chameleon/astutil.py
--- old/chameleon-4.5.2/src/chameleon/astutil.py 2024-01-29
21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/astutil.py 2024-04-08
09:10:10.000000000 +0200
@@ -5,35 +5,44 @@
import ast
from copy import deepcopy
from typing import TYPE_CHECKING
+from typing import Any
from typing import ClassVar
if TYPE_CHECKING:
from collections.abc import Callable
- from typing import Union
- _NodeTransform = Callable[[ast.AST], Union[ast.AST, None]]
+ from collections.abc import Hashable
+ from typing import Optional
+
+ from chameleon.tokenize import Token
+
+ _NodeTransform = Callable[[ast.AST], Optional[ast.AST]]
__docformat__ = 'restructuredtext en'
-def parse(source, mode='eval'):
+def parse(source, mode: str = 'eval') -> ast.AST:
return compile(source, '', mode, ast.PyCF_ONLY_AST)
-def load(name):
+def load(name: str) -> ast.Name:
return ast.Name(id=name, ctx=ast.Load())
-def store(name):
+def store(name: str) -> ast.Name:
return ast.Name(id=name, ctx=ast.Store())
-def param(name):
+def param(name: str) -> ast.Name:
return ast.Name(id=name, ctx=ast.Param())
-def subscript(name, value, ctx):
+def subscript(
+ name: str,
+ value: ast.expr,
+ ctx: ast.expr_context
+) -> ast.Subscript:
return ast.Subscript(
value=value,
slice=ast.Index(value=ast.Str(s=name)),
@@ -47,7 +56,7 @@
_fields: ClassVar[tuple[str, ...]] = ()
- def __init__(self, *args, **kwargs) -> None:
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
assert isinstance(self._fields, tuple)
self.__dict__.update(kwargs)
for name, value in zip(self._fields, args):
@@ -77,6 +86,7 @@
_fields = "id", "ctx"
+ id: str
ctx = ast.Load()
@@ -85,24 +95,32 @@
_fields = "value",
+ # Apart from a few builtins this should be type[Any]
+ value: type[Any] | Hashable
+
class Static(Node):
"""Represents a static value."""
_fields = "value", "name"
- name = None
+ value: ast.expr
+ name: str | None = None
class Comment(Node):
_fields = "text",
+ text: str
+
class TokenRef(Node):
"""Represents a source-code token reference."""
_fields = "token",
+ token: Token
+
class NodeTransformerBase(ast.NodeTransformer):
def __init__(self, transform: _NodeTransform):
@@ -120,34 +138,34 @@
self.scopes: list[set[str]] = [set()]
super().__init__(transform)
- def __call__(self, node) -> ast.AST:
+ def __call__(self, node: ast.AST) -> ast.AST:
clone = deepcopy(node)
- return self.visit(clone)
+ return self.visit(clone) # type: ignore[no-any-return]
- def visit_arg(self, node) -> ast.AST:
+ def visit_arg(self, node: ast.arg) -> ast.AST:
scope = self.scopes[-1]
scope.add(node.arg)
return node
- def visit_Name(self, node) -> ast.AST:
+ def visit_Name(self, node: ast.Name) -> ast.AST:
scope = self.scopes[-1]
if isinstance(node.ctx, ast.Param):
scope.add(node.id)
return node
if node.id not in scope:
- node = self.apply_transform(node)
+ return self.apply_transform(node)
return node
- def visit_FunctionDef(self, node) -> ast.AST:
+ def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.AST:
self.scopes[-1].add(node.name)
return super().generic_visit(node)
- def visit_alias(self, node) -> ast.AST:
+ def visit_alias(self, node: ast.alias) -> ast.AST:
name = node.asname if node.asname is not None else node.name
self.scopes[-1].add(name)
return super().generic_visit(node)
- def visit_Lambda(self, node) -> ast.AST:
+ def visit_Lambda(self, node: ast.Lambda) -> ast.AST:
self.scopes.append(set())
try:
return super().generic_visit(node)
@@ -156,6 +174,6 @@
class ItemLookupOnAttributeErrorVisitor(NodeTransformerBase):
- def visit_Attribute(self, node) -> ast.AST:
- node = self.apply_transform(node)
- return self.generic_visit(node)
+ def visit_Attribute(self, node: ast.Attribute) -> ast.AST:
+ transformed = self.apply_transform(node)
+ return self.generic_visit(transformed)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/codegen.py
new/chameleon-4.5.4/src/chameleon/codegen.py
--- old/chameleon-4.5.2/src/chameleon/codegen.py 2024-01-29
21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/codegen.py 2024-04-08
09:10:10.000000000 +0200
@@ -15,6 +15,8 @@
from ast import NodeTransformer
from ast import alias
from ast import unparse
+from typing import TYPE_CHECKING
+from typing import Any
from chameleon.astutil import Builtin
from chameleon.astutil import Symbol
@@ -24,7 +26,15 @@
from chameleon.exc import CompilationError
-reverse_builtin_map = {}
+if TYPE_CHECKING:
+ import ast
+ from collections.abc import Hashable
+
+ from chameleon.astutil import Comment
+ from chameleon.astutil import Static
+
+
+reverse_builtin_map: dict[type[Any] | Hashable, str] = {}
for name, value in builtins.__dict__.items():
try:
hash(value)
@@ -60,7 +70,7 @@
lineno=None,
)
- def visit_Name(self, node) -> AST:
+ def visit_Name(self, node: ast.Name) -> AST:
value = symbols.get(node.id, self)
if value is self:
if node.id == 'None' or \
@@ -77,7 +87,7 @@
if isinstance(value, str):
value = load(value)
- return value
+ return value # type: ignore[no-any-return]
expr = parse(textwrap.dedent(source), mode=mode)
@@ -103,6 +113,8 @@
names = ()
+ imports: dict[type[Any] | Hashable, ast.Name]
+
def __init__(self, tree):
self.comments = []
self.defines = {}
@@ -142,7 +154,7 @@
return load(name)
- def require(self, value):
+ def require(self, value: type[Any] | Hashable) -> ast.Name:
node = self.imports.get(value)
if node is None:
# we come up with a unique symbol based on the class name
@@ -155,9 +167,9 @@
return node
- def visit_Module(self, module) -> AST:
+ def visit_Module(self, module: Module) -> AST:
assert isinstance(module, Module)
- module = super().generic_visit(module)
+ module = super().generic_visit(module) # type: ignore[assignment]
preamble: list[AST] = []
for name, node in self.defines.items():
@@ -188,21 +200,21 @@
return Module(imports + preamble + module.body, ())
- def visit_Comment(self, node) -> AST:
+ def visit_Comment(self, node: Comment) -> AST:
self.comments.append(node.text)
return Expr(Constant(...))
- def visit_Builtin(self, node) -> AST:
+ def visit_Builtin(self, node: Builtin) -> AST:
name = load(node.id)
- return self.visit(name)
+ return self.visit(name) # type: ignore[no-any-return]
- def visit_Symbol(self, node) -> AST:
+ def visit_Symbol(self, node: Symbol) -> AST:
return self.require(node.value)
- def visit_Static(self, node) -> AST:
+ def visit_Static(self, node: Static) -> AST:
if node.name is None:
name = "_static_%s" % str(id(node.value)).replace('-', '_')
else:
name = node.name
node = self.define(name, node.value)
- return self.visit(node)
+ return self.visit(node) # type: ignore[no-any-return]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/compiler.py
new/chameleon-4.5.4/src/chameleon/compiler.py
--- old/chameleon-4.5.2/src/chameleon/compiler.py 2024-01-29
21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/compiler.py 2024-04-08
09:10:10.000000000 +0200
@@ -62,11 +62,11 @@
RE_NAME = re.compile('^%s$' % NAME)
-def identifier(prefix, suffix=None) -> str:
+def identifier(prefix: str, suffix: str | None = None) -> str:
return "__{}_{}".format(prefix, mangle(suffix or id(prefix)))
-def mangle(string):
+def mangle(string: int | str) -> str:
return RE_MANGLE.sub('_', str(string)).replace('\n', '').replace('-', '_')
@@ -74,12 +74,12 @@
return template("getname(KEY)", KEY=ast.Str(s=name), mode="eval")
-def store_econtext(name):
+def store_econtext(name: object) -> ast.Subscript:
name = str(name)
return subscript(name, load("econtext"), ast.Store())
-def store_rcontext(name):
+def store_rcontext(name: object) -> ast.Subscript:
name = str(name)
return subscript(name, load("rcontext"), ast.Store())
@@ -101,7 +101,7 @@
)
-def indent(s):
+def indent(s: str | None) -> str:
return textwrap.indent(s, " ") if s else ""
@@ -277,11 +277,11 @@
class Interpolator:
braces_required_regex = re.compile(
- r'(\$)?\$({(?P<expression>.*)})', re.DOTALL
+ r'\$({(?P<expression>.*)})', re.DOTALL
)
braces_optional_regex = re.compile(
- r'(\$)?\$({(?P<expression>.*)}|(?P<variable>[A-Za-z][A-Za-z0-9_]*))',
+ r'\$({(?P<expression>.*)}|(?P<variable>[A-Za-z][A-Za-z0-9_]*))',
re.DOTALL,
)
@@ -335,6 +335,7 @@
while text:
matched = text
+
m = self.regex.search(matched)
if m is None:
text = text.replace('$$', '$')
@@ -344,18 +345,18 @@
part = text[:m.start()]
text = text[m.start():]
- skip = text.startswith('$$')
- if skip:
- part = part + '$'
-
if part:
+ i = 0
+ length = len(part)
+ while i < length and part[-i - 1] == '$':
+ i += 1
+ skip = i & 1
part = part.replace('$$', '$')
node = ast.Str(s=part)
nodes.append(node)
-
- if skip:
- text = text[2:]
- continue
+ if skip:
+ text = text[1:]
+ continue
if not body:
target = name
@@ -1024,16 +1025,16 @@
def visit_EmitText(self, node) -> ast.AST:
append = load(self.scopes[-1].append or "__append")
- node = ast.Expr(ast.Call(
+ expr = ast.Expr(ast.Call(
func=append,
args=[ast.Str(s=node.s)],
keywords=[],
starargs=None,
kwargs=None
))
- return self.visit(node)
+ return self.visit(expr) # type: ignore[no-any-return]
- def visit_Name(self, node) -> ast.AST:
+ def visit_Name(self, node: ast.Name) -> ast.AST:
if isinstance(node.ctx, ast.Load):
scope = self.scopes[-1]
for name in ("append", "stream"):
@@ -1049,7 +1050,7 @@
self.scopes.pop()
return stmts
- def visit_TokenRef(self, node) -> ast.AST:
+ def visit_TokenRef(self, node: TokenRef) -> ast.AST:
self.tokens.append((node.token.pos, len(node.token)))
return ast.Assign(
[store("__token")],
@@ -1492,13 +1493,20 @@
msgid = ast.Str(s=node.msgid)
# emit the translation expression
- body += template(
- "if msgid: __append(translate("
+ translation = template(
+ "__append(translate("
"msgid, mapping=mapping, default=default, domain=__i18n_domain,
context=__i18n_context, target_language=target_language))", # noqa: E501 line
too long
msgid=msgid,
default=default,
mapping=mapping)
+ if not node.msgid:
+ translation = [ast.If(
+ test=load(msgid), body=translation, orelse=[]
+ )]
+
+ body += translation
+
# pop away translation block reference
self._translations.pop()
@@ -1703,7 +1711,7 @@
# generate code
code = self.visit(node.node)
- body.append(TranslationContext(code, append))
+ body.append(TranslationContext(code, append, stream))
# output msgid
text = Text('${%s}' % node.name)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/i18n.py
new/chameleon-4.5.4/src/chameleon/i18n.py
--- old/chameleon-4.5.2/src/chameleon/i18n.py 2024-01-29 21:55:50.000000000
+0100
+++ new/chameleon-4.5.4/src/chameleon/i18n.py 2024-04-08 09:10:10.000000000
+0200
@@ -69,11 +69,11 @@
return None
if target_language is not None or context is not None:
- result = translate(
+ result: str = translate(
msgid, domain=domain, mapping=mapping, context=context,
target_language=target_language, default=default)
if result != msgid:
- return result # type: ignore[no-any-return]
+ return result
if isinstance(msgid, Message):
default = msgid.default
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/template.py
new/chameleon-4.5.4/src/chameleon/template.py
--- old/chameleon-4.5.2/src/chameleon/template.py 2024-01-29
21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/template.py 2024-04-08
09:10:10.000000000 +0200
@@ -342,7 +342,7 @@
builtins=builtins,
strict=self.strict
)
- return compiler.code
+ return compiler.code # type: ignore[no-any-return]
class BaseTemplateFile(BaseTemplate):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/chameleon-4.5.2/src/chameleon/tests/inputs/007-content-interpolation.pt
new/chameleon-4.5.4/src/chameleon/tests/inputs/007-content-interpolation.pt
--- old/chameleon-4.5.2/src/chameleon/tests/inputs/007-content-interpolation.pt
2024-01-29 21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/tests/inputs/007-content-interpolation.pt
2024-04-08 09:10:10.000000000 +0200
@@ -14,6 +14,10 @@
${None or
'Hello world'}
$leftalone
+ $${'fred'}
+ $$${'fred'}
+ $$$${'fred'}
+ $$$$${'fred'}
<div>${None}</div>
<div>${1 < 2 and 'Hello world' or None}</div>
<div>${} is ignored.</div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/chameleon-4.5.2/src/chameleon/tests/inputs/128-translation-macro-name.pt
new/chameleon-4.5.4/src/chameleon/tests/inputs/128-translation-macro-name.pt
---
old/chameleon-4.5.2/src/chameleon/tests/inputs/128-translation-macro-name.pt
1970-01-01 01:00:00.000000000 +0100
+++
new/chameleon-4.5.4/src/chameleon/tests/inputs/128-translation-macro-name.pt
2024-04-08 09:10:10.000000000 +0200
@@ -0,0 +1,5 @@
+<a metal:define-macro="fancy-link" href="#">Fancy link</a>
+
+<tal:something i18n:translate="text_with_link">
+ Now follows a fancy link: <metal:fancy-link i18n:name="obj_link"
use-macro="macros['fancy-link']" />
+</tal:something>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/tests/outputs/007.pt
new/chameleon-4.5.4/src/chameleon/tests/outputs/007.pt
--- old/chameleon-4.5.2/src/chameleon/tests/outputs/007.pt 2024-01-29
21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/tests/outputs/007.pt 2024-04-08
09:10:10.000000000 +0200
@@ -13,6 +13,10 @@
Hello world
$leftalone
+ ${'fred'}
+ $fred
+ $${'fred'}
+ $$fred
<div></div>
<div>Hello world</div>
<div>${} is ignored.</div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/chameleon-4.5.2/src/chameleon/tests/outputs/128-en.pt
new/chameleon-4.5.4/src/chameleon/tests/outputs/128-en.pt
--- old/chameleon-4.5.2/src/chameleon/tests/outputs/128-en.pt 1970-01-01
01:00:00.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/tests/outputs/128-en.pt 2024-04-08
09:10:10.000000000 +0200
@@ -0,0 +1,3 @@
+<a href="#">Fancy link</a>
+
+Now follows a fancy link: <a href="#">Fancy link</a> ('text_with_link'
translation into 'en')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/src/chameleon/tests/outputs/128.pt
new/chameleon-4.5.4/src/chameleon/tests/outputs/128.pt
--- old/chameleon-4.5.2/src/chameleon/tests/outputs/128.pt 1970-01-01
01:00:00.000000000 +0100
+++ new/chameleon-4.5.4/src/chameleon/tests/outputs/128.pt 2024-04-08
09:10:10.000000000 +0200
@@ -0,0 +1,3 @@
+<a href="#">Fancy link</a>
+
+Now follows a fancy link: <a href="#">Fancy link</a>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/chameleon-4.5.2/tox.ini new/chameleon-4.5.4/tox.ini
--- old/chameleon-4.5.2/tox.ini 2024-01-29 21:55:50.000000000 +0100
+++ new/chameleon-4.5.4/tox.ini 2024-04-08 09:10:10.000000000 +0200
@@ -12,6 +12,9 @@
docs
coverage
mypy
+ z3c.macro
+ z3c.pt
+
[testenv]
usedevelop = true
deps =
@@ -110,3 +113,25 @@
mypy -p chameleon --python-version 3.10
mypy -p chameleon --python-version 3.11
mypy -p chameleon --python-version 3.12
+
+[testenv:z3c.macro]
+basepython = python3
+skip_install = true
+commands_pre =
+ pip install -e.
+usedevelop = true
+deps =
+ z3c.macro[test]
+commands =
+ zope-testrunner --path {env_site_packages_dir} --path . -s z3c.macro
{posargs:-vc}
+
+[testenv:z3c.pt]
+basepython = python3
+skip_install = true
+commands_pre =
+ pip install -e.
+usedevelop = true
+deps =
+ z3c.pt[test]
+commands =
+ zope-testrunner --path {env_site_packages_dir} --path . -s z3c.pt
{posargs:-vc}