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

gh-104504: cases generator: Add --warn-unreachable to the mypy config #108112

Merged
merged 9 commits into from
Aug 20, 2023

Conversation

AlexWaygood
Copy link
Member

@AlexWaygood AlexWaygood commented Aug 18, 2023

Backport typing.assert_never to the cases_generator directory, so that mypy doesn't complain about the fact that we're using a feature new in Python 3.11 when we have --python-version 3.10 in our config file.

@AlexWaygood AlexWaygood changed the title cases generator: Add --warn-unreachable to the mypy config gh-104504: cases generator: Add --warn-unreachable to the mypy config Aug 18, 2023
Tools/cases_generator/generate_cases.py Show resolved Hide resolved
@@ -388,7 +388,6 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
case parsing.Macro():
format = self.macro_instrs[thing.name].instr_fmt
case parsing.Pseudo():
format = None
Copy link
Member Author

Choose a reason for hiding this comment

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

Similarly, here mypy was eagerly narrowing the type of format to None, meaning that it was inferring the else branch on line 396 to be unreachable.

Copy link
Member

Choose a reason for hiding this comment

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

Still feels like a mypy bug to me, but your fix is fine.

@AlexWaygood
Copy link
Member Author

AlexWaygood commented Aug 18, 2023

Cc. @corona10, @sobolevn

@AlexWaygood AlexWaygood marked this pull request as ready for review August 20, 2023 15:18
@AlexWaygood
Copy link
Member Author

AlexWaygood commented Aug 20, 2023

@gvanrossum, are you happier with the new refactor? Now pushed and popped are always str, never None, in get_stack_effect_info(). Similarly, format is always str, never None, in write_metadata(). It resolves the mypy reachability-analysis issue just as well as my previous idea, and keeps the symmetry between the branches that we have on main.

@AlexWaygood AlexWaygood requested a review from gvanrossum August 20, 2023 15:23
@AlexWaygood
Copy link
Member Author

(The test_concurrent_futures failure on Azure Pipelines is unrelated)

Copy link
Member

@gvanrossum gvanrossum left a comment

Choose a reason for hiding this comment

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

Let's check this in.

# Calculate stack effect, and check that it's the the same
# for all targets.
for target in self.pseudos[thing.name].targets:
for idx, target in enumerate(self.pseudos[thing.name].targets):
Copy link
Member

Choose a reason for hiding this comment

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

Clever idea. I wrote a whole paragraph arguing against using enumerate() here, then realized it wasn't worth arguing over. :-)

Copy link
Member

Choose a reason for hiding this comment

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

FYI, the saga continues. Currently we get errors from pyright on this: "popped is possibly unbound" (on all occurrences of popped and pushed in this function below here).

Copy link
Member Author

Choose a reason for hiding this comment

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

FYI, the saga continues. Currently we get errors from pyright on this: "popped is possibly unbound" (on all occurrences of popped and pushed in this function below here).

Yeah, and mypy will also give you that error if you add --enable-error-code=possibly-undefined to the mypy config :/

There is a third way of fixing this. I'll make a PR and see how you like it.

@@ -388,7 +388,6 @@ def write_metadata(self, metadata_filename: str, pymetadata_filename: str) -> No
case parsing.Macro():
format = self.macro_instrs[thing.name].instr_fmt
case parsing.Pseudo():
format = None
Copy link
Member

Choose a reason for hiding this comment

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

Still feels like a mypy bug to me, but your fix is fine.

@AlexWaygood AlexWaygood merged commit 05ef4ca into python:main Aug 20, 2023
@AlexWaygood AlexWaygood deleted the cases-generator-reachability branch August 20, 2023 23:40
@AlexWaygood
Copy link
Member Author

Thanks for the review!

Comment on lines +389 to 395
if idx == 0:
format = target_instr.instr_fmt
else:
assert format == target_instr.instr_fmt
assert format is not None
case _:
typing.assert_never(thing)
assert_never(thing)
all_formats.add(format)
Copy link
Member

Choose a reason for hiding this comment

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

And ditto here for format.

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

Successfully merging this pull request may close these issues.

4 participants