ty icon indicating copy to clipboard operation
ty copied to clipboard

Explicitly included files without extension are not checked

Open janlarres opened this issue 2 months ago • 3 comments

Summary

I have a standalone script scripts/run in my project that I want to typecheck along with the main project code.

So I have this in my pyproject.toml:

[tool.ty.src]
include = ["mypackage", "scripts/run"]

However, the run script gets ignored. I'm assuming this is because of some filtering for *.py files in directories. I think that if the include is a file instead of a directory then it would be useful to include it as-is instead of filtering to allow this use case.

Interestingly it works fine if I explicitly run ty as ty check scripts/run.

Version

ty 0.0.7

janlarres avatar Dec 27 '25 07:12 janlarres

Hmm, yeah, this is a bit tricky. We support checking files without extension if you pass them directly to the CLI. But we currently don't support including files without a py, pyi, or ipynb extension when using include.

We could consider allowing exact matches in includes too. But I'm not sure this would be intuitive, and it also seems too limited if you want to check a handful of files that have no extension (or any other non-standard extension).

We could automatically change * to *.{py,pyi,ipynb} unless the glob ends with an extension (and the same for **/*), and, therefore, to the filtering as part of the globbing. However, this would only work for individual files. Including a set of files without an extension would not be possible.

Another alternative is to allow custom extension mappings, similar to what we have in ruff where you can map a file extension to a file type (like custompy -> py would make ty check all files ending with .custmpy as if they were regular python files). Adding a mapping for an empty extension would make ty check every file without an extension. That might be annoying too.

Are you aware of any other tools that allows checking files without an extension (e.g. what other tools did you use before). Do you know how they handle the extension-less case?

MichaReiser avatar Dec 27 '25 09:12 MichaReiser

I think we could append the *.{py,pyi,ipynb} filter if we see that the glob has no filename part (other than *).

MichaReiser avatar Dec 27 '25 11:12 MichaReiser

Pyright works for me with an identical include specification. As far as I can tell it supports simple file includes, but not wildcards that resolve to files:

https://github.com/microsoft/pyright/blob/1576956c32c8b75f3202203f3cdedd21c8d3f9f7/packages/pyright-internal/src/analyzer/sourceEnumerator.ts#L173

This behaviour got implemented here: https://github.com/microsoft/pyright/pull/5463

Pyrefly also supports explicitly specified files (i.e. no wildcards): https://github.com/facebook/pyrefly/blob/0cf3e5352f1be66e2fee0d038f38808b749e4108/crates/pyrefly_util/src/globs.rs#L160 https://github.com/facebook/pyrefly/blob/0cf3e5352f1be66e2fee0d038f38808b749e4108/crates/pyrefly_util/src/globs.rs#L343 https://github.com/facebook/pyrefly/blob/0cf3e5352f1be66e2fee0d038f38808b749e4108/crates/pyrefly_util/src/globs.rs#L104

janlarres avatar Dec 27 '25 23:12 janlarres