ModuleNotFoundError
Bug Report: Inconsistent behavior between packages = ["src/astrbot"] and packages = ["astrbot"] in editable installs
Background
I'm experiencing an issue that was initially reported to the uv project, but the maintainers correctly identified this as a hatch/hatchling behavior rather than a uv issue. I'm now reporting it here as suggested.
Original discussion: [link to uv issue if applicable]
Description
When using hatch/hatchling as a build backend, there's inconsistent behavior between packages = ["src/astrbot"] and packages = ["astrbot"] configurations. Regular builds work for both, but editable installations behave differently.
Environment
- OS: Windows
- hatch/hatchling version: [please specify]
- Python version: [please specify]
- Build frontend: uv (but likely reproducible with other PEP 517 frontends)
Expected Behavior
Both package path configurations should work consistently across regular builds and editable installs, or provide clear guidance on when to use each format.
Actual Behavior
- Regular builds (
uv build) work fine with both configurations - Editable installs show different behavior depending on the package path format
- One configuration works while the other fails with
ModuleNotFoundError
Reproduction Steps
Configuration A (Works with editable installs):
[tool.hatch.build.targets.wheel]
packages = ["src/astrbot"]
Configuration B (Fails with editable installs):
[tool.hatch.build.targets.wheel]
packages = ["astrbot"]
- Set up project with either configuration above
- Run
uv tool install -e .(or other editable install method) - Execute the script-defined executable
- ✅ Configuration A works
- ❌ Configuration B fails with
ModuleNotFoundError
Project Structure
project/
├── src/
│ └── astrbot/
│ ├── __init__.py
│ └── [other modules]
├── astrbot/ # or direct package location
│ ├── __init__.py
│ └── [other modules]
└── pyproject.toml
Questions
- What's the expected behavior difference between
packages = ["src/astrbot"]andpackages = ["astrbot"]? - Why do both work for regular builds but behave differently for editable installs?
- Is there documentation clarifying when to use each package path format?
- Should hatch provide better error messages to help users choose the correct configuration?
Additional Context
This inconsistency makes it confusing for users to configure their projects correctly, especially when migrating between different project layouts or when testing only covers regular builds but not editable installs.
Please show the contents of pyproject.toml.
[project] name = "AstrBot" version = "3.5.15" description = "易上手的多平台 LLM 聊天机器人及开发框架" readme = "README.md" requires-python = ">=3.10" dependencies = [ "aiocqhttp>=1.4.4", "aiodocker>=0.24.0", "aiohttp>=3.11.18", "aiosqlite>=0.21.0", "anthropic>=0.51.0", "anyio>=4.9.0", "apscheduler>=3.11.0", "beautifulsoup4>=4.13.4", "certifi>=2025.4.26", "chardet~=5.2.0", "colorlog>=6.9.0", "cryptography>=44.0.3", "dashscope>=1.23.2", "defusedxml>=0.7.1", "dingtalk-stream>=0.22.1", "docstring-parser>=0.16", "faiss-cpu>=1.10.0", "filelock>=3.18.0", "google-genai>=1.14.0", "googlesearch-python>=1.3.0", "lark-oapi>=1.4.15", "lxml-html-clean>=0.4.2", "mcp>=1.8.0", "nh3>=0.2.21", "openai>=1.78.0", "ormsgpack>=1.9.1", "pillow>=11.2.1", "pip>=25.1.1", "psutil>=5.8.0", "pydantic~=2.11.7", "pydub>=0.25.1", "pyjwt>=2.10.1", "python-telegram-bot>=22.0", "qq-botpy>=1.2.1", "quart>=0.20.0", "readability-lxml>=0.8.4.1", "silk-python", "telegramify-markdown>=0.5.1", "toml>=0.10.2", "watchfiles>=1.0.5", "websockets>=15.0.1", "wechatpy>=1.8.18", ]
[project.scripts] astrbot = "astrbot.cli:cli"
[build-system] requires = ["hatchling", "uv-dynamic-versioning"] build-backend = "hatchling.build"
[tool.ruff] exclude = [ "astrbot/core/utils/t2i/local_strategy.py", "astrbot/api/all.py", ] line-length = 88
target-version = "py310"
[tool.uv.sources] silk-python = { git = "https://github.com/synodriver/pysilk.git" }
[tool.hatch.build.targets.wheel] packages = ["src/astrbot"]
This is my corrected version. Previously, the astrbot project had: [tool.hatch.build.targets.wheel] packages = ["astrbot"]
I could use uv build normally, but I couldn't use uv tool install -e . properly.
I spent a lot of time researching this issue. Finally, I discovered that I only needed to move the folder to src/astrbot, and all problems were solved.
This is the corrected branch: https://github.com/LIghtJUNction/AstrBot
This is the branch before correction: https://github.com/LIghtJUNction/AstrBot/tree/test
I can't reproduce so far, what command are you running?
uv tool install -e .
astrbot
I can't reproduce so far, what command are you running?
I can't reproduce so far, what command are you running?
Thank you for your response!
[project.scripts] astrbot = "astrbot.cli:cli"
run: uv tool install -e . and astrbot
output:
That's strange. The issue above occurs when I use astrbot layout:
- Execute
uv tool install -e . - Run
astrbot - It fails
But when I change to src/astrbot layout:
- Execute
uv tool install -e . - Run
astrbot - It works successfully
I made sure to change the folder structure accordingly, and uv build runs normally in both cases.
When I changed src/astrbot back to astrbot and moved the files, I got the same error again.
The strange thing is that the astrbot layout sometimes works normally too - I have no idea why.
Anyway, src/astrbot layout always works without any issues.
Sorry, I have something to attend to and will be offline for a while. I might not be back to check for several hours.
So I may miss your reply and won't be able to respond promptly.
(I'm in UTC+8 timezone, by the way)
Works for me, perhaps try checking out the old branch in a completely new directory after a fresh clone:
Thank you for your patient response. I will also build it successfully like you did. I am now working hard to reproduce this bug.
I have created a new empty project and am trying to reproduce it.
I will notify you once I successfully reproduce it and tell you how to reproduce it.
PS C:\Users\light\Documents\GitHub\TestRepo> uv tool install -e .
Resolved 2 packages in 947ms
Installed 2 packages in 32ms
- silk-python==0.2.7 (from git+https://github.com/synodriver/pysilk.git@6666723883dd597da3a14bb694e10d2dd47c2581)
- testrepo==0.1.0 (from file:///C:/Users/light/Documents/GitHub/TestRepo)
Installed 1 executable: hi.exe
PS C:\Users\light\Documents\GitHub\TestRepo> hi
Traceback (most recent call last):
File "
", line 198, in _run_module_as_main File " ", line 88, in run_code File "C:\Users\light.local\bin\hi.exe_main.py", line 4, in from testrepo import hello ModuleNotFoundError: No module named 'testrepo' PS C:\Users\light\Documents\GitHub\TestRepo>
!!!! "I successfully reproduced it!"
Reproduction Steps: Any repository with project.scripts Follow my steps strictly, and you should see the same situation as I do For example, the test project I sent you
Step 1 (Normal situation test) uv tool install -e . Run hi Output: Hello from testrepo! Everything works normally
But if at this point: Win + X, A (Windows, open system terminal) pip install path/to/testrepo/ and pip uninstall path/to/testrepo
Then:
Then go back to the previous repository
Find that the hi command is no longer effective
Output:
Just like this
I'll try to reproduce this on a Linux system later!
WSL: ARCH
[moss@LIGHTJUNcPC TestRepo]$ uv tool install -e . Resolved 1 package in 17ms Built testrepo @ file:///mnt/c/Users/light/Documents/Gi Prepared 1 package in 3.43s Installed 1 package in 0.55ms
- testrepo==0.1.0 (from file:///mnt/c/Users/light/Documents/GitHub/TestRepo)
Installed 1 executable: hi
[moss@LIGHTJUNcPC TestRepo]$ hi
Traceback (most recent call last):
File "/home/moss/.local/bin/hi", line 4, in
from testrepo import hello ModuleNotFoundError: No module named 'testrepo' [moss@LIGHTJUNcPC TestRepo]$
Now I'm trying to create another empty project and attempt to fully reproduce it once on Linux.
Linux blocked pip install to protect the environment. both pip install and uv pip install
Thank you, Linux😭, for implementing these security measures to protect system stability. Although it may cause some inconvenience at times, this truly reflects its responsibility as a reliable operating system.
Once this bug is triggered, it becomes very difficult to recover from. I've tried restarting the computer, running uv cache clean, deleting pycache, deleting dist, deleting .venv and recreating it, re-running the activation script, changing the default Python version, and changing the project Python version - none of these methods successfully fixed the issue.
The most effective solution was to change the project structure, and then it worked. However, it became very difficult to reproduce the issue again afterwards. It took me quite a while to figure this out through trial and error.