pypa / hatch

Modern, extensible Python project management
https://hatch.pypa.io/latest/
MIT License
6.09k stars 308 forks source link

py.typed for single-file packages ? #1336

Closed AiroPi closed 8 months ago

AiroPi commented 8 months ago

My project looks like:

pyproject.toml
project_name.py
py.typed

I can build and install my package successfully, but I get a warning "stub not found" when I try to use it. Is it possible to get rid of this message ?

I also tried to refactor my project structure to looks like:

project_name/
├── project_name.py
└── py.typed
pyproject.toml

Which doesn't work because it needs a __init__.py. But a repo like https://github.com/python/typing_extensions has this file structure (but it doesn't use hatchling). Is something like this possible ?

Because, by adding an __init__.py file, I then needs to imports everything from project_name.py, which is not convenient. Another solution would be to replace the project_name.py file with __init__.py but I don't like this solution much.

ofek commented 8 months ago

Please show your config and exact directory structure.

AiroPi commented 8 months ago

Please show your config and exact directory structure.

https://github.com/airopi/minesweeper

I tested with exactly the same pyproject.toml and the same directory structure except with:

minesweeper.py
py.typed

Instead of:

minesweeper/
├── __init__.py
├── minesweeper.py
└── py.typed

Which gave me the stub files missing error.

And tested with

minesweeper/
├── minesweeper.py
└── py.typed

Which wasn't working at all. (Don't correspond to any of https://hatch.pypa.io/1.9/plugins/builder/wheel/#default-file-selection) I tried to manually specify the minesweeper.minesweeper file but I couldn't do it.

ofek commented 8 months ago

The config file is not formatted properly so I cannot test. Can you please fix that? In any case, you could probably achieve what you want with the following: https://hatch.pypa.io/latest/config/build/#rewriting-paths

AiroPi commented 8 months ago

The config file is not formatted properly so I cannot test. Can you please fix that? In any case, you could probably achieve what you want with the following: https://hatch.pypa.io/latest/config/build/#rewriting-paths

Thanks, I will check that! On my side, I don't have any issue with the config file, so I don't really know what to fix 😬

ofek commented 8 months ago

Interesting! When viewed on GitHub the formatting was all broken and there was messed up syntax highlighting because of that but now it's fixed somehow...

AiroPi commented 8 months ago

Ok with these configs, I am able to resolve the missing stubs files problem while have a singlefile package at root:

[tool.hatch.build.targets.wheel]
include = ["py.typed", "minesweeper.py"]

[tool.hatch.build.targets.wheel.sources]
"" = "minesweeper"

However, this implies to use minesweeper.minesweeper.xxx instead of minesweeper.xxx because the module is not directly in site-packages, which is the case if we don't care about py.typed.

This looks like a PEP561 limitation, but the typing_extensions package is directly inside site-packages without stub files issue. But maybe it is a special exception for this package, due to its utility.

image

By the way, the warning is raised by Pylance inside VSCode (when minesweeper.py is directly under site-packages like typing_extensions.py) image

ofek commented 8 months ago

What you could do is have two remappings to the direct location and for the code make that be minesweeper/__init__.py.

eli-schwartz commented 8 months ago

typing_extensions doesn't declare a py.typed as far as I can tell? What is the reason for thinking the desired goal can be achieved?

AiroPi commented 8 months ago

Ok I just founded this : https://github.com/python/typing/discussions/1297, my assumption was correct. How can I map minesweeper.py to minesweeper/__init__.py (if this is possible)? I only see how to map directories, not files.

Otherwise, I will just keep the current structure 🤷 which works fine, but adds a useless folder.

ofek commented 8 months ago

https://hatch.pypa.io/latest/config/build/#forced-inclusion

[tool.hatch.build.targets.wheel.force-include]
"minesweeper.py" = "minesweeper/__init__.py"
"py.typed" = "minesweeper/py.typed"
AiroPi commented 8 months ago

Thank you! For the help and for the quick response. This was exactly what I was looking for, it works like a charm.

ofek commented 8 months ago

Happy to help!