Skip to content

Add pyrefly type checker & lsp support (and fix defects)#23

Merged
posborne merged 5 commits into
mainfrom
posborne/pyrefly-type-checker
Dec 16, 2025
Merged

Add pyrefly type checker & lsp support (and fix defects)#23
posborne merged 5 commits into
mainfrom
posborne/pyrefly-type-checker

Conversation

@posborne
Copy link
Copy Markdown
Member

Pyrefly is fast and the defaults seem to be a bit less aggressive than basedpyright. Ty is another option but it doesn't seem to be as mature, potentially. This adds pyrefly and introduces changes in order to get a clean run via make check.

It does seem to have found a few bugs in my early testing; I stumbled upon it as it was an LSP option for zed.

@posborne posborne requested a review from erikrose December 10, 2025 20:41
Comment thread fastly_compute/wsgi.py
error_response.append_header("content-type", b"text/plain")
error_message = f"Internal Server Error: {e}"
http_body.write(error_body, error_message.encode(), http_body.WriteEnd.BACK)
http_body.write(error_body, error_message.encode())
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is a pretty good example of an error caught by the type checker.

Pyrefly is fast and the defaults seem to be a bit less
aggressive than basedpyright.  Ty is another option but
it doesn't seem to be as mature, potentially.
This adds pyrefly and introduces changes in order
to get a clean run via `make check`.

It does seem to have found a few bugs in my
early testing; I stumbled upon it as it was an LSP
option for zed.

One thing it did seem to catch was the session reuse bug
already fixed in upstream where we weren't checking
await_request for None.
Previously, we fully removed and regenerated
stubs for a bunch of stuff.  Now, only do so
based on changes to compute.wit which should
generally be a good proxy.

This also makes the lint checks much lighter
by not requiring the we build all the examples
just to get stubs.
This is a case where pyrefly was inferring the type
incorrectly.  Interestingly, I found that this was
also the case with mypy and pyright as well, so
just adding the cast.  Other frameworks seem to
have better support for typing than bottle.
@posborne posborne force-pushed the posborne/pyrefly-type-checker branch from 005b89d to 929f1bc Compare December 16, 2025 16:49
Copy link
Copy Markdown
Member

@erikrose erikrose left a comment

Choose a reason for hiding this comment

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

That extra list(…) is the only thing I really care about.

Comment thread Makefile
# Default target builds all examples
all: $(COMPOSED_WASMS)

$(STUBS_DIR): $(COMPUTE_WIT)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Might I venture to suggest we instead use stubs/wit_world/__init__.py as the target? Using a dir as a target tends toward fragility, as adding or removing anything from the dir updates its modification date. That includes OS detritus like .DS_Store and things I lack the foresight to enumerate.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good call, I'll do that in some way. I recall similar problems now that you mention it (and never really having a solution I'm entirely happy with).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I used to use Make targets to create virtualenvs. One strategy I'd use is to make the venv, then immediately touch some pointless little file inside it as a sentinel. The target would then be that sentinel. Avoids the dir modtime problem and doesn't assume anything about the eventual population of the folder.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Looks like another option, which we employ for BUILD_DIR is a https://www.gnu.org/software/make/manual/make.html#Prerequisite-Types

I will go ahead and use that as it seems to be designed and documented for this sort of case specifically.

Copy link
Copy Markdown
Member

@erikrose erikrose Dec 16, 2025

Choose a reason for hiding this comment

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

Though BUILD_DIR's only care is to create an empty dir. Stubs, OTOH, can go out of date, and we want them rebuilt if compute.wit changes. (I guess what I'm saying is that I wonder if | is transitive.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I pushed a change using | now, though I just saw the updates here concurrently.

Doing a test, I think the behavior is what we want:

$ make clean

$ make stubs
rm -rf stubs
uv run componentize-py -d wit -w fastly:compute/service bindings stubs

$ touch wit/deps/fastly/compute.wit
$ make stubs
rm -rf stubs
uv run componentize-py -d wit -w fastly:compute/service bindings stubs

# depends on stubs as `|` but we didn't regen after modifying a file
# within stubs
$ touch stubs/foo.txt
$ make lint
uv run --extra dev ruff check .
All checks passed!
uv run --extra dev --extra test pyrefly check .
 INFO 0 errors (1 suppressed)

# But we do regen if stubs was actually modified
$ touch wit/deps/fastly/compute.wit
$ make lint
rm -rf stubs
uv run componentize-py -d wit -w fastly:compute/service bindings stubs
uv run --extra dev ruff check .
All checks passed!
uv run --extra dev --extra test pyrefly check .
 INFO 0 errors (1 suppressed)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Going to merge; if we see cases where it isn't working as we want, we can revisit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sweet! Looks great!

Comment thread fastly_compute/testing.py
Comment thread fastly_compute/testing.py Outdated
@posborne posborne merged commit 8a4bc83 into main Dec 16, 2025
3 checks passed
@posborne posborne deleted the posborne/pyrefly-type-checker branch December 16, 2025 23:31
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.

2 participants