# 🧩 Build System Integration ```{tip} See [`example/`](https://github.com/basnijholt/unidep/tree/main/example/) for working examples of using `unidep` with different build systems. ``` `unidep` seamlessly integrates with popular Python build systems to simplify dependency management in your projects. ## Local Dependencies in Monorepos Local dependencies are essential for monorepos and multi-package projects, allowing you to: - Share code between packages during development - Maintain separate releases for each package - Test changes across multiple packages simultaneously However, when building wheels for distribution, local paths create non-portable packages that only work on the original system. ## PyPI Alternatives for Local Dependencies UniDep solves this problem by letting you specify both local paths (for development) and PyPI packages (for distribution): ```yaml # requirements.yaml dependencies: - numpy - pandas local_dependencies: # Standard string format for local dependencies - ../shared-lib # Dictionary format with optional PyPI alternative for build-time - local: ../auth-lib pypi: company-auth-lib>=1.0 - local: ../utils pypi: company-utils~=2.0 ``` Or in `pyproject.toml`: ```toml [tool.unidep] dependencies = ["numpy", "pandas"] local_dependencies = [ # Standard string format for local dependencies "../shared-lib", # Dictionary format with optional PyPI alternative for build-time {local = "../auth-lib", pypi = "company-auth-lib>=1.0"}, {local = "../utils", pypi = "company-utils~=2.0"}, ] ``` **How it works:** - **During development** (e.g., `unidep install` or `pip install -e .`): Uses local paths when they exist - **When building wheels**: PyPI alternatives (if specified) are used to create portable packages - The standard string format continues to work as always for local dependencies ```{tip} PyPI alternatives ensure your wheels are portable and can be installed anywhere, not just on the build system. ``` ## Build System Behavior **Important differences between build backends:** - **Setuptools**: Builds wheels containing `file://` URLs with absolute paths. These wheels only work on the original system. - **Hatchling**: Rejects `file://` URLs by default, preventing non-portable wheels. To ensure portable wheels, you can use the `UNIDEP_SKIP_LOCAL_DEPS` environment variable: ```bash # Force use of PyPI alternatives even when local paths exist UNIDEP_SKIP_LOCAL_DEPS=1 python -m build # For hatch projects UNIDEP_SKIP_LOCAL_DEPS=1 hatch build # For uv build UNIDEP_SKIP_LOCAL_DEPS=1 uv build ``` ```{note} **When `UNIDEP_SKIP_LOCAL_DEPS=1` is set:** - Local dependencies with PyPI alternatives → use PyPI package - Local dependencies without PyPI alternatives → skipped entirely - Dependencies from local packages are still included (from their `requirements.yaml`/`pyproject.toml`) ``` ## Example packages Explore these installable [example](https://github.com/basnijholt/unidep/tree/main/example/) packages to understand how `unidep` integrates with different build tools and configurations: | Project | Build Tool | `pyproject.toml` | `requirements.yaml` | `setup.py` | | ---------------------------------------------------------- | ------------ | ---------------- | ------------------- | ---------- | | [`setup_py_project`](https://github.com/basnijholt/unidep/tree/main/example/setup_py_project) | `setuptools` | ✅ | ✅ | ✅ | | [`setuptools_project`](https://github.com/basnijholt/unidep/tree/main/example/setuptools_project) | `setuptools` | ✅ | ✅ | ❌ | | [`pyproject_toml_project`](https://github.com/basnijholt/unidep/tree/main/example/pyproject_toml_project) | `setuptools` | ✅ | ❌ | ❌ | | [`hatch_project`](https://github.com/basnijholt/unidep/tree/main/example/hatch_project) | `hatch` | ✅ | ✅ | ❌ | | [`hatch2_project`](https://github.com/basnijholt/unidep/tree/main/example/hatch2_project) | `hatch` | ✅ | ❌ | ❌ | ## Setuptools Integration For projects using `setuptools`, configure `unidep` in `pyproject.toml` and either specify dependencies in a `requirements.yaml` file or include them in `pyproject.toml` too. - **Using `pyproject.toml` only**: The `[project.dependencies]` field in `pyproject.toml` gets automatically populated from `requirements.yaml` or from the `[tool.unidep]` section in `pyproject.toml`. - **Using `setup.py`**: The `install_requires` field in `setup.py` automatically reflects dependencies specified in `requirements.yaml` or `pyproject.toml`. **Example `pyproject.toml` Configuration**: ```toml [build-system] build-backend = "setuptools.build_meta" requires = ["setuptools", "unidep"] [project] dynamic = ["dependencies"] ``` ## Hatchling Integration For projects managed with [Hatch](https://hatch.pypa.io/), `unidep` can be configured in `pyproject.toml` to automatically process the dependencies from `requirements.yaml` or from the `[tool.unidep]` section in `pyproject.toml`. **Example Configuration for Hatch**: ```toml [build-system] requires = ["hatchling", "unidep"] build-backend = "hatchling.build" [project] dynamic = ["dependencies"] # Additional project configurations [tool.hatch.metadata.hooks.unidep] # Enable the unidep plugin [tool.hatch.metadata] allow-direct-references = true [tool.unidep] # Your dependencies configuration ```