WIP: adds better `namedtuple` semantic analyzer
This is almost a complete rewrite of inline NamedTuple and namedtuple semantic analyzer.
Changelog:
-
NamedTuplenow supports**kwargsas it should -
NamedTupleandnamedtuplenow have better validation for fields: keywords, underscores, duplication: basically the same ascollections.namedtupledoes at runtime -
namedtuplenow supportsrenameargument (it actually renames invalid fields) - We now also check
NamedTuple()andnamedtuple()calls during typechecking, this allows us to simplify the setup - Namedtuples no longer think that
bytesare valid arguments onpython3 -
NamedTupleandnamedtuplenow support named arguments as they should - I've moved all errors to a single place, now
semanal.pydoes not raise any namedtuple-expr-related errors - More consistent errors: I've copied texts from runtime version of
collections.namedtuple, added""everywhere
This is still WIP, but I've wrote several tests for this in testsemanal.py. They are passing. And self check also passes.
I can continue to work on this after #11162 is merged or rejected. Because I need better typing fixtures for NamedTuple type.
Closes #11047
Diff from mypy_primer, showing the effect of this PR on open source code:
optuna (https://github.com/optuna/optuna.git)
- tests/integration_tests/test_chainer.py:83: error: First argument to namedtuple() should be "MockTrainer", not "_MockTrainer"
+ tests/integration_tests/test_chainer.py:83: error: First argument to "namedtuple()" should be "MockTrainer", not "_MockTrainer"
- tests/integration_tests/test_chainer.py:84: error: First argument to namedtuple() should be "MockUpdater", not "_MockUpdater"
+ tests/integration_tests/test_chainer.py:84: error: First argument to "namedtuple()" should be "MockUpdater", not "_MockUpdater"
- tests/integration_tests/test_chainer.py:97: error: First argument to namedtuple() should be "MockTrainer", not "_MockTrainer"
+ tests/integration_tests/test_chainer.py:97: error: First argument to "namedtuple()" should be "MockTrainer", not "_MockTrainer"
pandas (https://github.com/pandas-dev/pandas.git)
+ pandas/core/frame.py:1355: error: unused "type: ignore" comment
+ pandas/core/frame.py:1356: error: "namedtuple()" expects a string literal as the typename argument [misc]
manticore (https://github.com/trailofbits/manticore.git)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
- manticore/native/cpu/aarch64.py:44: error: First argument to namedtuple() should be "Condspec", not "CondSpec"
+ manticore/native/cpu/aarch64.py:44: error: First argument to "namedtuple()" should be "Condspec", not "CondSpec"
- manticore/native/cpu/aarch64.py:79: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/aarch64.py:79: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
paasta (https://github.com/yelp/paasta.git)
- paasta_tools/iptables.py:23: error: First argument to namedtuple() should be "_RuleBase", not "Rule"
+ paasta_tools/iptables.py:23: error: First argument to "namedtuple()" should be "_RuleBase", not "Rule"
Diff from mypy_primer, showing the effect of this PR on open source code:
optuna (https://github.com/optuna/optuna.git)
- tests/integration_tests/test_chainer.py:83: error: First argument to namedtuple() should be "MockTrainer", not "_MockTrainer"
+ tests/integration_tests/test_chainer.py:83: error: First argument to "namedtuple()" should be "MockTrainer", not "_MockTrainer"
- tests/integration_tests/test_chainer.py:84: error: First argument to namedtuple() should be "MockUpdater", not "_MockUpdater"
+ tests/integration_tests/test_chainer.py:84: error: First argument to "namedtuple()" should be "MockUpdater", not "_MockUpdater"
- tests/integration_tests/test_chainer.py:97: error: First argument to namedtuple() should be "MockTrainer", not "_MockTrainer"
+ tests/integration_tests/test_chainer.py:97: error: First argument to "namedtuple()" should be "MockTrainer", not "_MockTrainer"
manticore (https://github.com/trailofbits/manticore.git)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
- manticore/native/cpu/aarch64.py:44: error: First argument to namedtuple() should be "Condspec", not "CondSpec"
+ manticore/native/cpu/aarch64.py:44: error: First argument to "namedtuple()" should be "Condspec", not "CondSpec"
- manticore/native/cpu/aarch64.py:79: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/aarch64.py:79: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas.git)
+ pandas/core/frame.py:1355: error: unused "type: ignore" comment
+ pandas/core/frame.py:1356: error: "namedtuple()" expects a string literal as the typename argument [misc]
paasta (https://github.com/yelp/paasta.git)
- paasta_tools/iptables.py:23: error: First argument to namedtuple() should be "_RuleBase", not "Rule"
+ paasta_tools/iptables.py:23: error: First argument to "namedtuple()" should be "_RuleBase", not "Rule"
This PR would also help us a lot: https://github.com/python/typeshed/pull/6080
Since we now typecheck NamedTupleExpr.call, together with that PR it can detect cases, when we use invalid kwargs and fields combination.
Diff from mypy_primer, showing the effect of this PR on open source code:
optuna (https://github.com/optuna/optuna.git)
- tests/integration_tests/test_chainer.py:83: error: First argument to namedtuple() should be "MockTrainer", not "_MockTrainer"
+ tests/integration_tests/test_chainer.py:83: error: First argument to "namedtuple()" should be "MockTrainer", not "_MockTrainer"
- tests/integration_tests/test_chainer.py:84: error: First argument to namedtuple() should be "MockUpdater", not "_MockUpdater"
+ tests/integration_tests/test_chainer.py:84: error: First argument to "namedtuple()" should be "MockUpdater", not "_MockUpdater"
- tests/integration_tests/test_chainer.py:97: error: First argument to namedtuple() should be "MockTrainer", not "_MockTrainer"
+ tests/integration_tests/test_chainer.py:97: error: First argument to "namedtuple()" should be "MockTrainer", not "_MockTrainer"
pandas (https://github.com/pandas-dev/pandas.git)
+ pandas/core/frame.py:1355: error: unused "type: ignore" comment
+ pandas/core/frame.py:1356: error: "namedtuple()" expects a string literal as the typename argument [misc]
manticore (https://github.com/trailofbits/manticore.git)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
- manticore/native/cpu/aarch64.py:44: error: First argument to namedtuple() should be "Condspec", not "CondSpec"
+ manticore/native/cpu/aarch64.py:44: error: First argument to "namedtuple()" should be "Condspec", not "CondSpec"
- manticore/native/cpu/aarch64.py:79: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/aarch64.py:79: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
paasta (https://github.com/yelp/paasta.git)
- paasta_tools/iptables.py:23: error: First argument to namedtuple() should be "_RuleBase", not "Rule"
+ paasta_tools/iptables.py:23: error: First argument to "namedtuple()" should be "_RuleBase", not "Rule"
I finally have the time to continue my work!
All PRs that I needed: https://github.com/python/typeshed/pull/6080 / https://github.com/python/mypy/pull/11303 / https://github.com/python/mypy/pull/11162 are merged!
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore.git)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
- manticore/native/cpu/aarch64.py:44: error: First argument to namedtuple() should be "Condspec", not "CondSpec"
+ manticore/native/cpu/aarch64.py:44: error: First argument to "namedtuple()" should be "Condspec", not "CondSpec"
- manticore/native/cpu/aarch64.py:79: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/aarch64.py:79: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas.git)
+ pandas/core/frame.py:1338: error: unused "type: ignore" comment
+ pandas/core/frame.py:1339: error: "namedtuple()" expects a string literal as the typename argument [misc]
All check-namedtuple.test cases are passing. Still a lot to fix though.

Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore.git)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
- manticore/native/cpu/aarch64.py:44: error: First argument to namedtuple() should be "Condspec", not "CondSpec"
+ manticore/native/cpu/aarch64.py:44: error: First argument to "namedtuple()" should be "Condspec", not "CondSpec"
- manticore/native/cpu/aarch64.py:79: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/aarch64.py:79: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas.git)
+ pandas/core/frame.py:1338: error: unused "type: ignore" comment
+ pandas/core/frame.py:1339: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
pandas (https://github.com/pandas-dev/pandas.git)
+ pandas/core/frame.py:1338: error: unused "type: ignore" comment
+ pandas/core/frame.py:1339: error: "namedtuple()" expects a string literal as the typename argument [misc]
manticore (https://github.com/trailofbits/manticore.git)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
- manticore/native/cpu/aarch64.py:44: error: First argument to namedtuple() should be "Condspec", not "CondSpec"
+ manticore/native/cpu/aarch64.py:44: error: First argument to "namedtuple()" should be "Condspec", not "CondSpec"
- manticore/native/cpu/aarch64.py:79: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/aarch64.py:79: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
manticore (https://github.com/trailofbits/manticore)
- manticore/native/cpu/x86.py:147: error: First argument to namedtuple() should be "Regspec", not "RegSpec"
+ manticore/native/cpu/x86.py:147: error: First argument to "namedtuple()" should be "Regspec", not "RegSpec"
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
You might use WORD_SIZE*1 and WORD_SIZE*2 to fix the failure on win32
@97littleleaf11 thank you! Can you please be more specific? 🙂 I don't understand your idea.
@sobolevn You can just replace +4 with + WORD_SIZE*1 and replace +8 with + WORD_SIZE*2 in testTypeAlias_toplevel.
Diff from mypy_primer, showing the effect of this PR on open source code:
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Diff from mypy_primer, showing the effect of this PR on open source code:
pandas (https://github.com/pandas-dev/pandas)
+ pandas/core/frame.py:1402: error: Unused "type: ignore" comment
+ pandas/core/frame.py:1403: error: "namedtuple()" expects a string literal as the typename argument [misc]
Awesome, thank you, @97littleleaf11 It now works.
I will add more tests for .call type checking. And this will be ready to be reviewed.