As far as I could tell, there's currently no way to specify that a dependency should be installed in editable mode, which would be a useful feature for monorepo-style projects.
A practical example of this is from Jupyverse, which has a monorepo structure with multiple packages in a ./plugins/ directory. Here are the relevant sections from pyproject.toml for Jupyverse:
[build-system]
requires = [ "hatchling",]
build-backend = "hatchling.build"
[project]
dependencies = [
"fastapi>=0.82.0",
"fps>=0.0.19",
"fps-uvicorn>=0.0.19",
"fps-auth-base>=0.0.42",
"fps-contents>=0.0.42",
"fps-kernels>=0.0.42",
"fps-terminals>=0.0.42",
"fps-nbconvert>=0.0.42",
"fps-yjs>=0.0.42"
]
[project.optional-dependencies]
jupyterlab = [ "fps-jupyterlab >=0.0.42",]
retrolab = [ "fps-retrolab >=0.0.42",]
auth = [ "fps-auth >=0.0.42",]
auth-fief = [ "fps-auth-fief >=0.0.42",]
noauth = ["fps-noauth >=0.0.42"]
test = [ "mypy", "types-setuptools", "pytest", "pytest-asyncio", "pytest-env", "requests", "websockets", "ipykernel",]
docs = [ "mkdocs", "mkdocs-material",]
[tool.hatch.envs.dev]
pre-install-commands = [
"pip install -e ./plugins/auth_base",
"pip install -e ./plugins/contents",
"pip install -e ./plugins/frontend",
"pip install -e ./plugins/kernels",
"pip install -e ./plugins/lab",
"pip install -e ./plugins/nbconvert",
"pip install -e ./plugins/terminals",
"pip install -e ./plugins/yjs",
]
dependencies = ["fastapi>=0.82.0"]
features = ["test"]
[tool.hatch.envs.dev.overrides]
matrix.auth.post-install-commands = [
{ value = "pip install -e ./plugins/noauth", if = ["noauth"] },
{ value = "pip install -e ./plugins/auth", if = ["auth"] },
{ value = "pip install -e ./plugins/auth_fief", if = ["auth_fief"] },
]
matrix.frontend.post-install-commands = [
{ value = "pip install -e ./plugins/jupyterlab", if = ["jupyterlab"]},
{ value = "pip install -e ./plugins/retrolab", if = ["retrolab"]},
]
[[tool.hatch.envs.dev.matrix]]
frontend = ["jupyterlab", "retrolab"]
auth = ["noauth", "auth", "auth_fief"]
For development you'd want to install the plugins in editable mode from the ./plugins/ directory, which is why [tool.hatch.envs.dev] defines a pre-install-command which runs pip install -e ./plugins/PLUGIN_NAME on core plugins, and then tool.hatch.envs.dev.overrides defines matrix post-install commands for specific additional packages.
As mentioned in this discussion post #516, there are a few ways I can think of to allow for this:
- Extend
dev-mode-dirs to work with environment installation as well as builds.
- Add another dependency category, something like
editable-dependencies, which would always perform a pip install -e ... on the provided dependency.
- Additional syntax for the dependency specification, maybe
-e proj @ URI, which when found installs the dependency in editable mode.
Out of these three, I think 2 and 3 make the most sense as they are more explicit over what's happening.
editable-dependencies Category
The additional category approach would add sections for editable-dependencies and extra-editable-dependencies to the configuration file. This would look like:
[tool.hatch.envs.dev]
editable-dependencies = [
"fps-auth-base @ {root:uri}/plugins/auth_base",
"fps-contents @ {root:uri}/plugins/contents",
...
]
[tool.hatch.envs.dev.overrides]
matrix.auth.extra-editable-dependencies = [
{ value = "fps-noauth @ {root:uri}/plugins/noauth", if = ["noauth"] },
...
]
Support -e Flag for Local Dependencies
The additional syntax approach would use the existing sections, but support the -e flag:
[tool.hatch.envs.dev]
dependencies = [
"-e fps-auth-base @ {root:uri}/plugins/auth_base",
"-e fps-contents @ {root:uri}/plugins/contents",
...
]
[tool.hatch.envs.dev.overrides]
matrix.auth.extra-dependencies = [
{ value = "-e fps-noauth @ {root:uri}/plugins/noauth", if = ["noauth"] },
...
]
In a way this is odd as it isn't really specified in any PEPs, however PDM uses this syntax for editable dependencies already, so it isn't that odd. In PDM the above dependencies would look like:
[tool.pdm.dev-dependencies]
dev = [
"-e file:///${PROJECT_ROOT}/plugins/auth_base#egg=fps-auth-base",
"-e file:///${PROJECT_ROOT}/plugins/contents#egg=fps-contents",
]
Next Steps?
I'm happy to implement either of these two options, but not sure which one to go with.
The -e flag support is pretty nice and avoids requiring a new section, however having that flag in a requirement it isn't officially defined in any PEP, but on the other hand it is already used in PDM.
Additional categories are much clearer but make the files a bit more verbose.
Personally I prefer the -e flag since it is already used in PDM which is quite popular.
As far as I could tell, there's currently no way to specify that a dependency should be installed in editable mode, which would be a useful feature for monorepo-style projects.
A practical example of this is from Jupyverse, which has a monorepo structure with multiple packages in a
./plugins/directory. Here are the relevant sections frompyproject.tomlfor Jupyverse:For development you'd want to install the plugins in editable mode from the
./plugins/directory, which is why[tool.hatch.envs.dev]defines apre-install-commandwhich runspip install -e ./plugins/PLUGIN_NAMEon core plugins, and thentool.hatch.envs.dev.overridesdefines matrix post-install commands for specific additional packages.As mentioned in this discussion post #516, there are a few ways I can think of to allow for this:
dev-mode-dirsto work with environment installation as well as builds.editable-dependencies, which would always perform apip install -e ...on the provided dependency.-e proj @ URI, which when found installs the dependency in editable mode.Out of these three, I think 2 and 3 make the most sense as they are more explicit over what's happening.
editable-dependenciesCategoryThe additional category approach would add sections for
editable-dependenciesandextra-editable-dependenciesto the configuration file. This would look like:Support
-eFlag for Local DependenciesThe additional syntax approach would use the existing sections, but support the
-eflag:In a way this is odd as it isn't really specified in any PEPs, however PDM uses this syntax for editable dependencies already, so it isn't that odd. In PDM the above dependencies would look like:
Next Steps?
I'm happy to implement either of these two options, but not sure which one to go with.
The
-eflag support is pretty nice and avoids requiring a new section, however having that flag in a requirement it isn't officially defined in any PEP, but on the other hand it is already used in PDM.Additional categories are much clearer but make the files a bit more verbose.
Personally I prefer the
-eflag since it is already used in PDM which is quite popular.