prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  RecursionError when installing mkdocs-material
  <!-- Checked checkbox should look like this: [x] -->
  - [x] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) Poetry version.
  - [x] I have searched the [issues](https://github.com/python-poetry/poetry/issues) of this repo and believe that this is not a duplicate.
  - [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).
  
  - **OS version and name**: Windows 10 Pro 1909 18363.719
  - **Poetry version**:  1.0.5
  - **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: https://gist.github.com/ndevln/f27b5b64251241d40e1b960ec96b8b68
  
  ## Issue
  Hi,
  
  when running: `poetry install -E docs_material` I get the following error:
  
  ```
  [RecursionError]
  maximum recursion depth exceeded
  ```
  
  There are quite a few similar issues (like #2329), but it seems that this problem is package specific?!?
  
  Thank you for poetry and your effort :)
  
  
  
  
  </issue>
  <code>
  [start of poetry/utils/extras.py]
  1 from typing import Iterator
  2 from typing import List
  3 from typing import Mapping
  4 from typing import Sequence
  5 
  6 from poetry.core.packages import Package
  7 from poetry.utils.helpers import canonicalize_name
  8 
  9 
  10 def get_extra_package_names(
  11     packages,  # type: Sequence[Package]
  12     extras,  # type: Mapping[str, List[str]]
  13     extra_names,  # type: Sequence[str]
  14 ):  # type: (...) -> Iterator[str]
  15     """
  16     Returns all package names required by the given extras.
  17 
  18     :param packages: A collection of packages, such as from Repository.packages
  19     :param extras: A mapping of `extras` names to lists of package names, as defined
  20         in the `extras` section of `poetry.lock`.
  21     :param extra_names: A list of strings specifying names of extra groups to resolve.
  22     """
  23     if not extra_names:
  24         return []
  25 
  26     # lookup for packages by name, faster than looping over packages repeatedly
  27     packages_by_name = {package.name: package for package in packages}
  28 
  29     # get and flatten names of packages we've opted into as extras
  30     extra_package_names = [
  31         canonicalize_name(extra_package_name)
  32         for extra_name in extra_names
  33         for extra_package_name in extras.get(extra_name, ())
  34     ]
  35 
  36     def _extra_packages(package_names):
  37         """Recursively find dependencies for packages names"""
  38         # for each extra pacakge name
  39         for package_name in package_names:
  40             # Find the actual Package object. A missing key indicates an implicit
  41             # dependency (like setuptools), which should be ignored
  42             package = packages_by_name.get(canonicalize_name(package_name))
  43             if package:
  44                 yield package.name
  45                 # Recurse for dependencies
  46                 for dependency_package_name in _extra_packages(
  47                     dependency.name for dependency in package.requires
  48                 ):
  49                     yield dependency_package_name
  50 
  51     return _extra_packages(extra_package_names)
  52
  [end of poetry/utils/extras.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/poetry/utils/extras.py b/poetry/utils/extras.py
  --- a/poetry/utils/extras.py
  +++ b/poetry/utils/extras.py
  @@ -33,6 +33,9 @@
           for extra_package_name in extras.get(extra_name, ())
       ]
   
  +    # keep record of packages seen during recursion in order to avoid recursion error
  +    seen_package_names = set()
  +
       def _extra_packages(package_names):
           """Recursively find dependencies for packages names"""
           # for each extra pacakge name
  @@ -41,11 +44,16 @@
               # dependency (like setuptools), which should be ignored
               package = packages_by_name.get(canonicalize_name(package_name))
               if package:
  -                yield package.name
  +                if package.name not in seen_package_names:
  +                    seen_package_names.add(package.name)
  +                    yield package.name
                   # Recurse for dependencies
                   for dependency_package_name in _extra_packages(
  -                    dependency.name for dependency in package.requires
  +                    dependency.name
  +                    for dependency in package.requires
  +                    if dependency.name not in seen_package_names
                   ):
  +                    seen_package_names.add(dependency_package_name)
                       yield dependency_package_name
   
       return _extra_packages(extra_package_names)
  
verification_info: {"golden_diff": "diff --git a/poetry/utils/extras.py b/poetry/utils/extras.py\n--- a/poetry/utils/extras.py\n+++ b/poetry/utils/extras.py\n@@ -33,6 +33,9 @@\n         for extra_package_name in extras.get(extra_name, ())\n     ]\n \n+    # keep record of packages seen during recursion in order to avoid recursion error\n+    seen_package_names = set()\n+\n     def _extra_packages(package_names):\n         \"\"\"Recursively find dependencies for packages names\"\"\"\n         # for each extra pacakge name\n@@ -41,11 +44,16 @@\n             # dependency (like setuptools), which should be ignored\n             package = packages_by_name.get(canonicalize_name(package_name))\n             if package:\n-                yield package.name\n+                if package.name not in seen_package_names:\n+                    seen_package_names.add(package.name)\n+                    yield package.name\n                 # Recurse for dependencies\n                 for dependency_package_name in _extra_packages(\n-                    dependency.name for dependency in package.requires\n+                    dependency.name\n+                    for dependency in package.requires\n+                    if dependency.name not in seen_package_names\n                 ):\n+                    seen_package_names.add(dependency_package_name)\n                     yield dependency_package_name\n \n     return _extra_packages(extra_package_names)\n", "issue": "RecursionError when installing mkdocs-material\n<!-- Checked checkbox should look like this: [x] -->\r\n- [x] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) Poetry version.\r\n- [x] I have searched the [issues](https://github.com/python-poetry/poetry/issues) of this repo and believe that this is not a duplicate.\r\n- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option).\r\n\r\n- **OS version and name**: Windows 10 Pro 1909 18363.719\r\n- **Poetry version**:  1.0.5\r\n- **Link of a [Gist](https://gist.github.com/) with the contents of your pyproject.toml file**: https://gist.github.com/ndevln/f27b5b64251241d40e1b960ec96b8b68\r\n\r\n## Issue\r\nHi,\r\n\r\nwhen running: `poetry install -E docs_material` I get the following error:\r\n\r\n```\r\n[RecursionError]\r\nmaximum recursion depth exceeded\r\n```\r\n\r\nThere are quite a few similar issues (like #2329), but it seems that this problem is package specific?!?\r\n\r\nThank you for poetry and your effort :)\r\n\r\n\r\n\n", "before_files": [{"content": "from typing import Iterator\nfrom typing import List\nfrom typing import Mapping\nfrom typing import Sequence\n\nfrom poetry.core.packages import Package\nfrom poetry.utils.helpers import canonicalize_name\n\n\ndef get_extra_package_names(\n    packages,  # type: Sequence[Package]\n    extras,  # type: Mapping[str, List[str]]\n    extra_names,  # type: Sequence[str]\n):  # type: (...) -> Iterator[str]\n    \"\"\"\n    Returns all package names required by the given extras.\n\n    :param packages: A collection of packages, such as from Repository.packages\n    :param extras: A mapping of `extras` names to lists of package names, as defined\n        in the `extras` section of `poetry.lock`.\n    :param extra_names: A list of strings specifying names of extra groups to resolve.\n    \"\"\"\n    if not extra_names:\n        return []\n\n    # lookup for packages by name, faster than looping over packages repeatedly\n    packages_by_name = {package.name: package for package in packages}\n\n    # get and flatten names of packages we've opted into as extras\n    extra_package_names = [\n        canonicalize_name(extra_package_name)\n        for extra_name in extra_names\n        for extra_package_name in extras.get(extra_name, ())\n    ]\n\n    def _extra_packages(package_names):\n        \"\"\"Recursively find dependencies for packages names\"\"\"\n        # for each extra pacakge name\n        for package_name in package_names:\n            # Find the actual Package object. A missing key indicates an implicit\n            # dependency (like setuptools), which should be ignored\n            package = packages_by_name.get(canonicalize_name(package_name))\n            if package:\n                yield package.name\n                # Recurse for dependencies\n                for dependency_package_name in _extra_packages(\n                    dependency.name for dependency in package.requires\n                ):\n                    yield dependency_package_name\n\n    return _extra_packages(extra_package_names)\n", "path": "poetry/utils/extras.py"}]}