tall-salesclerk-68028
05/08/2024, 10:27 PMhappy-kitchen-89482
05/08/2024, 11:03 PMtall-salesclerk-68028
05/09/2024, 3:01 PMpyproject.toml file for one of those projects, my_project, I have a relative path to an editable install: my_library = { path = ".../.../.../libraries/my_library", develop = true} , The usual poetry commands, poetry lock and install, correctly build this local library and let me use it throughout my project. However running pants generate-lockfiles --resolve=my_project omits my_library.cool-army-55106
05/09/2024, 3:52 PMpants and "regular" python tools: pip, virtual environments, etc.
Monorepo structure is currently something like this:
.
├── 3rdparty (will eventually hold references to all external libraries)
│ ├── java
│ │ └── ivy.xml
│ └── python
│ └── requirements.txt
└── src
├── libs (These can import one another; CAN NOT import projects)
│ ├── java
│ │ ├── library_1
| | │ └── ...
│ │ └── library_2
| | └── ...
│ │
│ └── python
│ ├── my_lib_1
│ | ├── pyproject.toml (and/or poetry lock file, whatever)
│ | ├── ...
│ | ├── my_lib_1
│ | | ├── __init__.py
│ | | └── ...
│ | └── tests
│ | └── ...
│ └── my_lib_2
│ ├── pyproject.toml (and/or poetry lock file, whatever)
│ ├── ...
│ ├── my_lib_2
│ | ├── __init__.py
│ | └── ...
│ └── tests
│ └── ...
│
└── projects (These can import from libs, and CAN NOT import each other)
├── java
│ ├── project_1
| │ └── ...
│ └── project_2
| └── ...
│
└── python
├── project_1
│ ├── pyproject.toml (and/or poetry lock file, whatever)
│ ├── project_1
│ | ├── __init__.py
| │ ├── ...
| └── tests
| └── ...
└── project_2
├── pyproject.toml (and/or poetry lock file, whatever)
├── project_2
| ├── __init__.py
│ ├── ...
└── tests
└── ...
Currently, each project or library has its own pyproject.toml / requirements file that specifies third-party dependencies and local dependencies. So, for example, the pyproject for project_1 might look something like this:
# pyproject.toml
dependencies = [
"flask",
# Internal tools
"lib_1 @ file:///absolute/path/to/src/libs/my_lib_1"
]
Each of our developers will have a different path for lib_1
It seems like pants supports some relative pathing, or path templating: https://www.pantsbuild.org/2.19/docs/python/overview/third-party-dependencies#local-requirements
To support "regular" pip-like functionality we've tried:
• hatch/hatchling, which supports local dependencies: https://hatch.pypa.io/latest/config/dependency/#local
• Stefan is currently also looking at poetry, which would support local dependencies as well https://python-poetry.org/docs/dependency-specification/#path-dependenciescool-army-55106
05/09/2024, 4:16 PMpants and pip
But the paths vary from developer to developer, and in CIcool-army-55106
05/09/2024, 7:21 PM# pyproject.toml
dependencies = [
"flask",
# In the string below, hatchling expands {root:parent:parent:parent:uri}
# into something like file:///absolute/path/to/src/libs/my_lib_1
# where:
# - 'root' is the location of the pyproject.toml file
# - 'parent' is equivalent to something like '/..' on a linux system
# - 'uri' yields the normalized absolute URI path prefixed by 'file:'
"lib_1 @ {root:parent:parent:parent:uri}/libs/python/my_lib_1"
]
And we'd write a pants plug-in that can interpret a requirement in that format to something pants understands. I think this seems like something a plug-in could be used for?happy-kitchen-89482
05/09/2024, 8:45 PMhappy-kitchen-89482
05/09/2024, 8:45 PMhappy-kitchen-89482
05/09/2024, 8:46 PMhappy-kitchen-89482
05/09/2024, 8:46 PMhappy-kitchen-89482
05/09/2024, 8:51 PMsrc/libs/python/my_lib_* should be a source root, assuming that the nested my_lib_* dirs are the top-level packages). And then pants will know how to map imports of them to those source files, and include them in the necessary contexts.happy-kitchen-89482
05/09/2024, 8:53 PMhappy-kitchen-89482
05/09/2024, 8:54 PMhappy-kitchen-89482
05/09/2024, 8:58 PMhappy-kitchen-89482
05/09/2024, 8:58 PMcool-army-55106
05/09/2024, 10:01 PMcool-army-55106
05/10/2024, 11:31 PMflask in our lockfile. And when we pip install from the pyproject, hatchling grabs flask and the local library and installs them in a virtual environment.
# pyproject.toml
dependencies = [
"flask",
# Dependencies that look like the one below get skipped
"lib_1 @ {root.parent.parent.uri}/path/to/a/lib"
]
I'm not sure overriding those behaviors was something the plug-in system was intended to support, but it seems to work. At least for now 🙂
Hoping it's a short-term shim while we roll pants out across our whole monorepo 🤞
Thanks again @happy-kitchen-89482!