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

Enable mypy's disallow_any_explicit flag. #3121

Merged
merged 33 commits into from
Nov 3, 2024

Conversation

CoolCat467
Copy link
Member

@CoolCat467 CoolCat467 commented Oct 27, 2024

agreed. disable ANN401 for now and enable `disallow_any_explicit` in a separate PR. Possibly same for `disallow_untyped_defs`.

Originally posted by @jakkdl in #3098 (comment)

In this pull request, we enable mypy's disallow_any_explicit flag. While we are at it, we also upgrade the version of mypy used, as well as enabling a new feature in mypy 1.13.0, where it has support for optional faster cache via a module called orjson.

              agreed. disable ANN401 for now and enable `disallow_any_explicit` in a separate PR. Possibly same for `disallow_untyped_defs`.

_Originally posted by @jakkdl in python-trio#3098 (comment)
@CoolCat467 CoolCat467 added dependencies Pull requests that update a dependency file skip newsfragment Newsfragment is not required labels Oct 27, 2024
Copy link

codecov bot commented Oct 27, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.62%. Comparing base (9d4fe27) to head (ba24f74).
Report is 35 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #3121   +/-   ##
=======================================
  Coverage   99.62%   99.62%           
=======================================
  Files         122      122           
  Lines       18340    18380   +40     
  Branches     3281     3281           
=======================================
+ Hits        18271    18311   +40     
  Misses         47       47           
  Partials       22       22           
Files with missing lines Coverage Δ
src/trio/_core/_concat_tb.py 100.00% <100.00%> (ø)
src/trio/_core/_entry_queue.py 100.00% <100.00%> (ø)
src/trio/_core/_instrumentation.py 100.00% <100.00%> (ø)
src/trio/_core/_io_windows.py 98.80% <100.00%> (ø)
src/trio/_core/_ki.py 100.00% <100.00%> (ø)
src/trio/_core/_run.py 99.02% <100.00%> (-0.01%) ⬇️
src/trio/_core/_tests/test_guest_mode.py 100.00% <100.00%> (ø)
src/trio/_core/_tests/test_ki.py 99.77% <100.00%> (ø)
src/trio/_core/_tests/test_parking_lot.py 100.00% <100.00%> (ø)
src/trio/_core/_tests/test_run.py 100.00% <100.00%> (ø)
... and 24 more

@A5rocks
Copy link
Contributor

A5rocks commented Oct 27, 2024

Honestly, I don't like the line changes due to having this option enabled. On the other hand, I do like the Any-> object changes you spotted.

I would prefer if we left this error code disabled, but you kept the changes in type signatures if they work. I doubt new type signatures will be added abusing Any to the same level as signatures we added in bulk when typing trio.

@TeamSpen210
Copy link
Contributor

I agree, in the core code there's a lot of passing callables around etc, which just has to be typed as Any. Not sure if there's much point enabling the explicit-any code, then disabling it for each line where we do use Any. Since it's explicit, we can just search for Any itself if we want to audit?

Agreed that we should change Any → object wherever it's possible.

@@ -103,8 +103,7 @@ class _NoStatus(metaclass=NoPublicConstructor):

# Decorator to mark methods public. This does nothing by itself, but
# trio/_tools/gen_exports.py looks for it.
# Explicit "Any" is not allowed
def _public(fn: FnT) -> FnT: # type: ignore[misc]
def _public(fn: Callable[PS, RetT]) -> Callable[PS, RetT]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, this should stay as a typevar bound=Callable[..., object]. There's a subtle difference between that and paramspec - the bound typevar means the callable must be exactly the same from input to output, so things like overloads are preserved. This still might work if type checkers special case it, but it's not clear in the spec how it'll interact with ParamSpec.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was considering changing to def _public(fn: T) -> T: because that's all it really does, and I think this cements that that might be a better solution.

Copy link
Member Author

Choose a reason for hiding this comment

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

Changed in 55964ad

Copy link
Member

Choose a reason for hiding this comment

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

I was considering changing to def _public(fn: T) -> T: because that's all it really does, and I think this cements that that might be a better solution.

well, the comment specifies that it's only used "to mark methods public" so using FnT is a way of enforcing that. But it's probably fine to do T->T

@CoolCat467
Copy link
Member Author

pypy cache issue strikes again

@A5rocks
Copy link
Contributor

A5rocks commented Oct 28, 2024

pypy cache issue strikes again

I'm going to make a few commits adding in debugging etc, feel free to remove them via git reset --hard aee4a770ddebb3d631a07e81399a2d1fd8982ece; git push --force later.

@A5rocks
Copy link
Contributor

A5rocks commented Oct 28, 2024

OK, so this time:

  1. the hashes were the same between PyPy and CPython on Windows
  2. the cache was still incorrect

I tried removing the cache from https://github.com/python-trio/trio/actions/caches for PyPy on Windows and that seems to work. Maybe it was just a really evil file that was living far past when it should have and this will never happen again. At least that gives us an easy fix if this happens again, though I don't like it.

Copy link
Member

@jakkdl jakkdl left a comment

Choose a reason for hiding this comment

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

I'm more positive on enabling this than a5rocks or teamspen, I think there's pretty good value from catching future PR's from adding unneeded Anys. Changing them after the fact with somebody manually searching for Any, or even having to complain in reviews, will be far less efficient.
If some file in _core gets really messy from having to type: ignore everything then we can disable it specifically for that file in the config.

Generally I also think that it's better practice to use object and then type: ignore[...] where the problem actually arises - that gives the reader a better understanding of where the type system stops giving any help and/or why we need to override it, rather than saying "we don't typecheck this parameter, go read the rest of the function to figure out why". But yeah if it surfaces several error messages then silencing it once is the way to go

A bit irritating that there's no type: ignore[no-explicit-any], could probably request that be added upstream.

src/trio/_core/_concat_tb.py Outdated Show resolved Hide resolved
src/trio/_core/_io_windows.py Outdated Show resolved Hide resolved
src/trio/_core/_run.py Outdated Show resolved Hide resolved
src/trio/_core/_tests/test_run.py Outdated Show resolved Hide resolved
Comment on lines +132 to +133
__slots__ = ("_default_name", "_job", "_thread", "_thread_cache", "_worker_lock")

Copy link
Member

Choose a reason for hiding this comment

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

lol. Why are there slots changes in this PR?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, after the fact I was considering moving that to another pull request, but basically while handling issues I noticed this didn't have slots, so I added it.

Comment on lines 214 to +219
class ThreadCache:
__slots__ = ("_idle_workers",)

def __init__(self) -> None:
self._idle_workers: dict[WorkerThread[Any], None] = {}
# Explicit "Any" not allowed
self._idle_workers: dict[WorkerThread[Any], None] = {} # type: ignore[misc]
Copy link
Member

Choose a reason for hiding this comment

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

prime opportunity for using attrs

from typing import TYPE_CHECKING, Any, Callable, NoReturn
from collections.abc import Awaitable

# Jedi gets mad in test_static_tool_sees_class_members if we use collections Callable
Copy link
Member

Choose a reason for hiding this comment

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

huh, something to report upstream?

src/trio/_core/_traps.py Outdated Show resolved Hide resolved
src/trio/_socket.py Outdated Show resolved Hide resolved
CoolCat467 and others added 2 commits October 28, 2024 11:07
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
@CoolCat467 CoolCat467 force-pushed the enable-disallow_any_explicit branch from a144f98 to c3c0a28 Compare October 28, 2024 16:11
@CoolCat467 CoolCat467 removed the skip newsfragment Newsfragment is not required label Oct 28, 2024
Copy link
Member

@jakkdl jakkdl left a comment

Choose a reason for hiding this comment

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

phew, big review!

src/trio/_core/_io_windows.py Outdated Show resolved Hide resolved
src/trio/_core/_ki.py Outdated Show resolved Hide resolved
@@ -103,8 +103,7 @@ class _NoStatus(metaclass=NoPublicConstructor):

# Decorator to mark methods public. This does nothing by itself, but
# trio/_tools/gen_exports.py looks for it.
# Explicit "Any" is not allowed
def _public(fn: FnT) -> FnT: # type: ignore[misc]
def _public(fn: Callable[PS, RetT]) -> Callable[PS, RetT]:
Copy link
Member

Choose a reason for hiding this comment

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

I was considering changing to def _public(fn: T) -> T: because that's all it really does, and I think this cements that that might be a better solution.

well, the comment specifies that it's only used "to mark methods public" so using FnT is a way of enforcing that. But it's probably fine to do T->T

src/trio/_core/_run.py Show resolved Hide resolved
src/trio/_core/_run.py Outdated Show resolved Hide resolved
src/trio/_threads.py Outdated Show resolved Hide resolved
src/trio/_threads.py Outdated Show resolved Hide resolved
src/trio/_util.py Outdated Show resolved Hide resolved
src/trio/_util.py Outdated Show resolved Hide resolved
src/trio/_util.py Outdated Show resolved Hide resolved
CoolCat467 and others added 11 commits October 30, 2024 00:14
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com>
Copy link
Member

@jakkdl jakkdl left a comment

Choose a reason for hiding this comment

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

Great!

@CoolCat467
Copy link
Member Author

@A5rocks ?

@A5rocks
Copy link
Contributor

A5rocks commented Nov 1, 2024

I'm neutral on this and looking at some of the changes this seems fine. It's a bit strange that mypy marks usage of typevars with Any bounds as usage of Any but oh well.

@CoolCat467
Copy link
Member Author

Will merge this in a day or two unless anyone has any other comments

@CoolCat467 CoolCat467 merged commit c7801ae into python-trio:main Nov 3, 2024
39 checks passed
@CoolCat467 CoolCat467 deleted the enable-disallow_any_explicit branch November 3, 2024 04:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dependencies Pull requests that update a dependency file
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants