diff --git a/src/poetry/packages/locker.py b/src/poetry/packages/locker.py
index 775e16c8a3d..69aadd292e2 100644
--- a/src/poetry/packages/locker.py
+++ b/src/poetry/packages/locker.py
@@ -32,6 +32,7 @@
 
 
 if TYPE_CHECKING:
+    from poetry.core.version.markers import BaseMarker
     from tomlkit.items import InlineTable
     from tomlkit.toml_document import TOMLDocument
 
@@ -203,69 +204,80 @@ def locked_repository(self, with_dev_reqs: bool = False) -> Repository:
 
     @staticmethod
     def __get_locked_package(
-        _dependency: Dependency, packages_by_name: dict[str, list[Package]]
+        dependency: Dependency,
+        packages_by_name: dict[str, list[Package]],
+        decided: dict[Package, Dependency] | None = None,
     ) -> Package | None:
         """
         Internal helper to identify corresponding locked package using dependency
         version constraints.
         """
-        for _package in packages_by_name.get(_dependency.name, []):
-            if _dependency.constraint.allows(_package.version):
-                return _package
-        return None
+        decided = decided or {}
+
+        # Get the packages that are consistent with this dependency.
+        packages = [
+            package
+            for package in packages_by_name.get(dependency.name, [])
+            if package.python_constraint.allows_all(dependency.python_constraint)
+            and dependency.constraint.allows(package.version)
+        ]
+
+        # If we've previously made a choice that is compatible with the current
+        # requirement, stick with it.
+        for package in packages:
+            old_decision = decided.get(package)
+            if (
+                old_decision is not None
+                and not old_decision.marker.intersect(dependency.marker).is_empty()
+            ):
+                return package
+
+        return next(iter(packages), None)
 
     @classmethod
-    def __walk_dependency_level(
+    def __walk_dependencies(
         cls,
         dependencies: list[Dependency],
-        level: int,
-        pinned_versions: bool,
         packages_by_name: dict[str, list[Package]],
-        project_level_dependencies: set[str],
-        nested_dependencies: dict[tuple[str, str], Dependency],
-    ) -> dict[tuple[str, str], Dependency]:
-        if not dependencies:
-            return nested_dependencies
-
-        next_level_dependencies = []
+    ) -> dict[Package, Dependency]:
+        nested_dependencies: dict[Package, Dependency] = {}
 
-        for requirement in dependencies:
-            key = (requirement.name, requirement.pretty_constraint)
-            locked_package = cls.__get_locked_package(requirement, packages_by_name)
-
-            if locked_package:
-                # create dependency from locked package to retain dependency metadata
-                # if this is not done, we can end-up with incorrect nested dependencies
-                constraint = requirement.constraint
-                pretty_constraint = requirement.pretty_constraint
-                marker = requirement.marker
-                requirement = locked_package.to_dependency()
-                requirement.marker = requirement.marker.intersect(marker)
-
-                key = (requirement.name, pretty_constraint)
+        visited: set[tuple[Dependency, BaseMarker]] = set()
+        while dependencies:
+            requirement = dependencies.pop(0)
+            if (requirement, requirement.marker) in visited:
+                continue
+            visited.add((requirement, requirement.marker))
 
-                if not pinned_versions:
-                    requirement.set_constraint(constraint)
+            locked_package = cls.__get_locked_package(
+                requirement, packages_by_name, nested_dependencies
+            )
 
-                for require in locked_package.requires:
-                    if require.marker.is_empty():
-                        require.marker = requirement.marker
-                    else:
-                        require.marker = require.marker.intersect(requirement.marker)
+            if not locked_package:
+                raise RuntimeError(f"Dependency walk failed at {requirement}")
 
-                    require.marker = require.marker.intersect(locked_package.marker)
+            # create dependency from locked package to retain dependency metadata
+            # if this is not done, we can end-up with incorrect nested dependencies
+            constraint = requirement.constraint
+            marker = requirement.marker
+            extras = requirement.extras
+            requirement = locked_package.to_dependency()
+            requirement.marker = requirement.marker.intersect(marker)
 
-                    if key not in nested_dependencies:
-                        next_level_dependencies.append(require)
+            requirement.set_constraint(constraint)
 
-            if requirement.name in project_level_dependencies and level == 0:
-                # project level dependencies take precedence
-                continue
+            for require in locked_package.requires:
+                if require.in_extras and extras.isdisjoint(require.in_extras):
+                    continue
 
-            if not locked_package:
-                # we make a copy to avoid any side-effects
-                requirement = deepcopy(requirement)
+                require = deepcopy(require)
+                require.marker = require.marker.intersect(
+                    requirement.marker.without_extras()
+                )
+                if not require.marker.is_empty():
+                    dependencies.append(require)
 
+            key = locked_package
             if key not in nested_dependencies:
                 nested_dependencies[key] = requirement
             else:
@@ -273,75 +285,32 @@ def __walk_dependency_level(
                     requirement.marker
                 )
 
-        return cls.__walk_dependency_level(
-            dependencies=next_level_dependencies,
-            level=level + 1,
-            pinned_versions=pinned_versions,
-            packages_by_name=packages_by_name,
-            project_level_dependencies=project_level_dependencies,
-            nested_dependencies=nested_dependencies,
-        )
+        return nested_dependencies
 
     @classmethod
     def get_project_dependencies(
         cls,
         project_requires: list[Dependency],
         locked_packages: list[Package],
-        pinned_versions: bool = False,
-        with_nested: bool = False,
-    ) -> Iterable[Dependency]:
+    ) -> Iterable[tuple[Package, Dependency]]:
         # group packages entries by name, this is required because requirement might use
-        # different constraints
+        # different constraints.
         packages_by_name: dict[str, list[Package]] = {}
         for pkg in locked_packages:
             if pkg.name not in packages_by_name:
                 packages_by_name[pkg.name] = []
             packages_by_name[pkg.name].append(pkg)
 
-        project_level_dependencies = set()
-        dependencies = []
+        # Put higher versions first so that we prefer them.
+        for packages in packages_by_name.values():
+            packages.sort(key=lambda package: package.version, reverse=True)
 
-        for dependency in project_requires:
-            dependency = deepcopy(dependency)
-            locked_package = cls.__get_locked_package(dependency, packages_by_name)
-            if locked_package:
-                locked_dependency = locked_package.to_dependency()
-                locked_dependency.marker = dependency.marker.intersect(
-                    locked_package.marker
-                )
-
-                if not pinned_versions:
-                    locked_dependency.set_constraint(dependency.constraint)
-
-                dependency = locked_dependency
-
-            project_level_dependencies.add(dependency.name)
-            dependencies.append(dependency)
-
-        if not with_nested:
-            # return only with project level dependencies
-            return dependencies
-
-        nested_dependencies = cls.__walk_dependency_level(
-            dependencies=dependencies,
-            level=0,
-            pinned_versions=pinned_versions,
+        nested_dependencies = cls.__walk_dependencies(
+            dependencies=project_requires,
             packages_by_name=packages_by_name,
-            project_level_dependencies=project_level_dependencies,
-            nested_dependencies={},
         )
 
-        # Merge same dependencies using marker union
-        for requirement in dependencies:
-            key = (requirement.name, requirement.pretty_constraint)
-            if key not in nested_dependencies:
-                nested_dependencies[key] = requirement
-            else:
-                nested_dependencies[key].marker = nested_dependencies[key].marker.union(
-                    requirement.marker
-                )
-
-        return sorted(nested_dependencies.values(), key=lambda x: x.name.lower())
+        return nested_dependencies.items()
 
     def get_project_dependency_packages(
         self,
@@ -379,16 +348,10 @@ def get_project_dependency_packages(
 
             selected.append(dependency)
 
-        for dependency in self.get_project_dependencies(
+        for package, dependency in self.get_project_dependencies(
             project_requires=selected,
             locked_packages=repository.packages,
-            with_nested=True,
         ):
-            try:
-                package = repository.find_packages(dependency=dependency)[0]
-            except IndexError:
-                continue
-
             for extra in dependency.extras:
                 package.requires_extras.append(extra)
 
diff --git a/src/poetry/utils/exporter.py b/src/poetry/utils/exporter.py
index 147b930fec2..5d33f1a808f 100644
--- a/src/poetry/utils/exporter.py
+++ b/src/poetry/utils/exporter.py
@@ -1,8 +1,8 @@
 from __future__ import annotations
 
-import itertools
 import urllib.parse
 
+from copy import deepcopy
 from typing import TYPE_CHECKING
 from typing import Sequence
 
@@ -70,21 +70,23 @@ def _export_requirements_txt(
         content = ""
         dependency_lines = set()
 
-        for package, groups in itertools.groupby(
-            self._poetry.locker.get_project_dependency_packages(
-                project_requires=self._poetry.package.all_requires,
-                dev=dev,
-                extras=extras,
-            ),
-            lambda dependency_package: dependency_package.package,
+        # Get project dependencies, and add the project-wide marker to them.
+        groups = ["dev"] if dev else []
+        root_package = self._poetry.package.with_dependency_groups(groups)
+        project_requires = []
+        for require in root_package.all_requires:
+            require = deepcopy(require)
+            require.marker = require.marker.intersect(root_package.python_marker)
+            project_requires.append(require)
+
+        for dependency_package in self._poetry.locker.get_project_dependency_packages(
+            project_requires=project_requires,
+            dev=dev,
+            extras=extras,
         ):
             line = ""
-            dependency_packages = list(groups)
-            dependency = dependency_packages[0].dependency
-            marker = dependency.marker
-            for dep_package in dependency_packages[1:]:
-                marker = marker.union(dep_package.dependency.marker)
-            dependency.marker = marker
+            dependency = dependency_package.dependency
+            package = dependency_package.package
 
             if package.develop:
                 line += "-e "
diff --git a/tests/console/commands/test_export.py b/tests/console/commands/test_export.py
index c277ffa6b0c..6e704b5338a 100644
--- a/tests/console/commands/test_export.py
+++ b/tests/console/commands/test_export.py
@@ -84,7 +84,9 @@ def _export_requirements(tester: CommandTester, poetry: Poetry) -> None:
     assert poetry.locker.lock.exists()
 
     expected = """\
-foo==1.0.0
+foo==1.0.0 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.4" and python_version < "4.0"
 """
 
     assert content == expected
@@ -113,7 +115,9 @@ def test_export_fails_on_invalid_format(tester: CommandTester, do_lock: None):
 def test_export_prints_to_stdout_by_default(tester: CommandTester, do_lock: None):
     tester.execute("--format requirements.txt")
     expected = """\
-foo==1.0.0
+foo==1.0.0 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.4" and python_version < "4.0"
 """
     assert tester.io.fetch_output() == expected
 
@@ -123,7 +127,9 @@ def test_export_uses_requirements_txt_format_by_default(
 ):
     tester.execute()
     expected = """\
-foo==1.0.0
+foo==1.0.0 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.4" and python_version < "4.0"
 """
     assert tester.io.fetch_output() == expected
 
@@ -131,8 +137,12 @@ def test_export_uses_requirements_txt_format_by_default(
 def test_export_includes_extras_by_flag(tester: CommandTester, do_lock: None):
     tester.execute("--format requirements.txt --extras feature_bar")
     expected = """\
-bar==1.1.0
-foo==1.0.0
+bar==1.1.0 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.4" and python_version < "4.0"
+foo==1.0.0 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.4" and python_version < "4.0"
 """
     assert tester.io.fetch_output() == expected
 
diff --git a/tests/utils/test_exporter.py b/tests/utils/test_exporter.py
index 4bee492ebe4..fd6a05d9188 100644
--- a/tests/utils/test_exporter.py
+++ b/tests/utils/test_exporter.py
@@ -1,7 +1,6 @@
 from __future__ import annotations
 
 import sys
-import textwrap
 
 from pathlib import Path
 from typing import TYPE_CHECKING
@@ -126,8 +125,12 @@ def test_exporter_can_export_requirements_txt_with_standard_packages(
         content = f.read()
 
     expected = """\
-bar==4.5.6
-foo==1.2.3
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -181,9 +184,15 @@ def test_exporter_can_export_requirements_txt_with_standard_packages_and_markers
         content = f.read()
 
     expected = """\
-bar==4.5.6
-baz==7.8.9 ; sys_platform == "win32"
-foo==1.2.3 ; python_version < "3.7"
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+baz==7.8.9 ;\
+ python_version >= "2.7" and python_version < "2.8" and sys_platform == "win32" or\
+ python_version >= "3.6" and python_version < "4.0" and sys_platform == "win32"
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "3.7"
 """
 
     assert content == expected
@@ -286,17 +295,29 @@ def test_exporter_can_export_requirements_txt_poetry(tmp_dir: str, poetry: Poetr
     # │       ├── cryptography >=2.0
     # │       │   └── six >=1.4.1
     # │       └── jeepney >=0.6 (circular dependency aborted here)
+    python27 = 'python_version >= "2.7" and python_version < "2.8"'
+    python36 = 'python_version >= "3.6" and python_version < "4.0"'
+    linux = 'sys_platform=="linux"'
     expected = {
-        "poetry": Dependency.create_from_pep_508("poetry==1.1.4"),
-        "junit-xml": Dependency.create_from_pep_508("junit-xml==1.9"),
-        "keyring": Dependency.create_from_pep_508("keyring==21.8.0"),
+        "poetry": Dependency.create_from_pep_508(
+            f"poetry==1.1.4; {python27} or {python36}"
+        ),
+        "junit-xml": Dependency.create_from_pep_508(
+            f"junit-xml==1.9 ; {python27} or {python36}"
+        ),
+        "keyring": Dependency.create_from_pep_508(
+            f"keyring==21.8.0 ; {python27} or {python36}"
+        ),
         "secretstorage": Dependency.create_from_pep_508(
-            "secretstorage==3.3.0 ; sys_platform=='linux'"
+            f"secretstorage==3.3.0 ; {python27} and {linux} or {python36} and {linux}"
         ),
         "cryptography": Dependency.create_from_pep_508(
-            "cryptography==3.2 ; sys_platform=='linux'"
+            f"cryptography==3.2 ; {python27} and {linux} or {python36} and {linux}"
+        ),
+        "six": Dependency.create_from_pep_508(
+            f"six==1.15.0 ; {python27} or {python36} or {python27} and {linux} or"
+            f" {python36} and {linux}"
         ),
-        "six": Dependency.create_from_pep_508("six==1.15.0"),
     }
 
     for line in content.strip().split("\n"):
@@ -368,11 +389,19 @@ def test_exporter_can_export_requirements_txt_pyinstaller(tmp_dir: str, poetry:
     # ├── altgraph *      dependencies into a single package.
     # ├── macholib >=1.8 -- only on Darwin
     # │   └── altgraph >=0.15
+    python27 = 'python_version >= "2.7" and python_version < "2.8"'
+    python36 = 'python_version >= "3.6" and python_version < "4.0"'
+    darwin = 'sys_platform=="darwin"'
     expected = {
-        "pyinstaller": Dependency.create_from_pep_508("pyinstaller==4.0"),
-        "altgraph": Dependency.create_from_pep_508("altgraph==0.17"),
+        "pyinstaller": Dependency.create_from_pep_508(
+            f"pyinstaller==4.0 ; {python27} or {python36}"
+        ),
+        "altgraph": Dependency.create_from_pep_508(
+            f"altgraph==0.17 ; {python27} or {python36} or {python27} and {darwin} or"
+            f" {python36} and {darwin}"
+        ),
         "macholib": Dependency.create_from_pep_508(
-            "macholib==1.8 ; sys_platform == 'darwin'"
+            f"macholib==1.8 ; {python27} and {darwin} or {python36} and {darwin}"
         ),
     }
 
@@ -441,17 +470,21 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers(
     with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
         content = f.read()
 
+    python27 = 'python_version >= "2.7" and python_version < "2.8"'
+    python36 = 'python_version >= "3.6" and python_version < "3.7"'
+    windows = 'platform_system == "Windows"'
+    win32 = 'sys_platform == "win32"'
     expected = {
-        "a": Dependency.create_from_pep_508("a==1.2.3 ; python_version < '3.7'"),
+        "a": Dependency.create_from_pep_508(f"a==1.2.3 ; {python27} or {python36}"),
         "b": Dependency.create_from_pep_508(
-            "b==4.5.6 ; platform_system == 'Windows' and python_version < '3.7'"
+            f"b==4.5.6 ; {python27} and {windows} or {python36} and {windows}"
         ),
         "c": Dependency.create_from_pep_508(
-            "c==7.8.9 ; sys_platform == 'win32' and python_version < '3.7'"
+            f"c==7.8.9 ; {python27} and {win32} or {python36} and {win32}"
         ),
         "d": Dependency.create_from_pep_508(
-            "d==0.0.1 ; platform_system == 'Windows' and python_version < '3.7' or"
-            " sys_platform == 'win32' and python_version < '3.7'"
+            f"d==0.0.1 ; {python27} and {windows} or {python36} and {windows} or"
+            f" {python27} and {win32} or {python36} and {win32}"
         ),
     }
 
@@ -467,7 +500,25 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers(
 
 @pytest.mark.parametrize(
     ["dev", "lines"],
-    [(False, ['a==1.2.3 ; python_version < "3.8"']), (True, ["a==1.2.3", "b==4.5.6"])],
+    [
+        (
+            False,
+            [
+                'a==1.2.3 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "3.8"'
+            ],
+        ),
+        (
+            True,
+            [
+                'a==1.2.3 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "3.8" or python_version'
+                ' >= "3.6" and python_version < "4.0"',
+                'b==4.5.6 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+            ],
+        ),
+    ],
 )
 def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_any(
     tmp_dir: str, poetry: Poetry, dev: bool, lines: list[str]
@@ -560,9 +611,13 @@ def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes(
         content = f.read()
 
     expected = """\
-bar==4.5.6 \\
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:67890
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -609,8 +664,12 @@ def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes_
         content = f.read()
 
     expected = """\
-bar==4.5.6
-foo==1.2.3
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -654,7 +713,9 @@ def test_exporter_exports_requirements_txt_without_dev_packages_by_default(
         content = f.read()
 
     expected = """\
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -699,9 +760,13 @@ def test_exporter_exports_requirements_txt_with_dev_packages_if_opted_in(
         content = f.read()
 
     expected = """\
-bar==4.5.6 \\
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:67890
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -746,7 +811,9 @@ def test_exporter_exports_requirements_txt_without_optional_packages(
         content = f.read()
 
     expected = """\
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -756,10 +823,42 @@ def test_exporter_exports_requirements_txt_without_optional_packages(
 @pytest.mark.parametrize(
     ["extras", "lines"],
     [
-        (None, ["foo==1.2.3"]),
-        (False, ["foo==1.2.3"]),
-        (True, ["bar==4.5.6", "foo==1.2.3", "spam==0.1.0"]),
-        (["feature_bar"], ["bar==4.5.6", "foo==1.2.3", "spam==0.1.0"]),
+        (
+            None,
+            [
+                'foo==1.2.3 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"'
+            ],
+        ),
+        (
+            False,
+            [
+                'foo==1.2.3 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"'
+            ],
+        ),
+        (
+            True,
+            [
+                'bar==4.5.6 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+                'foo==1.2.3 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+                'spam==0.1.0 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+            ],
+        ),
+        (
+            ["feature_bar"],
+            [
+                'bar==4.5.6 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+                'foo==1.2.3 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+                'spam==0.1.0 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+            ],
+        ),
     ],
 )
 def test_exporter_exports_requirements_txt_with_optional_packages(
@@ -859,7 +958,9 @@ def test_exporter_can_export_requirements_txt_with_git_packages(
         content = f.read()
 
     expected = """\
-foo @ git+https://github.com/foo/foo.git@123456
+foo @ git+https://github.com/foo/foo.git@123456 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -909,8 +1010,12 @@ def test_exporter_can_export_requirements_txt_with_nested_packages(
         content = f.read()
 
     expected = """\
-bar==4.5.6
-foo @ git+https://github.com/foo/foo.git@123456
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+foo @ git+https://github.com/foo/foo.git@123456 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -964,9 +1069,15 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_cyclic(
         content = f.read()
 
     expected = """\
-bar==4.5.6
-baz==7.8.9
-foo==1.2.3
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+baz==7.8.9 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -1036,26 +1147,21 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_multiple_
     with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
         content = f.read()
 
-    expected = (
-        # expectation for poetry-core <= 1.1.0a6
-        textwrap.dedent(
-            """\
-            bar==7.8.9 ; platform_system != "Windows" or platform_system == "Windows"
-            baz==10.11.13 ; platform_system == "Windows"
-            foo==1.2.3
-            """
-        ),
-        # expectation for poetry-core > 1.1.0a6
-        textwrap.dedent(
-            """\
-            bar==7.8.9
-            baz==10.11.13 ; platform_system == "Windows"
-            foo==1.2.3
-            """
-        ),
-    )
+    expected = """\
+bar==7.8.9 ;\
+ python_version >= "2.7" and python_version < "2.8" and platform_system != "Windows" or\
+ python_version >= "3.6" and python_version < "4.0" and platform_system != "Windows" or\
+ python_version >= "2.7" and python_version < "2.8" and platform_system == "Windows" or\
+ python_version >= "3.6" and python_version < "4.0" and platform_system == "Windows"
+baz==10.11.13 ;\
+ python_version >= "2.7" and python_version < "2.8" and platform_system == "Windows" or\
+ python_version >= "3.6" and python_version < "4.0" and platform_system == "Windows"
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+"""
 
-    assert content in expected
+    assert content == expected
 
 
 def test_exporter_can_export_requirements_txt_with_git_packages_and_markers(
@@ -1095,7 +1201,9 @@ def test_exporter_can_export_requirements_txt_with_git_packages_and_markers(
         content = f.read()
 
     expected = """\
-foo @ git+https://github.com/foo/foo.git@123456 ; python_version < "3.7"
+foo @ git+https://github.com/foo/foo.git@123456 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "3.7"
 """
 
     assert content == expected
@@ -1137,7 +1245,9 @@ def test_exporter_can_export_requirements_txt_with_directory_packages(
         content = f.read()
 
     expected = f"""\
-foo @ {working_directory.as_uri()}/tests/fixtures/sample_project
+foo @ {working_directory.as_uri()}/tests/fixtures/sample_project ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -1203,9 +1313,15 @@ def test_exporter_can_export_requirements_txt_with_nested_directory_packages(
         content = f.read()
 
     expected = f"""\
-bar @ {working_directory.as_uri()}/tests/fixtures/project_with_nested_local/bar
-baz @ {working_directory.as_uri()}/tests/fixtures/project_with_nested_local
-foo @ {working_directory.as_uri()}/tests/fixtures/sample_project
+bar @ {working_directory.as_uri()}/tests/fixtures/project_with_nested_local/bar ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+baz @ {working_directory.as_uri()}/tests/fixtures/project_with_nested_local ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+foo @ {working_directory.as_uri()}/tests/fixtures/sample_project ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -1248,8 +1364,9 @@ def test_exporter_can_export_requirements_txt_with_directory_packages_and_marker
         content = f.read()
 
     expected = f"""\
-foo @ {working_directory.as_uri()}/tests/fixtures/sample_project\
- ; python_version < "3.7"
+foo @ {working_directory.as_uri()}/tests/fixtures/sample_project ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "3.7"
 """
 
     assert content == expected
@@ -1291,7 +1408,9 @@ def test_exporter_can_export_requirements_txt_with_file_packages(
         content = f.read()
 
     expected = f"""\
-foo @ {working_directory.as_uri()}/tests/fixtures/distributions/demo-0.1.0.tar.gz
+foo @ {working_directory.as_uri()}/tests/fixtures/distributions/demo-0.1.0.tar.gz ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
 """
 
     assert content == expected
@@ -1334,8 +1453,9 @@ def test_exporter_can_export_requirements_txt_with_file_packages_and_markers(
         content = f.read()
 
     expected = f"""\
-foo @ {working_directory.as_uri()}/tests/fixtures/distributions/demo-0.1.0.tar.gz\
- ; python_version < "3.7"
+foo @ {working_directory.as_uri()}/tests/fixtures/distributions/demo-0.1.0.tar.gz ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "3.7"
 """
 
     assert content == expected
@@ -1392,9 +1512,13 @@ def test_exporter_exports_requirements_txt_with_legacy_packages(
     expected = """\
 --extra-index-url https://example.com/simple
 
-bar==4.5.6 \\
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:67890
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -1450,9 +1574,13 @@ def test_exporter_exports_requirements_txt_with_url_false(tmp_dir: str, poetry:
         content = f.read()
 
     expected = """\
-bar==4.5.6 \\
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:67890
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -1503,7 +1631,9 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_trusted_host(
 --trusted-host example.com
 --extra-index-url http://example.com/simple
 
-bar==4.5.6 \\
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:67890
 """
 
@@ -1513,8 +1643,26 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_trusted_host(
 @pytest.mark.parametrize(
     ["dev", "expected"],
     [
-        (True, ["bar==1.2.2", "baz==1.2.3", "foo==1.2.1"]),
-        (False, ["bar==1.2.2", "foo==1.2.1"]),
+        (
+            True,
+            [
+                'bar==1.2.2 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+                'baz==1.2.3 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+                'foo==1.2.1 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+            ],
+        ),
+        (
+            False,
+            [
+                'bar==1.2.2 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+                'foo==1.2.1 ; python_version >= "2.7" and python_version < "2.8" or'
+                ' python_version >= "3.6" and python_version < "4.0"',
+            ],
+        ),
     ],
 )
 def test_exporter_exports_requirements_txt_with_dev_extras(
@@ -1647,11 +1795,17 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_and_duplicate_so
 --extra-index-url https://example.com/simple
 --extra-index-url https://foobaz.com/simple
 
-bar==4.5.6 \\
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:67890
-baz==7.8.9 \\
+baz==7.8.9 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:24680
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -1718,9 +1872,13 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_and_credentials(
     expected = """\
 --extra-index-url https://foo:bar@example.com/simple
 
-bar==4.5.6 \\
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:67890
-foo==1.2.3 \\
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0" \\
     --hash=sha256:12345
 """
 
@@ -1763,8 +1921,232 @@ def test_exporter_exports_requirements_txt_to_standard_output(
 
     out, err = capsys.readouterr()
     expected = """\
-bar==4.5.6
-foo==1.2.3
+bar==4.5.6 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+foo==1.2.3 ;\
+ python_version >= "2.7" and python_version < "2.8" or\
+ python_version >= "3.6" and python_version < "4.0"
+"""
+
+    assert out == expected
+
+
+def test_exporter_doesnt_confuse_repeated_packages(
+    tmp_dir: str, poetry: Poetry, capsys: CaptureFixture
+):
+    # Testcase derived from <https://github.com/python-poetry/poetry/issues/5141>.
+    poetry.locker.mock_lock_data(
+        {
+            "package": [
+                {
+                    "name": "celery",
+                    "version": "5.1.2",
+                    "category": "main",
+                    "optional": False,
+                    "python-versions": "<3.7",
+                    "dependencies": {
+                        "click": ">=7.0,<8.0",
+                        "click-didyoumean": ">=0.0.3",
+                        "click-plugins": ">=1.1.1",
+                    },
+                },
+                {
+                    "name": "celery",
+                    "version": "5.2.3",
+                    "category": "main",
+                    "optional": False,
+                    "python-versions": ">=3.7",
+                    "dependencies": {
+                        "click": ">=8.0.3,<9.0",
+                        "click-didyoumean": ">=0.0.3",
+                        "click-plugins": ">=1.1.1",
+                    },
+                },
+                {
+                    "name": "click",
+                    "version": "7.1.2",
+                    "category": "main",
+                    "optional": False,
+                    "python-versions": (
+                        ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+                    ),
+                },
+                {
+                    "name": "click",
+                    "version": "8.0.3",
+                    "category": "main",
+                    "optional": False,
+                    "python-versions": ">=3.6",
+                    "dependencies": {},
+                },
+                {
+                    "name": "click-didyoumean",
+                    "version": "0.0.3",
+                    "category": "main",
+                    "optional": False,
+                    "python-versions": "*",
+                    "dependencies": {"click": "*"},
+                },
+                {
+                    "name": "click-didyoumean",
+                    "version": "0.3.0",
+                    "category": "main",
+                    "optional": False,
+                    "python-versions": ">=3.6.2,<4.0.0",
+                    "dependencies": {"click": ">=7"},
+                },
+                {
+                    "name": "click-plugins",
+                    "version": "1.1.1",
+                    "category": "main",
+                    "optional": False,
+                    "python-versions": "*",
+                    "dependencies": {"click": ">=4.0"},
+                },
+            ],
+            "metadata": {
+                "lock-version": "1.1",
+                "python-versions": "^3.6",
+                "content-hash": (
+                    "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6"
+                ),
+                "hashes": {
+                    "celery": [],
+                    "click-didyoumean": [],
+                    "click-plugins": [],
+                    "click": [],
+                },
+            },
+        }
+    )
+    root = poetry.package.with_dependency_groups([], only=True)
+    root.python_versions = "^3.6"
+    root.add_dependency(
+        Factory.create_dependency(
+            name="celery", constraint={"version": "5.1.2", "python": "<3.7"}
+        )
+    )
+    root.add_dependency(
+        Factory.create_dependency(
+            name="celery", constraint={"version": "5.2.3", "python": ">=3.7"}
+        )
+    )
+    poetry._package = root
+
+    exporter = Exporter(poetry)
+
+    exporter.export("requirements.txt", Path(tmp_dir), sys.stdout)
+
+    out, err = capsys.readouterr()
+    expected = """\
+celery==5.1.2 ; python_version >= "3.6" and python_version < "3.7"
+celery==5.2.3 ; python_version >= "3.7" and python_version < "4.0"
+click-didyoumean==0.0.3 ; python_version >= "3.6" and python_version < "3.7"
+click-didyoumean==0.3.0 ; python_version >= "3.7" and python_full_version < "4.0.0"
+click-plugins==1.1.1 ;\
+ python_version >= "3.6" and python_version < "3.7" or\
+ python_version >= "3.7" and python_version < "4.0"
+click==7.1.2 ; python_version >= "3.6" and python_version < "3.7"
+click==8.0.3 ;\
+ python_version >= "3.7" and python_version < "4.0" or\
+ python_version >= "3.7" and python_full_version < "4.0.0"
+"""
+
+    assert out == expected
+
+
+def test_exporter_handles_extras_next_to_non_extras(
+    tmp_dir: str, poetry: Poetry, capsys: CaptureFixture
+):
+    # Testcase similar to the solver testcase added at #5305.
+    poetry.locker.mock_lock_data(
+        {
+            "package": [
+                {
+                    "name": "localstack",
+                    "python-versions": "*",
+                    "version": "1.0.0",
+                    "category": "main",
+                    "optional": False,
+                    "dependencies": {
+                        "localstack-ext": [
+                            {"version": ">=1.0.0"},
+                            {
+                                "version": ">=1.0.0",
+                                "extras": ["bar"],
+                                "markers": 'extra == "foo"',
+                            },
+                        ]
+                    },
+                    "extras": {"foo": ["localstack-ext (>=1.0.0)"]},
+                },
+                {
+                    "name": "localstack-ext",
+                    "python-versions": "*",
+                    "version": "1.0.0",
+                    "category": "main",
+                    "optional": False,
+                    "dependencies": {
+                        "something": "*",
+                        "something-else": {
+                            "version": ">=1.0.0",
+                            "markers": 'extra == "bar"',
+                        },
+                    },
+                    "extras": {"bar": ["something-else (>=1.0.0)"]},
+                },
+                {
+                    "name": "something",
+                    "python-versions": "*",
+                    "version": "1.0.0",
+                    "category": "main",
+                    "optional": False,
+                    "dependencies": {},
+                },
+                {
+                    "name": "something-else",
+                    "python-versions": "*",
+                    "version": "1.0.0",
+                    "category": "main",
+                    "optional": False,
+                    "dependencies": {},
+                },
+            ],
+            "metadata": {
+                "lock-version": "1.1",
+                "python-versions": "^3.6",
+                "content-hash": (
+                    "832b13a88e5020c27cbcd95faa577bf0dbf054a65c023b45dc9442b640d414e6"
+                ),
+                "hashes": {
+                    "localstack": [],
+                    "localstack-ext": [],
+                    "something": [],
+                    "something-else": [],
+                },
+            },
+        }
+    )
+    root = poetry.package.with_dependency_groups([], only=True)
+    root.python_versions = "^3.6"
+    root.add_dependency(
+        Factory.create_dependency(
+            name="localstack", constraint={"version": "^1.0.0", "extras": ["foo"]}
+        )
+    )
+    poetry._package = root
+
+    exporter = Exporter(poetry)
+
+    exporter.export("requirements.txt", Path(tmp_dir), sys.stdout)
+
+    out, err = capsys.readouterr()
+    expected = """\
+localstack-ext==1.0.0 ; python_version >= "3.6" and python_version < "4.0"
+localstack==1.0.0 ; python_version >= "3.6" and python_version < "4.0"
+something-else==1.0.0 ; python_version >= "3.6" and python_version < "4.0"
+something==1.0.0 ; python_version >= "3.6" and python_version < "4.0"
 """
 
     assert out == expected