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

fix(types): typing fixes exposed by extra checking #2131

Merged
merged 2 commits into from
Apr 21, 2022

Conversation

henryiii
Copy link
Contributor

@henryiii henryiii commented Mar 29, 2022

Type of changes

  • Bug fix
  • New feature
  • Documentation / docstrings
  • Tests
  • Other

Checklist

  • I've run the latest black with default args on new code.
  • I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
  • I've added tests for new code.
  • I accept that @willmcgugan may be pedantic in the code review.

Description

This enables a few extra mypy checks, and fixes type bugs exposed by those. There were three features enabled, but I've left one off: warn_unrachable = true. While it is really useful, and helped expose a couple of the issues fixed here, it also requires type ignoring in about 5-7 places unavoidably, so I've left it off. The most irritating one is if sys.platform.startswith("win") constructs, which it will notice are unreachable if you are typing targeting a different platform. MyPy might fix this in python/mypy#12286, which would run all platforms/versions in parallel and then combine the results (which would be really fantastic!), but until then, it's likely better just to manually add --warn-unreachable once in a while and make sure the errors reported are expected. (Depending on your preference, of course - I've been turning it on mostly, but I usually don't have quite as many ignores due to it - I thik I counted at least 7 here. If you want to see it, let me know, and I'll PR it).

I'll comment inline on the others, but this is one fix:

x: Iterable[Any] = ...
len(x)

is invalid. You can't take the length of an iterator. Someone could correctly put an iterator function in here, and this will break. Either this should be Sequence (which is what I've used here), or you should iterate over the iterator and build a sequence like a list or a tuple and then use that.

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
@codecov-commenter
Copy link

codecov-commenter commented Mar 29, 2022

Codecov Report

Merging #2131 (46b1c95) into master (7105781) will decrease coverage by 0.39%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master    #2131      +/-   ##
==========================================
- Coverage   99.46%   99.07%   -0.40%     
==========================================
  Files          72       72              
  Lines        7339     7555     +216     
==========================================
+ Hits         7300     7485     +185     
- Misses         39       70      +31     
Flag Coverage Δ
unittests 99.07% <100.00%> (-0.40%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
rich/__main__.py 100.00% <ø> (ø)
rich/tree.py 100.00% <ø> (ø)
rich/console.py 99.21% <100.00%> (+0.06%) ⬆️
rich/measure.py 100.00% <100.00%> (ø)
rich/pretty.py 99.22% <100.00%> (+<0.01%) ⬆️
rich/progress.py 93.51% <100.00%> (-4.92%) ⬇️
rich/spinner.py 100.00% <100.00%> (ø)
rich/style.py 100.00% <100.00%> (ø)
rich/terminal_theme.py 100.00% <100.00%> (ø)
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9f43ccc...46b1c95. Read the comment docs.

rich/spinner.py Outdated
Comment on lines 82 to 83
# This normally can't be str, unless someone assigned it later.
if not self.text: # type: ignore[truthy-bool]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Typewise this can't happen, but I could see it possibly happing at runtime, so just added an ignore and note here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

self.text may be a Text instance, which has a __bool__

I suspect the root cause of the issue is that text in the constructor is typed as a RenderableType, where it should probably be a Union[Text, str].

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Above, in the constructor, self.text = Text.from_markup(text) if isinstance(text, str) else text is set. This can't be a str, but it could be Union[Text, RenderableType], perhaps? I'd rather have thought it would already have been inferred to have that type, actually, but maybe not due to Text fitting into the RenderableType protocol. I'll see if I can try that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that appears to be it, mypy assigns self.text: RenderableType because Text fits that Protocol. But the __bool__ behavior is unique to Text, so this confuses it below. Making this explicit solves the issue.

@@ -740,7 +740,7 @@ def __add__(self, style: Optional["Style"]) -> "Style":
new_style._link = style._link or self._link
new_style._link_id = style._link_id or self._link_id
new_style._hash = style._hash
new_style._null = self._null or style._null
new_style._null = style._null
Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's a guard about 10 lines above:

if self._null:
    return style

So self._null cannot be truthy at this point.

rich/tree.py Show resolved Hide resolved
@henryiii henryiii marked this pull request as ready for review March 29, 2022 18:22
@@ -54,10 +54,9 @@ build-backend = "poetry.core.masonry.api"

[tool.mypy]
files = ["rich"]
warn_unused_configs = true
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is included in strict, which I didn't realize until checking the mypy --help output just now.

Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
@henryiii henryiii force-pushed the henryiii/chore/mypy7 branch from 62b58d5 to 46b1c95 Compare April 1, 2022 17:12
@willmcgugan
Copy link
Collaborator

Thanks

@willmcgugan willmcgugan merged commit 7e180e0 into Textualize:master Apr 21, 2022
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.

3 participants