[Python-modules-commits] [python-cssselect] 01/06: New upstream version 1.0.3

Takaki Taniguchi takaki at moszumanska.debian.org
Sun Feb 4 02:22:00 UTC 2018


This is an automated email from the git hooks/post-receive script.

takaki pushed a commit to branch master
in repository python-cssselect.

commit dd112abaa6e17ae529a3e833b03b685fa32d4380
Author: TANIGUCHI Takaki <takaki at asis.media-as.org>
Date:   Sat Feb 3 18:50:34 2018 +0900

    New upstream version 1.0.3
---
 .bumpversion.cfg                        |    7 -
 .gitignore                              |    7 -
 .travis.yml                             |   29 -
 CHANGES                                 |   16 +
 PKG-INFO                                |   62 ++
 README.rst                              |   20 +-
 cssselect.egg-info/PKG-INFO             |   62 ++
 cssselect.egg-info/SOURCES.txt          |   18 +
 cssselect.egg-info/dependency_links.txt |    1 +
 cssselect.egg-info/top_level.txt        |    1 +
 cssselect/__init__.py                   |    2 +-
 cssselect/parser.py                     |   21 +-
 cssselect/xpath.py                      |    4 +-
 setup.cfg                               |   10 +-
 setup.py                                |    3 +-
 tests/__init__.py                       |    0
 tests/test_cssselect.py                 | 1236 -------------------------------
 tox.ini                                 |    6 +-
 18 files changed, 197 insertions(+), 1308 deletions(-)

diff --git a/.bumpversion.cfg b/.bumpversion.cfg
deleted file mode 100644
index 92c7bcb..0000000
--- a/.bumpversion.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[bumpversion]
-current_version = 1.0.1
-commit = True
-tag = True
-
-[bumpversion:file:cssselect/__init__.py]
-
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 4c89f4c..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-*.pyc
-*.egg-info
-/.tox
-/MANIFEST
-/dist
-/docs/_build
-/.coverage
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 5ddb1fd..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-language: python
-python:
-  - '2.6'
-  - '2.7'
-  - '3.3'
-  - '3.4'
-  - '3.5'
-  - '3.6'
-
-install:
-  - pip install lxml -e .
-  - pip install -U codecov pytest-cov
-
-script:
-  py.test --cov-report term --cov=cssselect
-
-after_success:
-  codecov
-
-deploy:
-  provider: pypi
-  distributions: sdist bdist_wheel
-  user: redapple
-  password:
-    secure: T1PBD+ocIGwHMbBHPqzu7UZxpkB0w98KtEIkNzLXNQcF7JpjugZNwz4xX2xVhi8yvUQ257VtLSKpIOT2FWxrfLrgTZKbTd6Q7V5Lf3HKzLomOKUKMAd54gsOuismE27CT/SHbexskACgwVwkyG9Y3dlG6m/ZBgqoPAGaJrScjEU=
-  on:
-    tags: true
-    repo: scrapy/cssselect
-    condition: "$TRAVIS_PYTHON_VERSION == '3.6'"
diff --git a/CHANGES b/CHANGES
index 92b0371..0a0e137 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,22 @@
 Changelog
 =========
 
+Version 1.0.3
+-------------
+
+Released on 2017-12-27.
+
+* Fix artifact uploads to pypi
+
+Version 1.0.2
+-------------
+
+Released on 2017-12-26.
+
+* Drop support for Python 2.6 and Python 3.3.
+* Fix deprecation warning in Python 3.6.
+* Minor cleanups.
+
 Version 1.0.1
 -------------
 
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..9cdd726
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,62 @@
+Metadata-Version: 1.2
+Name: cssselect
+Version: 1.0.3
+Summary: cssselect parses CSS3 Selectors and translates them to XPath 1.0
+Home-page: https://github.com/scrapy/cssselect
+Author: Paul Tremberth
+Author-email: paul.tremberth at gmail.com
+License: BSD
+Description-Content-Type: UNKNOWN
+Description: ===================================
+        cssselect: CSS Selectors for Python
+        ===================================
+        
+        .. image:: https://img.shields.io/pypi/v/cssselect.svg
+           :target: https://pypi.python.org/pypi/cssselect
+           :alt: PyPI Version
+        
+        .. image:: https://img.shields.io/pypi/pyversions/cssselect.svg
+           :target: https://pypi.python.org/pypi/cssselect
+           :alt: Supported Python Versions
+        
+        .. image:: https://img.shields.io/travis/scrapy/cssselect/master.svg
+           :target: https://travis-ci.org/scrapy/cssselect
+           :alt: Build Status
+        
+        .. image:: https://img.shields.io/codecov/c/github/scrapy/cssselect/master.svg
+           :target: https://codecov.io/github/scrapy/cssselect?branch=master
+           :alt: Coverage report
+        
+        *cssselect* parses `CSS3 Selectors`_ and translate them to `XPath 1.0`_
+        expressions. Such expressions can be used in lxml_ or another XPath engine
+        to find the matching elements in an XML or HTML document.
+        
+        This module used to live inside of lxml as ``lxml.cssselect`` before it was
+        extracted as a stand-alone project.
+        
+        .. _CSS3 Selectors: https://www.w3.org/TR/css3-selectors/
+        .. _XPath 1.0: https://www.w3.org/TR/xpath/
+        .. _lxml: http://lxml.de/
+        
+        
+        Quick facts:
+        
+        * Free software: BSD licensed
+        * Compatible with Python 2.7 and 3.4+
+        * Latest documentation `on Read the Docs <https://cssselect.readthedocs.io/>`_
+        * Source, issues and pull requests `on GitHub
+          <https://github.com/scrapy/cssselect>`_
+        * Releases `on PyPI <http://pypi.python.org/pypi/cssselect>`_
+        * Install with ``pip install cssselect``
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+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.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
diff --git a/README.rst b/README.rst
index 587c2d7..9bcd648 100644
--- a/README.rst
+++ b/README.rst
@@ -2,6 +2,22 @@
 cssselect: CSS Selectors for Python
 ===================================
 
+.. image:: https://img.shields.io/pypi/v/cssselect.svg
+   :target: https://pypi.python.org/pypi/cssselect
+   :alt: PyPI Version
+
+.. image:: https://img.shields.io/pypi/pyversions/cssselect.svg
+   :target: https://pypi.python.org/pypi/cssselect
+   :alt: Supported Python Versions
+
+.. image:: https://img.shields.io/travis/scrapy/cssselect/master.svg
+   :target: https://travis-ci.org/scrapy/cssselect
+   :alt: Build Status
+
+.. image:: https://img.shields.io/codecov/c/github/scrapy/cssselect/master.svg
+   :target: https://codecov.io/github/scrapy/cssselect?branch=master
+   :alt: Coverage report
+
 *cssselect* parses `CSS3 Selectors`_ and translate them to `XPath 1.0`_
 expressions. Such expressions can be used in lxml_ or another XPath engine
 to find the matching elements in an XML or HTML document.
@@ -17,9 +33,9 @@ extracted as a stand-alone project.
 Quick facts:
 
 * Free software: BSD licensed
-* Compatible with Python 2.6+ and 3.3+
+* Compatible with Python 2.7 and 3.4+
 * Latest documentation `on Read the Docs <https://cssselect.readthedocs.io/>`_
-* Source, issues and pull requests `on Github
+* Source, issues and pull requests `on GitHub
   <https://github.com/scrapy/cssselect>`_
 * Releases `on PyPI <http://pypi.python.org/pypi/cssselect>`_
 * Install with ``pip install cssselect``
diff --git a/cssselect.egg-info/PKG-INFO b/cssselect.egg-info/PKG-INFO
new file mode 100644
index 0000000..9cdd726
--- /dev/null
+++ b/cssselect.egg-info/PKG-INFO
@@ -0,0 +1,62 @@
+Metadata-Version: 1.2
+Name: cssselect
+Version: 1.0.3
+Summary: cssselect parses CSS3 Selectors and translates them to XPath 1.0
+Home-page: https://github.com/scrapy/cssselect
+Author: Paul Tremberth
+Author-email: paul.tremberth at gmail.com
+License: BSD
+Description-Content-Type: UNKNOWN
+Description: ===================================
+        cssselect: CSS Selectors for Python
+        ===================================
+        
+        .. image:: https://img.shields.io/pypi/v/cssselect.svg
+           :target: https://pypi.python.org/pypi/cssselect
+           :alt: PyPI Version
+        
+        .. image:: https://img.shields.io/pypi/pyversions/cssselect.svg
+           :target: https://pypi.python.org/pypi/cssselect
+           :alt: Supported Python Versions
+        
+        .. image:: https://img.shields.io/travis/scrapy/cssselect/master.svg
+           :target: https://travis-ci.org/scrapy/cssselect
+           :alt: Build Status
+        
+        .. image:: https://img.shields.io/codecov/c/github/scrapy/cssselect/master.svg
+           :target: https://codecov.io/github/scrapy/cssselect?branch=master
+           :alt: Coverage report
+        
+        *cssselect* parses `CSS3 Selectors`_ and translate them to `XPath 1.0`_
+        expressions. Such expressions can be used in lxml_ or another XPath engine
+        to find the matching elements in an XML or HTML document.
+        
+        This module used to live inside of lxml as ``lxml.cssselect`` before it was
+        extracted as a stand-alone project.
+        
+        .. _CSS3 Selectors: https://www.w3.org/TR/css3-selectors/
+        .. _XPath 1.0: https://www.w3.org/TR/xpath/
+        .. _lxml: http://lxml.de/
+        
+        
+        Quick facts:
+        
+        * Free software: BSD licensed
+        * Compatible with Python 2.7 and 3.4+
+        * Latest documentation `on Read the Docs <https://cssselect.readthedocs.io/>`_
+        * Source, issues and pull requests `on GitHub
+          <https://github.com/scrapy/cssselect>`_
+        * Releases `on PyPI <http://pypi.python.org/pypi/cssselect>`_
+        * Install with ``pip install cssselect``
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+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.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
diff --git a/cssselect.egg-info/SOURCES.txt b/cssselect.egg-info/SOURCES.txt
new file mode 100644
index 0000000..91a07c6
--- /dev/null
+++ b/cssselect.egg-info/SOURCES.txt
@@ -0,0 +1,18 @@
+.coveragerc
+AUTHORS
+CHANGES
+LICENSE
+MANIFEST.in
+README.rst
+setup.cfg
+setup.py
+tox.ini
+cssselect/__init__.py
+cssselect/parser.py
+cssselect/xpath.py
+cssselect.egg-info/PKG-INFO
+cssselect.egg-info/SOURCES.txt
+cssselect.egg-info/dependency_links.txt
+cssselect.egg-info/top_level.txt
+docs/conf.py
+docs/index.rst
\ No newline at end of file
diff --git a/cssselect.egg-info/dependency_links.txt b/cssselect.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/cssselect.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/cssselect.egg-info/top_level.txt b/cssselect.egg-info/top_level.txt
new file mode 100644
index 0000000..d2a154e
--- /dev/null
+++ b/cssselect.egg-info/top_level.txt
@@ -0,0 +1 @@
+cssselect
diff --git a/cssselect/__init__.py b/cssselect/__init__.py
index 3b06261..e9f9ce1 100644
--- a/cssselect/__init__.py
+++ b/cssselect/__init__.py
@@ -18,5 +18,5 @@ from cssselect.parser import (parse, Selector, FunctionalPseudoElement,
 from cssselect.xpath import GenericTranslator, HTMLTranslator, ExpressionError
 
 
-VERSION = '1.0.1'
+VERSION = '1.0.3'
 __version__ = VERSION
diff --git a/cssselect/parser.py b/cssselect/parser.py
index d155252..9bb039c 100644
--- a/cssselect/parser.py
+++ b/cssselect/parser.py
@@ -358,8 +358,6 @@ def parse(css):
 #        message = "%s at %s -> %r" % (
 #            e, stream.used, stream.peek())
 #        e.msg = message
-#        if sys.version_info < (2,6):
-#            e.message = message
 #        e.args = tuple([message])
 #        raise
 
@@ -554,14 +552,14 @@ def parse_series(tokens):
             raise ValueError('String tokens not allowed in series.')
     s = ''.join(token.value for token in tokens).strip()
     if s == 'odd':
-        return (2, 1)
+        return 2, 1
     elif s == 'even':
-        return (2, 0)
+        return 2, 0
     elif s == 'n':
-        return (1, 0)
+        return 1, 0
     if 'n' not in s:
         # Just b
-        return (0, int(s))
+        return 0, int(s)
     a, b = s.split('n', 1)
     if not a:
         a = 1
@@ -573,7 +571,7 @@ def parse_series(tokens):
         b = 0
     else:
         b = int(b)
-    return (a, b)
+    return a, b
 
 
 #### Token objects
@@ -617,7 +615,7 @@ def _compile(pattern):
     return re.compile(pattern % vars(TokenMacros), re.IGNORECASE).match
 
 _match_whitespace = _compile(r'[ \t\r\n\f]+')
-_match_number = _compile('[+-]?(?:[0-9]*\.[0-9]+|[0-9]+)')
+_match_number = _compile(r'[+-]?(?:[0-9]*\.[0-9]+|[0-9]+)')
 _match_hash = _compile('#(?:%(nmchar)s)+')
 _match_ident = _compile('-?(?:%(nmstart)s)(?:%(nmchar)s)*')
 _match_string_by_quote = {
@@ -630,12 +628,7 @@ _sub_unicode_escape = re.compile(TokenMacros.unicode_escape, re.I).sub
 _sub_newline_escape =re.compile(r'\\(?:\n|\r\n|\r|\f)').sub
 
 # Same as r'\1', but faster on CPython
-if hasattr(operator, 'methodcaller'):
-    # Python 2.6+
-    _replace_simple = operator.methodcaller('group', 1)
-else:
-    def _replace_simple(match):
-        return match.group(1)
+_replace_simple = operator.methodcaller('group', 1)
 
 def _replace_unicode(match):
     codepoint = int(match.group(1), 16)
diff --git a/cssselect/xpath.py b/cssselect/xpath.py
index 698748a..22cd029 100644
--- a/cssselect/xpath.py
+++ b/cssselect/xpath.py
@@ -114,7 +114,7 @@ class GenericTranslator(object):
     ####
     ####  You are welcome to hook into this to change some behavior,
     ####  but do so at your own risks.
-    ####  Until is has recieved a lot more work and review,
+    ####  Until it has received a lot more work and review,
     ####  I reserve the right to change this API in backward-incompatible ways
     ####  with any minor version of cssselect.
     ####  See https://github.com/scrapy/cssselect/pull/22
@@ -490,7 +490,7 @@ class GenericTranslator(object):
             b_neg = (-b_min_1) % abs(a)
 
             if b_neg != 0:
-                b_neg = '+%s' % (b_neg)
+                b_neg = '+%s' % b_neg
                 left = '(%s %s)' % (left, b_neg)
 
             expr.append('%s mod %s = 0' % (left, a))
diff --git a/setup.cfg b/setup.cfg
index b8c93b1..57caa3e 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,9 +1,8 @@
 [build_sphinx]
 source-dir = docs
-build-dir  = docs/_build
-#all_files  = 1
+build-dir = docs/_build
 
-[upload_sphinx] # Sphinx-PyPI-upload
+[upload_sphinx]
 upload-dir = docs/_build/html
 
 [tool:pytest]
@@ -11,3 +10,8 @@ testpaths = tests
 
 [bdist_wheel]
 universal = 1
+
+[egg_info]
+tag_build = 
+tag_date = 0
+
diff --git a/setup.py b/setup.py
index 199ffc7..243927d 100644
--- a/setup.py
+++ b/setup.py
@@ -29,15 +29,14 @@ setup(
     url='https://github.com/scrapy/cssselect',
     license='BSD',
     packages=['cssselect'],
+    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
     classifiers=[
         'Development Status :: 4 - Beta',
         'Intended Audience :: Developers',
         'License :: OSI Approved :: BSD License',
         'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.6',
         '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',
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/test_cssselect.py b/tests/test_cssselect.py
deleted file mode 100644
index 4a0bd39..0000000
--- a/tests/test_cssselect.py
+++ /dev/null
@@ -1,1236 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-    Tests for cssselect
-    ===================
-
-    These tests can be run either by py.test or by the standard library's
-    unittest. They use plain ``assert`` statements and do little reporting
-    themselves in case of failure.
-
-    Use py.test to get fancy error reporting and assert introspection.
-
-
-    :copyright: (c) 2007-2012 Ian Bicking and contributors.
-                See AUTHORS for more details.
-    :license: BSD, see LICENSE for more details.
-
-"""
-
-import sys
-import unittest
-
-from lxml import etree, html
-from cssselect import (parse, GenericTranslator, HTMLTranslator,
-                       SelectorSyntaxError, ExpressionError)
-from cssselect.parser import (tokenize, parse_series, _unicode,
-                              FunctionalPseudoElement)
-from cssselect.xpath import _unicode_safe_getattr, XPathExpr
-
-
-if sys.version_info[0] < 3:
-    # Python 2
-    def u(text):
-        return text.decode('utf8')
-else:
-    # Python 3
-    def u(text):
-        return text
-
-
-class TestCssselect(unittest.TestCase):
-    def test_tokenizer(self):
-        tokens = [
-            _unicode(item) for item in tokenize(
-                u(r'E\ é > f [a~="y\"x"]:nth(/* fu /]* */-3.7)'))]
-        assert tokens == [
-            u("<IDENT 'E é' at 0>"),
-            "<S ' ' at 4>",
-            "<DELIM '>' at 5>",
-            "<S ' ' at 6>",
-            # the no-break space is not whitespace in CSS
-            u("<IDENT 'f ' at 7>"),  # f\xa0
-            "<DELIM '[' at 9>",
-            "<IDENT 'a' at 10>",
-            "<DELIM '~' at 11>",
-            "<DELIM '=' at 12>",
-            "<STRING 'y\"x' at 13>",
-            "<DELIM ']' at 19>",
-            "<DELIM ':' at 20>",
-            "<IDENT 'nth' at 21>",
-            "<DELIM '(' at 24>",
-            "<NUMBER '-3.7' at 37>",
-            "<DELIM ')' at 41>",
-            "<EOF at 42>",
-        ]
-
-    def test_parser(self):
-        def repr_parse(css):
-            selectors = parse(css)
-            for selector in selectors:
-                assert selector.pseudo_element is None
-            return [repr(selector.parsed_tree).replace("(u'", "('")
-                    for selector in selectors]
-
-        def parse_many(first, *others):
-            result = repr_parse(first)
-            for other in others:
-                assert repr_parse(other) == result
-            return result
-
-        assert parse_many('*') == ['Element[*]']
-        assert parse_many('*|*') == ['Element[*]']
-        assert parse_many('*|foo') == ['Element[foo]']
-        assert parse_many('foo|*') == ['Element[foo|*]']
-        assert parse_many('foo|bar') == ['Element[foo|bar]']
-        # This will never match, but it is valid:
-        assert parse_many('#foo#bar') == ['Hash[Hash[Element[*]#foo]#bar]']
-        assert parse_many(
-            'div>.foo',
-            'div> .foo',
-            'div >.foo',
-            'div > .foo',
-            'div \n>  \t \t .foo', 'div\r>\n\n\n.foo', 'div\f>\f.foo'
-        ) == ['CombinedSelector[Element[div] > Class[Element[*].foo]]']
-        assert parse_many('td.foo,.bar',
-            'td.foo, .bar',
-            'td.foo\t\r\n\f ,\t\r\n\f .bar'
-        ) == [
-            'Class[Element[td].foo]',
-            'Class[Element[*].bar]'
-        ]
-        assert parse_many('div, td.foo, div.bar span') == [
-            'Element[div]',
-            'Class[Element[td].foo]',
-            'CombinedSelector[Class[Element[div].bar] '
-                '<followed> Element[span]]']
-        assert parse_many('div > p') == [
-            'CombinedSelector[Element[div] > Element[p]]']
-        assert parse_many('td:first') == [
-            'Pseudo[Element[td]:first]']
-        assert parse_many('td:first') == [
-            'Pseudo[Element[td]:first]']
-        assert parse_many('td :first') == [
-            'CombinedSelector[Element[td] '
-                '<followed> Pseudo[Element[*]:first]]']
-        assert parse_many('td :first') == [
-            'CombinedSelector[Element[td] '
-                '<followed> Pseudo[Element[*]:first]]']
-        assert parse_many('a[name]', 'a[ name\t]') == [
-            'Attrib[Element[a][name]]']
-        assert parse_many('a [name]') == [
-            'CombinedSelector[Element[a] <followed> Attrib[Element[*][name]]]']
-        assert parse_many('a[rel="include"]', 'a[rel = include]') == [
-            "Attrib[Element[a][rel = 'include']]"]
-        assert parse_many("a[hreflang |= 'en']", "a[hreflang|=en]") == [
-            "Attrib[Element[a][hreflang |= 'en']]"]
-        assert parse_many('div:nth-child(10)') == [
-            "Function[Element[div]:nth-child(['10'])]"]
-        assert parse_many(':nth-child(2n+2)') == [
-            "Function[Element[*]:nth-child(['2', 'n', '+2'])]"]
-        assert parse_many('div:nth-of-type(10)') == [
-            "Function[Element[div]:nth-of-type(['10'])]"]
-        assert parse_many('div div:nth-of-type(10) .aclass') == [
-            'CombinedSelector[CombinedSelector[Element[div] <followed> '
-                "Function[Element[div]:nth-of-type(['10'])]] "
-                '<followed> Class[Element[*].aclass]]']
-        assert parse_many('label:only') == [
-            'Pseudo[Element[label]:only]']
-        assert parse_many('a:lang(fr)') == [
-            "Function[Element[a]:lang(['fr'])]"]
-        assert parse_many('div:contains("foo")') == [
-            "Function[Element[div]:contains(['foo'])]"]
-        assert parse_many('div#foobar') == [
-            'Hash[Element[div]#foobar]']
-        assert parse_many('div:not(div.foo)') == [
-            'Negation[Element[div]:not(Class[Element[div].foo])]']
-        assert parse_many('td ~ th') == [
-            'CombinedSelector[Element[td] ~ Element[th]]']
-
-    def test_pseudo_elements(self):
-        def parse_pseudo(css):
-            result = []
-            for selector in parse(css):
-                pseudo = selector.pseudo_element
-                pseudo = _unicode(pseudo) if pseudo else pseudo
-                # No Symbol here
-                assert pseudo is None or type(pseudo) is _unicode
-                selector = repr(selector.parsed_tree).replace("(u'", "('")
-                result.append((selector, pseudo))
-            return result
-
-        def parse_one(css):
-            result = parse_pseudo(css)
-            assert len(result) == 1
-            return result[0]
-
-        assert parse_one('foo') == ('Element[foo]', None)
-        assert parse_one('*') == ('Element[*]', None)
-        assert parse_one(':empty') == ('Pseudo[Element[*]:empty]', None)
-
-        # Special cases for CSS 2.1 pseudo-elements
-        assert parse_one(':BEfore') == ('Element[*]', 'before')
-        assert parse_one(':aftER') == ('Element[*]', 'after')
-        assert parse_one(':First-Line') == ('Element[*]', 'first-line')
-        assert parse_one(':First-Letter') == ('Element[*]', 'first-letter')
-
-        assert parse_one('::befoRE') == ('Element[*]', 'before')
-        assert parse_one('::AFter') == ('Element[*]', 'after')
-        assert parse_one('::firsT-linE') == ('Element[*]', 'first-line')
-        assert parse_one('::firsT-letteR') == ('Element[*]', 'first-letter')
-
-        assert parse_one('::text-content') == ('Element[*]', 'text-content')
-        assert parse_one('::attr(name)') == (
-            "Element[*]", "FunctionalPseudoElement[::attr(['name'])]")
-
-        assert parse_one('::Selection') == ('Element[*]', 'selection')
-        assert parse_one('foo:after') == ('Element[foo]', 'after')
-        assert parse_one('foo::selection') == ('Element[foo]', 'selection')
-        assert parse_one('lorem#ipsum ~ a#b.c[href]:empty::selection') == (
-            'CombinedSelector[Hash[Element[lorem]#ipsum] ~ '
-                'Pseudo[Attrib[Class[Hash[Element[a]#b].c][href]]:empty]]',
-            'selection')
-
-        parse_pseudo('foo:before, bar, baz:after') == [
-            ('Element[foo]', 'before'),
-            ('Element[bar]', None),
-            ('Element[baz]', 'after')]
-
-        # Special cases for CSS 2.1 pseudo-elements are ignored by default
-        for pseudo in ('after', 'before', 'first-line', 'first-letter'):
-            selector, = parse('e:%s' % pseudo)
-            assert selector.pseudo_element == pseudo
-            assert GenericTranslator().selector_to_xpath(selector, prefix='') == "e"
-
-        # Pseudo Elements are ignored by default, but if allowed they are not
-        # supported by GenericTranslator
-        tr = GenericTranslator()
-        selector, = parse('e::foo')
-        assert selector.pseudo_element == 'foo'
-        assert tr.selector_to_xpath(selector, prefix='') == "e"
-        self.assertRaises(ExpressionError, tr.selector_to_xpath, selector,
-                          translate_pseudo_elements=True)
-
-    def test_specificity(self):
-        def specificity(css):
-            selectors = parse(css)
-            assert len(selectors) == 1
-            return selectors[0].specificity()
-
-        assert specificity('*') == (0, 0, 0)
-        assert specificity(' foo') == (0, 0, 1)
-        assert specificity(':empty ') == (0, 1, 0)
-        assert specificity(':before') == (0, 0, 1)
-        assert specificity('*:before') == (0, 0, 1)
-        assert specificity(':nth-child(2)') == (0, 1, 0)
-        assert specificity('.bar') == (0, 1, 0)
-        assert specificity('[baz]') == (0, 1, 0)
-        assert specificity('[baz="4"]') == (0, 1, 0)
-        assert specificity('[baz^="4"]') == (0, 1, 0)
-        assert specificity('#lipsum') == (1, 0, 0)
-
-        assert specificity(':not(*)') == (0, 0, 0)
-        assert specificity(':not(foo)') == (0, 0, 1)
-        assert specificity(':not(.foo)') == (0, 1, 0)
-        assert specificity(':not([foo])') == (0, 1, 0)
-        assert specificity(':not(:empty)') == (0, 1, 0)
-        assert specificity(':not(#foo)') == (1, 0, 0)
-
-        assert specificity('foo:empty') == (0, 1, 1)
-        assert specificity('foo:before') == (0, 0, 2)
-        assert specificity('foo::before') == (0, 0, 2)
-        assert specificity('foo:empty::before') == (0, 1, 2)
-
-        assert specificity('#lorem + foo#ipsum:first-child > bar:first-line'
-            ) == (2, 1, 3)
-
-    def test_parse_errors(self):
-        def get_error(css):
-            try:
-                parse(css)
-            except SelectorSyntaxError:
-                # Py2, Py3, ...
-                return str(sys.exc_info()[1]).replace("(u'", "('")
-
-        assert get_error('attributes(href)/html/body/a') == (
-            "Expected selector, got <DELIM '(' at 10>")
-        assert get_error('attributes(href)') == (
-            "Expected selector, got <DELIM '(' at 10>")
-        assert get_error('html/body/a') == (
-            "Expected selector, got <DELIM '/' at 4>")
-        assert get_error(' ') == (
-            "Expected selector, got <EOF at 1>")
-        assert get_error('div, ') == (
-            "Expected selector, got <EOF at 5>")
-        assert get_error(' , div') == (
-            "Expected selector, got <DELIM ',' at 1>")
-        assert get_error('p, , div') == (
-            "Expected selector, got <DELIM ',' at 3>")
-        assert get_error('div > ') == (
-            "Expected selector, got <EOF at 6>")
-        assert get_error('  > div') == (
-            "Expected selector, got <DELIM '>' at 2>")
-        assert get_error('foo|#bar') == (
-            "Expected ident or '*', got <HASH 'bar' at 4>")
-        assert get_error('#.foo') == (
-            "Expected selector, got <DELIM '#' at 0>")
-        assert get_error('.#foo') == (
-            "Expected ident, got <HASH 'foo' at 1>")
-        assert get_error(':#foo') == (
-            "Expected ident, got <HASH 'foo' at 1>")
-        assert get_error('[*]') == (
-            "Expected '|', got <DELIM ']' at 2>")
-        assert get_error('[foo|]') == (
-            "Expected ident, got <DELIM ']' at 5>")
-        assert get_error('[#]') == (
-            "Expected ident or '*', got <DELIM '#' at 1>")
-        assert get_error('[foo=#]') == (
-            "Expected string or ident, got <DELIM '#' at 5>")
-        assert get_error('[href]a') == (
-            "Expected selector, got <IDENT 'a' at 6>")
-        assert get_error('[rel=stylesheet]') == None
-        assert get_error('[rel:stylesheet]') == (
-            "Operator expected, got <DELIM ':' at 4>")
-        assert get_error('[rel=stylesheet') == (
-            "Expected ']', got <EOF at 15>")
-        assert get_error(':lang(fr)') == None
-        assert get_error(':lang(fr') == (
-            "Expected an argument, got <EOF at 8>")
-        assert get_error(':contains("foo') == (
-            "Unclosed string at 10")
-        assert get_error('foo!') == (
-            "Expected selector, got <DELIM '!' at 3>")
-
-        # Mis-placed pseudo-elements
-        assert get_error('a:before:empty') == (
-            "Got pseudo-element ::before not at the end of a selector")
-        assert get_error('li:before a') == (
-            "Got pseudo-element ::before not at the end of a selector")
-        assert get_error(':not(:before)') == (
-            "Got pseudo-element ::before inside :not() at 12")
-        assert get_error(':not(:not(a))') == (
-            "Got nested :not()")
-
-    def test_translation(self):
-        def xpath(css):
-            return _unicode(GenericTranslator().css_to_xpath(css, prefix=''))
-
-        assert xpath('*') == "*"
-        assert xpath('e') == "e"
-        assert xpath('*|e') == "e"
-        assert xpath('e|f') == "e:f"
-        assert xpath('e[foo]') == "e[@foo]"
-        assert xpath('e[foo|bar]') == "e[@foo:bar]"
-        assert xpath('e[foo="bar"]') == "e[@foo = 'bar']"
-        assert xpath('e[foo~="bar"]') == (
-            "e[@foo and contains("
-               "concat(' ', normalize-space(@foo), ' '), ' bar ')]")
-        assert xpath('e[foo^="bar"]') == (
-            "e[@foo and starts-with(@foo, 'bar')]")
-        assert xpath('e[foo$="bar"]') == (
-            "e[@foo and substring(@foo, string-length(@foo)-2) = 'bar']")
-        assert xpath('e[foo*="bar"]') == (
-            "e[@foo and contains(@foo, 'bar')]")
-        assert xpath('e[hreflang|="en"]') == (
-            "e[@hreflang and ("
-               "@hreflang = 'en' or starts-with(@hreflang, 'en-'))]")
-
-        # --- nth-* and nth-last-* -------------------------------------
-        assert xpath('e:nth-child(1)') == (
-            "e[count(preceding-sibling::*) = 0]")
-
-        # always true
-        assert xpath('e:nth-child(n)') == (
-            "e")
-        assert xpath('e:nth-child(n+1)') == (
-            "e")
-        # always true too
-        assert xpath('e:nth-child(n-10)') == (
-            "e")
-        # b=2 is the limit...
-        assert xpath('e:nth-child(n+2)') == (
-            "e[count(preceding-sibling::*) >= 1]")
-        # always false
-        assert xpath('e:nth-child(-n)') == (
-            "e[0]")
-        # equivalent to first child
-        assert xpath('e:nth-child(-n+1)') == (
-            "e[count(preceding-sibling::*) <= 0]")
-
-        assert xpath('e:nth-child(3n+2)') == (
-            "e[count(preceding-sibling::*) >= 1 and "
-              "(count(preceding-sibling::*) +2) mod 3 = 0]")
-        assert xpath('e:nth-child(3n-2)') == (
-            "e[count(preceding-sibling::*) mod 3 = 0]")
-        assert xpath('e:nth-child(-n+6)') == (
-            "e[count(preceding-sibling::*) <= 5]")
-
-        assert xpath('e:nth-last-child(1)') == (
-            "e[count(following-sibling::*) = 0]")
-        assert xpath('e:nth-last-child(2n)') == (
-            "e[(count(following-sibling::*) +1) mod 2 = 0]")
-        assert xpath('e:nth-last-child(2n+1)') == (
-            "e[count(following-sibling::*) mod 2 = 0]")
-        assert xpath('e:nth-last-child(2n+2)') == (
-            "e[count(following-sibling::*) >= 1 and "
-              "(count(following-sibling::*) +1) mod 2 = 0]")
-        assert xpath('e:nth-last-child(3n+1)') == (
-            "e[count(following-sibling::*) mod 3 = 0]")
-        # represents the two last e elements
-        assert xpath('e:nth-last-child(-n+2)') == (
-            "e[count(following-sibling::*) <= 1]")
-
-        assert xpath('e:nth-of-type(1)') == (
-            "e[count(preceding-sibling::e) = 0]")
-        assert xpath('e:nth-last-of-type(1)') == (
-            "e[count(following-sibling::e) = 0]")
-        assert xpath('div e:nth-last-of-type(1) .aclass') == (
-            "div/descendant-or-self::*/e[count(following-sibling::e) = 0]"
-               "/descendant-or-self::*/*[@class and contains("
-               "concat(' ', normalize-space(@class), ' '), ' aclass ')]")
-
-        assert xpath('e:first-child') == (
-            "e[count(preceding-sibling::*) = 0]")
-        assert xpath('e:last-child') == (
-            "e[count(following-sibling::*) = 0]")
-        assert xpath('e:first-of-type') == (
-            "e[count(preceding-sibling::e) = 0]")
-        assert xpath('e:last-of-type') == (
-            "e[count(following-sibling::e) = 0]")
-        assert xpath('e:only-child') == (
-            "e[count(parent::*/child::*) = 1]")
-        assert xpath('e:only-of-type') == (
-            "e[count(parent::*/child::e) = 1]")
-        assert xpath('e:empty') == (
-            "e[not(*) and not(string-length())]")
-        assert xpath('e:EmPTY') == (
-            "e[not(*) and not(string-length())]")
-        assert xpath('e:root') == (
-            "e[not(parent::*)]")
-        assert xpath('e:hover') == (
-            "e[0]")  # never matches
-        assert xpath('e:contains("foo")') == (
-            "e[contains(., 'foo')]")
-        assert xpath('e:ConTains(foo)') == (
-            "e[contains(., 'foo')]")
-        assert xpath('e.warning') == (
-            "e[@class and contains("
-               "concat(' ', normalize-space(@class), ' '), ' warning ')]")
-        assert xpath('e#myid') == (
-            "e[@id = 'myid']")
-        assert xpath('e:not(:nth-child(odd))') == (
-            "e[not(count(preceding-sibling::*) mod 2 = 0)]")
-        assert xpath('e:nOT(*)') == (
-            "e[0]")  # never matches
-        assert xpath('e f') == (
-            "e/descendant-or-self::*/f")
-        assert xpath('e > f') == (
-            "e/f")
-        assert xpath('e + f') == (
-            "e/following-sibling::*[name() = 'f' and (position() = 1)]")
-        assert xpath('e ~ f') == (
-            "e/following-sibling::f")
-        assert xpath('e ~ f:nth-child(3)') == (
-            "e/following-sibling::f[count(preceding-sibling::*) = 2]")
-        assert xpath('div#container p') == (
-            "div[@id = 'container']/descendant-or-self::*/p")
-
-        # Invalid characters in XPath element names
-        assert xpath(r'di\a0 v') == (
-            u("*[name() = 'di v']"))  # di\xa0v
-        assert xpath(r'di\[v') == (
-            "*[name() = 'di[v']")
-        assert xpath(r'[h\a0 ref]') == (
-            u("*[attribute::*[name() = 'h ref']]"))  # h\xa0ref
-        assert xpath(r'[h\]ref]') == (
-            "*[attribute::*[name() = 'h]ref']]")
-
-        self.assertRaises(ExpressionError, xpath, u(':fİrst-child'))
-        self.assertRaises(ExpressionError, xpath, ':first-of-type')
-        self.assertRaises(ExpressionError, xpath, ':only-of-type')
-        self.assertRaises(ExpressionError, xpath, ':last-of-type')
-        self.assertRaises(ExpressionError, xpath, ':nth-of-type(1)')
-        self.assertRaises(ExpressionError, xpath, ':nth-last-of-type(1)')
-        self.assertRaises(ExpressionError, xpath, ':nth-child(n-)')
-        self.assertRaises(ExpressionError, xpath, ':after')
-        self.assertRaises(ExpressionError, xpath, ':lorem-ipsum')
-        self.assertRaises(ExpressionError, xpath, ':lorem(ipsum)')
-        self.assertRaises(ExpressionError, xpath, '::lorem-ipsum')
-        self.assertRaises(TypeError, GenericTranslator().css_to_xpath, 4)
-        self.assertRaises(TypeError, GenericTranslator().selector_to_xpath,
-            'foo')
-
-    def test_unicode(self):
-        if sys.version_info[0] < 3:
-            css = '.a\xc1b'.decode('ISO-8859-1')
-        else:
-            css = '.a\xc1b'
-
-        xpath = GenericTranslator().css_to_xpath(css)
-        assert css[1:] in xpath
-        xpath = xpath.encode('ascii', 'xmlcharrefreplace').decode('ASCII')
-        assert xpath == (
-            "descendant-or-self::*[@class and contains("
-            "concat(' ', normalize-space(@class), ' '), ' aÁb ')]")
-
-    def test_quoting(self):
-        css_to_xpath = GenericTranslator().css_to_xpath
-        assert css_to_xpath('*[aval="\'"]') == (
-            '''descendant-or-self::*[@aval = "'"]''')
-        assert css_to_xpath('*[aval="\'\'\'"]') == (
-            """descendant-or-self::*[@aval = "'''"]""")
-        assert css_to_xpath('*[aval=\'"\']') == (
-            '''descendant-or-self::*[@aval = '"']''')
-        assert css_to_xpath('*[aval=\'"""\']') == (
-            '''descendant-or-self::*[@aval = '"""']''')
-
-    def test_unicode_escapes(self):
-        # \22 == '"'  \20 == ' '
-        css_to_xpath = GenericTranslator().css_to_xpath
-        assert css_to_xpath(r'*[aval="\'\22\'"]') == (
-            '''descendant-or-self::*[@aval = concat("'",'"',"'")]''')
-        assert css_to_xpath(r'*[aval="\'\22 2\'"]') == (
-            '''descendant-or-self::*[@aval = concat("'",'"2',"'")]''')
-        assert css_to_xpath(r'*[aval="\'\20  \'"]') == (
-            '''descendant-or-self::*[@aval = "'  '"]''')
-        assert css_to_xpath('*[aval="\'\\20\r\n \'"]') == (
-            '''descendant-or-self::*[@aval = "'  '"]''')
-
-    def test_xpath_pseudo_elements(self):
-        class CustomTranslator(GenericTranslator):
-            def xpath_pseudo_element(self, xpath, pseudo_element):
-                if isinstance(pseudo_element, FunctionalPseudoElement):
-                    method = 'xpath_%s_functional_pseudo_element' % (
-                        pseudo_element.name.replace('-', '_'))
-                    method = _unicode_safe_getattr(self, method, None)
-                    if not method:
-                        raise ExpressionError(
-                            "The functional pseudo-element ::%s() is unknown"
-                        % pseudo_element.name)
-                    xpath = method(xpath, pseudo_element.arguments)
-                else:
-                    method = 'xpath_%s_simple_pseudo_element' % (
-                        pseudo_element.replace('-', '_'))
-                    method = _unicode_safe_getattr(self, method, None)
-                    if not method:
-                        raise ExpressionError(
-                            "The pseudo-element ::%s is unknown"
-                            % pseudo_element)
-                    xpath = method(xpath)
-                return xpath
... 735 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-cssselect.git



More information about the Python-modules-commits mailing list