Hello community,

here is the log from the commit of package python-cssselect for 
openSUSE:Factory checked in at 2013-11-24 12:27:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cssselect (Old)
 and      /work/SRC/openSUSE:Factory/.python-cssselect.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cssselect"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cssselect/python-cssselect.changes        
2013-07-12 20:54:27.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-cssselect.new/python-cssselect.changes   
2013-11-24 12:27:31.000000000 +0100
@@ -1,0 +2,21 @@
+Sat Nov 23 18:09:44 UTC 2013 - [email protected]
+
+- Update to version 0.9.1
+  + **Backward incompatible change from 0.9**:
+    :meth:`~GenericTranslator.selector_to_xpath` defaults to ignoring
+    pseudo-elements, as it did in 0.8 and previous versions.
+    (:meth:`~GenericTranslator.css_to_xpath` doesn’t change.)
+  + Drop official support for Python 2.4 and 3.1,
+    as testing was becoming difficult. Nothing will break overnight,
+    but future releases may on may not work on these versions.
+    Older releases will remain available on PyPI.
+- Changes from 0.9
+  + Add parser support for :attr:`functional pseudo-elements
+    <Selector.pseudo_element>`.
+  + This version accidentally introduced a backward incompatible change:
+    :meth:`~GenericTranslator.selector_to_xpath` defaults to rejecting
+    pseudo-elements instead of ignoring them.
+- Remove useless CFLAGS definition
+- Add README.rst, CHANGES and AUTHORS in package documentation
+
+-------------------------------------------------------------------

Old:
----
  cssselect-0.8.tar.gz

New:
----
  cssselect-0.9.1.tar.gz

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

Other differences:
------------------
++++++ python-cssselect.spec ++++++
--- /var/tmp/diff_new_pack.DNdujF/_old  2013-11-24 12:27:32.000000000 +0100
+++ /var/tmp/diff_new_pack.DNdujF/_new  2013-11-24 12:27:32.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           python-cssselect
-Version:        0.8
+Version:        0.9.1
 Release:        0
 Summary:        CSS3 selectors for Python
 License:        BSD-3-Clause
@@ -45,7 +45,7 @@
 sed -i '/#!\/usr\/bin\/env python/d' cssselect/tests.py
 
 %build
-CFLAGS="%{optflags}" python setup.py build
+python setup.py build
 
 %install
 python setup.py install --prefix=%{_prefix} --root=%{buildroot}
@@ -53,6 +53,6 @@
 %files
 %defattr(-,root,root,-)
 %{python_sitelib}/*
-%doc LICENSE
+%doc README.rst LICENSE CHANGES AUTHORS
 
 %changelog

++++++ cssselect-0.8.tar.gz -> cssselect-0.9.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/AUTHORS new/cssselect-0.9.1/AUTHORS
--- old/cssselect-0.8/AUTHORS   2013-03-14 19:52:38.000000000 +0100
+++ new/cssselect-0.9.1/AUTHORS 2013-10-15 16:58:30.000000000 +0200
@@ -1,5 +1,9 @@
+Daniel Graña
 Ian Bicking
 Laurence Rowe
+Mikhail Korobov
+Paul Tremberth
 Simon Potter
 Simon Sapin
 Stefan Behnel
+Varialus
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/CHANGES new/cssselect-0.9.1/CHANGES
--- old/cssselect-0.8/CHANGES   2013-03-15 16:51:05.000000000 +0100
+++ new/cssselect-0.9.1/CHANGES 2013-10-17 15:32:13.000000000 +0200
@@ -1,6 +1,37 @@
 Changelog
 =========
 
+Version 0.9.1
+-------------
+
+Released on 2013-10-17.
+
+* **Backward incompatible change from 0.9**:
+  :meth:`~GenericTranslator.selector_to_xpath` defaults to
+  ignoring pseudo-elements,
+  as it did in 0.8 and previous versions.
+  (:meth:`~GenericTranslator.css_to_xpath` doesn’t change.)
+* Drop official support for Python 2.4 and 3.1,
+  as testing was becoming difficult.
+  Nothing will break overnight,
+  but future releases may on may not work on these versions.
+  Older releases will remain available on PyPI.
+
+
+Version 0.9
+-----------
+
+Released on 2013-10-11.
+
+Add parser support for :attr:`functional
+pseudo-elements <Selector.pseudo_element>`.
+
+*Update:*
+This version accidentally introduced a **backward incompatible** change:
+:meth:`~GenericTranslator.selector_to_xpath` defaults to
+rejecting pseudo-elements instead of ignoring them.
+
+
 Version 0.8
 -----------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/PKG-INFO new/cssselect-0.9.1/PKG-INFO
--- old/cssselect-0.8/PKG-INFO  2013-03-15 16:53:20.000000000 +0100
+++ new/cssselect-0.9.1/PKG-INFO        2013-10-17 15:39:34.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cssselect
-Version: 0.8
+Version: 0.9.1
 Summary: cssselect parses CSS3 Selectors and translates them to XPath 1.0
 Home-page: http://packages.python.org/cssselect/
 Author: Simon Sapin
@@ -25,7 +25,7 @@
         Quick facts:
         
         * Free software: BSD licensed
-        * Compatible with Python 2.4+ and 3.x
+        * Compatible with Python 2.5+ and 3.2+
         * Latest documentation `on python.org 
<http://packages.python.org/cssselect/>`_
         * Source, issues and pull requests `on Github
           <https://github.com/SimonSapin/cssselect/>`_
@@ -37,10 +37,8 @@
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.4
 Classifier: Programming Language :: Python :: 2.5
 Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/README.rst 
new/cssselect-0.9.1/README.rst
--- old/cssselect-0.8/README.rst        2012-04-16 10:56:57.000000000 +0200
+++ new/cssselect-0.9.1/README.rst      2013-10-15 16:54:36.000000000 +0200
@@ -17,7 +17,7 @@
 Quick facts:
 
 * Free software: BSD licensed
-* Compatible with Python 2.4+ and 3.x
+* Compatible with Python 2.5+ and 3.2+
 * Latest documentation `on python.org <http://packages.python.org/cssselect/>`_
 * Source, issues and pull requests `on Github
   <https://github.com/SimonSapin/cssselect/>`_
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/cssselect/__init__.py 
new/cssselect-0.9.1/cssselect/__init__.py
--- old/cssselect-0.8/cssselect/__init__.py     2013-03-15 16:52:22.000000000 
+0100
+++ new/cssselect-0.9.1/cssselect/__init__.py   2013-10-17 15:38:51.000000000 
+0200
@@ -13,10 +13,10 @@
 
 """
 
-from cssselect.parser import (parse, Selector, SelectorError,
-                              SelectorSyntaxError)
+from cssselect.parser import (parse, Selector, FunctionalPseudoElement,
+                              SelectorError, SelectorSyntaxError)
 from cssselect.xpath import GenericTranslator, HTMLTranslator, ExpressionError
 
 
-VERSION = '0.8'
+VERSION = '0.9.1'
 __version__ = VERSION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/cssselect/parser.py 
new/cssselect-0.9.1/cssselect/parser.py
--- old/cssselect-0.8/cssselect/parser.py       2012-06-29 15:02:47.000000000 
+0200
+++ new/cssselect-0.9.1/cssselect/parser.py     2013-10-11 17:14:37.000000000 
+0200
@@ -57,27 +57,34 @@
     """
     def __init__(self, tree, pseudo_element=None):
         self.parsed_tree = tree
-        if pseudo_element is not None:
+        if pseudo_element is not None and not isinstance(
+                pseudo_element, FunctionalPseudoElement):
             pseudo_element = ascii_lower(pseudo_element)
-        #: The identifier for the pseudo-element as a string, or ``None``.
+        #: A :class:`FunctionalPseudoElement`,
+        #: or the identifier for the pseudo-element as a string,
+        #  or ``None``.
         #:
-        #: +-------------------------+----------------+----------------+
-        #: |                         | Selector       | Pseudo-element |
-        #: +=========================+================+================+
-        #: | CSS3 syntax             | ``a::before``  | ``'before'``   |
-        #: +-------------------------+----------------+----------------+
-        #: | Older syntax            | ``a:before``   | ``'before'``   |
-        #: +-------------------------+----------------+----------------+
-        #: | From the Lists3_ draft, | ``li::marker`` | ``'marker'``   |
-        #: | not in Selectors3       |                |                |
-        #: +-------------------------+----------------+----------------+
-        #: | Invalid pseudo-class    | ``li:marker``  | ``None``       |
-        #: +-------------------------+----------------+----------------+
+        #: 
+-------------------------+----------------+--------------------------------+
+        #: |                         | Selector       | Pseudo-element         
        |
+        #: 
+=========================+================+================================+
+        #: | CSS3 syntax             | ``a::before``  | ``'before'``           
        |
+        #: 
+-------------------------+----------------+--------------------------------+
+        #: | Older syntax            | ``a:before``   | ``'before'``           
        |
+        #: 
+-------------------------+----------------+--------------------------------+
+        #: | From the Lists3_ draft, | ``li::marker`` | ``'marker'``           
        |
+        #: | not in Selectors3       |                |                        
        |
+        #: 
+-------------------------+----------------+--------------------------------+
+        #: | Invalid pseudo-class    | ``li:marker``  | ``None``               
        |
+        #: 
+-------------------------+----------------+--------------------------------+
+        #: | Functinal               | ``a::foo(2)``  | 
``FunctionalPseudoElement(…)`` |
+        #: 
+-------------------------+----------------+--------------------------------+
         #:
         #: .. _Lists3: 
http://www.w3.org/TR/2011/WD-css3-lists-20110524/#marker-pseudoelement
         self.pseudo_element = pseudo_element
 
     def __repr__(self):
+        if isinstance(self.pseudo_element, FunctionalPseudoElement):
+            pseudo_element = repr(self.pseudo_element)
         if self.pseudo_element:
             pseudo_element = '::%s' % self.pseudo_element
         else:
@@ -115,6 +122,41 @@
         return a, b, c
 
 
+class FunctionalPseudoElement(object):
+    """
+    Represents selector::name(arguments)
+
+    .. attribute:: name
+
+        The name (identifier) of the pseudo-element, as a string.
+
+    .. attribute:: arguments
+
+        The arguments of the pseudo-element, as a list of tokens.
+
+        **Note:** tokens are not part of the public API,
+        and may change between cssselect versions.
+        Use at your own risks.
+
+    """
+    def __init__(self, name, arguments):
+        self.name = ascii_lower(name)
+        self.arguments = arguments
+
+    def __repr__(self):
+        return '%s[::%s(%r)]' % (
+            self.__class__.__name__, self.name,
+            [token.value for token in self.arguments])
+
+    def argument_types(self):
+        return [token.type for token in self.arguments]
+
+    def specificity(self):
+        a, b, c = self.selector.specificity()
+        b += 1
+        return a, b, c
+
+
 class Function(object):
     """
     Represents selector:name(expr)
@@ -398,6 +440,10 @@
             if stream.peek() == ('DELIM', ':'):
                 stream.next()
                 pseudo_element = stream.next_ident()
+                if stream.peek() == ('DELIM', '('):
+                    stream.next()
+                    pseudo_element = FunctionalPseudoElement(
+                        pseudo_element, parse_arguments(stream))
                 continue
             ident = stream.next_ident()
             if ident.lower() in ('first-line', 'first-letter',
@@ -425,22 +471,7 @@
                     raise SelectorSyntaxError("Expected ')', got %s" % (next,))
                 result = Negation(result, argument)
             else:
-                arguments = []
-                while 1:
-                    stream.skip_whitespace()
-                    next = stream.next()
-                    if next.type in ('IDENT', 'STRING', 'NUMBER') or next in [
-                            ('DELIM', '+'), ('DELIM', '-')]:
-                        arguments.append(next)
-                    elif next == ('DELIM', ')'):
-                        break
-                    else:
-                        raise SelectorSyntaxError(
-                            "Expected an argument, got %s" % (next,))
-                if not arguments:
-                    raise SelectorSyntaxError(
-                        "Expected at least one argument, got %s" % (next,))
-                result = Function(result, ident, arguments)
+                result = Function(result, ident, parse_arguments(stream))
         else:
             raise SelectorSyntaxError(
                 "Expected selector, got %s" % (peek,))
@@ -450,6 +481,21 @@
     return result, pseudo_element
 
 
+def parse_arguments(stream):
+    arguments = []
+    while 1:
+        stream.skip_whitespace()
+        next = stream.next()
+        if next.type in ('IDENT', 'STRING', 'NUMBER') or next in [
+                ('DELIM', '+'), ('DELIM', '-')]:
+            arguments.append(next)
+        elif next == ('DELIM', ')'):
+            return arguments
+        else:
+            raise SelectorSyntaxError(
+                "Expected an argument, got %s" % (next,))
+
+
 def parse_attrib(selector, stream):
     stream.skip_whitespace()
     attrib = stream.next_ident_or_star()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/cssselect/tests.py 
new/cssselect-0.9.1/cssselect/tests.py
--- old/cssselect-0.8/cssselect/tests.py        2013-03-14 19:52:38.000000000 
+0100
+++ new/cssselect-0.9.1/cssselect/tests.py      2013-10-17 15:27:16.000000000 
+0200
@@ -23,7 +23,9 @@
 from lxml import etree, html
 from cssselect import (parse, GenericTranslator, HTMLTranslator,
                        SelectorSyntaxError, ExpressionError)
-from cssselect.parser import tokenize, parse_series, _unicode
+from cssselect.parser import (tokenize, parse_series, _unicode,
+                              FunctionalPseudoElement)
+from cssselect.xpath import _unicode_safe_getattr, XPathExpr
 
 
 if sys.version_info[0] < 3:
@@ -150,6 +152,7 @@
             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'", "('")
@@ -176,6 +179,10 @@
         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')
@@ -264,8 +271,6 @@
             "Expected ident or '*', got <DELIM '#' at 1>")
         assert get_error('[foo=#]') == (
             "Expected string or ident, got <DELIM '#' at 5>")
-        assert get_error(':nth-child()') == (
-            "Expected at least one argument, got <DELIM ')' at 11>")
         assert get_error('[href]a') == (
             "Expected selector, got <IDENT 'a' at 6>")
         assert get_error('[rel=stylesheet]') == None
@@ -352,9 +357,9 @@
         assert xpath('e:hover') == (
             "e[0]")  # never matches
         assert xpath('e:contains("foo")') == (
-            "e[contains(string(.), 'foo')]")
+            "e[contains(., 'foo')]")
         assert xpath('e:ConTains(foo)') == (
-            "e[contains(string(.), 'foo')]")
+            "e[contains(., 'foo')]")
         assert xpath('e.warning') == (
             "e[@class and contains("
                "concat(' ', normalize-space(@class), ' '), ' warning ')]")
@@ -375,6 +380,11 @@
         assert xpath('div#container p') == (
             "div[@id = 'container']/descendant-or-self::*/p")
 
+        selector, = parse('e:after')
+        assert selector.pseudo_element == 'after'
+        # Pseudo-element is ignored:
+        assert GenericTranslator().selector_to_xpath(selector, prefix='') == 
"e"
+
         # Invalid characters in XPath element names
         assert xpath(r'di\a0 v') == (
             u("*[name() = 'di v']"))  # di\xa0v
@@ -436,6 +446,71 @@
         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
+
+            # functional pseudo-class:
+            # elements that have a certain number of attributes
+            def xpath_nb_attr_function(self, xpath, function):
+                nb_attributes = int(function.arguments[0].value)
+                return xpath.add_condition(
+                    "count(@*)=%d" % nb_attributes)
+
+            # pseudo-class:
+            # elements that have 5 attributes
+            def xpath_five_attributes_pseudo(self, xpath):
+                return xpath.add_condition("count(@*)=5")
+
+            # functional pseudo-element:
+            # element's attribute by name
+            def xpath_attr_functional_pseudo_element(self, xpath, arguments):
+                attribute_name = arguments[0].value
+                other = XPathExpr('@%s' % attribute_name, '', )
+                return xpath.join('/', other)
+
+            # pseudo-element:
+            # element's text() nodes
+            def xpath_text_node_simple_pseudo_element(self, xpath):
+                other = XPathExpr('text()', '', )
+                return xpath.join('/', other)
+
+            # pseudo-element:
+            # element's href attribute
+            def xpath_attr_href_simple_pseudo_element(self, xpath):
+                other = XPathExpr('@href', '', )
+                return xpath.join('/', other)
+
+        def xpath(css):
+            return _unicode(CustomTranslator().css_to_xpath(css))
+
+        assert xpath(':five-attributes') == 
"descendant-or-self::*[count(@*)=5]"
+        assert xpath(':nb-attr(3)') == "descendant-or-self::*[count(@*)=3]"
+        assert xpath('::attr(href)') == "descendant-or-self::*/@href"
+        assert xpath('::text-node') == "descendant-or-self::*/text()"
+        assert xpath('::attr-href') == "descendant-or-self::*/@href"
+        assert xpath('p img::attr(src)') == (
+            "descendant-or-self::p/descendant-or-self::*/img/@src")
+
     def test_series(self):
         def series(css):
             selector, = parse(':nth-child(%s)' % css)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/cssselect/xpath.py 
new/cssselect-0.9.1/cssselect/xpath.py
--- old/cssselect-0.8/cssselect/xpath.py        2013-03-14 19:52:38.000000000 
+0100
+++ new/cssselect-0.9.1/cssselect/xpath.py      2013-10-17 15:37:58.000000000 
+0200
@@ -26,6 +26,12 @@
     _unicode = str
 
 
+def _unicode_safe_getattr(obj, name, default=None):
+    # getattr() with a non-ASCII name fails on Python 2.x
+    name = name.encode('ascii', 'replace').decode('ascii')
+    return getattr(obj, name, default)
+
+
 class ExpressionError(SelectorError, RuntimeError):
     """Unknown or unsupported selector (eg. pseudo-class)."""
 
@@ -170,6 +176,9 @@
 
         :param css:
             A *group of selectors* as an Unicode string.
+        :param prefix:
+            This string is prepended to the XPath expression for each selector.
+            The default makes selectors scoped to the context node’s subtree.
         :raises:
             :class:`SelectorSyntaxError` on invalid selectors,
             :class:`ExpressionError` on unknown/unsupported selectors,
@@ -178,24 +187,26 @@
             The equivalent XPath 1.0 expression as an Unicode string.
 
         """
-        selectors = parse(css)
-        for selector in selectors:
-            if selector.pseudo_element:
-                raise ExpressionError('Pseudo-elements are not supported.')
-
-        return ' | '.join(
-            self.selector_to_xpath(selector, prefix)
-            for selector in selectors)
+        return ' | '.join(self.selector_to_xpath(selector, prefix,
+                                                 
translate_pseudo_elements=True)
+                          for selector in parse(css))
 
-    def selector_to_xpath(self, selector, prefix='descendant-or-self::'):
+    def selector_to_xpath(self, selector, prefix='descendant-or-self::',
+                          translate_pseudo_elements=False):
         """Translate a parsed selector to XPath.
 
-        The :attr:`~Selector.pseudo_element` attribute of the selector
-        is ignored. It is the caller's responsibility to reject selectors
-        with pseudo-elements, or to account for them somehow.
 
         :param selector:
             A parsed :class:`Selector` object.
+        :param prefix:
+            This string is prepended to the resulting XPath expression.
+            The default makes selectors scoped to the context node’s subtree.
+        :param translate_pseudo_elements:
+            Unless this is set to ``True`` (as :meth:`css_to_xpath` does),
+            the :attr:`~Selector.pseudo_element` attribute of the selector
+            is ignored.
+            It is the caller's responsibility to reject selectors
+            with pseudo-elements, or to account for them somehow.
         :raises:
             :class:`ExpressionError` on unknown/unsupported selectors.
         :returns:
@@ -207,8 +218,19 @@
             raise TypeError('Expected a parsed selector, got %r' % (selector,))
         xpath = self.xpath(tree)
         assert isinstance(xpath, self.xpathexpr_cls)  # help debug a missing 
'return'
+        if translate_pseudo_elements and selector.pseudo_element:
+            xpath = self.xpath_pseudo_element(xpath, selector.pseudo_element)
         return (prefix or '') + _unicode(xpath)
 
+    def xpath_pseudo_element(self, xpath, pseudo_element):
+        """Translate a pseudo-element.
+
+        Defaults to not supporting pseudo-elements at all,
+        but can be overridden by sub-classes.
+
+        """
+        raise ExpressionError('Pseudo-elements are not supported.')
+
     @staticmethod
     def xpath_literal(s):
         s = _unicode(s)
@@ -226,7 +248,9 @@
     def xpath(self, parsed_selector):
         """Translate any parsed selector object."""
         type_name = type(parsed_selector).__name__
-        method = getattr(self, 'xpath_%s' % type_name.lower())
+        method = getattr(self, 'xpath_%s' % type_name.lower(), None)
+        if method is None:
+            raise ExpressionError('%s is not supported.' %  type_name)
         return method(parsed_selector)
 
 
@@ -251,9 +275,7 @@
     def xpath_function(self, function):
         """Translate a functional pseudo-class."""
         method = 'xpath_%s_function' % function.name.replace('-', '_')
-        # getattr() with a non-ASCII name fails on Python 2.x
-        method = method.encode('ascii', 'replace').decode('ascii')
-        method = getattr(self, method, None)
+        method = _unicode_safe_getattr(self, method, None)
         if not method:
             raise ExpressionError(
                 "The pseudo-class :%s() is unknown" % function.name)
@@ -262,9 +284,7 @@
     def xpath_pseudo(self, pseudo):
         """Translate a pseudo-class."""
         method = 'xpath_%s_pseudo' % pseudo.ident.replace('-', '_')
-        # getattr() with a non-ASCII name fails on Python 2.x
-        method = method.encode('ascii', 'replace').decode('ascii')
-        method = getattr(self, method, None)
+        method = _unicode_safe_getattr(self, method, None)
         if not method:
             # TODO: better error message for pseudo-elements?
             raise ExpressionError(
@@ -417,7 +437,7 @@
                 % function.arguments)
         value = function.arguments[0].value
         return xpath.add_condition(
-            'contains(string(.), %s)' % self.xpath_literal(value))
+            'contains(., %s)' % self.xpath_literal(value))
 
     def xpath_lang_function(self, xpath, function):
         if function.argument_types() not in (['STRING'], ['IDENT']):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/cssselect.egg-info/PKG-INFO 
new/cssselect-0.9.1/cssselect.egg-info/PKG-INFO
--- old/cssselect-0.8/cssselect.egg-info/PKG-INFO       2013-03-15 
16:53:20.000000000 +0100
+++ new/cssselect-0.9.1/cssselect.egg-info/PKG-INFO     2013-10-17 
15:39:34.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cssselect
-Version: 0.8
+Version: 0.9.1
 Summary: cssselect parses CSS3 Selectors and translates them to XPath 1.0
 Home-page: http://packages.python.org/cssselect/
 Author: Simon Sapin
@@ -25,7 +25,7 @@
         Quick facts:
         
         * Free software: BSD licensed
-        * Compatible with Python 2.4+ and 3.x
+        * Compatible with Python 2.5+ and 3.2+
         * Latest documentation `on python.org 
<http://packages.python.org/cssselect/>`_
         * Source, issues and pull requests `on Github
           <https://github.com/SimonSapin/cssselect/>`_
@@ -37,10 +37,8 @@
 Classifier: Intended Audience :: Developers
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.4
 Classifier: Programming Language :: Python :: 2.5
 Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/docs/index.rst 
new/cssselect-0.9.1/docs/index.rst
--- old/cssselect-0.8/docs/index.rst    2012-04-24 16:59:07.000000000 +0200
+++ new/cssselect-0.9.1/docs/index.rst  2013-10-11 17:00:04.000000000 +0200
@@ -54,6 +54,8 @@
 .. autoclass:: Selector()
     :members:
 
+.. autoclass:: FunctionalPseudoElement
+
 .. autoclass:: GenericTranslator
     :members: css_to_xpath, selector_to_xpath
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/setup.py new/cssselect-0.9.1/setup.py
--- old/cssselect-0.8/setup.py  2012-04-24 17:24:50.000000000 +0200
+++ new/cssselect-0.9.1/setup.py        2013-10-15 16:54:41.000000000 +0200
@@ -34,12 +34,10 @@
         'Intended Audience :: Developers',
         'License :: OSI Approved :: BSD License',
         'Programming Language :: Python :: 2',
-        'Programming Language :: Python :: 2.4',
         'Programming Language :: Python :: 2.5',
         'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.1',
         'Programming Language :: Python :: 3.2',
     ],
     **extra_kwargs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cssselect-0.8/tox.ini new/cssselect-0.9.1/tox.ini
--- old/cssselect-0.8/tox.ini   2012-10-18 17:59:35.000000000 +0200
+++ new/cssselect-0.9.1/tox.ini 2013-10-15 16:54:16.000000000 +0200
@@ -1,6 +1,10 @@
 [tox]
-envlist = py24,py25,py26,py27,py31,py32,py33
+envlist = py25,py26,py27,py32,py33
 
 [testenv]
 deps=lxml
 commands = python cssselect/tests.py
+
+[testenv:py25]
+setenv =
+    PIP_INSECURE = 1

-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to