Add `--no-editable` support to `uv sync` and `uv export` (#7371)

## Summary

Closes https://github.com/astral-sh/uv/issues/5792.
This commit is contained in:
Charlie Marsh 2024-09-17 10:50:36 -04:00 committed by GitHub
parent bb0ffa32e4
commit 778da3350a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 362 additions and 22 deletions

View File

@ -76,15 +76,34 @@ impl Resolution {
pub fn filter(self, predicate: impl Fn(&ResolvedDist) -> bool) -> Self {
let packages = self
.packages
.iter()
.into_iter()
.filter(|(_, dist)| predicate(dist))
.map(|(name, dist)| (name.clone(), dist.clone()))
.collect::<BTreeMap<_, _>>();
let hashes = self
.hashes
.iter()
.into_iter()
.filter(|(name, _)| packages.contains_key(name))
.collect();
let diagnostics = self.diagnostics.clone();
Self {
packages,
hashes,
diagnostics,
}
}
/// Map over the resolved distributions in this resolution.
#[must_use]
pub fn map(self, predicate: impl Fn(ResolvedDist) -> ResolvedDist) -> Self {
let packages = self
.packages
.into_iter()
.map(|(name, dist)| (name, predicate(dist)))
.collect::<BTreeMap<_, _>>();
let hashes = self
.hashes
.into_iter()
.filter(|(name, _)| packages.contains_key(name))
.map(|(name, hashes)| (name.clone(), hashes.clone()))
.collect();
let diagnostics = self.diagnostics.clone();
Self {

View File

@ -2408,6 +2408,11 @@ pub struct RunArgs {
#[arg(long, conflicts_with("no_dev"))]
pub only_dev: bool,
/// Install any editable dependencies, including the project and any workspace members, as
/// non-editable.
#[arg(long)]
pub no_editable: bool,
/// The command to run.
///
/// If the path to a Python script (i.e., ending in `.py`), it will be
@ -2560,6 +2565,11 @@ pub struct SyncArgs {
#[arg(long, conflicts_with("no_dev"))]
pub only_dev: bool,
/// Install any editable dependencies, including the project and any workspace members, as
/// non-editable.
#[arg(long)]
pub no_editable: bool,
/// Do not remove extraneous packages present in the environment.
///
/// When enabled, uv will make the minimum necessary changes to satisfy the requirements.
@ -3002,6 +3012,11 @@ pub struct ExportArgs {
#[arg(long, conflicts_with("no_dev"))]
pub only_dev: bool,
/// Install any editable dependencies, including the project and any workspace members, as
/// non-editable.
#[arg(long)]
pub no_editable: bool,
/// Include hashes for all dependencies.
#[arg(long, overrides_with("no_hashes"), hide = true)]
pub hashes: bool,

View File

@ -0,0 +1,17 @@
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum EditableMode {
#[default]
Editable,
NonEditable,
}
impl EditableMode {
/// Determine the editable mode based on the command-line arguments.
pub fn from_args(no_editable: bool) -> Self {
if no_editable {
Self::NonEditable
} else {
Self::Editable
}
}
}

View File

@ -4,6 +4,7 @@ pub use concurrency::*;
pub use config_settings::*;
pub use constraints::*;
pub use dev::*;
pub use editable::*;
pub use export_format::*;
pub use extras::*;
pub use hash::*;
@ -22,6 +23,7 @@ mod concurrency;
mod config_settings;
mod constraints;
mod dev;
mod editable;
mod export_format;
mod extras;
mod hash;

View File

@ -13,7 +13,7 @@ use url::Url;
use distribution_filename::{DistExtension, SourceDistExtension};
use pep508_rs::MarkerTree;
use pypi_types::{ParsedArchiveUrl, ParsedGitUrl};
use uv_configuration::{DevSpecification, ExtrasSpecification, InstallOptions};
use uv_configuration::{DevSpecification, EditableMode, ExtrasSpecification, InstallOptions};
use uv_fs::Simplified;
use uv_git::GitReference;
use uv_normalize::{ExtraName, PackageName};
@ -35,6 +35,7 @@ struct Node<'lock> {
pub struct RequirementsTxtExport<'lock> {
nodes: Vec<Node<'lock>>,
hashes: bool,
editable: EditableMode,
}
impl<'lock> RequirementsTxtExport<'lock> {
@ -43,6 +44,7 @@ impl<'lock> RequirementsTxtExport<'lock> {
root_name: &PackageName,
extras: &ExtrasSpecification,
dev: DevSpecification<'_>,
editable: EditableMode,
hashes: bool,
install_options: &'lock InstallOptions,
) -> Result<Self, LockError> {
@ -166,7 +168,11 @@ impl<'lock> RequirementsTxtExport<'lock> {
NodeComparator::from(a.package).cmp(&NodeComparator::from(b.package))
});
Ok(Self { nodes, hashes })
Ok(Self {
nodes,
hashes,
editable,
})
}
}
@ -216,9 +222,18 @@ impl std::fmt::Display for RequirementsTxtExport<'_> {
write!(f, "{}", anchor(path).portable_display())?;
}
}
Source::Editable(path) => {
write!(f, "-e {}", anchor(path).portable_display())?;
}
Source::Editable(path) => match self.editable {
EditableMode::Editable => {
write!(f, "-e {}", anchor(path).portable_display())?;
}
EditableMode::NonEditable => {
if path.is_absolute() {
write!(f, "{}", Url::from_file_path(path).unwrap())?;
} else {
write!(f, "{}", anchor(path).portable_display())?;
}
}
},
Source::Virtual(_) => {
continue;
}

View File

@ -16,7 +16,8 @@ use uv_auth::{store_credentials_from_url, Credentials};
use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
Concurrency, Constraints, DevMode, ExtrasSpecification, InstallOptions, SourceStrategy,
Concurrency, Constraints, DevMode, EditableMode, ExtrasSpecification, InstallOptions,
SourceStrategy,
};
use uv_dispatch::BuildDispatch;
use uv_distribution::DistributionDatabase;
@ -755,6 +756,7 @@ async fn lock_and_sync(
&lock,
&extras,
dev,
EditableMode::Editable,
InstallOptions::default(),
Modifications::Sufficient,
settings.into(),

View File

@ -8,7 +8,8 @@ use std::path::PathBuf;
use uv_cache::Cache;
use uv_client::Connectivity;
use uv_configuration::{
Concurrency, DevMode, DevSpecification, ExportFormat, ExtrasSpecification, InstallOptions,
Concurrency, DevMode, DevSpecification, EditableMode, ExportFormat, ExtrasSpecification,
InstallOptions,
};
use uv_fs::CWD;
use uv_normalize::{PackageName, DEV_DEPENDENCIES};
@ -33,6 +34,7 @@ pub(crate) async fn export(
output_file: Option<PathBuf>,
extras: ExtrasSpecification,
dev: DevMode,
editable: EditableMode,
locked: bool,
frozen: bool,
python: Option<String>,
@ -130,6 +132,7 @@ pub(crate) async fn export(
project.project_name(),
&extras,
dev,
editable,
hashes,
&install_options,
)?;

View File

@ -6,7 +6,7 @@ use owo_colors::OwoColorize;
use pep508_rs::PackageName;
use uv_cache::Cache;
use uv_client::Connectivity;
use uv_configuration::{Concurrency, DevMode, ExtrasSpecification, InstallOptions};
use uv_configuration::{Concurrency, DevMode, EditableMode, ExtrasSpecification, InstallOptions};
use uv_fs::{Simplified, CWD};
use uv_python::{PythonDownloads, PythonPreference, PythonRequest};
use uv_scripts::Pep723Script;
@ -188,8 +188,8 @@ pub(crate) async fn remove(
// Perform a full sync, because we don't know what exactly is affected by the removal.
// TODO(ibraheem): Should we accept CLI overrides for this? Should we even sync here?
let extras = ExtrasSpecification::All;
let dev = DevMode::Include;
let extras = ExtrasSpecification::All;
let install_options = InstallOptions::default();
// Initialize any shared state.
@ -201,6 +201,7 @@ pub(crate) async fn remove(
&lock,
&extras,
dev,
EditableMode::Editable,
install_options,
Modifications::Exact,
settings.as_ref().into(),

View File

@ -14,7 +14,9 @@ use tracing::{debug, warn};
use uv_cache::Cache;
use uv_cli::ExternalCommand;
use uv_client::{BaseClientBuilder, Connectivity};
use uv_configuration::{Concurrency, DevMode, ExtrasSpecification, InstallOptions, SourceStrategy};
use uv_configuration::{
Concurrency, DevMode, EditableMode, ExtrasSpecification, InstallOptions, SourceStrategy,
};
use uv_distribution::LoweredRequirement;
use uv_fs::{PythonExt, Simplified, CWD};
use uv_installer::{SatisfiesResult, SitePackages};
@ -58,6 +60,7 @@ pub(crate) async fn run(
no_config: bool,
extras: ExtrasSpecification,
dev: DevMode,
editable: EditableMode,
python: Option<String>,
settings: ResolverInstallerSettings,
python_preference: PythonPreference,
@ -501,6 +504,7 @@ pub(crate) async fn run(
result.lock(),
&extras,
dev,
editable,
install_options,
Modifications::Sufficient,
settings.as_ref().into(),

View File

@ -1,14 +1,14 @@
use anyhow::{Context, Result};
use itertools::Itertools;
use distribution_types::{Dist, ResolvedDist, SourceDist};
use distribution_types::{DirectorySourceDist, Dist, ResolvedDist, SourceDist};
use pep508_rs::MarkerTree;
use uv_auth::store_credentials_from_url;
use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
Concurrency, Constraints, DevMode, DevSpecification, ExtrasSpecification, HashCheckingMode,
InstallOptions,
Concurrency, Constraints, DevMode, DevSpecification, EditableMode, ExtrasSpecification,
HashCheckingMode, InstallOptions,
};
use uv_dispatch::BuildDispatch;
use uv_fs::CWD;
@ -36,6 +36,7 @@ pub(crate) async fn sync(
package: Option<PackageName>,
extras: ExtrasSpecification,
dev: DevMode,
editable: EditableMode,
install_options: InstallOptions,
modifications: Modifications,
python: Option<String>,
@ -133,6 +134,7 @@ pub(crate) async fn sync(
&lock,
&extras,
dev,
editable,
install_options,
modifications,
settings.as_ref().into(),
@ -157,6 +159,7 @@ pub(super) async fn do_sync(
lock: &Lock,
extras: &ExtrasSpecification,
dev: DevMode,
editable: EditableMode,
install_options: InstallOptions,
modifications: Modifications,
settings: InstallerSettingsRef<'_>,
@ -242,6 +245,9 @@ pub(super) async fn do_sync(
// Always skip virtual projects, which shouldn't be built or installed.
let resolution = apply_no_virtual_project(resolution);
// If necessary, convert editable to non-editable distributions.
let resolution = apply_editable_mode(resolution, editable);
// Add all authenticated sources to the cache.
for url in index_locations.urls() {
store_credentials_from_url(url);
@ -358,3 +364,38 @@ fn apply_no_virtual_project(
!dist.r#virtual
})
}
/// If necessary, convert any editable requirements to non-editable.
fn apply_editable_mode(
resolution: distribution_types::Resolution,
editable: EditableMode,
) -> distribution_types::Resolution {
match editable {
// No modifications are necessary for editable mode; retain any editable distributions.
EditableMode::Editable => resolution,
// Filter out any editable distributions.
EditableMode::NonEditable => resolution.map(|dist| {
let ResolvedDist::Installable(Dist::Source(SourceDist::Directory(
DirectorySourceDist {
name,
install_path,
editable: true,
r#virtual: false,
url,
},
))) = dist
else {
return dist;
};
ResolvedDist::Installable(Dist::Source(SourceDist::Directory(DirectorySourceDist {
name,
install_path,
editable: false,
r#virtual: false,
url,
})))
}),
}
}

View File

@ -1157,6 +1157,7 @@ async fn run_project(
no_config,
args.extras,
args.dev,
args.editable,
args.python,
args.settings,
globals.python_preference,
@ -1187,6 +1188,7 @@ async fn run_project(
args.package,
args.extras,
args.dev,
args.editable,
args.install_options,
args.modifications,
args.python,
@ -1355,6 +1357,7 @@ async fn run_project(
args.output_file,
args.extras,
args.dev,
args.editable,
args.locked,
args.frozen,
args.python,

View File

@ -22,9 +22,9 @@ use uv_cli::{
};
use uv_client::Connectivity;
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, DevMode, ExportFormat, ExtrasSpecification,
HashCheckingMode, IndexStrategy, InstallOptions, KeyringProviderType, NoBinary, NoBuild,
PreviewMode, Reinstall, SourceStrategy, TargetTriple, TrustedHost, Upgrade,
BuildOptions, Concurrency, ConfigSettings, DevMode, EditableMode, ExportFormat,
ExtrasSpecification, HashCheckingMode, IndexStrategy, InstallOptions, KeyringProviderType,
NoBinary, NoBuild, PreviewMode, Reinstall, SourceStrategy, TargetTriple, TrustedHost, Upgrade,
};
use uv_normalize::PackageName;
use uv_python::{Prefix, PythonDownloads, PythonPreference, PythonVersion, Target};
@ -210,6 +210,7 @@ pub(crate) struct RunSettings {
pub(crate) frozen: bool,
pub(crate) extras: ExtrasSpecification,
pub(crate) dev: DevMode,
pub(crate) editable: EditableMode,
pub(crate) with: Vec<String>,
pub(crate) with_editable: Vec<String>,
pub(crate) with_requirements: Vec<PathBuf>,
@ -234,6 +235,7 @@ impl RunSettings {
dev,
no_dev,
only_dev,
no_editable,
command: _,
with,
with_editable,
@ -259,6 +261,7 @@ impl RunSettings {
extra.unwrap_or_default(),
),
dev: DevMode::from_args(dev, no_dev, only_dev),
editable: EditableMode::from_args(no_editable),
with,
with_editable,
with_requirements: with_requirements
@ -661,6 +664,7 @@ pub(crate) struct SyncSettings {
pub(crate) frozen: bool,
pub(crate) extras: ExtrasSpecification,
pub(crate) dev: DevMode,
pub(crate) editable: EditableMode,
pub(crate) install_options: InstallOptions,
pub(crate) modifications: Modifications,
pub(crate) package: Option<PackageName>,
@ -680,6 +684,7 @@ impl SyncSettings {
dev,
no_dev,
only_dev,
no_editable,
inexact,
exact,
no_install_project,
@ -707,6 +712,7 @@ impl SyncSettings {
extra.unwrap_or_default(),
),
dev: DevMode::from_args(dev, no_dev, only_dev),
editable: EditableMode::from_args(no_editable),
install_options: InstallOptions::new(
no_install_project,
no_install_workspace,
@ -961,6 +967,7 @@ pub(crate) struct ExportSettings {
pub(crate) package: Option<PackageName>,
pub(crate) extras: ExtrasSpecification,
pub(crate) dev: DevMode,
pub(crate) editable: EditableMode,
pub(crate) hashes: bool,
pub(crate) install_options: InstallOptions,
pub(crate) output_file: Option<PathBuf>,
@ -984,6 +991,7 @@ impl ExportSettings {
dev,
no_dev,
only_dev,
no_editable,
hashes,
no_hashes,
output_file,
@ -1006,6 +1014,7 @@ impl ExportSettings {
extra.unwrap_or_default(),
),
dev: DevMode::from_args(dev, no_dev, only_dev),
editable: EditableMode::from_args(no_editable),
hashes: flag(hashes, no_hashes).unwrap_or(true),
install_options: InstallOptions::new(
no_emit_project,

View File

@ -905,3 +905,73 @@ fn no_emit() -> Result<()> {
Ok(())
}
#[test]
fn no_editable() -> Result<()> {
let context = TestContext::new("3.12");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["anyio==3.7.0", "child"]
[tool.uv.workspace]
members = ["child"]
[tool.uv.sources]
child = { workspace = true }
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
"#,
)?;
let child = context.temp_dir.child("child");
child.child("pyproject.toml").write_str(
r#"
[project]
name = "child"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["iniconfig>=2"]
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
"#,
)?;
context.lock().assert().success();
uv_snapshot!(context.filters(), context.export().arg("--no-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv export --cache-dir [CACHE_DIR] --no-editable
.
./child
anyio==3.7.0 \
--hash=sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce \
--hash=sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0
idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
iniconfig==2.0.0 \
--hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
--hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
sniffio==1.3.1 \
--hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc \
--hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2
----- stderr -----
Resolved 6 packages in [TIME]
"###);
Ok(())
}

View File

@ -2392,6 +2392,89 @@ fn transitive_dev() -> Result<()> {
Ok(())
}
/// Avoid installing dev dependencies of transitive dependencies.
#[test]
fn sync_no_editable() -> Result<()> {
let context = TestContext::new("3.12");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "root"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["child"]
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
[tool.uv.sources]
child = { workspace = true }
[tool.uv.workspace]
members = ["child"]
"#,
)?;
let src = context.temp_dir.child("src").child("albatross");
src.create_dir_all()?;
let init = src.child("__init__.py");
init.touch()?;
let child = context.temp_dir.child("child");
fs_err::create_dir_all(&child)?;
let pyproject_toml = child.child("pyproject.toml");
pyproject_toml.write_str(
r#"
[project]
name = "child"
version = "0.1.0"
requires-python = ">=3.12"
[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
"#,
)?;
let src = child.child("src").child("child");
src.create_dir_all()?;
let init = src.child("__init__.py");
init.touch()?;
uv_snapshot!(context.filters(), context.sync().arg("--no-editable"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 2 packages in [TIME]
Prepared 2 packages in [TIME]
Installed 2 packages in [TIME]
+ child==0.1.0 (from file://[TEMP_DIR]/child)
+ root==0.1.0 (from file://[TEMP_DIR]/)
"###);
// Remove the project.
fs_err::remove_dir_all(&child)?;
// Ensure that we can still import it.
uv_snapshot!(context.filters(), context.run().arg("--no-sync").arg("python").arg("-c").arg("import child"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
"###);
Ok(())
}
#[test]
/// Check warning message for <https://github.com/astral-sh/uv/issues/6998>
/// if no `build-system` section is defined.

View File

@ -67,9 +67,9 @@ project should be packaged and installed.
uv uses the presence of a build system to determine if a project contains a package that should be
installed in the project virtual environment. If a build system is not defined, uv will not attempt
to build or install the project itself, just its dependencies. If a build system is defined, uv will
build and install the project into the project environment. Projects are installed in
build and install the project into the project environment. By default, projects are installed in
[editable mode](https://setuptools.pypa.io/en/latest/userguide/development_mode.html) so changes to
the source code are reflected immediately, without reinstallation.
the source code are reflected immediately, without re-installation.
### Configuring project packaging
@ -297,6 +297,12 @@ use [`uvx`](../guides/tools.md) or
managed = false
```
By default, the project will be installed in editable mode, such that changes to the source code are
immediately reflected in the environment. `uv sync` and `uv run` both accept a `--no-editable` flag,
which instructs uv to install the project in non-editable mode. `--no-editable` is intended for
deployment use-cases, such as building a Docker container, in which the project should be included
in the deployed environment without a dependency on the originating source code.
### Configuring the project environment path
The `UV_PROJECT_ENVIRONMENT` environment variable can be used to configure the project virtual

View File

@ -360,6 +360,50 @@ _contents_ are not copied into the image until the final `uv sync` command.
If you want to remove specific packages from the sync, use `--no-install-package <name>`.
### Non-editable installs
By default, uv installs projects and workspace members in editable mode, such that changes to the
source code are immediately reflected in the environment.
`uv sync` and `uv run` both accept a `--no-editable` flag, which instructs uv to install the project
in non-editable mode, removing any dependency on the source code.
In the context of a multi-stage Docker image, `--no-editable` can be used to include the project in
the synced virtual environment from one stage, then copy the virtual environment alone (and not the
source code) into the final image.
For example:
```dockerfile title="Dockerfile"
# Install uv
FROM python:3.12-slim AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
# Change the working directory to the `app` directory
WORKDIR /app
# Install dependencies
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-editable
# Copy the project into the intermediate image
ADD . /app
# Sync the project
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-editable
FROM python:3.12-slim
# Copy the environment, but not the source code
COPY --from=builder --chown=app:app /app/.venv /app/.venv
# Run the application
CMD ["/app/.venv/bin/hello"]
```
### Using uv temporarily
If uv isn't needed in the final image, the binary can be mounted in each invocation:

View File

@ -249,6 +249,8 @@ uv run [OPTIONS] <COMMAND>
<p>This option is only available when running in a project.</p>
</dd><dt><code>--no-editable</code></dt><dd><p>Install any editable dependencies, including the project and any workspace members, as non-editable</p>
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
</dd><dt><code>--no-progress</code></dt><dd><p>Hide all progress outputs.</p>
@ -1313,6 +1315,8 @@ uv sync [OPTIONS]
<p>May also be set with the <code>UV_NO_CONFIG</code> environment variable.</p>
</dd><dt><code>--no-dev</code></dt><dd><p>Omit development dependencies</p>
</dd><dt><code>--no-editable</code></dt><dd><p>Install any editable dependencies, including the project and any workspace members, as non-editable</p>
</dd><dt><code>--no-index</code></dt><dd><p>Ignore the registry index (e.g., PyPI), instead relying on direct URL dependencies and those provided via <code>--find-links</code></p>
</dd><dt><code>--no-install-package</code> <i>no-install-package</i></dt><dd><p>Do not install the given package(s).</p>
@ -1869,6 +1873,8 @@ uv export [OPTIONS]
<p>May also be set with the <code>UV_NO_CONFIG</code> environment variable.</p>
</dd><dt><code>--no-dev</code></dt><dd><p>Omit development dependencies</p>
</dd><dt><code>--no-editable</code></dt><dd><p>Install any editable dependencies, including the project and any workspace members, as non-editable</p>
</dd><dt><code>--no-emit-package</code> <i>no-emit-package</i></dt><dd><p>Do not emit the given package(s).</p>
<p>By default, all of the project&#8217;s dependencies are included in the exported requirements file. The <code>--no-install-package</code> option allows exclusion of specific packages.</p>