Skip to content

Fix :in-range and :out-of-range on inputs without a type - #326

Merged
facelessuser merged 1 commit into
facelessuser:mainfrom
lprnmns:fix-range-untyped-input
Oct 22, 2026
Merged

facelessuser merged 1 commit into
facelessuser:mainfrom
lprnmns:fix-range-untyped-input

Conversation

@lprnmns

@lprnmns lprnmns commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

:in-range and :out-of-range raise a TypeError as soon as the document contains an input without a type attribute:

import soupsieve as sv
from bs4 import BeautifulSoup

soup = BeautifulSoup('<form><input name="q"><input type="number" min="1" max="3" value="5"></form>', 'html.parser')
sv.select(':out-of-range', soup)
# TypeError: 'NoneType' object is not iterable  (soupsieve/util.py, in lower)

It happens with html.parser, lxml and html5lib, and on 2.7 and 3.0.0 through 3.0.4 as well as main.

In _match_selectors the range check runs right after the attribute check, but the [type=...] filter of the :in-range/:out-of-range pattern lives in an :is(...) sub-selector, which is evaluated later. So match_range() is called for every input, and util.lower(self.get_attribute_by_name(el, 'type')) gets None when there is no type attribute.

This passes '' as the default, as other attribute lookups do. An untyped input is a text input, so Inputs.parse_value() returns None for its bounds and match_range() returns False before the :is([type=...]) filter would reject it anyway. Chrome agrees on the new test markup: :in-range matches only #1 and :out-of-range only #2.

Tests: test_in_range_untyped_input and test_out_of_range_untyped_input fail on main with the TypeError and pass with the change. pytest tests (428 passed), ruff check . and mypy pass. I added a changelog entry under "Unreleased".

@gir-bot gir-bot added S: needs-review Needs to be reviewed and/or approved. C: css-level-4 CSS level 4 selectors. C: css-matching Related to CSS matching. C: docs Related to documentation. C: source Related to source code. C: tests Related to testing. labels Oct 22, 2026
@facelessuser

Copy link
Copy Markdown
Owner

@gir-bot lgtm

@gir-bot gir-bot added S: approved The pull request is ready to be merged. and removed S: needs-review Needs to be reviewed and/or approved. labels Oct 22, 2026
@facelessuser
facelessuser merged commit 69af65d into facelessuser:main Oct 22, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C: css-level-4 CSS level 4 selectors. C: css-matching Related to CSS matching. C: docs Related to documentation. C: source Related to source code. C: tests Related to testing. S: approved The pull request is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants