Hello community, here is the log from the commit of package python-tinycss2 for openSUSE:Factory checked in at 2019-05-05 21:18:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-tinycss2 (Old) and /work/SRC/openSUSE:Factory/.python-tinycss2.new.5148 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-tinycss2" Sun May 5 21:18:32 2019 rev:4 rq:699150 version:1.0.2 Changes: -------- --- /work/SRC/openSUSE:Factory/python-tinycss2/python-tinycss2.changes 2019-04-19 18:37:22.299107635 +0200 +++ /work/SRC/openSUSE:Factory/.python-tinycss2.new.5148/python-tinycss2.changes 2019-05-05 21:18:33.548809678 +0200 @@ -1,0 +2,12 @@ +Fri Apr 26 07:27:51 UTC 2019 - pgaj...@suse.com + +- version update to 1.0.2 + * Don't crash when indent tokens have no lowercase equivalent name + * Parse "--" ident tokens correctly + * Drop Python 2.7, 3.3 and 3.4 support. + * Allow leading double dash syntax for ident tokens, allowing CSS variables to + be parsed correctly. + * Force tests to parse JSON files as UTF-8. +- python3 package only + +------------------------------------------------------------------- Old: ---- tinycss2-0.6.1.tar.gz New: ---- tinycss2-1.0.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-tinycss2.spec ++++++ --- /var/tmp/diff_new_pack.fnzUgz/_old 2019-05-05 21:18:34.032810997 +0200 +++ /var/tmp/diff_new_pack.fnzUgz/_new 2019-05-05 21:18:34.036811007 +0200 @@ -17,8 +17,9 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} +%define skip_python2 1 Name: python-tinycss2 -Version: 0.6.1 +Version: 1.0.2 Release: 0 Summary: Low-level CSS parser for Python License: BSD-3-Clause @@ -59,7 +60,7 @@ %python_expand py.test-%{$python_bin_suffix} -v -k 'not FLAKE8-check' %files %{python_files} -%doc CHANGES README.rst +%doc README.rst %license LICENSE %{python_sitelib}/* ++++++ tinycss2-0.6.1.tar.gz -> tinycss2-1.0.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/.coveragerc new/tinycss2-1.0.2/.coveragerc --- old/tinycss2-0.6.1/.coveragerc 2017-08-16 18:14:17.000000000 +0200 +++ new/tinycss2-1.0.2/.coveragerc 1970-01-01 01:00:00.000000000 +0100 @@ -1,10 +0,0 @@ -[run] -branch = True - -[report] -exclude_lines = - pragma: no cover - def __repr__ - raise NotImplementedError -omit = - .* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/.gitignore new/tinycss2-1.0.2/.gitignore --- old/tinycss2-0.6.1/.gitignore 2017-08-16 18:09:59.000000000 +0200 +++ new/tinycss2-1.0.2/.gitignore 1970-01-01 01:00:00.000000000 +0100 @@ -1,8 +0,0 @@ -*.pyc -*.egg-info -.cache -.coverage -.eggs -/htmlcov -/dist -/build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/.travis.yml new/tinycss2-1.0.2/.travis.yml --- old/tinycss2-0.6.1/.travis.yml 2017-08-16 17:50:48.000000000 +0200 +++ new/tinycss2-1.0.2/.travis.yml 1970-01-01 01:00:00.000000000 +0100 @@ -1,30 +0,0 @@ -language: python -sudo: false - -git: - submodules: false - -matrix: - include: - - os: linux - python: 2.7 - - os: linux - python: 3.3 - - os: linux - python: 3.4 - - os: linux - python: 3.5 - - os: linux - python: 3.6 - - os: osx - language: generic - env: PYTHON_VERSION=3 - -before_install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python3; fi - -install: - - pip$PYTHON_VERSION install --upgrade -e.[test] - -script: - - python$PYTHON_VERSION setup.py test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/CHANGES new/tinycss2-1.0.2/CHANGES --- old/tinycss2-0.6.1/CHANGES 2017-10-02 11:03:13.000000000 +0200 +++ new/tinycss2-1.0.2/CHANGES 1970-01-01 01:00:00.000000000 +0100 @@ -1,83 +0,0 @@ -tinycss2 changelog -================== - - -Version 0.6.1 -------------- - -Released on 2017-10-02. - -* Update documentation. - - -Version 0.6.0 -------------- - -Released on 2017-08-16. - -* Don't allow identifiers starting with two dashes. -* Don't use Tox for tests. -* Follow semantic versioning. - - -Version 0.5 ------------ - -Released on 2014-08-19. - -* Update for spec changes. -* Add a :attr:`~tinycss2.ast.WhitespaceToken.value` attribute - to :class:`~tinycss2.ast.WhitespaceToken`. -* **Breaking change**: CSS comments are now preserved - as :class:`~tinycss2.ast.Comment` objects by default. - Pass ``skip_comments=True`` to parsing functions to get the old behavior. -* **Breaking change**: Top-level comments and whitespace are now preserved - when parsing a stylesheet, rule list, or declaration list. - Pass ``skip_comments=True`` and ``skip_whitespace=True`` - to get the old behavior. -* Test on Python 3.4 and PyPy3. -* Set up continous integration on Travis-CI. - - -Version 0.4 ------------ - -Released on 2014-01-04. - -* Fix :class:`~tinycss2.ast.HashToken` starting with a non-ASCII character. -* Fix :func:`repr` on AST nodes. - - -Version 0.3 ------------ - -Released on 2013-12-27. - -* Document all the things! -* Add :ref:`serialization` -* Merge :func:`tinycss2.color3.parse_color_string` behavior into - :func:`~tinycss2.color3.parse_color`. -* Fix and test parsing form bytes and tokenization of <unicode-range>. - - -Version 0.2 ------------ - -Released on 2013-09-02. - -Add parsing for <An+B>, -as in ``:nth-child()`` and related Selectors pseudo-classes. - - -Version 0.1 ------------ - -Released on 2013-08-31. - -First PyPI release. Contains: - -* Decoding from bytes (``@charset``, etc.) -* Tokenization -* Parsing for "generic" rules and declarations -* Parsing for CSS Color Level 3 -* Tests for all of the above, except for decoding from bytes. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/LICENSE new/tinycss2-1.0.2/LICENSE --- old/tinycss2-0.6.1/LICENSE 2017-08-14 17:24:31.000000000 +0200 +++ new/tinycss2-1.0.2/LICENSE 2019-03-04 13:44:12.000000000 +0100 @@ -1,31 +1,29 @@ -Copyright (c) 2013 by Simon Sapin. - -Some rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * The names of the contributors may not be used to endorse or - promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +BSD 3-Clause License + +Copyright (c) 2013-2019, Simon Sapin and contributors (see AUTHORS). +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/MANIFEST.in new/tinycss2-1.0.2/MANIFEST.in --- old/tinycss2-0.6.1/MANIFEST.in 2017-08-14 17:24:31.000000000 +0200 +++ new/tinycss2-1.0.2/MANIFEST.in 1970-01-01 01:00:00.000000000 +0100 @@ -1,4 +0,0 @@ -include CHANGES -include LICENSE -include docs/* -include tinycss2/css-parsing-tests/* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/PKG-INFO new/tinycss2-1.0.2/PKG-INFO --- old/tinycss2-0.6.1/PKG-INFO 2017-10-02 11:11:04.000000000 +0200 +++ new/tinycss2-1.0.2/PKG-INFO 2019-03-21 15:32:24.000000000 +0100 @@ -1,41 +1,48 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: tinycss2 -Version: 0.6.1 +Version: 1.0.2 Summary: Low-level CSS parser for Python -Home-page: UNKNOWN +Home-page: https://tinycss2.readthedocs.io/ Author: Simon Sapin -Author-email: simon.sa...@exyr.org +Author-email: commun...@kozea.fr License: BSD -Description-Content-Type: UNKNOWN -Description: tinycss2: Low-level CSS parser for Python - ################################################# +Project-URL: Documentation, https://tinycss2.readthedocs.io/ +Project-URL: Code, https://github.com/Kozea/tinycss2/ +Project-URL: Issue tracker, https://github.com/Kozea/tinycss2/issues +Project-URL: Donation, https://www.patreon.com/kozea +Description: ======== + tinycss2 + ======== - tinycss2 is a rewrite of tinycss_ with a simpler API, - based on the more recent `CSS Syntax Level 3`_ specification. + tinycss2 is a low-level CSS parser and generator: it can parse strings, return + Python objects representing tokens and blocks, and generate CSS strings + corresponding to these objects. - .. _tinycss: http://pythonhosted.org/tinycss/ - .. _CSS Syntax Level 3: http://dev.w3.org/csswg/css-syntax-3/ + Based on the `CSS Syntax Level 3`_ specification, tinycss2 knows the grammar of + CSS but doesn't know specific rules, properties or values supported in various + CSS modules. + + .. _CSS Syntax Level 3: https://drafts.csswg.org/css-syntax-3/ * BSD licensed - * For Python 2.7 or 3.3+ (tested on CPython) + * For Python 3.5+ (tested on CPython and Pypy3) * Latest documentation: http://tinycss2.readthedocs.io/ * Source code and issue tracker: https://github.com/Kozea/tinycss2 * PyPI releases: https://pypi.python.org/pypi/tinycss2/ - * Continuous integration: |travis| - - .. |travis| image:: https://travis-ci.org/Kozea/tinycss2.svg?branch=master - :target: https://travis-ci.org/Kozea/tinycss2 - :alt: https://travis-ci.org/Kozea/tinycss2 -Platform: UNKNOWN +Keywords: css,parser +Platform: Linux +Platform: macOS +Platform: Windows Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Text Processing +Requires-Python: >= 3.5 +Description-Content-Type: text/x-rst +Provides-Extra: doc +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/README.rst new/tinycss2-1.0.2/README.rst --- old/tinycss2-0.6.1/README.rst 2017-09-30 22:47:40.000000000 +0200 +++ new/tinycss2-1.0.2/README.rst 2019-03-04 13:52:45.000000000 +0100 @@ -1,19 +1,19 @@ -tinycss2: Low-level CSS parser for Python -################################################# +======== +tinycss2 +======== -tinycss2 is a rewrite of tinycss_ with a simpler API, -based on the more recent `CSS Syntax Level 3`_ specification. +tinycss2 is a low-level CSS parser and generator: it can parse strings, return +Python objects representing tokens and blocks, and generate CSS strings +corresponding to these objects. -.. _tinycss: http://pythonhosted.org/tinycss/ -.. _CSS Syntax Level 3: http://dev.w3.org/csswg/css-syntax-3/ +Based on the `CSS Syntax Level 3`_ specification, tinycss2 knows the grammar of +CSS but doesn't know specific rules, properties or values supported in various +CSS modules. + +.. _CSS Syntax Level 3: https://drafts.csswg.org/css-syntax-3/ * BSD licensed -* For Python 2.7 or 3.3+ (tested on CPython) +* For Python 3.5+ (tested on CPython and Pypy3) * Latest documentation: http://tinycss2.readthedocs.io/ * Source code and issue tracker: https://github.com/Kozea/tinycss2 * PyPI releases: https://pypi.python.org/pypi/tinycss2/ -* Continuous integration: |travis| - -.. |travis| image:: https://travis-ci.org/Kozea/tinycss2.svg?branch=master - :target: https://travis-ci.org/Kozea/tinycss2 - :alt: https://travis-ci.org/Kozea/tinycss2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/TODO new/tinycss2-1.0.2/TODO --- old/tinycss2-0.6.1/TODO 2017-08-14 17:24:31.000000000 +0200 +++ new/tinycss2-1.0.2/TODO 1970-01-01 01:00:00.000000000 +0100 @@ -1,4 +0,0 @@ -Test preserve_comments=True - -Test declaration corner cases: top-level ! and ; - … once that is all figured out in the spec diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/docs/conf.py new/tinycss2-1.0.2/docs/conf.py --- old/tinycss2-0.6.1/docs/conf.py 2017-09-30 22:43:09.000000000 +0200 +++ new/tinycss2-1.0.2/docs/conf.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,84 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# tinycss2 documentation build configuration file. - -import codecs -import re -import sys -from os import path - - -sys.path.append(path.dirname(path.abspath(__file__))) - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'css_diagram_role'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'tinycss2' -copyright = '2013-2017, Simon Sapin' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The full version, including alpha/beta/rc tags. -release = re.search("VERSION = '([^']+)'", codecs.open( - path.join(path.dirname(path.dirname(__file__)), 'tinycss2', '__init__.py'), - encoding='utf-8', -).read().strip()).group(1) - -# The short X.Y version. -version = '.'.join(release.split('.')[:2]) - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'sphinx_rtd_theme' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Output file base name for HTML help builder. -htmlhelp_basename = 'tinycss2doc' - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'tinycss2', 'tinycss2 Documentation', - ['Simon Sapin'], 1) -] - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'tinycss2', 'tinycss2 Documentation', - 'Simon Sapin', 'tinycss2', 'One line description of project.', - 'Miscellaneous'), -] - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = { - 'py2': ('http://docs.python.org/2', None), - 'py3': ('http://docs.python.org/3', None), - 'webencodings': ('http://pythonhosted.org/webencodings/', None)} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/docs/css_diagram_role.py new/tinycss2-1.0.2/docs/css_diagram_role.py --- old/tinycss2-0.6.1/docs/css_diagram_role.py 2017-09-30 22:28:23.000000000 +0200 +++ new/tinycss2-1.0.2/docs/css_diagram_role.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,21 +0,0 @@ -# coding: utf8 -""" -A Sphinx extension adding a 'css' role creating links to -the spec’s railroad diagrams. - -""" - -from docutils import nodes - - -def role_fn(_name, rawtext, text, lineno, inliner, options={}, content=()): - ref = 'http://dev.w3.org/csswg/css-syntax-3/#%s-diagram' % text.replace( - ' ', '-') - if text.endswith(('-token', '-block')): - text = '<%s>' % text - ref = nodes.reference(rawtext, text, refuri=ref, **options) - return [ref], [] - - -def setup(app): - app.add_role_to_domain('py', 'diagram', role_fn) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/docs/index.rst new/tinycss2-1.0.2/docs/index.rst --- old/tinycss2-0.6.1/docs/index.rst 2017-09-30 22:23:08.000000000 +0200 +++ new/tinycss2-1.0.2/docs/index.rst 1970-01-01 01:00:00.000000000 +0100 @@ -1,157 +0,0 @@ -:tocdepth: 3 - -.. include:: ../README.rst - - -Installation -============ - -Installing tinycss2 with pip_ should Just Work:: - - pip install tinycss2 - -This will also automatically install tinycss2’s only dependency, webencodings_. -tinycss2 and webencodings both only contain Python code and should work on any -Python implementation, although they’re only tested on CPython. - -.. _pip: http://pip-installer.org/ -.. _webencodings: http://pythonhosted.org/webencodings/ - - -.. _parsing: - -Parsing -======= - -tinycss2 is “low-level” in that it doesn’t parse all of CSS: -it doesn’t know about the syntax of any specific properties or at-rules. -Instead, it provides a set of functions that can be composed -to support exactly the parts of CSS you’re interested in, -including new or non-standard rules or properties, -without modifying tinycss or having a complex hook/plugin system. - -In many cases, parts of the parsed values -(such as the :attr:`~tinycss2.ast.AtRule.content` -of a :class:`~tinycss2.ast.AtRule`) -is given as :term:`component values` that can be parsed further -with other functions. - -.. module:: tinycss2 -.. autofunction:: parse_stylesheet_bytes -.. autofunction:: parse_stylesheet -.. autofunction:: parse_rule_list -.. autofunction:: parse_one_rule -.. autofunction:: parse_declaration_list -.. autofunction:: parse_one_declaration -.. autofunction:: parse_component_value_list -.. autofunction:: parse_one_component_value - - -.. _serialization: - -Serialization -============= - -In addition to each node’s a :meth:`~tinycss2.ast.Node.serialize` method, -some serialization-related functions are available: - -.. autofunction:: serialize -.. autofunction:: serialize_identifier - - -.. module:: tinycss2.color3 - -Color -===== - -.. autofunction:: parse_color -.. autoclass:: RGBA - - -.. module:: tinycss2.nth - -<An+B> -====== - -.. autofunction:: parse_nth - - -.. module:: tinycss2.ast - -AST nodes -========= - -Various parsing functions return a **node** or a list of nodes. -Some types of nodes contain nested nodes which may in turn contain more nodes, -forming together an **abstract syntax tree**. - -Although you typically don’t need to import it, -the :mod:`tinycss2.ast` module defines a class for every type of node. - -.. autoclass:: Node() - -.. autoclass:: QualifiedRule() -.. autoclass:: AtRule() -.. autoclass:: Declaration() - - -Component values ----------------- - -.. autoclass:: ParseError() -.. autoclass:: Comment() -.. autoclass:: WhitespaceToken() -.. autoclass:: LiteralToken() -.. autoclass:: IdentToken() -.. autoclass:: AtKeywordToken() -.. autoclass:: HashToken() -.. autoclass:: StringToken() -.. autoclass:: URLToken() -.. autoclass:: UnicodeRangeToken() -.. autoclass:: NumberToken() -.. autoclass:: PercentageToken() -.. autoclass:: DimensionToken() -.. autoclass:: ParenthesesBlock() -.. autoclass:: SquareBracketsBlock() -.. autoclass:: CurlyBracketsBlock() -.. autoclass:: FunctionBlock() - - -Glossary -======== - -.. currentmodule:: tinycss2.ast -.. glossary:: - - String - In this documentation “a string” means an Unicode string: - :func:`unicode <py2:unicode>` on Python 2.x and - :class:`py3:str` on Python 3.x. - On 2.x, - a byte string (:func:`str <py2:str>`) that only contains ASCII bytes - is also accepted and implicitly decoded. - - Component value - Component values - A :class:`ParseError`, - :class:`WhitespaceToken`, - :class:`LiteralToken`, - :class:`IdentToken`, - :class:`AtKeywordToken`, - :class:`HashToken`, - :class:`StringToken`, - :class:`URLToken`, - :class:`NumberToken`, - :class:`PercentageToken`, - :class:`DimensionToken`, - :class:`UnicodeRangeToken`, - :class:`ParenthesesBlock`, - :class:`SquareBracketsBlock`, - :class:`CurlyBracketsBlock`, - :class:`FunctionBlock`, - or :class:`Comment` - object. - - -.. currentmodule:: tinycss2 -.. include:: ../CHANGES diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/setup.cfg new/tinycss2-1.0.2/setup.cfg --- old/tinycss2-0.6.1/setup.cfg 2017-10-02 11:11:04.000000000 +0200 +++ new/tinycss2-1.0.2/setup.cfg 2019-03-21 15:32:24.000000000 +0100 @@ -1,12 +1,84 @@ -[aliases] -test = pytest +[metadata] +name = tinycss2 +url = https://tinycss2.readthedocs.io/ +version = file: tinycss2/VERSION +license = BSD +license_file = LICENSE +description = Low-level CSS parser for Python +long_description = file: README.rst +long_description_content_type = text/x-rst +author = Simon Sapin +author_email = commun...@kozea.fr +platforms = + Linux + macOS + Windows +keywords = + css + parser +classifiers = + Development Status :: 5 - Production/Stable + Intended Audience :: Developers + License :: OSI Approved :: BSD License + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.5 + Programming Language :: Python :: 3.6 + Programming Language :: Python :: 3.7 + Topic :: Text Processing +project_urls = + Documentation = https://tinycss2.readthedocs.io/ + Code = https://github.com/Kozea/tinycss2/ + Issue tracker = https://github.com/Kozea/tinycss2/issues + Donation = https://www.patreon.com/kozea + +[options] +packages = find: +setup_requires = pytest-runner +install_requires = + setuptools >= 39.2.0 + webencodings >= 0.4 +tests_require = + pytest-runner + pytest-cov + pytest-flake8 + pytest-isort +python_requires = >= 3.5 + +[options.package_data] +tinycss2 = + VERSION + css-parsing-tests/* + +[options.extras_require] +doc = + sphinx + sphinx_rtd_theme +test = + pytest-runner + pytest-cov + pytest-flake8 + pytest-isort [bdist_wheel] -universal = 1 +python-tag = py3 + +[build_sphinx] +source-dir = docs +build-dir = docs/_build + +[aliases] +test = pytest [tool:pytest] -addopts = --cov=tinycss2 --flake8 --isort tinycss2/test.py -norecursedirs = dist .cache .git build *.egg-info .eggs venv +addopts = --flake8 --isort +norecursedirs = build dist .cache .eggs .git + +[coverage:run] +branch = True +include = tinycss2/* + +[isort] +default_section = THIRDPARTY [egg_info] tag_build = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/setup.py new/tinycss2-1.0.2/setup.py --- old/tinycss2-0.6.1/setup.py 2017-09-30 21:32:36.000000000 +0200 +++ new/tinycss2-1.0.2/setup.py 2019-03-04 13:43:51.000000000 +0100 @@ -1,55 +1,10 @@ -#!/usr/bin/env python -# coding: utf8 - -import codecs -import os.path -import re import sys from setuptools import setup +if sys.version_info.major < 3: + raise RuntimeError( + 'tinycss2 does not support Python 2.x anymore. ' + 'Please use Python 3 or install an older version of tinycss2.') -VERSION = re.search("VERSION = '([^']+)'", codecs.open( - os.path.join(os.path.dirname(__file__), 'tinycss2', '__init__.py'), - encoding='utf-8', -).read().strip()).group(1) - -README = codecs.open( - os.path.join(os.path.dirname(__file__), 'README.rst'), - encoding='utf-8', -).read() - -needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) -pytest_runner = ['pytest-runner'] if needs_pytest else [] - -setup( - name='tinycss2', - version=VERSION, - description='Low-level CSS parser for Python', - long_description=README, - license='BSD', - author='Simon Sapin', - author_email='simon.sa...@exyr.org', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Topic :: Text Processing', - ], - packages=['tinycss2'], - install_requires=['webencodings>=0.4'], - package_data={'tinycss2': ['css-parsing-tests/*']}, - setup_requires=pytest_runner, - test_suite='tinycss2.test', - tests_require=[ - 'pytest-runner', 'pytest-cov', 'pytest-flake8', 'pytest-isort'], - extras_require={'test': [ - 'pytest-runner', 'pytest-cov', 'pytest-flake8', 'pytest-isort']}, -) +setup() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/VERSION new/tinycss2-1.0.2/tinycss2/VERSION --- old/tinycss2-0.6.1/tinycss2/VERSION 1970-01-01 01:00:00.000000000 +0100 +++ new/tinycss2-1.0.2/tinycss2/VERSION 2019-03-21 15:26:58.000000000 +0100 @@ -0,0 +1 @@ +1.0.2 \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/__init__.py new/tinycss2-1.0.2/tinycss2/__init__.py --- old/tinycss2-0.6.1/tinycss2/__init__.py 2017-10-02 11:03:25.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/__init__.py 2019-03-04 14:05:09.000000000 +0100 @@ -1,9 +1,10 @@ -VERSION = '0.6.1' +from pathlib import Path - -from .tokenizer import parse_component_value_list # noqa -from .parser import ( # noqa - parse_one_component_value, parse_one_declaration, parse_declaration_list, - parse_one_rule, parse_rule_list, parse_stylesheet) from .bytes import parse_stylesheet_bytes # noqa +from .parser import (parse_declaration_list, parse_one_component_value, # noqa + parse_one_declaration, parse_one_rule, parse_rule_list, + parse_stylesheet) from .serializer import serialize, serialize_identifier # noqa +from .tokenizer import parse_component_value_list # noqa + +VERSION = __version__ = (Path(__file__).parent / 'VERSION').read_text() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/_compat.py new/tinycss2-1.0.2/tinycss2/_compat.py --- old/tinycss2-0.6.1/tinycss2/_compat.py 2017-08-16 17:56:39.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/_compat.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +0,0 @@ -if str is bytes: # pragma: no cover - unichr = unichr # noqa - basestring = basestring # noqa -else: # pragma: no cover - unichr = chr # noqa - basestring = str # noqa diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/ast.py new/tinycss2-1.0.2/tinycss2/ast.py --- old/tinycss2-0.6.1/tinycss2/ast.py 2017-08-16 17:57:16.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/ast.py 2019-03-06 16:01:28.000000000 +0100 @@ -1,4 +1,3 @@ -# coding: utf8 """ Data structures for the CSS abstract syntax tree. @@ -248,7 +247,10 @@ def __init__(self, line, column, value): Node.__init__(self, line, column) self.value = value - self.lower_value = ascii_lower(value) + try: + self.lower_value = ascii_lower(value) + except UnicodeEncodeError: + self.lower_value = value def _serialize_to(self, write): write(serialize_identifier(self.value)) @@ -285,7 +287,10 @@ def __init__(self, line, column, value): Node.__init__(self, line, column) self.value = value - self.lower_value = ascii_lower(value) + try: + self.lower_value = ascii_lower(value) + except UnicodeEncodeError: + self.lower_value = value def _serialize_to(self, write): write('@') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/color3.py new/tinycss2-1.0.2/tinycss2/color3.py --- old/tinycss2-0.6.1/tinycss2/color3.py 2017-08-16 18:09:15.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/color3.py 2019-03-04 13:43:51.000000000 +0100 @@ -3,7 +3,6 @@ import collections import re -from ._compat import basestring from .parser import parse_one_component_value @@ -49,7 +48,7 @@ ``(-0.1, 1.2, 0, 1)``.) """ - if isinstance(input, basestring): + if isinstance(input, str): token = parse_one_component_value(input, skip_comments=True) else: token = input @@ -174,8 +173,8 @@ _HASH_REGEXPS = ( - (2, re.compile('^([\da-f])([\da-f])([\da-f])$', re.I).match), - (1, re.compile('^([\da-f]{2})([\da-f]{2})([\da-f]{2})$', re.I).match), + (2, re.compile('^([\\da-f])([\\da-f])([\\da-f])$', re.I).match), + (1, re.compile('^([\\da-f]{2})([\\da-f]{2})([\\da-f]{2})$', re.I).match), ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/css-parsing-tests/component_value_list.json new/tinycss2-1.0.2/tinycss2/css-parsing-tests/component_value_list.json --- old/tinycss2-0.6.1/tinycss2/css-parsing-tests/component_value_list.json 2017-08-16 18:33:53.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/css-parsing-tests/component_value_list.json 2019-03-06 15:47:26.000000000 +0100 @@ -22,11 +22,12 @@ ["ident", "red--"], ">" ], -"\\- red0 -red --red -\\-red\\ blue 0red -0red \u0000red _Red .red rêd r\\êd \u007F\u0080\u0081", [ +"\\- red0 -red --red -- -\\-red\\ blue 0red -0red \u0000red _Red .red rêd r\\êd \u007F\u0080\u0081", [ ["ident", "-"], " ", ["ident", "red0"], " ", ["ident", "-red"], " ", - "-", ["ident", "-red"], " ", + ["ident", "--red"], " ", + ["ident", "--"], " ", ["ident", "--red blue"], " ", ["dimension", "0", 0, "integer", "red"], " ", ["dimension", "-0", 0, "integer", "red"], " ", @@ -55,7 +56,7 @@ "rgba0() -rgba() --rgba() -\\-rgba() 0rgba() -0rgba() _rgba() .rgba() rgbâ() \\30rgba() rgba () @rgba() #rgba()", [ ["function", "rgba0"], " ", ["function", "-rgba"], " ", - "-", ["function", "-rgba"], " ", + ["function", "--rgba"], " ", ["function", "--rgba"], " ", ["dimension", "0", 0, "integer", "rgba"], ["()"], " ", ["dimension", "-0", 0, "integer", "rgba"], ["()"], " ", @@ -71,7 +72,7 @@ "@media0 @-Media @--media @-\\-media @0media @-0media @_media @.media @medİa @\\30 media\\", [ ["at-keyword", "media0"], " ", ["at-keyword", "-Media"], " ", - "@", "-", ["ident", "-media"], " ", + ["at-keyword", "--media"], " ", ["at-keyword", "--media"], " ", "@", ["dimension", "0", 0, "integer", "media"], " ", "@", ["dimension", "-0", 0, "integer", "media"], " ", @@ -84,7 +85,7 @@ "#red0 #-Red #--red #-\\-red #0red #-0red #_Red #.red #rêd #êrd #\\.red\\", [ ["hash", "red0", "id"], " ", ["hash", "-Red", "id"], " ", - ["hash", "--red", "unrestricted"], " ", + ["hash", "--red", "id"], " ", ["hash", "--red", "id"], " ", ["hash", "0red", "unrestricted"], " ", ["hash", "-0red", "unrestricted"], " ", @@ -309,8 +310,8 @@ "12red0 12.0-red 12--red 12-\\-red 120red 12-0red 12\u0000red 12_Red 12.red 12rêd", [ ["dimension", "12", 12.0, "integer", "red0"], " ", ["dimension", "12.0", 12.0, "number", "-red"], " ", - ["number", "12", 12.0, "integer"], "-", ["ident", "-red"], " ", - ["dimension", "12", 12.0, "integer", "--red"], " ", + ["dimension", "12", 12.0, "integer", "--red"], " ", + ["dimension", "12", 12.0, "integer", "--red"], " ", ["dimension", "120", 120.0, "integer", "red"], " ", ["number", "12", 12.0, "integer"], ["dimension", "-0", 0, "integer", "red"], " ", ["dimension", "12", 12.0, "integer", "\uFFFDred"], " ", @@ -393,7 +394,7 @@ ], "~=|=^=$=*=||<!------> |/**/| ~/**/=", [ - "~=", "|=", "^=", "$=", "*=", "||", "<!--", "-", "-", "-->", + "~=", "|=", "^=", "$=", "*=", "||", "<!--", ["ident", "----"], ">", " ", "|", "|", " ", "~", "=" ], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/parser.py new/tinycss2-1.0.2/tinycss2/parser.py --- old/tinycss2-0.6.1/tinycss2/parser.py 2017-08-16 18:08:04.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/parser.py 2019-03-04 13:43:51.000000000 +0100 @@ -1,6 +1,3 @@ -# coding: utf-8 - -from ._compat import basestring from .ast import AtRule, Declaration, ParseError, QualifiedRule from .tokenizer import parse_component_value_list @@ -15,7 +12,7 @@ """ # Accept ASCII-only byte strings on Python 2, with implicit conversion. - if isinstance(input, basestring): + if isinstance(input, str): input = parse_component_value_list(input, skip_comments) return iter(input) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/serializer.py new/tinycss2-1.0.2/tinycss2/serializer.py --- old/tinycss2-0.6.1/tinycss2/serializer.py 2017-08-16 18:07:21.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/serializer.py 2019-03-04 13:43:51.000000000 +0100 @@ -33,6 +33,9 @@ if value == '-': return r'\-' + if value[:2] == '--': + return '--' + serialize_name(value[2:]) + if value[0] == '-': result = '-' value = value[1:] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/test.py new/tinycss2-1.0.2/tinycss2/test.py --- old/tinycss2-0.6.1/tinycss2/test.py 2017-08-16 18:36:49.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/test.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,230 +0,0 @@ -# coding: utf8 - -import functools -import json -import os.path -import pprint - -import pytest -from webencodings import Encoding, lookup - -from . import (parse_component_value_list, parse_declaration_list, - parse_one_component_value, parse_one_declaration, - parse_one_rule, parse_rule_list, parse_stylesheet, - parse_stylesheet_bytes, serialize) -from .ast import (AtKeywordToken, AtRule, Comment, CurlyBracketsBlock, - Declaration, DimensionToken, FunctionBlock, HashToken, - IdentToken, LiteralToken, NumberToken, ParenthesesBlock, - ParseError, PercentageToken, QualifiedRule, - SquareBracketsBlock, StringToken, UnicodeRangeToken, - URLToken, WhitespaceToken) -from .color3 import RGBA, parse_color -from .nth import parse_nth - - -def generic(func): - implementations = func() - - @functools.wraps(func) - def run(value): - repr(value) # Test that this does not raise. - return implementations[type(value)](value) - return run - - -@generic -def to_json(): - def numeric(t): - return [ - t.representation, t.value, - 'integer' if t.int_value is not None else 'number'] - return { - type(None): lambda _: None, - str: lambda s: s, - int: lambda s: s, - list: lambda l: [to_json(el) for el in l], - tuple: lambda l: [to_json(el) for el in l], - Encoding: lambda e: e.name, - ParseError: lambda e: ['error', e.kind], - - Comment: lambda t: '/* … */', - WhitespaceToken: lambda t: ' ', - LiteralToken: lambda t: t.value, - IdentToken: lambda t: ['ident', t.value], - AtKeywordToken: lambda t: ['at-keyword', t.value], - HashToken: lambda t: ['hash', t.value, - 'id' if t.is_identifier else 'unrestricted'], - StringToken: lambda t: ['string', t.value], - URLToken: lambda t: ['url', t.value], - NumberToken: lambda t: ['number'] + numeric(t), - PercentageToken: lambda t: ['percentage'] + numeric(t), - DimensionToken: lambda t: ['dimension'] + numeric(t) + [t.unit], - UnicodeRangeToken: lambda t: ['unicode-range', t.start, t.end], - - CurlyBracketsBlock: lambda t: ['{}'] + to_json(t.content), - SquareBracketsBlock: lambda t: ['[]'] + to_json(t.content), - ParenthesesBlock: lambda t: ['()'] + to_json(t.content), - FunctionBlock: lambda t: ['function', t.name] + to_json(t.arguments), - - Declaration: lambda d: ['declaration', d.name, - to_json(d.value), d.important], - AtRule: lambda r: ['at-rule', r.at_keyword, to_json(r.prelude), - to_json(r.content)], - QualifiedRule: lambda r: ['qualified rule', to_json(r.prelude), - to_json(r.content)], - - RGBA: lambda v: [round(c, 10) for c in v], - } - - -def load_json(filename): - json_data = json.load(open(os.path.join( - os.path.dirname(__file__), 'css-parsing-tests', filename))) - return list(zip(json_data[::2], json_data[1::2])) - - -def json_test(filename=None): - def decorator(function): - filename_ = filename or function.__name__.split('_', 1)[-1] + '.json' - - @pytest.mark.parametrize(('css', 'expected'), load_json(filename_)) - def test(css, expected): - value = to_json(function(css)) - if value != expected: # pragma: no cover - pprint.pprint(value) - assert value == expected - return test - return decorator - - -SKIP = dict(skip_comments=True, skip_whitespace=True) - - -@json_test() -def test_component_value_list(input): - return parse_component_value_list(input, skip_comments=True) - - -@json_test() -def test_one_component_value(input): - return parse_one_component_value(input, skip_comments=True) - - -@json_test() -def test_declaration_list(input): - return parse_declaration_list(input, **SKIP) - - -@json_test() -def test_one_declaration(input): - return parse_one_declaration(input, skip_comments=True) - - -@json_test() -def test_stylesheet(input): - return parse_stylesheet(input, **SKIP) - - -@json_test() -def test_rule_list(input): - return parse_rule_list(input, **SKIP) - - -@json_test() -def test_one_rule(input): - return parse_one_rule(input, skip_comments=True) - - -@json_test() -def test_color3(input): - return parse_color(input) - - -@json_test(filename='An+B.json') -def test_nth(input): - return parse_nth(input) - - -# Do not use @pytest.mark.parametrize because it is slow with that many values. -def test_color3_hsl(): - for css, expected in load_json('color3_hsl.json'): - assert to_json(parse_color(css)) == expected - - -def test_color3_keywords(): - for css, expected in load_json('color3_keywords.json'): - result = parse_color(css) - if result is not None: - r, g, b, a = result - result = [r * 255, g * 255, b * 255, a] - assert result == expected - - -@json_test() -def test_stylesheet_bytes(kwargs): - kwargs['css_bytes'] = kwargs['css_bytes'].encode('latin1') - kwargs.pop('comment', None) - if kwargs.get('environment_encoding'): - kwargs['environment_encoding'] = lookup(kwargs['environment_encoding']) - kwargs.update(SKIP) - return parse_stylesheet_bytes(**kwargs) - - -@json_test(filename='component_value_list.json') -def test_serialization(css): - parsed = parse_component_value_list(css, skip_comments=True) - return parse_component_value_list(serialize(parsed), skip_comments=True) - - -def test_skip(): - source = ''' - /* foo */ - @media print { - #foo { - width: /* bar*/4px; - color: green; - } - } - ''' - no_ws = parse_stylesheet(source, skip_whitespace=True) - no_comment = parse_stylesheet(source, skip_comments=True) - default = parse_component_value_list(source) - assert serialize(no_ws) != source - assert serialize(no_comment) != source - assert serialize(default) == source - - -def test_comment_eof(): - source = '/* foo ' - parsed = parse_component_value_list(source) - assert serialize(parsed) == '/* foo */' - - -def test_parse_declaration_value_color(): - source = 'color:#369' - declaration = parse_one_declaration(source) - (value_token,) = declaration.value - assert parse_color(value_token) == (.2, .4, .6, 1) - assert declaration.serialize() == source - - -def test_serialize_rules(): - source = '@import "a.css"; foo#bar.baz { color: red } /**/ @media print{}' - rules = parse_rule_list(source) - assert serialize(rules) == source - - -def test_serialize_declarations(): - source = 'color: #123; /**/ @top-left {} width:7px !important;' - rules = parse_declaration_list(source) - assert serialize(rules) == source - - -def test_backslash_delim(): - source = '\\\nfoo' - tokens = parse_component_value_list(source) - assert [t.type for t in tokens] == ['literal', 'whitespace', 'ident'] - assert tokens[0].value == '\\' - del tokens[1] - assert [t.type for t in tokens] == ['literal', 'ident'] - assert serialize(tokens) == source diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/test_tinycss2.py new/tinycss2-1.0.2/tinycss2/test_tinycss2.py --- old/tinycss2-0.6.1/tinycss2/test_tinycss2.py 1970-01-01 01:00:00.000000000 +0100 +++ new/tinycss2-1.0.2/tinycss2/test_tinycss2.py 2019-03-06 15:12:12.000000000 +0100 @@ -0,0 +1,230 @@ +import functools +import json +import os.path +import pprint +from io import open + +import pytest +from webencodings import Encoding, lookup + +from . import (parse_component_value_list, parse_declaration_list, + parse_one_component_value, parse_one_declaration, + parse_one_rule, parse_rule_list, parse_stylesheet, + parse_stylesheet_bytes, serialize) +from .ast import (AtKeywordToken, AtRule, Comment, CurlyBracketsBlock, + Declaration, DimensionToken, FunctionBlock, HashToken, + IdentToken, LiteralToken, NumberToken, ParenthesesBlock, + ParseError, PercentageToken, QualifiedRule, + SquareBracketsBlock, StringToken, UnicodeRangeToken, + URLToken, WhitespaceToken) +from .color3 import RGBA, parse_color +from .nth import parse_nth + + +def generic(func): + implementations = func() + + @functools.wraps(func) + def run(value): + repr(value) # Test that this does not raise. + return implementations[type(value)](value) + return run + + +@generic +def to_json(): + def numeric(t): + return [ + t.representation, t.value, + 'integer' if t.int_value is not None else 'number'] + return { + type(None): lambda _: None, + str: lambda s: s, + int: lambda s: s, + list: lambda l: [to_json(el) for el in l], + tuple: lambda l: [to_json(el) for el in l], + Encoding: lambda e: e.name, + ParseError: lambda e: ['error', e.kind], + + Comment: lambda t: '/* … */', + WhitespaceToken: lambda t: ' ', + LiteralToken: lambda t: t.value, + IdentToken: lambda t: ['ident', t.value], + AtKeywordToken: lambda t: ['at-keyword', t.value], + HashToken: lambda t: ['hash', t.value, + 'id' if t.is_identifier else 'unrestricted'], + StringToken: lambda t: ['string', t.value], + URLToken: lambda t: ['url', t.value], + NumberToken: lambda t: ['number'] + numeric(t), + PercentageToken: lambda t: ['percentage'] + numeric(t), + DimensionToken: lambda t: ['dimension'] + numeric(t) + [t.unit], + UnicodeRangeToken: lambda t: ['unicode-range', t.start, t.end], + + CurlyBracketsBlock: lambda t: ['{}'] + to_json(t.content), + SquareBracketsBlock: lambda t: ['[]'] + to_json(t.content), + ParenthesesBlock: lambda t: ['()'] + to_json(t.content), + FunctionBlock: lambda t: ['function', t.name] + to_json(t.arguments), + + Declaration: lambda d: ['declaration', d.name, + to_json(d.value), d.important], + AtRule: lambda r: ['at-rule', r.at_keyword, to_json(r.prelude), + to_json(r.content)], + QualifiedRule: lambda r: ['qualified rule', to_json(r.prelude), + to_json(r.content)], + + RGBA: lambda v: [round(c, 10) for c in v], + } + + +def load_json(filename): + json_data = json.load(open(os.path.join( + os.path.dirname(__file__), 'css-parsing-tests', filename), + encoding='utf-8')) + return list(zip(json_data[::2], json_data[1::2])) + + +def json_test(filename=None): + def decorator(function): + filename_ = filename or function.__name__.split('_', 1)[-1] + '.json' + + @pytest.mark.parametrize(('css', 'expected'), load_json(filename_)) + def test(css, expected): + value = to_json(function(css)) + if value != expected: # pragma: no cover + pprint.pprint(value) + assert value == expected + return test + return decorator + + +SKIP = dict(skip_comments=True, skip_whitespace=True) + + +@json_test() +def test_component_value_list(input): + return parse_component_value_list(input, skip_comments=True) + + +@json_test() +def test_one_component_value(input): + return parse_one_component_value(input, skip_comments=True) + + +@json_test() +def test_declaration_list(input): + return parse_declaration_list(input, **SKIP) + + +@json_test() +def test_one_declaration(input): + return parse_one_declaration(input, skip_comments=True) + + +@json_test() +def test_stylesheet(input): + return parse_stylesheet(input, **SKIP) + + +@json_test() +def test_rule_list(input): + return parse_rule_list(input, **SKIP) + + +@json_test() +def test_one_rule(input): + return parse_one_rule(input, skip_comments=True) + + +@json_test() +def test_color3(input): + return parse_color(input) + + +@json_test(filename='An+B.json') +def test_nth(input): + return parse_nth(input) + + +# Do not use @pytest.mark.parametrize because it is slow with that many values. +def test_color3_hsl(): + for css, expected in load_json('color3_hsl.json'): + assert to_json(parse_color(css)) == expected + + +def test_color3_keywords(): + for css, expected in load_json('color3_keywords.json'): + result = parse_color(css) + if result is not None: + r, g, b, a = result + result = [r * 255, g * 255, b * 255, a] + assert result == expected + + +@json_test() +def test_stylesheet_bytes(kwargs): + kwargs['css_bytes'] = kwargs['css_bytes'].encode('latin1') + kwargs.pop('comment', None) + if kwargs.get('environment_encoding'): + kwargs['environment_encoding'] = lookup(kwargs['environment_encoding']) + kwargs.update(SKIP) + return parse_stylesheet_bytes(**kwargs) + + +@json_test(filename='component_value_list.json') +def test_serialization(css): + parsed = parse_component_value_list(css, skip_comments=True) + return parse_component_value_list(serialize(parsed), skip_comments=True) + + +def test_skip(): + source = ''' + /* foo */ + @media print { + #foo { + width: /* bar*/4px; + color: green; + } + } + ''' + no_ws = parse_stylesheet(source, skip_whitespace=True) + no_comment = parse_stylesheet(source, skip_comments=True) + default = parse_component_value_list(source) + assert serialize(no_ws) != source + assert serialize(no_comment) != source + assert serialize(default) == source + + +def test_comment_eof(): + source = '/* foo ' + parsed = parse_component_value_list(source) + assert serialize(parsed) == '/* foo */' + + +def test_parse_declaration_value_color(): + source = 'color:#369' + declaration = parse_one_declaration(source) + (value_token,) = declaration.value + assert parse_color(value_token) == (.2, .4, .6, 1) + assert declaration.serialize() == source + + +def test_serialize_rules(): + source = '@import "a.css"; foo#bar.baz { color: red } /**/ @media print{}' + rules = parse_rule_list(source) + assert serialize(rules) == source + + +def test_serialize_declarations(): + source = 'color: #123; /**/ @top-left {} width:7px !important;' + rules = parse_declaration_list(source) + assert serialize(rules) == source + + +def test_backslash_delim(): + source = '\\\nfoo' + tokens = parse_component_value_list(source) + assert [t.type for t in tokens] == ['literal', 'whitespace', 'ident'] + assert tokens[0].value == '\\' + del tokens[1] + assert [t.type for t in tokens] == ['literal', 'ident'] + assert serialize(tokens) == source diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2/tokenizer.py new/tinycss2-1.0.2/tinycss2/tokenizer.py --- old/tinycss2-0.6.1/tinycss2/tokenizer.py 2017-08-16 18:05:06.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2/tokenizer.py 2019-03-06 15:48:56.000000000 +0100 @@ -5,7 +5,6 @@ from webencodings import ascii_lower -from ._compat import unichr from .ast import (AtKeywordToken, Comment, CurlyBracketsBlock, DimensionToken, FunctionBlock, HashToken, IdentToken, LiteralToken, NumberToken, ParenthesesBlock, ParseError, PercentageToken, @@ -196,14 +195,15 @@ def _is_ident_start(css, pos): """Return True if the given position is the start of a CSS identifier.""" - # https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier + # https://drafts.csswg.org/css-syntax/#would-start-an-identifier if _is_name_start(css, pos): return True elif css[pos] == '-': pos += 1 return ( - # Name-start code point: - (pos < len(css) and _is_name_start(css, pos)) or + # Name-start code point or hyphen: + (pos < len(css) and ( + _is_name_start(css, pos) or css[pos] == '-')) or # Valid escape: (css.startswith('\\', pos) and not css.startswith('\\\n', pos))) elif css[pos] == '\\': @@ -284,7 +284,7 @@ if hex_match: codepoint = int(hex_match.group(1), 16) return ( - unichr(codepoint) if 0 < codepoint <= sys.maxunicode else '\uFFFD', + chr(codepoint) if 0 < codepoint <= sys.maxunicode else '\uFFFD', hex_match.end()) elif pos < len(css): return css[pos], pos + 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2.egg-info/PKG-INFO new/tinycss2-1.0.2/tinycss2.egg-info/PKG-INFO --- old/tinycss2-0.6.1/tinycss2.egg-info/PKG-INFO 2017-10-02 11:11:04.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2.egg-info/PKG-INFO 2019-03-21 15:32:23.000000000 +0100 @@ -1,41 +1,48 @@ -Metadata-Version: 1.1 +Metadata-Version: 2.1 Name: tinycss2 -Version: 0.6.1 +Version: 1.0.2 Summary: Low-level CSS parser for Python -Home-page: UNKNOWN +Home-page: https://tinycss2.readthedocs.io/ Author: Simon Sapin -Author-email: simon.sa...@exyr.org +Author-email: commun...@kozea.fr License: BSD -Description-Content-Type: UNKNOWN -Description: tinycss2: Low-level CSS parser for Python - ################################################# +Project-URL: Documentation, https://tinycss2.readthedocs.io/ +Project-URL: Code, https://github.com/Kozea/tinycss2/ +Project-URL: Issue tracker, https://github.com/Kozea/tinycss2/issues +Project-URL: Donation, https://www.patreon.com/kozea +Description: ======== + tinycss2 + ======== - tinycss2 is a rewrite of tinycss_ with a simpler API, - based on the more recent `CSS Syntax Level 3`_ specification. + tinycss2 is a low-level CSS parser and generator: it can parse strings, return + Python objects representing tokens and blocks, and generate CSS strings + corresponding to these objects. - .. _tinycss: http://pythonhosted.org/tinycss/ - .. _CSS Syntax Level 3: http://dev.w3.org/csswg/css-syntax-3/ + Based on the `CSS Syntax Level 3`_ specification, tinycss2 knows the grammar of + CSS but doesn't know specific rules, properties or values supported in various + CSS modules. + + .. _CSS Syntax Level 3: https://drafts.csswg.org/css-syntax-3/ * BSD licensed - * For Python 2.7 or 3.3+ (tested on CPython) + * For Python 3.5+ (tested on CPython and Pypy3) * Latest documentation: http://tinycss2.readthedocs.io/ * Source code and issue tracker: https://github.com/Kozea/tinycss2 * PyPI releases: https://pypi.python.org/pypi/tinycss2/ - * Continuous integration: |travis| - - .. |travis| image:: https://travis-ci.org/Kozea/tinycss2.svg?branch=master - :target: https://travis-ci.org/Kozea/tinycss2 - :alt: https://travis-ci.org/Kozea/tinycss2 -Platform: UNKNOWN +Keywords: css,parser +Platform: Linux +Platform: macOS +Platform: Windows Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 -Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 Classifier: Topic :: Text Processing +Requires-Python: >= 3.5 +Description-Content-Type: text/x-rst +Provides-Extra: doc +Provides-Extra: test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2.egg-info/SOURCES.txt new/tinycss2-1.0.2/tinycss2.egg-info/SOURCES.txt --- old/tinycss2-0.6.1/tinycss2.egg-info/SOURCES.txt 2017-10-02 11:11:04.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2.egg-info/SOURCES.txt 2019-03-21 15:32:23.000000000 +0100 @@ -1,25 +1,16 @@ -.coveragerc -.gitignore -.travis.yml -CHANGES LICENSE -MANIFEST.in README.rst -TODO setup.cfg setup.py -docs/conf.py -docs/css_diagram_role.py -docs/index.rst +tinycss2/VERSION tinycss2/__init__.py -tinycss2/_compat.py tinycss2/ast.py tinycss2/bytes.py tinycss2/color3.py tinycss2/nth.py tinycss2/parser.py tinycss2/serializer.py -tinycss2/test.py +tinycss2/test_tinycss2.py tinycss2/tokenizer.py tinycss2.egg-info/PKG-INFO tinycss2.egg-info/SOURCES.txt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tinycss2-0.6.1/tinycss2.egg-info/requires.txt new/tinycss2-1.0.2/tinycss2.egg-info/requires.txt --- old/tinycss2-0.6.1/tinycss2.egg-info/requires.txt 2017-10-02 11:11:04.000000000 +0200 +++ new/tinycss2-1.0.2/tinycss2.egg-info/requires.txt 2019-03-21 15:32:23.000000000 +0100 @@ -1,5 +1,10 @@ +setuptools>=39.2.0 webencodings>=0.4 +[doc] +sphinx +sphinx_rtd_theme + [test] pytest-runner pytest-cov