diff --git a/python-Genshi-0.7-disable-speedups-for-python34.patch b/python-Genshi-0.7-disable-speedups-for-python34.patch new file mode 100644 index 0000000..73bc6b8 --- /dev/null +++ b/python-Genshi-0.7-disable-speedups-for-python34.patch @@ -0,0 +1,24 @@ +------------------------------------------------------------------------ +r1247 | hodgestar | 2014-02-16 19:32:21 +0100 (So, 16. Feb 2014) | 1 Zeile + +Disable the speedups C extension on CPython >= 3.3 since Genshi doesn't support the new Unicode C API yet. +------------------------------------------------------------------------ +Index: setup.py +=================================================================== +--- setup.py (Revision 1246) ++++ setup.py (Revision 1247) +@@ -65,9 +65,13 @@ + + + if Feature: ++ # Optional C extension module for speeding up Genshi: ++ # Not activated by default on: ++ # - PyPy (where it harms performance) ++ # - CPython >= 3.3 (the new Unicode C API is not supported yet) + speedups = Feature( + "optional C speed-enhancements", +- standard = not is_pypy, ++ standard = not is_pypy and sys.version_info < (3, 3), + ext_modules = [ + Extension('genshi._speedups', ['genshi/_speedups.c']), + ], diff --git a/python-Genshi-0.7-isstring-helper.patch b/python-Genshi-0.7-isstring-helper.patch new file mode 100644 index 0000000..0533b80 --- /dev/null +++ b/python-Genshi-0.7-isstring-helper.patch @@ -0,0 +1,30 @@ +------------------------------------------------------------------------ +r1248 | hodgestar | 2014-02-16 19:43:20 +0100 (So, 16. Feb 2014) | 1 Zeile + +Add isstring helper. +------------------------------------------------------------------------ +Index: genshi/compat.py +=================================================================== +--- genshi/compat.py (Revision 1247) ++++ genshi/compat.py (Revision 1248) +@@ -35,6 +35,15 @@ + 'Python 2 compatibility function. Not usable in Python 3.') + + ++# We need to test if an object is an instance of a string type in places ++ ++if IS_PYTHON2: ++ def isstring(obj): ++ return isinstance(obj, basestring) ++else: ++ def isstring(obj): ++ return isinstance(obj, str) ++ + # We need to differentiate between StringIO and BytesIO in places + + if IS_PYTHON2: +@@ -112,4 +121,3 @@ + if not x: + return False + return True +- diff --git a/python-Genshi-0.7-python34-ast-support.patch b/python-Genshi-0.7-python34-ast-support.patch new file mode 100644 index 0000000..4f01a59 --- /dev/null +++ b/python-Genshi-0.7-python34-ast-support.patch @@ -0,0 +1,142 @@ +------------------------------------------------------------------------ +r1249 | hodgestar | 2014-02-16 19:46:15 +0100 (So, 16. Feb 2014) | 1 Zeile + +Add support for Python 3.4 AST (support for NameConstants and changes to existing to arguments node attributes). +------------------------------------------------------------------------ +Index: genshi/template/astutil.py +=================================================================== +--- genshi/template/astutil.py (Revision 1248) ++++ genshi/template/astutil.py (Revision 1249) +@@ -21,7 +21,7 @@ + def parse(source, mode): + return compile(source, '', mode, _ast.PyCF_ONLY_AST) + +-from genshi.compat import IS_PYTHON2 ++from genshi.compat import IS_PYTHON2, isstring + + __docformat__ = 'restructuredtext en' + +@@ -103,8 +103,13 @@ + self._new_line() + return self.visit(node.body) + ++ # Python < 3.4 + # arguments = (expr* args, identifier? vararg, + # identifier? kwarg, expr* defaults) ++ # ++ # Python >= 3.4 ++ # arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults, ++ # arg? kwarg, expr* defaults) + def visit_arguments(self, node): + first = True + no_default_count = len(node.args) - len(node.defaults) +@@ -122,13 +127,21 @@ + self._write(', ') + else: + first = False +- self._write('*' + node.vararg) ++ self._write('*') ++ if isstring(node.vararg): ++ self._write(node.vararg) ++ else: ++ self.visit(node.vararg) + if getattr(node, 'kwarg', None): + if not first: + self._write(', ') + else: + first = False +- self._write('**' + node.kwarg) ++ self._write('**') ++ if isstring(node.kwarg): ++ self._write(node.kwarg) ++ else: ++ self.visit(node.kwarg) + + if not IS_PYTHON2: + # In Python 3 arguments get a special node +@@ -724,6 +737,17 @@ + def visit_Name(self, node): + self._write(node.id) + ++ # NameConstant(singleton value) ++ def visit_NameConstant(self, node): ++ if node.value is None: ++ self._write('None') ++ elif node.value is True: ++ self._write('True') ++ elif node.value is False: ++ self._write('False') ++ else: ++ raise Exception("Unknown NameConstant %r" % (node.value,)) ++ + # List(expr* elts, expr_context ctx) + def visit_List(self, node): + self._write('[') +@@ -829,6 +853,7 @@ + visit_Attribute = _clone + visit_Subscript = _clone + visit_Name = _clone ++ visit_NameConstant = _clone + visit_List = _clone + visit_Tuple = _clone + +Index: genshi/template/eval.py +=================================================================== +--- genshi/template/eval.py (Revision 1248) ++++ genshi/template/eval.py (Revision 1249) +@@ -24,7 +24,8 @@ + from genshi.template.base import TemplateRuntimeError + from genshi.util import flatten + +-from genshi.compat import get_code_params, build_code_chunk, IS_PYTHON2 ++from genshi.compat import get_code_params, build_code_chunk, isstring, \ ++ IS_PYTHON2 + + __all__ = ['Code', 'Expression', 'Suite', 'LenientLookup', 'StrictLookup', + 'Undefined', 'UndefinedError'] +@@ -495,28 +496,31 @@ + def __init__(self): + self.locals = [CONSTANTS] + ++ def _process(self, names, node): ++ if not IS_PYTHON2 and isinstance(node, _ast.arg): ++ names.add(node.arg) ++ elif isstring(node): ++ names.add(node) ++ elif isinstance(node, _ast.Name): ++ names.add(node.id) ++ elif isinstance(node, _ast.alias): ++ names.add(node.asname or node.name) ++ elif isinstance(node, _ast.Tuple): ++ for elt in node.elts: ++ self._process(names, elt) ++ + def _extract_names(self, node): + names = set() +- def _process(node): +- if not IS_PYTHON2 and isinstance(node, _ast.arg): +- names.add(node.arg) +- if isinstance(node, _ast.Name): +- names.add(node.id) +- elif isinstance(node, _ast.alias): +- names.add(node.asname or node.name) +- elif isinstance(node, _ast.Tuple): +- for elt in node.elts: +- _process(elt) + if hasattr(node, 'args'): + for arg in node.args: +- _process(arg) ++ self._process(names, arg) + if hasattr(node, 'vararg'): +- names.add(node.vararg) ++ self._process(names, node.vararg) + if hasattr(node, 'kwarg'): +- names.add(node.kwarg) ++ self._process(names, node.kwarg) + elif hasattr(node, 'names'): + for elt in node.names: +- _process(elt) ++ self._process(names, elt) + return names + + def visit_Str(self, node): diff --git a/python-Genshi-0.7-sanitizer-test-fixes.patch b/python-Genshi-0.7-sanitizer-test-fixes.patch new file mode 100644 index 0000000..971630c --- /dev/null +++ b/python-Genshi-0.7-sanitizer-test-fixes.patch @@ -0,0 +1,43 @@ +------------------------------------------------------------------------ +r1246 | hodgestar | 2014-02-16 19:25:17 +0100 (So, 16. Feb 2014) | 1 Zeile + +Also allow stripping of unsafe script tags (Python 3.4 parses the second example as a tag whose name is script&xyz). +------------------------------------------------------------------------ +Index: genshi/filters/tests/test_html.py +=================================================================== +--- genshi/filters/tests/test_html.py (Revision 1245) ++++ genshi/filters/tests/test_html.py (Revision 1246) +@@ -368,12 +368,16 @@ + + class HTMLSanitizerTestCase(unittest.TestCase): + +- def assert_parse_error_or_equal(self, expected, exploit): ++ def assert_parse_error_or_equal(self, expected, exploit, ++ allow_strip=False): + try: + html = HTML(exploit) + except ParseError: + return +- self.assertEquals(expected, (html | HTMLSanitizer()).render()) ++ sanitized_html = (html | HTMLSanitizer()).render() ++ if not sanitized_html and allow_strip: ++ return ++ self.assertEquals(expected, sanitized_html) + + def test_sanitize_unchanged(self): + html = HTML(u'fo
o
') +@@ -416,10 +420,12 @@ + html = HTML(u'') + self.assertEquals('', (html | HTMLSanitizer()).render()) + src = u'alert("foo")' +- self.assert_parse_error_or_equal('<SCR\x00IPT>alert("foo")', src) ++ self.assert_parse_error_or_equal('<SCR\x00IPT>alert("foo")', src, ++ allow_strip=True) + src = u'' + self.assert_parse_error_or_equal('<SCRIPT&XYZ; ' +- 'SRC="http://example.com/">', src) ++ 'SRC="http://example.com/">', src, ++ allow_strip=True) + + def test_sanitize_remove_onclick_attr(self): + html = HTML(u'
') diff --git a/python-Genshi-bug-602-python35-support-python27-fix.patch b/python-Genshi-bug-602-python35-support-python27-fix.patch new file mode 100644 index 0000000..bcc34fa --- /dev/null +++ b/python-Genshi-bug-602-python35-support-python27-fix.patch @@ -0,0 +1,15 @@ +http://genshi.edgewall.org/ticket/602#comment:2 + +diff --git a/genshi/template/directives.py b/genshi/template/directives.py +index 6fd0f28..1f70ef6 100644 +--- a/genshi/template/directives.py ++++ b/genshi/template/directives.py +@@ -266,7 +266,7 @@ class DefDirective(Directive): + if isinstance(ast, _ast.Call): + self.name = ast.func.id + for arg in ast.args: +- if isinstance(arg, _ast.Starred): ++ if hasattr(_ast, 'Starred') and isinstance(arg, _ast.Starred): + # Python 3.5+ + self.star_args = arg.value.id + else: diff --git a/python-Genshi-bug-602-python35-support.patch b/python-Genshi-bug-602-python35-support.patch new file mode 100644 index 0000000..cca9aef --- /dev/null +++ b/python-Genshi-bug-602-python35-support.patch @@ -0,0 +1,100 @@ +Patch from Tim Hatch +http://genshi.edgewall.org/ticket/602 + +diff --git a/genshi/filters/i18n.py b/genshi/filters/i18n.py +index b724956..dfb52b8 100644 +--- a/genshi/filters/i18n.py ++++ b/genshi/filters/i18n.py +@@ -1187,8 +1187,10 @@ def extract_from_code(code, gettext_functions): + elif arg: + strings.append(None) + [_add(arg) for arg in node.args] +- _add(node.starargs) +- _add(node.kwargs) ++ if hasattr(node, 'starargs'): ++ _add(node.starargs) ++ if hasattr(node, 'kwargs'): ++ _add(node.kwargs) + if len(strings) == 1: + strings = strings[0] + else: +diff --git a/genshi/template/astutil.py b/genshi/template/astutil.py +index a3946b4..07edc92 100644 +--- a/genshi/template/astutil.py ++++ b/genshi/template/astutil.py +@@ -148,6 +148,10 @@ class ASTCodeGenerator(object): + def visit_arg(self, node): + self._write(node.arg) + ++ def visit_Starred(self, node): ++ self._write('*') ++ self.visit(node.value) ++ + # FunctionDef(identifier name, arguments args, + # stmt* body, expr* decorator_list) + def visit_FunctionDef(self, node): +@@ -661,9 +665,13 @@ class ASTCodeGenerator(object): + if not first: + self._write(', ') + first = False +- # keyword = (identifier arg, expr value) +- self._write(keyword.arg) +- self._write('=') ++ if not keyword.arg: ++ # Python 3.5+ star-star args ++ self._write('**') ++ else: ++ # keyword = (identifier arg, expr value) ++ self._write(keyword.arg) ++ self._write('=') + self.visit(keyword.value) + if getattr(node, 'starargs', None): + if not first: +diff --git a/genshi/template/directives.py b/genshi/template/directives.py +index 7301c2d..6fd0f28 100644 +--- a/genshi/template/directives.py ++++ b/genshi/template/directives.py +@@ -266,13 +266,21 @@ class DefDirective(Directive): + if isinstance(ast, _ast.Call): + self.name = ast.func.id + for arg in ast.args: +- # only names +- self.args.append(arg.id) ++ if isinstance(arg, _ast.Starred): ++ # Python 3.5+ ++ self.star_args = arg.value.id ++ else: ++ # only names ++ self.args.append(arg.id) + for kwd in ast.keywords: +- self.args.append(kwd.arg) +- exp = Expression(kwd.value, template.filepath, +- lineno, lookup=template.lookup) +- self.defaults[kwd.arg] = exp ++ if kwd.arg is None: ++ # Python 3.5+ ++ self.dstar_args = kwd.value.id ++ else: ++ self.args.append(kwd.arg) ++ exp = Expression(kwd.value, template.filepath, ++ lineno, lookup=template.lookup) ++ self.defaults[kwd.arg] = exp + if getattr(ast, 'starargs', None): + self.star_args = ast.starargs.id + if getattr(ast, 'kwargs', None): +diff --git a/genshi/template/eval.py b/genshi/template/eval.py +index de4bc86..065c0c7 100644 +--- a/genshi/template/eval.py ++++ b/genshi/template/eval.py +@@ -597,6 +597,11 @@ class TemplateASTTransformer(ASTTransformer): + finally: + self.locals.pop() + ++ # Only used in Python 3.5+ ++ def visit_Starred(self, node): ++ node.value = self.visit(node.value) ++ return node ++ + def visit_Name(self, node): + # If the name refers to a local inside a lambda, list comprehension, or + # generator expression, leave it alone diff --git a/python-Genshi.changes b/python-Genshi.changes index 06fad44..beaf6f7 100644 --- a/python-Genshi.changes +++ b/python-Genshi.changes @@ -1,3 +1,31 @@ +------------------------------------------------------------------- +Tue Apr 6 17:08:45 UTC 2017 - jmatejek@suse.com + +- always build as arch-dependent +- build docs as a single noarch package + +------------------------------------------------------------------- +Tue Apr 6 17:08:35 UTC 2017 - aloisio@gmx.com + +- Added python-Genshi-0.7-disable-speedups-for-python34.patch, + python-Genshi-0.7-isstring-helper.patch, + python-Genshi-0.7-python34-ast-support.patch, + python-Genshi-0.7-sanitizer-test-fixes.patch, + python-Genshi-bug-602-python35-support.patch, + python-Genshi-bug-602-python35-support-python27-fix.patch +- Enabled tests + +------------------------------------------------------------------- +Thu Apr 6 15:53:52 UTC 2017 - toddrme2178@gmail.com + +- Update singlespec build +- Use pypi download url + +------------------------------------------------------------------- +Mon Dec 19 17:34:46 UTC 2016 - jmatejek@suse.com + +- update for multipython build + ------------------------------------------------------------------- Fri Jul 24 20:36:31 UTC 2015 - seife+obs@b1-systems.com diff --git a/python-Genshi.spec b/python-Genshi.spec index 106598e..c0d3337 100644 --- a/python-Genshi.spec +++ b/python-Genshi.spec @@ -1,7 +1,7 @@ # # spec file for package python-Genshi # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 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 @@ -16,6 +16,7 @@ # +%{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-Genshi Version: 0.7 Release: 0 @@ -23,22 +24,37 @@ Url: http://genshi.edgewall.org/ Summary: A toolkit for generation of output for the web License: BSD-3-Clause Group: Development/Languages/Python -Source: http://ftp.edgewall.com/pub/genshi/Genshi-%{version}.tar.gz -# FIX-UPSTREAM http://genshi.edgewall.org/ticket/566 +Source: https://files.pythonhosted.org/packages/source/G/Genshi/Genshi-%{version}.tar.gz +# PATCH-FIX-UPSTREAM http://genshi.edgewall.org/ticket/566 Patch1: changeset_r1242.diff -BuildRoot: %{_tmppath}/%{name}-%{version}-build -BuildRequires: python-Babel -BuildRequires: python-devel -BuildRequires: python-setuptools -BuildRequires: python-xml +# PATCH-FIX-UPSTREAM python-Genshi-0.7-sanitizer-test-fixes.patch https://genshi.edgewall.org/ticket/500 +Patch2: %{name}-0.7-sanitizer-test-fixes.patch +# PATCH-FIX-UPSTREAM python-Genshi-0.7-disable-speedups-for-python34.patch https://genshi.edgewall.org/ticket/555 +Patch3: %{name}-0.7-disable-speedups-for-python34.patch +# PATCH-FIX-UPSTREAM python-Genshi-0.7-isstring-helper.patch https://genshi.edgewall.org/ticket/582 +Patch4: %{name}-0.7-isstring-helper.patch +# PATCH-FIX-UPSTREAM python-Genshi-python34-ast-support.patch https://genshi.edgewall.org/ticket/582 +Patch5: %{name}-0.7-python34-ast-support.patch +# PATCH-FIX-UPSTREAM python-Genshi-python35-support.patch http://genshi.edgewall.org/ticket/602 +Patch6: %{name}-bug-602-python35-support.patch +# PATCH-FIX-UPSTREAM python-Genshi-python35-support-python27-fix.patch http://genshi.edgewall.org/ticket/602 +Patch7: %{name}-bug-602-python35-support-python27-fix.patch +BuildRequires: %{python_module Babel} +BuildRequires: %{python_module devel} +BuildRequires: %{python_module setuptools} +BuildRequires: %{python_module xml} +BuildRequires: fdupes +BuildRequires: gcc +BuildRequires: python-rpm-macros Requires: python-Babel Requires: python-xml -Provides: python-genshi = %{version} -Obsoletes: python-genshi < %{version} -%if 0%{?suse_version} && 0%{?suse_version} <= 1110 -%{!?python_sitearch: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib(True)")} -%{py_requires} +%define oldpython python +%ifpython2 +Obsoletes: %{oldpython}-genshi < %{version} +Provides: %{oldpython}-genshi = %{version} %endif +BuildRoot: %{_tmppath}/%{name}-%{version}-build +%python_subpackages %description Genshi is a Python library that provides an integrated set of @@ -46,13 +62,15 @@ components for parsing, generating, and processing HTML, XML or other textual content for output generation on the web. The major feature is a template language, which is heavily inspired by Kid. -%package doc +%package -n %{name}-doc Summary: A toolkit for generation of output for the web - Documentation Group: Development/Libraries/Python Requires: %{name} = %{version} +Provides: %{python_module Genshi-doc = %{version}} +BuildArch: noarch -%description doc +%description -n %{name}-doc Genshi is a Python library that provides an integrated set of components for parsing, generating, and processing HTML, XML or other textual content for output generation on the web. The major @@ -63,21 +81,40 @@ This package contains documentation and examples. %prep %setup -q -n Genshi-%{version} %patch1 -p2 +%patch2 +%patch3 +%patch4 +%patch5 +%patch6 -p1 +%patch7 -p1 sed -i "1d" examples/{basic/run,basic/kidrun,tutorial/geddit/controller}.py # Fix non-excutable bits +%fdupes -s doc +pushd examples/bench/clearsilver +ln -s -f ../mako/footer.html footer.cs +popd +pushd examples/bench/cheetah +ln -s -f ../mako/footer.html footer.tmpl +popd %build -python setup.py build +%python_build %install -python setup.py install --prefix=%{_prefix} --root=%{buildroot} +%{python_expand %$python_install --install-lib=%{$python_sitearch} +rm -f %{buildroot}%{$python_sitearch}/genshi/_speedups.c +%fdupes -s %{buildroot}%{$python_sitearch} +} -%files +%check +%python_exec setup.py test + +%files %{python_files} %defattr(-,root,root,-) %doc COPYING ChangeLog README.txt %{python_sitearch}/genshi/ -%{python_sitearch}/Genshi-%{version}-py*.egg-info +%{python_sitearch}/Genshi-%{version}-py%{python_version}.egg-info -%files doc +%files -n %{name}-doc %defattr(-,root,root,-) %doc doc examples