python-jsonschema / python-jsonschema/jsonschema
regex format checker crashes with ValueError on conflicting inline flags
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5k
- Forks
- 671
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 10
Description
The regex format checker is registered with raises=re.error:
@_checks_drafts(name="regex", raises=re.error)
def is_regex(instance: object) -> bool:
if not isinstance(instance, str):
return True
return bool(re.compile(instance))
FormatChecker.check only converts the declared exception into a FormatError. But re.compile raises ValueError (not an re.error subclass) when a pattern sets two incompatible inline flags, so the exception escapes uncaught and the format check crashes instead of reporting the string as an invalid regex.
Reproduction
from jsonschema import FormatChecker
fc = FormatChecker()
fc.conforms("[unterminated", "regex") # False - re.error, caught correctly
fc.conforms("(?u)(?a)", "regex") # ValueError: ASCII and UNICODE flags are incompatible
Also reproduces with the flags in the other order ("(?a)(?u)"). Note that "(?ua)" - both flags in a single group - returns False correctly, so this is specific to the two-group form.
Expected
"(?u)(?a)" is not a valid regular expression, so the instance should be reported as invalid, exactly like "[unterminated" is.
Cause
ValueError is not a subclass of re.error:
>>> import re
>>> issubclass(ValueError, re.error)
False
>>> re.error.__mro__
(<class 're.PatternError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>)
so raises=re.error does not cover it.
Related
Same root cause as #1526 (OverflowError on an oversized repeat count) and #1538 (RecursionError on deep nesting) - three exception types, one declaration that only catches re.error.
There is a fourth case worth mentioning because it shows the set is not stable across CPython versions: "(?(1)a|b)" (a conditional) raised an uncaught RuntimeError on Python 3.9.6, but on 3.13 re.compile raises re.error for it and it is now handled correctly. So which exception types escape depends on the CPython release, not just on jsonschema.
Given three open issues with one cause, it may be worth widening what is_regex catches rather than adding types one at a time - re.compile does not document re.error as the only exception it can raise.
Versions
Reproduced on:
- jsonschema 4.26.0, Python 3.13.11
- jsonschema 4.25.1, Python 3.9.6
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the regex format checker and FormatChecker.check, then inspect the existing handling for re.error and the related issues #1526 and #1538. Add regression coverage for conflicting inline flags and the other reported escaping cases, and verify invalid patterns return False or a FormatError without an uncaught exception across supported Python versions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100