Hello community,

here is the log from the commit of package python-Kajiki for openSUSE:Factory 
checked in at 2019-03-12 09:52:01
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-Kajiki (Old)
 and      /work/SRC/openSUSE:Factory/.python-Kajiki.new.28833 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-Kajiki"

Tue Mar 12 09:52:01 2019 rev:9 rq:681852 version:0.7.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-Kajiki/python-Kajiki.changes      
2019-01-24 14:02:30.680113386 +0100
+++ /work/SRC/openSUSE:Factory/.python-Kajiki.new.28833/python-Kajiki.changes   
2019-03-12 09:52:11.283552732 +0100
@@ -1,0 +2,8 @@
+Tue Mar  5 16:35:50 UTC 2019 - Tomáš Chvátal <[email protected]>
+
+- Update to 0.7.2:
+  * Allow to replace gettext function by providing it in the template context 
or through base_globals in Loader
+  * Improve parsing of ${} expressions and fix syntax errors reporting in 
braced expressions.
+  * Improve parsing of documents with comments before the root element
+
+-------------------------------------------------------------------

Old:
----
  Kajiki-0.7.0.tar.gz

New:
----
  Kajiki-0.7.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-Kajiki.spec ++++++
--- /var/tmp/diff_new_pack.tb9RpI/_old  2019-03-12 09:52:11.867552616 +0100
+++ /var/tmp/diff_new_pack.tb9RpI/_new  2019-03-12 09:52:11.867552616 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-Kajiki
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,16 +18,18 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-Kajiki
-Version:        0.7.0
+Version:        0.7.2
 Release:        0
 Summary:        Compiler for Genshi syntax outputting Python bytecode
 License:        MIT
 Group:          Development/Languages/Python
-URL:            http://sourceforge.net/p/kajiki/home/
+URL:            https://github.com/nandoflorestan/kajiki
 Source:         
https://files.pythonhosted.org/packages/source/K/Kajiki/Kajiki-%{version}.tar.gz
 BuildRequires:  %{python_module Babel}
 BuildRequires:  %{python_module nine}
+BuildRequires:  %{python_module nose}
 BuildRequires:  %{python_module setuptools}
+BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 Requires:       python-nine
 BuildArch:      noarch
@@ -47,6 +49,8 @@
 
 %install
 %python_install
+%python_expand rm -r %{buildroot}%{$python_sitelib}/kajiki/tests
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
 
 %check
 %python_exec setup.py test

++++++ Kajiki-0.7.0.tar.gz -> Kajiki-0.7.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/CHANGES.rst new/Kajiki-0.7.2/CHANGES.rst
--- old/Kajiki-0.7.0/CHANGES.rst        2017-06-27 12:11:50.000000000 +0200
+++ new/Kajiki-0.7.2/CHANGES.rst        2018-04-16 22:53:18.000000000 +0200
@@ -1,6 +1,17 @@
 CHANGES
 =======
 
+0.7.2 (2018-04-16)
+------------------
+
+* Improve parsing of ``${}`` expressions and fix syntax errors reporting in 
braced expressions.
+* Improve parsing of documents with comments before the root element
+
+0.7.1 (2017-09-11)
+------------------
+
+* Allow to replace ``gettext`` function by providing it in the template 
context or through ``base_globals`` in Loader
+
 0.7.0 (2017-06-27)
 ------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/Kajiki.egg-info/PKG-INFO 
new/Kajiki-0.7.2/Kajiki.egg-info/PKG-INFO
--- old/Kajiki-0.7.0/Kajiki.egg-info/PKG-INFO   2017-06-27 12:42:59.000000000 
+0200
+++ new/Kajiki-0.7.2/Kajiki.egg-info/PKG-INFO   2018-04-16 22:54:38.000000000 
+0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: Kajiki
-Version: 0.7.0
+Version: 0.7.2
 Summary: Fast XML-based template engine with Genshi syntax and Jinja blocks
 Home-page: https://github.com/nandoflorestan/kajiki
 Author: Nando Florestan
 Author-email: [email protected]
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: Kajiki provides fast well-formed XML templates
         ==============================================
         
@@ -78,6 +79,17 @@
         CHANGES
         =======
         
+        0.7.2 (2018-04-16)
+        ------------------
+        
+        * Improve parsing of ``${}`` expressions and fix syntax errors 
reporting in braced expressions.
+        * Improve parsing of documents with comments before the root element
+        
+        0.7.1 (2017-09-11)
+        ------------------
+        
+        * Allow to replace ``gettext`` function by providing it in the 
template context or through ``base_globals`` in Loader
+        
         0.7.0 (2017-06-27)
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/Kajiki.egg-info/SOURCES.txt 
new/Kajiki-0.7.2/Kajiki.egg-info/SOURCES.txt
--- old/Kajiki-0.7.0/Kajiki.egg-info/SOURCES.txt        2017-06-27 
12:42:59.000000000 +0200
+++ new/Kajiki-0.7.2/Kajiki.egg-info/SOURCES.txt        2018-04-16 
22:54:38.000000000 +0200
@@ -60,4 +60,6 @@
 kajiki/tests/data/debug.html
 kajiki/tests/data/debug.txt
 kajiki/tests/data/error.html
+kajiki/tests/data/file_child.html
+kajiki/tests/data/file_parent.html
 kajiki/tests/data/simple.html
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/Kajiki.egg-info/requires.txt 
new/Kajiki-0.7.2/Kajiki.egg-info/requires.txt
--- old/Kajiki-0.7.0/Kajiki.egg-info/requires.txt       2017-06-27 
12:42:59.000000000 +0200
+++ new/Kajiki-0.7.2/Kajiki.egg-info/requires.txt       2018-04-16 
22:54:38.000000000 +0200
@@ -2,4 +2,4 @@
 
 [testing]
 babel
-nose
\ No newline at end of file
+nose
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/PKG-INFO new/Kajiki-0.7.2/PKG-INFO
--- old/Kajiki-0.7.0/PKG-INFO   2017-06-27 12:42:59.000000000 +0200
+++ new/Kajiki-0.7.2/PKG-INFO   2018-04-16 22:54:38.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: Kajiki
-Version: 0.7.0
+Version: 0.7.2
 Summary: Fast XML-based template engine with Genshi syntax and Jinja blocks
 Home-page: https://github.com/nandoflorestan/kajiki
 Author: Nando Florestan
 Author-email: [email protected]
 License: MIT
+Description-Content-Type: UNKNOWN
 Description: Kajiki provides fast well-formed XML templates
         ==============================================
         
@@ -78,6 +79,17 @@
         CHANGES
         =======
         
+        0.7.2 (2018-04-16)
+        ------------------
+        
+        * Improve parsing of ``${}`` expressions and fix syntax errors 
reporting in braced expressions.
+        * Improve parsing of documents with comments before the root element
+        
+        0.7.1 (2017-09-11)
+        ------------------
+        
+        * Allow to replace ``gettext`` function by providing it in the 
template context or through ``base_globals`` in Loader
+        
         0.7.0 (2017-06-27)
         ------------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/docs/conf.py 
new/Kajiki-0.7.2/docs/conf.py
--- old/Kajiki-0.7.0/docs/conf.py       2016-10-28 22:12:06.000000000 +0200
+++ new/Kajiki-0.7.2/docs/conf.py       2018-04-16 22:54:13.000000000 +0200
@@ -42,7 +42,7 @@
 
 # General information about the project.
 project = u'Kajiki'
-copyright = u'2010-2016, Rick Copeland, Nando Florestan and Alessandro Molina'
+copyright = u'2010-2018, Rick Copeland, Nando Florestan and Alessandro Molina'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/kajiki/i18n.py 
new/Kajiki-0.7.2/kajiki/i18n.py
--- old/Kajiki-0.7.0/kajiki/i18n.py     2017-06-27 10:02:35.000000000 +0200
+++ new/Kajiki-0.7.2/kajiki/i18n.py     2018-04-16 19:00:57.000000000 +0200
@@ -43,4 +43,4 @@
                                         keywords, comment_tags, options):
                     yield (node.lineno, e[1], e[2], e[3])
             except (TokenError, SyntaxError) as e:
-                raise KajikiSyntaxError(e, source, '<string>', node.lineno, 0)
\ No newline at end of file
+                raise KajikiSyntaxError(e, source, '<string>', node.lineno, 0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/kajiki/template.py 
new/Kajiki-0.7.2/kajiki/template.py
--- old/Kajiki-0.7.0/kajiki/template.py 2017-06-27 10:02:35.000000000 +0200
+++ new/Kajiki-0.7.2/kajiki/template.py 2017-09-11 13:50:13.000000000 +0200
@@ -64,11 +64,11 @@
             context = {}
         self._context = context
         base_globals = self.base_globals or {}
-        self.__globals__ = dict(base_globals, local=self, self=self,
+        self.__globals__ = dict(local=self, self=self,
             defined=lambda x: x in self.__globals__,
-            literal=literal, Markup=literal, _=i18n.gettext,
+            literal=literal, Markup=literal, gettext=i18n.gettext,
             __builtins__=__builtins__, __kj__=kajiki)
-        self.__globals__['value_of'] = self.__globals__.get
+        self.__globals__.update(base_globals)
         for k, v in self.__methods__:
             v = v.bind_instance(self)
             setattr(self, k, v)
@@ -80,7 +80,7 @@
             case=self._case,
             import_=self._import,
             escape=self._escape,
-            gettext=i18n.gettext,
+            gettext=self._gettext,
             render_attrs=self._render_attrs,
             push_with=self._push_with,
             pop_with=self._pop_with,
@@ -89,6 +89,8 @@
         self._switch_stack = []
         self._with_stack = []
         self.__globals__.update(context)
+        self.__globals__['_'] = self.__globals__['gettext']
+        self.__globals__['value_of'] = self.__globals__.get
 
     def __iter__(self):
         """We convert the chunk to string because it can be of any type
@@ -102,6 +104,10 @@
         """Render the template to a string."""
         return ''.join(self)
 
+    def _gettext(self, s):
+        """Used by the code generated by the template to translate static 
text"""
+        return self.__globals__['gettext'](s)
+
     def _push_with(self, locals_, vars):
         """Enter a ``py:with`` block.
 
@@ -122,6 +128,11 @@
         return self._with_stack.pop()
 
     def _extend(self, parent):
+        """
+        Called when a child template extends a parent template
+        the first thing it does is asking the loader of the
+        child template to load the parent template
+        """
         if isinstance(parent, basestring):
             parent = self.loader.import_(parent)
         p_inst = parent(self._context)
@@ -279,13 +290,18 @@
     return type(ns.__name__, (_Template,), dct)
 
 
-def from_ir(ir_node):
+def from_ir(ir_node, base_globals=None):
     """Creates a template class from Intermediate Representation TemplateNode.
 
     This actually creates the class defined by the TemplateNode by executing
     its code and returns a subclass of it.
     The returned class is a subclass of :class:`kajiki.template._Template`.
+
+    It is possible to use `base_globals` to set context values
+    or replace default ones
     """
+    if base_globals is None:
+        base_globals = dict()
     py_lines = list(generate_python(ir_node))
     py_text = '\n'.join(map(str, py_lines))
     py_linenos = []
@@ -300,7 +316,8 @@
     except (SyntaxError, IndentationError) as e:  # pragma no cover
         raise KajikiSyntaxError(e.msg, py_text, e.filename, e.lineno, e.offset)
     tpl = dct['template']
-    tpl.base_globals = dct
+    tpl.base_globals = base_globals.copy()
+    tpl.base_globals.update(dct)
     tpl.py_text = py_text
     tpl.filename = ir_node.filename
     tpl.annotate_lnotab(py_linenos)
@@ -438,4 +455,4 @@
         try:
             return source.splitlines()[linen]
         except:
-            return ''
\ No newline at end of file
+            return ''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/kajiki/tests/data/file_child.html 
new/Kajiki-0.7.2/kajiki/tests/data/file_child.html
--- old/Kajiki-0.7.0/kajiki/tests/data/file_child.html  1970-01-01 
01:00:00.000000000 +0100
+++ new/Kajiki-0.7.2/kajiki/tests/data/file_child.html  2017-09-11 
13:50:13.000000000 +0200
@@ -0,0 +1 @@
+<py:extends href="file_parent.html"><div>child</div></py:extends>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/kajiki/tests/data/file_parent.html 
new/Kajiki-0.7.2/kajiki/tests/data/file_parent.html
--- old/Kajiki-0.7.0/kajiki/tests/data/file_parent.html 1970-01-01 
01:00:00.000000000 +0100
+++ new/Kajiki-0.7.2/kajiki/tests/data/file_parent.html 2017-09-11 
13:50:13.000000000 +0200
@@ -0,0 +1 @@
+<div>parent</div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/kajiki/tests/test_xml.py 
new/Kajiki-0.7.2/kajiki/tests/test_xml.py
--- old/Kajiki-0.7.0/kajiki/tests/test_xml.py   2017-06-27 10:14:59.000000000 
+0200
+++ new/Kajiki-0.7.2/kajiki/tests/test_xml.py   2018-04-16 22:29:29.000000000 
+0200
@@ -9,6 +9,7 @@
 import xml.dom.minidom
 from io import BytesIO
 from unittest import TestCase, main
+from nose import SkipTest
 
 from kajiki import i18n
 from kajiki.template import KajikiSyntaxError
@@ -16,7 +17,7 @@
 import kajiki
 from kajiki import MockLoader, XMLTemplate, FileLoader, PackageLoader
 from kajiki.ir import TranslatableTextNode
-from kajiki.xml_template import _Compiler, _Parser, XMLTemplateCompileError
+from kajiki.xml_template import _Compiler, _Parser, XMLTemplateCompileError, 
XMLTemplateParseError
 
 DATA = os.path.join(os.path.dirname(__file__), 'data')
 
@@ -182,6 +183,15 @@
                                  'age': 26}['name']}</div>""",
                 '<div>Hello, Rick</div>')
 
+    def test_expr_multiline_and_IndentationError(self):
+        try:
+            XMLTemplate("""<div>Hello, ${ 'pippo' +
+                'baudo'}</div>""")().render()
+        except XMLTemplateCompileError as e:
+            assert "`'pippo' +\n                'baudo'`" in str(e), str(e)
+            assert 'Hello' in str(e)
+            assert 'baudo' in str(e)
+
     def test_expr_multiline_cdata(self):
         perform("""<script><![CDATA[Hello, ${{'name': 'Rick',
                                  'age': 26}['name']}]]></script>""",
@@ -872,16 +882,57 @@
             i18n.gettext = default_gettext
 
     def test_extract_python_inside_invalid(self):
-        src = '''<xml><div>${_('hi' +}</div></xml>'''
+        src = '''<xml><div>${_('hi' +)}</div></xml>'''
         try:
             x = list(i18n.extract(BytesIO(src.encode('utf-8')), [], None, {
                 'extract_python': True
             }))
-        except KajikiSyntaxError as e:
-            assert "${_('hi' +" in str(e)
+        except XMLTemplateCompileError as e:
+            assert "_('hi' +)" in str(e)
         else:
             assert False, 'Should have raised'
 
+    def test_substituting_gettext_with_lambda(self):
+        src = '''<xml>hi</xml>'''
+        expected = '''<xml>spam</xml>'''
+
+        perform(src, expected, context=dict(gettext=lambda x: 'spam'))
+
+    def test_substituting_gettext_with_lambda_extending(self):
+        gettext = lambda x: 'egg'
+        loader = MockLoader({
+            'parent.html': XMLTemplate('''<div>parent</div>'''),
+            'child.html': XMLTemplate('''<py:extends 
href="parent.html"><div>child</div></py:extends>''')})
+        tpl = loader.import_('child.html')
+        rsp = tpl(dict(gettext=gettext)).render()
+        assert rsp == '''<div>egg</div><div>egg</div>''', rsp
+
+    def test_substituting_gettext_with_lambda_extending_twice(self):
+        gettext = lambda x: 'egg'
+        loader = MockLoader({
+            'parent.html': XMLTemplate('''<div>parent</div>'''),
+            'mid.html': XMLTemplate('''<py:extends 
href="parent.html"><div>${variable}</div></py:extends>'''),
+            'child.html': XMLTemplate('''<py:extends 
href="mid.html"><div>child</div></py:extends>''')})
+        tpl = loader.import_('child.html')
+        rsp = tpl(dict(variable='spam', gettext=gettext)).render()
+        # variables must not be translated
+        assert rsp == '''<div>egg</div><div>spam</div><div>egg</div>''', rsp
+
+    def test_substituting_gettext_with_lambda_extending_file(self):
+        loader = FileLoader(path=os.path.join(os.path.dirname(__file__),
+                            'data'), base_globals=dict(gettext=lambda x: 
'egg'))
+        tpl = loader.import_('file_child.html')
+        rsp = tpl(dict()).render()
+        assert rsp == '''<div>egg</div><div>egg</div>''', rsp
+
+    def test_without_substituting_gettext_with_lambda_extending_file(self):
+        # this should use i18n.gettext
+        loader = FileLoader(path=os.path.join(os.path.dirname(__file__),
+                            'data'))
+        tpl = loader.import_('file_child.html')
+        rsp = tpl(dict()).render()
+        assert rsp == '''<div>parent</div><div>child</div>''', rsp
+
 
 class TestDOMTransformations(TestCase):
     def test_empty_text_extraction(self):
@@ -927,5 +978,93 @@
                 assert False
 
 
+class TestBracketsInExpression(TestCase):
+    def test_simple(self):
+        perform('<x>${\'ok\'}</x>', '<x>ok</x>')
+
+    def test_some_brackets(self):
+        perform('<x>${\'{ok}\'}</x>', '<x>{ok}</x>')
+
+    def test_brackets_asymmetric(self):
+        perform('<x>${\'{o{k}k  { \'}</x>', '<x>{o{k}k  { </x>')
+
+    def test_complex(self):
+        perform(u"<xml><div>${'ciao {  } {' + \"a {} b {{{{} 
w}}rar\"}${'sd{}'} ${1+1}</div></xml>",
+                u"<xml><div>ciao {  } {a {} b {{{{} w}}rarsd{} 2</div></xml>")
+
+    def test_with_padding_space(self):
+        perform('<x y="${ 1 + 1}"> ${  "hello"     +   "world"   }  </x>',
+                '<x y="2"> helloworld  </x>')
+
+    def test_raise_unclosed_string(self):
+        try:
+            XMLTemplate('<x>${"ciao}</x>')
+            assert False, 'must raise'
+        except XMLTemplateCompileError as e:
+            # assert "can't compile" in str(e), e  # different between pypy 
and cpython
+            assert '"ciao' in str(e), e
+
+    def test_raise_plus_with_an_operand(self):
+        try:
+            XMLTemplate('<x>${"ciao" + }</x>')
+            assert False, 'must raise'
+        except XMLTemplateCompileError as e:
+            assert 'detected an invalid python expression' in str(e), e
+            assert '"ciao" +' in str(e), e
+
+    def test_unclosed_braced(self):
+        try:
+            XMLTemplate('<x>${"ciao"</x>')
+            assert False, 'must raise'
+        except XMLTemplateCompileError as e:
+            assert 'Braced expression not terminated' in str(e), e
+
+    def test_leading_opening_brace(self):
+        if sys.version_info[:2] == (2, 6):
+            raise SkipTest('Python 2.6 compiler raises a different kind of 
error')
+
+        try:
+            XMLTemplate('<x>${{"a", "b"}</x>')
+            assert False, 'must raise'
+        except XMLTemplateCompileError as e:
+            assert 'Braced expression not terminated' in str(e), e
+
+
+class TestMultipleChildrenInDOM(TestCase):
+    def test_ok(self):
+        XMLTemplate('<xml><!--  a  --><x>${1+1}</x></xml>')
+
+    def test_comment(self):
+        res = XMLTemplate('<!-- a --><x>${1+1}</x>')().render()
+        assert res == '<x>2</x>'
+
+    def test_multiple_nodes(self):
+        try:
+            XMLTemplate('<!-- a --><x>${1+1}</x><y>${1+1}</y>')
+        except XMLTemplateParseError as e:
+            assert 'junk after document element' in str(e), e
+        else:
+            assert False, 'should have raised'
+
+    def test_only_comment(self):
+        try:
+            XMLTemplate('<!-- a -->')
+        except XMLTemplateParseError as e:
+            assert 'no element found' in str(e), e
+        else:
+            assert False, 'should have raised'
+
+
+class TestSyntaxErrorCallingWithTrailingParenthesis(TestCase):
+    def test_raise(self):
+        try:
+            XMLTemplate(u'''<div py:strip="True"
+><py:def function="echo(x)">$x</py:def
+>${echo('hello'))}</div>''')
+            assert False, 'should raise'
+        except XMLTemplateCompileError as e:
+            pass
+
+
 if __name__ == '__main__':
     main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/kajiki/version.py 
new/Kajiki-0.7.2/kajiki/version.py
--- old/Kajiki-0.7.0/kajiki/version.py  2017-06-27 12:42:56.000000000 +0200
+++ new/Kajiki-0.7.2/kajiki/version.py  2018-04-16 22:53:36.000000000 +0200
@@ -2,5 +2,5 @@
 from __future__ import (absolute_import, division, print_function,
                         unicode_literals)
 
-__version__ = '0.6'
-__release__ = '0.7.0'
+__version__ = '0.7'
+__release__ = '0.7.2'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/kajiki/xml_template.py 
new/Kajiki-0.7.2/kajiki/xml_template.py
--- old/Kajiki-0.7.0/kajiki/xml_template.py     2017-05-28 14:43:48.000000000 
+0200
+++ new/Kajiki-0.7.2/kajiki/xml_template.py     2018-04-16 22:29:55.000000000 
+0200
@@ -29,7 +29,7 @@
 
 def XMLTemplate(source=None, filename=None, mode=None, is_fragment=False,
                 encoding='utf-8', autoblocks=None, cdata_scripts=True,
-                strip_text=False):
+                strip_text=False, base_globals=None):
     """Given XML source code of a Kajiki Templates parses and returns a 
template class.
 
     The source code is parsed to its DOM representation by :class:`._Parser`,
@@ -53,7 +53,8 @@
     doc = _DomTransformer(doc, strip_text=strip_text).transform()
     ir_ = _Compiler(filename, doc, mode=mode, is_fragment=is_fragment,
                     autoblocks=autoblocks, 
cdata_scripts=cdata_scripts).compile()
-    return template.from_ir(ir_)
+    t = template.from_ir(ir_, base_globals=base_globals)
+    return t
 
 
 def annotate(gen):
@@ -114,7 +115,12 @@
             registries of the compiler ``compile`` should
             never be called twice or might lead to unexpected results.
         """
-        body = list(self._compile_node(self.doc.firstChild))
+        templateNodes = [n for n in self.doc.childNodes if not isinstance(n, 
dom.Comment)]
+        if len(templateNodes) != 1:
+            raise XMLTemplateCompileError('expected a single root node in 
document',
+                                          self.doc, self.filename, 0)
+
+        body = list(self._compile_node(templateNodes[0]))
         # Never emit doctypes on fragments
         if not self.is_fragment and not self.is_child:
             if self.doc._dtd:
@@ -218,7 +224,7 @@
         yield ir.TextNode('<%s' % node.tagName, guard)
         for k, v in sorted(node.attributes.items()):
             tc = _TextCompiler(self.filename, v, node.lineno,
-                               ir.TextNode, in_html_attr=True)
+                               ir.TextNode, in_html_attr=True, 
compiler_instance=self)
             v = list(tc)
             if k == 'py:content':
                 content = node.getAttribute('py:content')
@@ -373,7 +379,7 @@
             # script and style should always be untranslatable.
             kwargs['node_type'] = ir.TextNode
 
-        tc = _TextCompiler(self.filename, node.data, node.lineno, **kwargs)
+        tc = _TextCompiler(self.filename, node.data, node.lineno, 
compiler_instance=self, **kwargs)
         for x in tc:
             yield x
 
@@ -465,7 +471,7 @@
     instances and :class:`.ir.TextNode` instances accordingly.
     """
     def __init__(self, filename, source, lineno,
-                 node_type=make_text_node, in_html_attr=False):
+                 node_type=make_text_node, in_html_attr=False, 
compiler_instance=None):
         self.filename = filename
         self.source = source
         self.orig_lineno = lineno
@@ -473,6 +479,8 @@
         self.pos = 0
         self.node_type = node_type
         self.in_html_attr = in_html_attr
+        self.compiler_instance = compiler_instance
+        self.doc = self.compiler_instance.doc
 
     def text(self, text):
         node = self.node_type(text)
@@ -524,15 +532,44 @@
             yield self.text(source[self.pos:])
 
     def _get_braced_expr(self):
+        # see https://github.com/nandoflorestan/kajiki/pull/38
+        # Trying to get the position of a closing } in braced expressions
+        # So, self.source can be something like `1+1=${1+1} ahah`
+        # in this case this function gets called only once with self.pos equal 
to 6
+        # this function must return the result of self.expr('1+1') and must 
set self.pos to 9
+        def py_expr(end=None):
+            return self.source[self.pos:end]
         try:
-            compile(self.source[self.pos:], '', 'eval')
+            self.pos += len(py_expr()) - len(py_expr().lstrip())
+            compile(py_expr(), 'find_}', 'eval')
         except SyntaxError as se:
-            end = self.pos + sum([se.offset] + [len(line) + 1
-                                                for idx, line in 
enumerate(self.source[self.pos:].splitlines())
-                                                if idx < se.lineno - 1])
-            text = self.source[self.pos:end - 1]
+            end = sum(
+                [self.pos, se.offset] +
+                [len(line) + 1
+                 for idx, line in enumerate(py_expr().splitlines())
+                 if idx < se.lineno - 1]
+            )
+            if py_expr(end)[-1] != '}':
+                # for example unclosed strings
+                raise XMLTemplateCompileError(
+                    "Kajiki can't compile the python expression `%s`" % 
py_expr()[:-1],
+                    doc=self.doc, filename=self.filename, linen=self.lineno)
+            else:
+                # if the expression ends in a } then it may be valid
+                try:
+                    compile(py_expr(end-1), 'check_validity', 'eval')
+                except SyntaxError as se:
+                    # for example + operators with a single operand
+                    raise XMLTemplateCompileError(
+                        "Kajiki detected an invalid python expression `%s`" % 
py_expr()[:-1],
+                        doc=self.doc, filename=self.filename, 
linen=self.lineno)
+
+            py_text = py_expr(end - 1)
             self.pos = end
-            return self.expr(text)
+            return self.expr(py_text)
+        else:
+            raise XMLTemplateCompileError("Braced expression not terminated",
+                                          doc=self.doc, 
filename=self.filename, linen=self.lineno)
 
 
 class _Parser(sax.ContentHandler):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/setup.cfg new/Kajiki-0.7.2/setup.cfg
--- old/Kajiki-0.7.0/setup.cfg  2017-06-27 12:42:59.000000000 +0200
+++ new/Kajiki-0.7.2/setup.cfg  2018-04-16 22:54:38.000000000 +0200
@@ -1,5 +1,4 @@
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Kajiki-0.7.0/setup.py new/Kajiki-0.7.2/setup.py
--- old/Kajiki-0.7.0/setup.py   2017-06-27 10:02:35.000000000 +0200
+++ new/Kajiki-0.7.2/setup.py   2018-04-16 19:00:57.000000000 +0200
@@ -70,7 +70,7 @@
       extras_require = {
         'testing': TEST_DEPENDENCIES,
       },
-      test_suite='kajiki.tests',
+      test_suite='nose.collector',
       entry_points="""
           [babel.extractors]
           kajiki = kajiki.i18n:extract


Reply via email to