Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support recursive NamedTuple classes #13029

Closed
wants to merge 2 commits into from

Conversation

niklasl
Copy link

@niklasl niklasl commented Jun 26, 2022

Description

Recursive named tuple classes like this now pass:

from __future__ import annotations
from typing import NamedTuple

class Node(NamedTuple):
    parent: Node | None

(Instead of causing a Cannot resolve name "MyNamedTuple" (possible cyclic definition) error.)

This is done by letting mypy.semanal_namedtuple.analyze_namedtuple_classdef complete recursive type references in a subsequent pass.

Fixes #9397.

Test Plan

Tests are updated to reflect this new support. (I did not add my own use case above since the existing tests already cover this feature which previously caused the error (along with many more special cases).)

Questions

I believe this change is good, but it raises some questions.

  1. The now conditional call to add_symbol in mypy.semanal.prepare_class_def does add to the somewhat complex situation already in there, regarding func scope nesting. I tried to make the logic clear, but would you prefer me to attempt to improve it further?

    (I did note the already present TODO in there. It seems hard to get at the clarity without untangling that, which I think is a separate task. I initially added a flag to avoid the double check, which I can't say made it more understandable, but rather indicated the already noted need for a refactoring.)

  2. Related but distinct, an odd error cropped up in check-incremental.test::testIncrementalWithDifferentKindsOfNestedTypesWithinMethod which made lookup_fully_qualified throw an error:

    E   AssertionError: Cannot find component 'NT1@11' for 'b.NT1@11'
    

    Somehow this is prevented by a call to reveal_type (regardless of value). Did I stumble upon a separate issue, or is there an obvious mistake in this change?

  3. In check-namedtuple.test::testSelfRefNT4 it is shown that reveal_type for an item-accessed named tuple value now returns builtins.object instead of Any. While it is beyond the scope of this PR to fix type-inference for named tuple item access in general, would you consider the resulting semantics a regression or an improvement?

  4. I used a for ... else in analyze_namedtuple_classdef since (IMHO) it's a good fit and made things clearer. But if you're adverse to that language feature I can change it (and if so reasonably also advice against it in the coding conventions).

This is done by letting
`mypy.semanal_namedtuple.analyze_namedtuple_classdef` complete recursive
type references in a subsequent pass.

Fixes python#9397.
@github-actions

This comment has been minimized.

Define explicit `None` return type.

Co-authored-by: Alex Waygood <[email protected]>
@github-actions
Copy link
Contributor

According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉

@niklasl niklasl requested a review from AlexWaygood July 13, 2022 14:49
@AlexWaygood
Copy link
Member

I'm not a mypy core dev, and know very little about the parts of mypy that provide namedtuple support, so I'm not a good reviewer for this PR, sorry :)

@AlexWaygood AlexWaygood removed their request for review July 13, 2022 14:51
@niklasl
Copy link
Author

niklasl commented Jul 13, 2022

@AlexWaygood I see; no problem!

Copy link
Collaborator

@hauntsaninja hauntsaninja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the PR! This is a tricky feature to contribute to a tricky codebase. But superseded by https://github.com/python/mypy/pull/13371/files

@niklasl
Copy link
Author

niklasl commented Aug 10, 2022

@hauntsaninja Thanks for the feedback! I'm glad progress is being made on this in any case (and at least I got some insight into the codebase from this attempt).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support recursive NamedTuple
3 participants