Widen tarfile.open() preset to int - #16443
Merged
Merged
Conversation
`tarfile.open()` typed `preset` as `Literal[0, ..., 9] | None`, which rejects `9 | lzma.PRESET_EXTREME` even though that is the documented way to request extreme compression. `_lzma.LZMACompressor` and `TarFile.xzopen()` already type the same parameter as `int | None`, so the three now agree. Widening loses the static rejection of out-of-range values: `preset=-1` raises OverflowError at runtime and `preset=10` raises LZMAError. The test case is updated to cover the PRESET_EXTREME form instead. Fixes python#16442
Contributor
|
Diff from mypy_primer, showing the effect of this PR on open source code: nionutils (https://github.com/nion-software/nionutils)
+ error: INTERNAL ERROR -- Please try using mypy master on GitHub:
+ https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
+ Please report a bug at https://github.com/python/mypy/issues
+ version: 2.3.0
+ note: use --pdb to drop into pdb
+ Traceback (most recent call last):
+ File "/__main__.py", line 16, in console_entry
+ main()
+ ~~~~^^
+ File "mypy/main.py", line 154, in main
+ File "mypy/main.py", line 244, in run_build
+ res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
+ File "mypy/build.py", line 385, in build
+ File "mypy/build.py", line 1908, in create_metastore
+ mds: MetadataStore = SqliteMetadataStore(
+ File "mypy/metastore.py", line 200, in __init__
+ File "mypy/metastore.py", line 174, in connect_db
+ db.execute("PRAGMA journal_mode=WAL")
+ sqlite3.OperationalError: database is locked
+
|
srittau
approved these changes
Sep 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #16442.
tarfile.open()typespresetasLiteral[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] | None,so the documented way to ask for extreme compression is rejected:
lzma.PRESET_EXTREMEis a flag you or onto the preset level, so
9 | lzma.PRESET_EXTREMEis9 | 0x80000000= 2147483657 — not a member of theLiteral.tarfile.open()passes
presetstraight through toTarFile.xzopen(), which hands it tolzma.LZMAFile, so the value it accepts is whateverlzmaaccepts.The two sibling APIs already use the lenient type, so this change makes the
three agree:
stdlib/tarfile.pyi—TarFile.open()x2Literal[0..9] | Noneint | Nonestdlib/tarfile.pyi—TarFile.xzopen()int | Nonestdlib/_lzma.pyi—LZMACompressorint | NoneThe trade-off
Widening to
intgives up static rejection of out-of-range values. Those nowfail at runtime instead of at type-check time:
preset=-1raisesOverflowError: can't convert negative int to unsigned, andpreset=10raisesLZMAError: Invalid or unsupported options.That is the same trade-off
_lzma.pyiandxzopen()already make, and theLiteralcannot express "0-9, optionally or-ed withPRESET_EXTREME" withoutenumerating both ranges. If you would rather keep the narrow form, the
alternative is
Literal[0..9] | intspelled as a separate alias — say the wordand I will switch it.
Test case
stdlib/@tests/test_cases/check_tarfile.pyasserted the old behaviour:Those
type: ignorecomments become unused under the new signature, whichfails
regr_test.py. They are replaced with a case covering the actual bug.Note that
mypy --warn-unused-ignoresdoes not surface this when run on filesinside typeshed; it only appears once the test case is copied out, the way
tests/regr_test.pydoes it.Verification
Windows 11, mypy 2.3.0, Python 3.12.
Reproduction before the change, and clean after:
preset="nine"is still rejected.