Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Let extended translators override what XPathExpr class is used

GenericTranslator offers an excelent way to support custom selectors
trough method hooks and allowing to return a *new* XPathExpr from this

The main problem is that returning extended `XPathExpr` instances fail
for combiners because `XPathExpr.join()` assume a fixed XPathExpr
instance attributes (element, path and condition) to copy from `other` to `self`

`XPathExpr.join()` can be extended in subclass but needs that `left`
xpath instance to be of the extended class too, and right now we can
only control `right` xpath type.

The problem can be mitigated by recasting all xpath returned from
`GenericTranslator.xpath_element()` that only works because it is the
only hook that cast `XPathExpr` instances.

The proposed change allow projects extending GenericTranslator to also
safely extend `XPathExpr` to correctly support combiners in extended
  • Loading branch information...
commit 91e752d4994f3d95b89b850b96672f47418623d8 1 parent 653a5a5
@dangra dangra authored
Showing with 5 additions and 2 deletions.
  1. +5 −2 cssselect/
7 cssselect/
@@ -146,6 +146,9 @@ class GenericTranslator(object):
lower_case_attribute_names = False
lower_case_attribute_values = False
+ # class used to represent and xpath expression
+ xpathexpr_cls = XPathExpr
def css_to_xpath(self, css, prefix='descendant-or-self::'):
"""Translate a *group of selectors* to XPath.
@@ -190,7 +193,7 @@ def selector_to_xpath(self, selector, prefix='descendant-or-self::'):
if not tree:
raise TypeError('Expected a parsed selector, got %r' % (selector,))
xpath = self.xpath(tree)
- assert isinstance(xpath, XPathExpr) # help debug a missing 'return'
+ assert isinstance(xpath, self.xpathexpr_cls) # help debug a missing 'return'
return (prefix or '') + _unicode(xpath)
@@ -305,7 +308,7 @@ def xpath_element(self, selector):
element = '%s:%s' % (selector.namespace, element)
safe = safe and is_safe_name(selector.namespace)
- xpath = XPathExpr(element=element)
+ xpath = self.xpathexpr_cls(element=element)
if not safe:
return xpath
Please sign in to comment.
Something went wrong with that request. Please try again.