prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  --upgrade-package downgrades unrelated pre-release package when --pre not given
  <!-- Describe the issue briefly here. -->
  
  #### Environment Versions
  
  1. OS Type: macOS 10.15.4
  1. Python version: 3.7.7
  1. pip version:  20.0.2
  1. pip-tools version: 4.5.1
  
  #### Steps to replicate
  
  (Note: this example will stop working when `gevent` releases 1.5 final but it can be replicated with any other package that currently has a pre-release version.)
  
  1. Example `req.in` file:
      ```
      click<7
      gevent
      ```
  2. `pip-compile req.in`
      Output:
      ```
      #
      # This file is autogenerated by pip-compile
      # To update, run:
      #
      #    pip-compile req.in
      #
      click==6.7                # via -r req.in
      gevent==1.4.0             # via -r req.in
      greenlet==0.4.15          # via gevent
      ```
  3. Upgrade gevent to pre-relese
      `pip-compile --pre --upgrade-package gevent req.in`
      Output:
      ```
      #
      # This file is autogenerated by pip-compile
      # To update, run:
      #
      #    pip-compile --pre req.in
      #
      click==6.7                # via -r req.in
      gevent==1.5a4             # via -r req.in
      greenlet==0.4.15          # via gevent
      ```
  4. Remove version pin of `click` in `.in` file:
      ```
      click
      gevent
      ```
  5. Upgrade click:
      `pip-compile --upgrade-package click req.in`
      Output:
      ```
      #
      # This file is autogenerated by pip-compile
      # To update, run:
      #
      #    pip-compile req.in
      #
      click==6.7                # via -r req.in
      gevent==1.4.0             # via -r req.in
      greenlet==0.4.15          # via gevent
      ```
  
  #### Expected result
  
  Once a package has been resolved to a pre-release version it should never "magically" be downgraded. Especially if only unrelated other packages are concerned.
  
  I could see that there may be an argument for a plain `pip-compile` run to revert to the non-prerelease version, but I would disagree even there. But for `--upgrade-package` I see no way where this is correct behaviour.
  
  #### Actual result
  
  Not giving `--pre` at any time after it has been used once and a package is resolved to a pre-release version will downgrade it back to the last released version.
  
  </issue>
  <code>
  [start of piptools/repositories/local.py]
  1 # coding: utf-8
  2 from __future__ import absolute_import, division, print_function, unicode_literals
  3 
  4 from contextlib import contextmanager
  5 
  6 from pip._internal.utils.hashes import FAVORITE_HASH
  7 
  8 from .._compat import PIP_VERSION
  9 from .base import BaseRepository
  10 
  11 from piptools.utils import as_tuple, key_from_ireq, make_install_requirement
  12 
  13 
  14 def ireq_satisfied_by_existing_pin(ireq, existing_pin):
  15     """
  16     Return True if the given InstallationRequirement is satisfied by the
  17     previously encountered version pin.
  18     """
  19     version = next(iter(existing_pin.req.specifier)).version
  20     return version in ireq.req.specifier
  21 
  22 
  23 class LocalRequirementsRepository(BaseRepository):
  24     """
  25     The LocalRequirementsRepository proxied the _real_ repository by first
  26     checking if a requirement can be satisfied by existing pins (i.e. the
  27     result of a previous compile step).
  28 
  29     In effect, if a requirement can be satisfied with a version pinned in the
  30     requirements file, we prefer that version over the best match found in
  31     PyPI.  This keeps updates to the requirements.txt down to a minimum.
  32     """
  33 
  34     def __init__(self, existing_pins, proxied_repository):
  35         self.repository = proxied_repository
  36         self.existing_pins = existing_pins
  37 
  38     @property
  39     def options(self):
  40         return self.repository.options
  41 
  42     @property
  43     def finder(self):
  44         return self.repository.finder
  45 
  46     @property
  47     def session(self):
  48         return self.repository.session
  49 
  50     @property
  51     def DEFAULT_INDEX_URL(self):
  52         return self.repository.DEFAULT_INDEX_URL
  53 
  54     def clear_caches(self):
  55         self.repository.clear_caches()
  56 
  57     def freshen_build_caches(self):
  58         self.repository.freshen_build_caches()
  59 
  60     def find_best_match(self, ireq, prereleases=None):
  61         key = key_from_ireq(ireq)
  62         existing_pin = self.existing_pins.get(key)
  63         if existing_pin and ireq_satisfied_by_existing_pin(ireq, existing_pin):
  64             project, version, _ = as_tuple(existing_pin)
  65             return make_install_requirement(
  66                 project, version, ireq.extras, constraint=ireq.constraint
  67             )
  68         else:
  69             return self.repository.find_best_match(ireq, prereleases)
  70 
  71     def get_dependencies(self, ireq):
  72         return self.repository.get_dependencies(ireq)
  73 
  74     def get_hashes(self, ireq):
  75         key = key_from_ireq(ireq)
  76         existing_pin = self.existing_pins.get(key)
  77         if existing_pin and ireq_satisfied_by_existing_pin(ireq, existing_pin):
  78             if PIP_VERSION[:2] <= (20, 0):
  79                 hashes = existing_pin.options.get("hashes", {})
  80             else:
  81                 hashes = existing_pin.hash_options
  82             hexdigests = hashes.get(FAVORITE_HASH)
  83             if hexdigests:
  84                 return {
  85                     ":".join([FAVORITE_HASH, hexdigest]) for hexdigest in hexdigests
  86                 }
  87         return self.repository.get_hashes(ireq)
  88 
  89     @contextmanager
  90     def allow_all_wheels(self):
  91         with self.repository.allow_all_wheels():
  92             yield
  93
  [end of piptools/repositories/local.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/piptools/repositories/local.py b/piptools/repositories/local.py
  --- a/piptools/repositories/local.py
  +++ b/piptools/repositories/local.py
  @@ -17,7 +17,9 @@
       previously encountered version pin.
       """
       version = next(iter(existing_pin.req.specifier)).version
  -    return version in ireq.req.specifier
  +    return ireq.req.specifier.contains(
  +        version, prereleases=existing_pin.req.specifier.prereleases
  +    )
   
   
   class LocalRequirementsRepository(BaseRepository):
  
verification_info: {"golden_diff": "diff --git a/piptools/repositories/local.py b/piptools/repositories/local.py\n--- a/piptools/repositories/local.py\n+++ b/piptools/repositories/local.py\n@@ -17,7 +17,9 @@\n     previously encountered version pin.\n     \"\"\"\n     version = next(iter(existing_pin.req.specifier)).version\n-    return version in ireq.req.specifier\n+    return ireq.req.specifier.contains(\n+        version, prereleases=existing_pin.req.specifier.prereleases\n+    )\n \n \n class LocalRequirementsRepository(BaseRepository):\n", "issue": "--upgrade-package downgrades unrelated pre-release package when --pre not given\n<!-- Describe the issue briefly here. -->\r\n\r\n#### Environment Versions\r\n\r\n1. OS Type: macOS 10.15.4\r\n1. Python version: 3.7.7\r\n1. pip version:  20.0.2\r\n1. pip-tools version: 4.5.1\r\n\r\n#### Steps to replicate\r\n\r\n(Note: this example will stop working when `gevent` releases 1.5 final but it can be replicated with any other package that currently has a pre-release version.)\r\n\r\n1. Example `req.in` file:\r\n    ```\r\n    click<7\r\n    gevent\r\n    ```\r\n2. `pip-compile req.in`\r\n    Output:\r\n    ```\r\n    #\r\n    # This file is autogenerated by pip-compile\r\n    # To update, run:\r\n    #\r\n    #    pip-compile req.in\r\n    #\r\n    click==6.7                # via -r req.in\r\n    gevent==1.4.0             # via -r req.in\r\n    greenlet==0.4.15          # via gevent\r\n    ```\r\n3. Upgrade gevent to pre-relese\r\n    `pip-compile --pre --upgrade-package gevent req.in`\r\n    Output:\r\n    ```\r\n    #\r\n    # This file is autogenerated by pip-compile\r\n    # To update, run:\r\n    #\r\n    #    pip-compile --pre req.in\r\n    #\r\n    click==6.7                # via -r req.in\r\n    gevent==1.5a4             # via -r req.in\r\n    greenlet==0.4.15          # via gevent\r\n    ```\r\n4. Remove version pin of `click` in `.in` file:\r\n    ```\r\n    click\r\n    gevent\r\n    ```\r\n5. Upgrade click:\r\n    `pip-compile --upgrade-package click req.in`\r\n    Output:\r\n    ```\r\n    #\r\n    # This file is autogenerated by pip-compile\r\n    # To update, run:\r\n    #\r\n    #    pip-compile req.in\r\n    #\r\n    click==6.7                # via -r req.in\r\n    gevent==1.4.0             # via -r req.in\r\n    greenlet==0.4.15          # via gevent\r\n    ```\r\n\r\n#### Expected result\r\n\r\nOnce a package has been resolved to a pre-release version it should never \"magically\" be downgraded. Especially if only unrelated other packages are concerned.\r\n\r\nI could see that there may be an argument for a plain `pip-compile` run to revert to the non-prerelease version, but I would disagree even there. But for `--upgrade-package` I see no way where this is correct behaviour.\r\n\r\n#### Actual result\r\n\r\nNot giving `--pre` at any time after it has been used once and a package is resolved to a pre-release version will downgrade it back to the last released version.\n", "before_files": [{"content": "# coding: utf-8\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nfrom contextlib import contextmanager\n\nfrom pip._internal.utils.hashes import FAVORITE_HASH\n\nfrom .._compat import PIP_VERSION\nfrom .base import BaseRepository\n\nfrom piptools.utils import as_tuple, key_from_ireq, make_install_requirement\n\n\ndef ireq_satisfied_by_existing_pin(ireq, existing_pin):\n    \"\"\"\n    Return True if the given InstallationRequirement is satisfied by the\n    previously encountered version pin.\n    \"\"\"\n    version = next(iter(existing_pin.req.specifier)).version\n    return version in ireq.req.specifier\n\n\nclass LocalRequirementsRepository(BaseRepository):\n    \"\"\"\n    The LocalRequirementsRepository proxied the _real_ repository by first\n    checking if a requirement can be satisfied by existing pins (i.e. the\n    result of a previous compile step).\n\n    In effect, if a requirement can be satisfied with a version pinned in the\n    requirements file, we prefer that version over the best match found in\n    PyPI.  This keeps updates to the requirements.txt down to a minimum.\n    \"\"\"\n\n    def __init__(self, existing_pins, proxied_repository):\n        self.repository = proxied_repository\n        self.existing_pins = existing_pins\n\n    @property\n    def options(self):\n        return self.repository.options\n\n    @property\n    def finder(self):\n        return self.repository.finder\n\n    @property\n    def session(self):\n        return self.repository.session\n\n    @property\n    def DEFAULT_INDEX_URL(self):\n        return self.repository.DEFAULT_INDEX_URL\n\n    def clear_caches(self):\n        self.repository.clear_caches()\n\n    def freshen_build_caches(self):\n        self.repository.freshen_build_caches()\n\n    def find_best_match(self, ireq, prereleases=None):\n        key = key_from_ireq(ireq)\n        existing_pin = self.existing_pins.get(key)\n        if existing_pin and ireq_satisfied_by_existing_pin(ireq, existing_pin):\n            project, version, _ = as_tuple(existing_pin)\n            return make_install_requirement(\n                project, version, ireq.extras, constraint=ireq.constraint\n            )\n        else:\n            return self.repository.find_best_match(ireq, prereleases)\n\n    def get_dependencies(self, ireq):\n        return self.repository.get_dependencies(ireq)\n\n    def get_hashes(self, ireq):\n        key = key_from_ireq(ireq)\n        existing_pin = self.existing_pins.get(key)\n        if existing_pin and ireq_satisfied_by_existing_pin(ireq, existing_pin):\n            if PIP_VERSION[:2] <= (20, 0):\n                hashes = existing_pin.options.get(\"hashes\", {})\n            else:\n                hashes = existing_pin.hash_options\n            hexdigests = hashes.get(FAVORITE_HASH)\n            if hexdigests:\n                return {\n                    \":\".join([FAVORITE_HASH, hexdigest]) for hexdigest in hexdigests\n                }\n        return self.repository.get_hashes(ireq)\n\n    @contextmanager\n    def allow_all_wheels(self):\n        with self.repository.allow_all_wheels():\n            yield\n", "path": "piptools/repositories/local.py"}]}