Repository navigation
Releases
Releases · facelessuser/soupsieve
4.1
4.1
- NEW: Soup Sieve is now thread safe, and this is now tested, including on free-threaded Python. This is assuming
read only operations on a document. Check out our documentation for more details. - FIX: Fix a race where compiling selectors in multiple threads at the same time could fail with a bogus
syntax error or silently parse a selector incorrectly. - FIX: Fix issue where trailing whitespace and comments can sometimes fail to be consumed properly.
- FIX: Fix a selector that starts with a comment followed by whitespace, such as
/* comment */ div, failing
with a syntax error. - FIX: Custom selector names should be checked with ASCII only lowercase.
- FIX: Fix
[attr=value],[attr$=value],[attr|=value], and[attr!=value]ignoring a trailing newline in
the attribute value, so[type=hidden]no longer matchestype="hidden ". - FIX: Cache the language, the
contenteditablestate, theselectof anoption, and the tree that an element
is in, as found from its ancestors, when matching:lang(),:read-write,:read-only,:checked,:default,
and:indeterminateto avoid quadratic time on deeply nested documents. - FIX: Fix
:lang('')not matching every element without any language information, which per the HTML spec has
an empty language tag. It missed the first such element checked, or all of them when there was nohead. - FIX:
:lang()no longer matches an element whose language tag is not well-formed BCP 47 syntax, such as-,
en-,en_US, or a subtag longer than 8 characters, and a language range that is not well-formed matches
nothing. Previously,lang="-"matched:lang(''), and ill-formed tags matched:lang('*'). - FIX: Fix
:lang()ranges that end in a wildcard, such asen-*or*-*, never matching. As RFC 4647 extended
filtering specifies, wildcards after the first subtag are ignored, soen-*matches the same asen. - FIX: Fix
[attr*=value]and[attr$=value]taking time quadratic in the length of the value when it nearly
matches a long attribute value, including when matching case insensitive.
4.0.1
4.0.1
- FIX: Cache whether an element is or has a matching descendant when matching
:has()to avoid quadratic time
on deeply nested documents. - FIX: Cache whether the parent matches when matching the child combinator (
a > b) so it is matched once for
all of its children, avoiding quadratic time when the parent is expensive, such asdiv:has(> p) > span.
4.0
4.0
- BREAK: The contents of an HTML
templateare no longer treated as part of the document. Selectors do not
descend into atemplate, and elements inside one can't see beyond it, which also applies to pseudo-classes such
as:lang(),:disabled, and:default.selectandfilterwill still reach the contents of atemplatewhen
they are called on thetemplateitself, for examplesoup.template.select('p'). See the
FAQ for more information. - BREAK: The contents of an
iframeare no longer treated as a separate document, as they are not one in a
browser. Elements in aniframeare normal children, so:rootdoes not match them, and:default,
:indeterminate,:checked,:dir(),:lang(), and:read-writetreat them like any other element. Recent
versions ofhtml.parser,lxml, andhtml5liball escape the contents of aniframelike a browser does, so
this mostly affects XHTML, Python versions that still don't escape such content in their specifichtml.parser,
and elements added to aniframeby hand.:-soup-contains()now also includes the escaped text in aniframe.
See the FAQ for more information. - NEW: Update
:disabledand:enabledto treatoptionandoptgroupelements inside a disabledselectas
disabled, following a recent HTML specification update. - FIX: Fix the subsequent-sibling combinator and
:has(~ ...)never matching top level elements of a fragment
that has no root element, unless caching was disabled. - FIX:
:indeterminatenow treats a radio button group without a form as extending across the whole document
instead of the top level element that contains it, and it no longer ignores radio buttons at the top level. - FIX: Fix
:defaultto treat abuttonwith a missing or invalidtype, and aninputwithtype="image",
as submit buttons. - FIX: Fix
:in-rangeand:out-of-rangeraisingTypeErrorwhen the document contains aninputwithout a
typeattribute. - FIX:
:read-write(and:read-only) now treatcontenteditable="plaintext-only"elements as editing hosts and
match the editable elements inside an editing host, following the nearestcontenteditablestate. - FIX:
:read-write(and:read-only) now ignorecontenteditableon non-HTML elements, such as an SVG
foreignObject, as the attribute only applies to HTML elements. Such elements inherit the state of their parent. - FIX:
:checkednow only matches the last radio button with acheckedattribute in a radio button group, as
in a browser, where a group is the radio buttons with the samenameand form, including theformattribute.
:defaultstill matches all of them, and the contents of atemplateare unaffected as they are not connected. - FIX:
:dir()and:definedno longer affect the rest of the selector list they are in. Previously, a selector
list that used either of them could not have its combinators cross aniframe, ignored the specified namespaces,
and matched nothing in XML, not even the parts that didn't use them. They still do not match in XML, but
:not(:dir(ltr))and:not(:defined)now do. - FIX:
:defaultand:indeterminatenow honor theformattribute, which can associate a submit button or
radio button with a form it is not in, or leave it without a form. It is ignored in atemplate, as in the HTML
specification. Submit buttons outside of a form can now be its default button. - FIX:
:default,:checked, and:indeterminatenow handle a form inside a form like a browser. In HTML, a
browser ignores the nested form and takes its end tag for that of the parent, which matters for parsers that keep
the nested form, such ashtml.parser. In XHTML and in atemplate, nested forms are real forms. - FIX:
:checkednow matches theoptionthat a browser would select. Withoutmultiple, that is only the
lastoptionwith aselectedattribute in aselect, and if there are none and theselectshows a single
option, the firstoptionthat is not disabled.:defaultstill only considers theselectedattribute. - FIX: Fix
[attribute!=value]excluding values that only start with the specified value, and in XML documents,
typevalues that contain a newline. - FIX: Match the values of every attribute that the HTML specification lists as ASCII case insensitive (
rel,
method,lang,dir, ...) without ASCII case sensitivity on HTML elements in HTML documents, not justtype.
Non-HTML elements are matched case sensitively. - FIX:
:dir()now matches non-HTML elements, such as SVG and MathML, by the direction they inherit from their
parent (thedirattribute only applies to HTML elements), and HTML elements inside them, such as in an SVG
foreignObject, by the direction of their ancestors. - FIX: Fix
:dir()ignoring the value of aninputwithdir="auto"and a missing or emptytype. - FIX:
:dir()now uses a table generated from Unicode 18 instead ofunicodedata, so results no longer depend
on the Unicode version of the Python in use, and unassigned code points use their default direction. - FIX:
:dir()now uses the value of aninputwithdir="auto"whentypeishidden,password,submit,
reset, orbutton, as the HTML specification does. - FIX:
dir="auto"andbdinow analyze the text of non-HTML elements, such as SVG and MathML, and only ignore
HTML elements such asscript,style, andbdi. The text directly in aniframeis analyzed as well, and the
contents of atemplate, which are not part of the document, are not. - FIX:
:dir()no longer lets the contents of atemplateinherit direction from thetemplateor its
ancestors, as they are not part of the document. They are left to right unless they specify otherwise. - FIX:
:dir()now matches abdielement that is the root by its text instead of assuming left to right. - FIX:
:dir()now treats any element without a parent element as left to right, not just the root. Before,
all but the first top level element of a fragment parsed withhtml.parsernever matched. - FIX:
:dir()now accepts any identifier, as CSS requires, including escaped ones. Values other thanltrand
rtldo not match anything. - FIX: Respect namespaces provided by the parser when the root is not an HTML element, such as an
svgelement
extracted from anhtml5libdocument. Previously every element in such a tree was treated as an HTML element,
which affected namespace selectors, namespaced attributes, and HTML specific pseudo-classes. - FIX: Fix
:lang()treating an element with an emptylangorxml:langattribute as having the language of
a tagged ancestor. - FIX: Cache forms without a default button when matching
:defaultto avoid quadratic time on forms with
many non-default submit candidates. - FIX: Fix
:in-rangeand:out-of-rangematching elements whose value,min, ormaxhas a trailing newline;
per HTML, such values are not valid, so they are treated like a missing value and cannot be out of range. - FIX: Fix
:in-rangeand:out-of-rangeraisingValueErrorwhen a date, month, week, or local date and
timeinputhas a year with more digits than Python will convert; such a year is now treated as invalid. - FIX: Fix
:in-rangeand:out-of-rangenot recognizing adatetime-localvalue,min, ormaxthat uses a
single space instead ofTto separate the date and time. - FIX: Search a form only once for checked radio buttons when matching
:indeterminateto avoid quadratic time
on forms with many radio button groups. - FIX:
:lang()now uses thelangattribute of SVG elements, as the HTML specification does (withxml:lang
taking precedence). Previously onlyxml:langwas considered for elements outside the HTML namespace. - FIX:
:definedno longer matches HTML elements with anisattribute (customized built-in elements), which,
like custom elements, are undefined until they are registered. - FIX: Cache the index of each child when matching the general sibling combinator (
a ~ band:has(~ b)) to
avoid quadratic time when the first matching sibling is far into a long list of siblings. - FIX: Match attribute values with the
imodifier using ASCII case insensitivity. - FIX: Treat an
inputwith an unknowntype, such astype="foo", as a text input in:placeholder-shown,
:read-write,:read-onlyand:dir(), as an invalidtypeis in the Text state in the HTML specification. - FIX: Fix
:enabledand:disablednever matchinginputelements withtype="hidden". - FIX:
:requiredno longer matchesinputelements of types therequiredattribute does not apply to
(hidden,range,color,submit,image,resetandbutton). Like in browsers, they match:optional. - FIX: Cache whether an element is or has a matching ancestor when matching the descendant combinator (
a b) to
avoid time that grows with the depth of the document to the power of the number of combinators.
3.0.4
3.0.4
- FIX: Keep own and descendant text separate when combining
:-soup-contains()and:-soup-contains-own(). - FIX: Cache resolved directionality when matching
:dir()to avoid quadratic time on deeply nested
dir="auto"elements. - FIX: Fix
autohandling in regard to:dir()selector. When an element withdir="auto"(or a<bdi>)
contains no strong direction characters, it should be assumed as left-to-right and not assume the direction of the
parent. - FIX: Match numeric input ranges correctly when values or bounds use scientific notation.
- FIX: Fix
:in-rangeand:out-of-rangeraisingValueErrorforweekinputs whose week-year is 10000 or
greater. - FIX: Fix
:nth-last-child(an+b of S)matching the wrong elements when the first sibling tested does not
matchS. - FIX:
escape()now only leaves non-ASCII identifier code points unescaped, as defined by the CSS specification.
All other non-ASCII characters are escaped. - FIX: Allow unescaped U+0080 - U+009F characters in identifiers to match browser behavior.
- FIX: Fix
:in-rangeand:out-of-rangetreatingtimeanddatetime-localvalues with seconds as
invalid.
3.0.3
3.0.3
- FIX: When matching with
>, theBeautifulSoupobject should not count as a parent. - FIX: Fix case where relative sibling matching under
:has(~)would incorrectly match a sibling that came before
the target element.
3.0.2
3.0.2
- FIX: Python versions less than 3.11.5 have broken possessive quantifiers, so require at least 3.11.5 for Soup
Sieve 3.0+. 3.0 and 3.0.1 will be yanked from PyPI to avoid having the 3.0 series installed on Python < 3.11.5
which will cause the library to be broken.
3.0.1
3.0.1
- FIX: Fix regression related to
[attribute!=value]where previously it would match if the attribute was not
present and recent changes broke that. Essentially,[attribute!=value]should be the same as
:not([attribute=value]).
3.0
3.0
- BREAK:
:has(), by default, now behaves according to CSS more strictly, disallowing complex selectors that use
combinators and prevents nesting:has()within:has(). This gives a safer, more performant default for Soup
Sieve. If in a safe environment, these restrictions can be lifted by passing the newNOSTRICTflag restoring
behavior to before 3.0. - BREAK: Custom selectors must be provided in order. If one custom selector depends on another custom selector,
the custom selector dependency must be defined first in the dictionary. This eliminates recursive processing of
custom selectors. Users are encouraged to pre-compile custom selectors via
my_selectors = soupsive.CustomSelectors({custm: selector, ...}). - NEW: Drop Python 3.10.
- NEW: Aggressively use possessive quantifiers and atomic groups in CSS pattern parsing to reduce backtracking.
- NEW: Eliminate recursion within the parser and the matcher.
- NEW: Expose new parameter
max_selectorsthat can be used to control the maximum allowed selectors in a given
input. - FIX: A CSS escape that is a surrogate, or past the Unicode range, is
U+FFFD. (#307)
2.10
2.10
- NEW: Support Python 3.15.
- NEW: Add new
ignoreoption to API methods that allows the specification of specific pseudo-classes to be
ignored. - NEW: Tighten restrictions such that
namespacesandcustomobjects must always be a Mapping, previously lists
of tuples were also allowed. - NEW: Use a singleton for null selectors internally via called
Nullof typeSelectorNull. - NEW: For performance, Soup Sieve will no longer try and coerce bad attribute values to useable strings.
- NEW: Add
NOCACHEflag that can be used to disable caching optimizations selectors and possibly other future
caching optimizations. Provided for disabling and also disabling if issues are found with the new caching approach. - FIX: Improve performance of
~for various cases by employing caching. - FIX: Improve performance of
nth-*family of selectors in certain scenarios by employing caching. - FIX: Ensure
customis properly passed down from API functions to compilation.
2.9.2
2.9.2
- FIX: Fix issue where
:is()and:where()were not accounting for empty selectors in the max selector count as
they should (@arpitjain099). - FIX: Fix issue where
:has()was allowing empty selectors in some circumstances even though it is not
forgiving. - FIX: Reduce selector object size when
:is()and:where()contain empty selectors.