Skip to content

Switch backend to libCST #124

Open
Open
@jakkdl

Description

@jakkdl

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

  1. 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.

Converted to libCST:

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: or except 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 awaiting 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 with nursery.start.
  • TRIO115: Replace trio.sleep(0) with the more suggestive trio.lowlevel.checkpoint().
  • TRIO117: Don't raise or catch trio.[NonBase]MultiError, prefer [exceptiongroup.][Base]ExceptionGroup. Even if Trio still raises MultiError for legacy code, it can be caught with BaseExceptionGroup 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 for urllib3 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 in await 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 using trio.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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions