Skip to content

Replace lists with tuples to improve type-inferrence - #17194

Closed
freundTech wants to merge 1 commit into
zulip:masterfrom
freundTech:better-config-type
Closed

freundTech wants to merge 1 commit into
zulip:masterfrom
freundTech:better-config-type

Conversation

@freundTech

Copy link
Copy Markdown

I recently submitted a PR to mypy, which improves handling of generic types. This PR, if accepted, would lead to a type-error being reported in your code which was previously not reported.
I described it in detail here in the mypy PR: python/mypy#9994 (comment)

Testing plan: I ran mypy, both the current version and the version with my PR against the source code

@freundTech

Copy link
Copy Markdown
Author

The workflow failure seems to be related to CircleCI and not caused by my code. Maybe a rerun can fix it. CircleCI won't let the PR author trigger a rerun by themselves though.

@timabbott

Copy link
Copy Markdown
Member

You can always rerun by rebasing, but I'm comfortable merging given the nature of the failure.

@timabbott

Copy link
Copy Markdown
Member

@freundTech can you explain your reasoning for why you think those objects should be tuples rather than lists?

@freundTech

Copy link
Copy Markdown
Author

The main reason those should be tuples is that the contained types are heterogeneous. The first entry is a value (object), the second a description (str).
Lists are homogeneous, therefor all entries are of the same type.

In addition Lists are mutable and therefor invariant. This means that for B subtype of A List[B] is not a subtype of List[A]
Tuples are immutable and therefor contravariant. This means that for B subtype A Tuple[B] is a subtype of Typle[A]

Using a tuple allows mypy to infer the types as Tuple[List[Tuple[str, str, int]], str], Tuple[int, str] and Tuple[bool, str] which are joined to Tuple[object, str]
With a List mypy currently infers List[object] for all three, which are then joined to List[object].
If my PR is accepted by mypy it would instead infer List[Sequence[Sequence[object]] for the first (which is also correct, but more specific) and List[object] for the other two. Because lists are invariant they can't be combined to List[object] (despite Sequence[Sequence[object]] being a subtype of object) and are instead combined to object

This then goes on to cause a type-error in line 2044, because you obviously can't use an index accessor on object

@showell

showell commented Feb 5, 2021

Copy link
Copy Markdown
Contributor

I agree with the reasoning here. @freundTech Can you re-push to get a clean build?

@andersk

andersk commented Feb 5, 2021 •

Copy link
Copy Markdown
Member

I believe it’s not correct to replace these lists with tuples, because Python-Markdown needs them to be mutable:

https://github.com/Python-Markdown/markdown/blob/3.3.3/markdown/extensions/__init__.py#L63

@andersk

andersk commented Feb 5, 2021 •

Copy link
Copy Markdown
Member

Oh I see. This is a Markdown, not an Extension, so the only user of the self.config dict and the getConfig method is our own code. We should replace the dict with three normal instance variables instead: #17213.

@freundTech

Copy link
Copy Markdown
Author

I just rebased this and the CI checks pass now. @andersk's solution looks good too,

@showell

showell commented Feb 5, 2021

Copy link
Copy Markdown
Contributor

@freundTech Thanks for your work here! I ended up merging the commit from @andersk. Looking forward to more contributions.

@showell showell closed this Feb 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants