Repository: pypa/pip

Issue:
Installation report does not include `requested_extras` if pkg referenced by path
### Description

Hello,

While trying out the fantastic new installation report feature, I've noticed different behavior when installing packages with extras by name (i.e. `Jinja2[i18n]`) compared to installing them by Path (i.e. `.[i18n]` or `/tmp/Jinja2.tar.gz[i18n]`.

[`requested_extras`](https://pip.pypa.io/en/stable/reference/installation-report/#installationreportitem) in the installation reports gets correctly set to `[i18n]` in the first case, but missing in the latter. 
This seems only to affect extras in the report, the packages are installed correctly in both cases. `requested: true` on Jinaj2 is also set correctly in both cases.

### Expected behavior

I'd expect the installation report the same w.r.t. requested_extras if the effective output, the installed packages, are the same. 
i.e. the two pip install commands below should yield the same output.

### pip version

23.0.1

### Python version

3.10

### OS

NixOS 22.11

### How to Reproduce

1. Create a fresh venv
2. Do a dry-run install of `Jinja2[i18n]` by name
3. Do a dry-run install of `Jinja2-3.1.2.tar.gz[i18n]` as downloaded from [pypi](https://files.pythonhosted.org/packages/7a/ff/75c28576a1d900e87eb6335b063fab47a8ef3c8b4d88524c4bf78f670cce/Jinja2-3.1.2.tar.gz)
4. Notice that the report generated by the first does correctly include `requested_extras: ["i18n"]` while the latter does not. 

### Output

```console
$ mkdir -p /tmp/venv; python -m venv /tmp/venv

$ /tmp/venv/bin/pip install --dry-run --report /tmp/venv/report-with-name.json Jinja2[i18n] ; jq '.["install"][] | select(.metadata.name == "Jinja2") | .requested_extras' /tmp/venv/report-with-name.json                                                                                                                   
Collecting Jinja2[i18n]                                                                                                                                                     
  Using cached Jinja2-3.1.2-py3-none-any.whl (133 kB)                                                                                                                       
Collecting MarkupSafe>=2.0                                                                                                                                                  
  Using cached MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)                                                                          
Collecting Babel>=2.7                                                                                                                                                       
  Using cached Babel-2.12.1-py3-none-any.whl (10.1 MB)                                                                                                                      
Would install Babel-2.12.1 Jinja2-3.1.2 MarkupSafe-2.1.1                                                                                                                    
[                                                                                                                                                                           
  "i18n"                                                                                                                                                                    
]                                                                                                                                                                           
                                                                                                                                                                            
$ /tmp/venv/bin/pip install --dry-run --report /tmp/venv/report-with-path.json ~/Downloads/Jinja2-3.1.2.tar.gz[i18n] ; jq '.["install"][] | select(.metadata.name == "Jinja2") | .requested_extras' /tmp/venv/report-with-path.json                                                                                          
Processing /home/phaer/Downloads/Jinja2-3.1.2.tar.gz                                                                                                                        
  Preparing metadata (setup.py) ... done                                                                                                                                    
Collecting MarkupSafe>=2.0                                                                                                                                                  
  Using cached MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)                                                                          
Collecting Babel>=2.7                                                                                                                                                       
  Using cached Babel-2.12.1-py3-none-any.whl (10.1 MB)                                                                                                                      
Would install Babel-2.12.1 Jinja2-3.1.2 MarkupSafe-2.1.1                                                                                                                    
null                                                                             
```

### Code of Conduct

- [X] I agree to follow the [PSF Code of Conduct](https://www.python.org/psf/conduct/).


Discussion:
@phaer Thanks for reporting. I could reproduce. I'll investigate.

Resolving patch:
diff --git a/src/pip/_internal/resolution/resolvelib/candidates.py b/src/pip/_internal/resolution/resolvelib/candidates.py
--- a/src/pip/_internal/resolution/resolvelib/candidates.py
+++ b/src/pip/_internal/resolution/resolvelib/candidates.py
@@ -71,6 +71,7 @@ def make_install_req_from_link(
     )
     ireq.original_link = template.original_link
     ireq.link = link
+    ireq.extras = template.extras
     return ireq
 
 
@@ -78,7 +79,7 @@ def make_install_req_from_editable(
     link: Link, template: InstallRequirement
 ) -> InstallRequirement:
     assert template.editable, "template not editable"
-    return install_req_from_editable(
+    ireq = install_req_from_editable(
         link.url,
         user_supplied=template.user_supplied,
         comes_from=template.comes_from,
@@ -90,6 +91,8 @@ def make_install_req_from_editable(
         hash_options=template.hash_options,
         config_settings=template.config_settings,
     )
+    ireq.extras = template.extras
+    return ireq
 
 
 def _make_install_req_from_dist(


Test patch:
diff --git a/tests/functional/test_install_report.py b/tests/functional/test_install_report.py
--- a/tests/functional/test_install_report.py
+++ b/tests/functional/test_install_report.py
@@ -1,4 +1,5 @@
 import json
+import textwrap
 from pathlib import Path
 from typing import Any, Dict
 
@@ -178,6 +179,97 @@ def test_install_report_vcs_editable(
     assert pip_test_package_report["download_info"]["dir_info"]["editable"] is True
 
 
+@pytest.mark.network
+def test_install_report_local_path_with_extras(
+    script: PipTestEnvironment, tmp_path: Path, shared_data: TestData
+) -> None:
+    """Test report remote editable."""
+    project_path = tmp_path / "pkga"
+    project_path.mkdir()
+    project_path.joinpath("pyproject.toml").write_text(
+        textwrap.dedent(
+            """\
+            [project]
+            name = "pkga"
+            version = "1.0"
+
+            [project.optional-dependencies]
+            test = ["simple"]
+            """
+        )
+    )
+    report_path = tmp_path / "report.json"
+    script.pip(
+        "install",
+        "--dry-run",
+        "--no-build-isolation",
+        "--no-index",
+        "--find-links",
+        str(shared_data.root / "packages/"),
+        "--report",
+        str(report_path),
+        str(project_path) + "[test]",
+    )
+    report = json.loads(report_path.read_text())
+    assert len(report["install"]) == 2
+    pkga_report = report["install"][0]
+    assert pkga_report["metadata"]["name"] == "pkga"
+    assert pkga_report["is_direct"] is True
+    assert pkga_report["requested"] is True
+    assert pkga_report["requested_extras"] == ["test"]
+    simple_report = report["install"][1]
+    assert simple_report["metadata"]["name"] == "simple"
+    assert simple_report["is_direct"] is False
+    assert simple_report["requested"] is False
+    assert "requested_extras" not in simple_report
+
+
+@pytest.mark.network
+def test_install_report_editable_local_path_with_extras(
+    script: PipTestEnvironment, tmp_path: Path, shared_data: TestData
+) -> None:
+    """Test report remote editable."""
+    project_path = tmp_path / "pkga"
+    project_path.mkdir()
+    project_path.joinpath("pyproject.toml").write_text(
+        textwrap.dedent(
+            """\
+            [project]
+            name = "pkga"
+            version = "1.0"
+
+            [project.optional-dependencies]
+            test = ["simple"]
+            """
+        )
+    )
+    report_path = tmp_path / "report.json"
+    script.pip(
+        "install",
+        "--dry-run",
+        "--no-build-isolation",
+        "--no-index",
+        "--find-links",
+        str(shared_data.root / "packages/"),
+        "--report",
+        str(report_path),
+        "--editable",
+        str(project_path) + "[test]",
+    )
+    report = json.loads(report_path.read_text())
+    assert len(report["install"]) == 2
+    pkga_report = report["install"][0]
+    assert pkga_report["metadata"]["name"] == "pkga"
+    assert pkga_report["is_direct"] is True
+    assert pkga_report["requested"] is True
+    assert pkga_report["requested_extras"] == ["test"]
+    simple_report = report["install"][1]
+    assert simple_report["metadata"]["name"] == "simple"
+    assert simple_report["is_direct"] is False
+    assert simple_report["requested"] is False
+    assert "requested_extras" not in simple_report
+
+
 def test_install_report_to_stdout(
     script: PipTestEnvironment, shared_data: TestData
 ) -> None: