Repository navigation
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #220 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 3 3
Lines 1019 1021 +2
Branches 170 171 +1
=========================================
+ Hits 1019 1021 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I am not sure about this one. Given nested |
|
fair point, the spec rule doesn't mean cssselect has to reject it. I checked master and nested so all this PR really buys is cutting off the per-level cost. that could also be handled the way #219 did for |
nested :has() is accepted and its XPath blows up per level
selectors 4 says :has() can't be nested (browsers reject
a:has(b:has(c))), but the parser takes it directly, after a combinator in the argument, or through:is()/:where()/:not(). each level becomes a predicate nested in the previous one, and libxml2 re-evaluates it for every node the outer axis reaches, so one short selector can stall anything that runs user-supplied selectors on fetched pages (parsel/scrapy-based scraping APIs). on lxml,i:has(~ i:has(~ i:has(~ x)))(28 chars) takes 1.5 s on a flat list of 300<i/>, and*:has(*:has(*:has(*:has(x))))(29 chars) takes 20 s on a 200-deep document; every extra level multiplies that again. these now raiseSelectorSyntaxError("Got nested :has()")by threading the existinginside_relative_selectorflag through the whole:has()argument;:scopewas already rejected at all those positions so nothing else changes.