Skip to content

pyrefly coverage should respect project-excludes from the config #3909

Description

@jorenham

NumPy's pyproject.toml
(src) looks like this:

[tool.pyrefly]
project-includes = ["numpy/**/*.pyi"]
project-excludes = ["numpy/typing/tests/**"]

But pyrefly coverage check numpy (pyrefly==1.1.1) still reports symbols from numpy/typing/tests/**. They only disappear if I repeat the glob on the CLI with --project-excludes="numpy/typing/tests/**".

I know passing a path switches to single-file mode, where config project-includes/project-excludes are ignored (same as #1360, closed as by-design). But dropping the excludes is surprising for coverage: pointing it at a package while keeping the project's tests/** excludes seems like a pretty natural thing to want. I, at least, fully expected this to "just work", and had to spend a lot of time figuring out that it had to do with the numpy path I specified, and that using pyrefly coverage check (without the numpy path) will respect the configured project-excludes.

The docs justify this behavior by files resolving to different configs. But there's no ambiguity when there's a single config at the root, which I expect to be the most common scenario in practice.

So I propose that, in "single-file mode", the config's project-excludes still apply when all files resolve to the same config (still ignoring project-includes, since the path already narrows those).

Since this is broader than just pyrefly coverage, I'll wait to see what you think about this before I'll start working on a PR.

Activity

  1. yangdanny97 commented on Jun 23, 2026

    @yangdanny97
    Collaborator

    If it's not too complex to implement I'm in favor

    cc @connernilsen for second opinion

  2. self-assigned this
    on Oct 29, 2026
  3. kinto0 commented on Oct 30, 2026

    @kinto0
    Contributor

    The "when the same config applies to all FILES" part gets tricky: if certain files in a file-based check read one config and other files read the other config, the excludes can differ and which should we honor?

    What you're really doing when running pyrefly coverage check path/to/dir is explicitly saying you want a folder checked, so it gets confusing if that folder is excluded in the config (0 errors just because nothing was checked is not a great scenario). Maybe we can have some heuristics that include the exact folder you tell it and exclude all others, but that gets tricky.

    What I might propose instead is a project-based check. After something like this, you can do pyrefly coverage check --project-dir numpy which will do a project-based check (meaning check the config) of the folder at numpy. It will automatically exclude sibling folders even if they're included in the project. How does that sound?

    Maybe this is what everyone means when they do a files-based check on a folder. Maybe we should automatically do that when you run pyrefly check numpy but do a files-based check when you run pyrefly check numpy/.

    Thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions