Description
Moving from #70
what does the UX look like if we're not leaning on flake8 for that? I presume similar, so how much work is that to add?
Quickly looked at whether the flake8 interface could still work - and it's possible to still use flake8 without much problem. You can indicate that you want the lines of a file and then that can be dumped into libcst.parse_module()
. Flake8 does require plugins to accept one of tree
, logical_line
or physical_line
as parameter in __init__
for it to classify the plugin and run it at the correct time, so we'd have to still accept the tree
parameter - but we can just throw it out and construct our own tree from the lines
sent at the same time.
Somewhat hackish, but means that the consideration of ditching flake8 is pretty much fully independent.
This even means that the transition can even be gradual - where in the intermediate phase you have both an AST and a libCST tree, and run separate runners for them.
TODO
Standalone functionality
- Color support - I was most of the way to replicating flake8's color printing, but once it got into testing/coverage and windows support I abandoned it and threw it out. For a later PR, if ever.
- Disable visitors with other ways than --enable-visitor-codes-regex add standalone command line args #163
- pre-commit support add libcst as install_requires, print errors to stderr & return 1/0, add pre-commit hook & update config, #161
- Standalone
flake8-async
could read config files likeflake8
#189 - Add parallell processing of files Switch backend to libCST #124 (comment)
- test that autofixed files don't generate errors test for autofix_files, fix some 91x autofixes, rejig eval_files #159
- first transform, then visit, to not get incorrect line markers #193
- test
- CLI toggle whether autofix generates an error #192
- test partial enabling of autofixers #191
- Write documentation
Converted to libCST:
- TRIO100 reimplement trio100 & trio101 with libcst #142
- TRIO101 reimplement trio100 & trio101 with libcst #142
- TRIO102
- TRIO103
- TRIO104
- TRIO105
- TRIO106
- TRIO109
- TRIO110
- TRIO111
- TRIO112
- TRIO113
- TRIO114
- TRIO115
- TRIO116
- TRIO117
- TRIO118
- TRIO200
- TRIO210
- TRIO211
- TRIO212
- TRIO220
- TRIO221
- TRIO222
- TRIO230
- TRIO231
- TRIO232
- TRIO240
- TRIO900
- TRIO910 reimplement 91X in libcst #143
- TRIO911 reimplement 91X in libcst #143
Autofixing
- TRIO100: implement autofix for TRIO100 #149
- don't autofix if there's other warnings about the content of the context. (?)
- TRIO102: it's unsafe to await inside
finally:
orexcept BaseException/trio.Cancelled
unless you use a shielded
cancel scope with a timeout.- I think a context manager can be added around it?
- TRIO105: Calling a trio async function without immediately
await
ing it. - TRIO112: nursery body with only a call to
nursery.start[_soon]
and not passing itself as a parameter can be replaced with a regular async function call. - TRIO113: using
nursery.start_soon
in__aenter__
doesn't wait for the task to begin. Consider replacing withnursery.start
. - TRIO115: Replace
trio.sleep(0)
with the more suggestivetrio.lowlevel.checkpoint()
. - TRIO117: Don't raise or catch
trio.[NonBase]MultiError
, prefer[exceptiongroup.][Base]ExceptionGroup
. Even if Trio still raisesMultiError
for legacy code, it can be caught withBaseExceptionGroup
so it's fully redundant.
user-configured
- TRIO200: User-configured error for blocking sync calls in async functions. Does nothing by default, see
trio200-blocking-calls
for how to configure it.- Could probably add some fancy config flag that will replace stuff. Although the possibly ways of morphing the call might be too complicated to support more than the most basic stuff, will find that out as other 2xx autofixers are written / researched.
I think many of these can be fixed, but needs a long list of what to replace with
- TRIO210: Sync HTTP call in async function, use
httpx.AsyncClient
. - TRIO211: Likely sync HTTP call in async function, use
httpx.AsyncClient
. Looks forurllib3
method calls on pool objects, but only matching on the method signature and not the object. - TRIO212: Blocking sync HTTP call on httpx object, use httpx.AsyncClient.
- TRIO220: Sync process call in async function, use
await nursery.start(trio.run_process, ...)
. - TRIO221: Sync process call in async function, use
await trio.run_process(...)
. - TRIO222: Sync
os.*
call in async function, wrap inawait trio.to_thread.run_sync()
. - TRIO230: Sync IO call in async function, use
trio.open_file(...)
. - TRIO231: Sync IO call in async function, use
trio.wrap_file(...)
. - TRIO232: Blocking sync call on file object, wrap the file object in
trio.wrap_file()
to get an async file object. - TRIO240: Avoid using
os.path
in async functions, prefer usingtrio.Path
objects.
Requires a bunch of logic
I think I can chuck in a bunch of trio.lowlevel.checkpoint()
just before the line that would raise these - but there's going to be a bunch of edge cases that are tricky.
higher priority
- TRIO910: implement autofix for 91x #158
- TRIO911: implement autofix for 91x #158