Repository: PyO3/maturin (Rust)

Issue:
How to specify extras to install optional-dependencies?
Hi,
I would like to install the dependencies specified in "optional-dependencies" in pyproject.toml as [pyO3-pure](https://github.com/PyO3/maturin/blob/d257dbbcd96874a28e3d9bb30c20df55732176e2/test-crates/pyo3-pure/pyproject.toml#L17). However, I don't know how to add `extras` argument in `maturin develop`. There is no related information in help message. Thank you.


Discussion:
`maturin develop` doesn't support install optional dependencies yet. For now you can do `maturin build` and using pip to install the wheel to specify `extras` for example `pip install path/to/pyo3-pure.whl[test]'`
I think this could be useful feature, any idea what the effort might be to add this ability?
https://github.com/PyO3/maturin/blob/b556ed1d3a1eab65f180e5da5c00648173e77f1d/src/develop.rs#L50-L67

Just need to add optional dependencies here. The question is what to install since you can specify multiple extras with multiple dependencies in `pyproject.toml` for example:

```toml
[project.optional-dependencies]
test = [
  "pytest < 5.0.0",
  "pytest-cov[all]"
]
web = ["flask"]
```
are you referring to test / web or that pytest-cov[all] is nested in test ?
> are you referring to test / web or that pytest-cov[all] is nested in test ?

test / web
how about passing selected extras as arguments for the `develop` command?
> how about passing selected extras as arguments for the `develop` command?

I think it's ok.
Released in v0.11.4-beta.4: https://pypi.org/project/maturin/0.11.4_beta.4/#files , you can install it with `pip install -U --pre maturin`.



Patch:
diff --git a/Changelog.md b/Changelog.md
index fefef68d0..c49a38c27 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 * auditwheel: detect musl libc in [#629](https://github.com/PyO3/maturin/pull/629)
 * Fixed Python 3.10 and later versions detection on Windows in [#630](https://github.com/PyO3/maturin/pull/630)
 * Install entrypoint scripts in `maturin develop` command in [#633](https://github.com/PyO3/maturin/pull/633) and [#634](https://github.com/PyO3/maturin/pull/634)
+* Add support for installing optional dependencies in `maturin develop` command in [#635](https://github.com/PyO3/maturin/pull/635)
 
 ## [0.11.3] - 2021-08-25
 
diff --git a/src/develop.rs b/src/develop.rs
index a1da79637..42ad78b51 100644
--- a/src/develop.rs
+++ b/src/develop.rs
@@ -36,6 +36,7 @@ static WIN_LAUNCHER_W64_ARM: &[u8] = include_bytes!("resources/w64-arm.exe");
 /// Also adds the dist-info directory to make sure pip and other tools detect the library
 ///
 /// Works only in a virtualenv.
+#[allow(clippy::too_many_arguments)]
 pub fn develop(
     bindings: Option<String>,
     manifest_file: &Path,
@@ -44,6 +45,7 @@ pub fn develop(
     venv_dir: &Path,
     release: bool,
     strip: bool,
+    extras: Vec<String>,
 ) -> Result<()> {
     let target = Target::from_target_triple(None)?;
 
@@ -71,14 +73,17 @@ pub fn develop(
 
     // Install dependencies
     if !build_context.metadata21.requires_dist.is_empty() {
-        let mut args = vec!["-m", "pip", "install"];
-        args.extend(
-            build_context
-                .metadata21
-                .requires_dist
-                .iter()
-                .map(|x| x.as_str()),
-        );
+        let mut args = vec!["-m".to_string(), "pip".to_string(), "install".to_string()];
+        args.extend(build_context.metadata21.requires_dist.iter().map(|x| {
+            let mut pkg = x.clone();
+            // Remove extra marker to make it installable with pip
+            for extra in &extras {
+                pkg = pkg
+                    .replace(&format!(" and extra == '{}'", extra), "")
+                    .replace(&format!("; extra == '{}'", extra), "");
+            }
+            pkg
+        }));
         let status = Command::new(&interpreter.executable)
             .args(&args)
             .status()
diff --git a/src/main.rs b/src/main.rs
index 76383fc3b..cf728c36a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -244,6 +244,11 @@ enum Opt {
         /// Use as `--rustc-extra-args="--my-arg"`
         #[structopt(long = "rustc-extra-args")]
         rustc_extra_args: Vec<String>,
+        /// Install extra requires aka. optional dependencies
+        ///
+        /// Use as `--extras=extra1,extra2`
+        #[structopt(short = "E", long, use_delimiter = true, multiple = false)]
+        extras: Vec<String>,
     },
     /// Build only a source distribution (sdist) without compiling.
     ///
@@ -549,6 +554,7 @@ fn run() -> Result<()> {
             rustc_extra_args,
             release,
             strip,
+            extras,
         } => {
             let venv_dir = match (env::var_os("VIRTUAL_ENV"), env::var_os("CONDA_PREFIX")) {
                 (Some(dir), None) => PathBuf::from(dir),
@@ -574,6 +580,7 @@ fn run() -> Result<()> {
                 &venv_dir,
                 release,
                 strip,
+                extras,
             )?;
         }
         Opt::SDist { manifest_path, out } => {


Test patch:
diff --git a/tests/common/develop.rs b/tests/common/develop.rs
index fa304cf71..dee0c46e1 100644
--- a/tests/common/develop.rs
+++ b/tests/common/develop.rs
@@ -70,6 +70,7 @@ pub fn test_develop(package: impl AsRef<Path>, bindings: Option<String>) -> Resu
         &venv_dir,
         false,
         cfg!(feature = "faster-tests"),
+        vec![],
     )?;
 
     check_installed(&package.as_ref(), &python)?;