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

Give Pyright what it wants (alias attributes everywhere) #3114

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

A5rocks
Copy link
Contributor

@A5rocks A5rocks commented Oct 19, 2024

I don't like pyright nor this behavior, but that doesn't mean users should have to care. We can add a test to prevent any sort of regression regarding this, forever.

cc @mikenerone cause this is from Gitter.

also @CoolCat467 I ran into issues with running the regenerate-files pre-commit hook and couldn't figure them out after about 15 minutes. It was complaining about attrs not being possible to import but unfortunately there's no way to get it to use the test-requirements.txt file. Have you run into this issue regarding it not picking up the virtual environment? (I'm using a seperate git client so that kind of makes sense, but now's the first time I ran into this...)

Copy link

codecov bot commented Oct 19, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 99.59%. Comparing base (8850705) to head (819797a).
Report is 39 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3114      +/-   ##
==========================================
+ Coverage   99.58%   99.59%   +0.01%     
==========================================
  Files         121      121              
  Lines       18157    18872     +715     
  Branches     3272     3535     +263     
==========================================
+ Hits        18082    18796     +714     
- Misses         52       53       +1     
  Partials       23       23              
Files with missing lines Coverage Δ
src/trio/_core/_local.py 100.00% <100.00%> (ø)
src/trio/_core/_run.py 99.02% <100.00%> (ø)
src/trio/_tests/test_exports.py 99.67% <100.00%> (+0.05%) ⬆️

... and 10 files with indirect coverage changes

@jakkdl
Copy link
Member

jakkdl commented Oct 19, 2024

this makes me want to write a linter rule, but also feels ridiculous (and idk which flake8 plugin it would fit) to write an attrs+pyright-specific rule.

How slow/fast is the test? If it's anything but trivial I could rewrite it as an ast visitor.

@A5rocks
Copy link
Contributor Author

A5rocks commented Oct 19, 2024

this makes me want to write a linter rule, but also feels ridiculous (and idk which flake8 plugin it would fit) to write an attrs+pyright-specific rule.

How slow/fast is the test? If it's anything but trivial I could rewrite it as an ast visitor.

Yeah lint rule would make more sense but unfortunately a lint rule would miss context that's helpful (like whether a class is exported).

It takes 1.75 seconds to run locally, though that's with the overhead of starting pytest.

Copy link
Member

@CoolCat467 CoolCat467 left a comment

Choose a reason for hiding this comment

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

Alias changes make sense and test looks like it would work pretty well but didn't look into the details super closely, but general idea of it seems solid.

If test is slow, do we need to mark it with @slow or something?

@A5rocks
Copy link
Contributor Author

A5rocks commented Oct 20, 2024

If test is slow, do we need to mark it with @slow or something?

Maybe? Here's the output at the end of pytest --durations=10 locally:

================================================ slowest 10 durations =================================================
3.66s call     src/trio/_tests/tools/test_gen_exports.py::test_process[from collections import Counter\n]
2.73s call     src/trio/_tests/tools/test_gen_exports.py::test_process[from collections import Counter\nimport os\n]
2.53s call     src/trio/_tests/tools/test_gen_exports.py::test_process[from typing import TYPE_CHECKING\nif TYPE_CHECKING:\n    from collections import Counter\n]
2.11s call     src/trio/_tests/test_socket.py::test_many_sockets
2.05s call     src/trio/_tests/test_socket.py::test_SocketType_connect_paths
2.04s call     src/trio/_tests/test_socket.py::test_address_in_socket_error
2.02s call     src/trio/_tests/test_highlevel_open_tcp_listeners.py::test_open_tcp_listeners_ipv6_v6only
1.73s call     src/trio/_tests/test_exports.py::test_pyright_recognizes_init_attributes
0.65s call     src/trio/_tests/test_exports.py::test_static_tool_sees_all_symbols[jedi-trio]
0.41s call     src/trio/_tests/tools/test_gen_exports.py::test_lint_failure

I don't think it's an appreciable slowdown. Maybe it's a good idea to put @slow on everything over 1 second? I can probably write the test to be faster (by not rescanning the tokenizations, not including tests in the glob). Actually I'll do just that.

EDIT: just the second optimization there changed it to 0.64s locally, so I think it's fine if not marked @slow.

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.

maybe also good to add a comment or two on what this token thing is doing, I find it hard to understand at a glance what the code is doing.

Comment on lines 622 to 623
# linters don't like my not using the index, go figure.
for end_offset, token in enumerate(file[start:]): # noqa: B007
Copy link
Member

Choose a reason for hiding this comment

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

if you declare end_offset outside the loop I think the warning goes away (and makes the code easier to read).

codecov wants a pragma: no branch on the loop to hit 100%

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately the warning doesn't go away; it does make the code more correct (previously it didn't handle start==len(file)-1, I think)

Copy link
Member

Choose a reason for hiding this comment

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

I think with the zero-initialization now that should be good

Copy link
Member

Choose a reason for hiding this comment

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

This is fairly gnarly to fix in an AST visitor, I don't see any way of doing it that's not overkill, but I think you could open an issue for ruff and see if they have a decent way of getting at it.

@A5rocks A5rocks requested a review from jakkdl October 20, 2024 23:52
@TeamSpen210
Copy link
Contributor

There’s another approach we could use, but it’d might require starting an additional interpreter. Run a script which monkeypatches attrs.field to store whether alias was set into the metadata dict, import trio, then we can just loop through fields.

Unsure if that’d be faster though. We could avoid the new interpreter if the monkeypatch was done before any tests import trio, but that means it affects all tests. Probably not too much of an issue since metadata does nothing, and just wrapping the function should be fairly safe.

@A5rocks
Copy link
Contributor Author

A5rocks commented Oct 21, 2024

There’s another approach we could use, but it’d might require starting an additional interpreter. Run a script which monkeypatches attrs.field to store whether alias was set into the metadata dict, import trio, then we can just loop through fields.

Unsure if that’d be faster though. We could avoid the new interpreter if the monkeypatch was done before any tests import trio, but that means it affects all tests. Probably not too much of an issue since metadata does nothing, and just wrapping the function should be fairly safe.

It's not significantly faster:

(.venv) PS C:\Users\A5rocks\Documents\trio> hyperfine 'python -c \"import trio\"'
Benchmark 1: python -c "import trio"
  Time (mean ± σ):     410.5 ms ±  14.2 ms    [User: 45.3 ms, System: 22.9 ms]
  Range (min … max):   390.3 ms … 435.0 ms    10 runs

I think the main improvement would be that it's slightly more reliable. It sounds annoying to implement though.

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.

4 participants