prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Is there a reason python-dateutil is pinned to v2.7.5?
  In this [commit](https://github.com/spotify/luigi/commit/ca0aa9afedecda539339e51974ef38cecf180d4b), I can see that python-dateutil has been pinned to version 2.7.5 -  is this strictly necessary? Version 2.8.0 was released a couple of weeks ago and It's causing `ContextualVersionConflict` errors for us.
  
  
  
  </issue>
  <code>
  [start of setup.py]
  1 # Copyright (c) 2012 Spotify AB
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
  4 # use this file except in compliance with the License. You may obtain a copy of
  5 # the License at
  6 #
  7 # http://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12 # License for the specific language governing permissions and limitations under
  13 # the License.
  14 
  15 import os
  16 import sys
  17 
  18 from setuptools import setup
  19 
  20 
  21 def get_static_files(path):
  22     return [os.path.join(dirpath.replace("luigi/", ""), ext)
  23             for (dirpath, dirnames, filenames) in os.walk(path)
  24             for ext in ["*.html", "*.js", "*.css", "*.png",
  25                         "*.eot", "*.svg", "*.ttf", "*.woff", "*.woff2"]]
  26 
  27 
  28 luigi_package_data = sum(map(get_static_files, ["luigi/static", "luigi/templates"]), [])
  29 
  30 readme_note = """\
  31 .. note::
  32 
  33    For the latest source, discussion, etc, please visit the
  34    `GitHub repository <https://github.com/spotify/luigi>`_\n\n
  35 """
  36 
  37 with open('README.rst') as fobj:
  38     long_description = readme_note + fobj.read()
  39 
  40 install_requires = [
  41     'tornado>=4.0,<5',
  42     # https://pagure.io/python-daemon/issue/18
  43     'python-daemon<2.2.0',
  44     'python-dateutil==2.7.5',
  45 ]
  46 
  47 # Note: To support older versions of setuptools, we're explicitly not
  48 #   using conditional syntax (i.e. 'enum34>1.1.0;python_version<"3.4"').
  49 #   This syntax is a problem for setuptools as recent as `20.1.1`,
  50 #   published Feb 16, 2016.
  51 if sys.version_info[:2] < (3, 4):
  52     install_requires.append('enum34>1.1.0')
  53 
  54 if os.environ.get('READTHEDOCS', None) == 'True':
  55     # So that we can build documentation for luigi.db_task_history and luigi.contrib.sqla
  56     install_requires.append('sqlalchemy')
  57     # readthedocs don't like python-daemon, see #1342
  58     install_requires.remove('python-daemon<2.2.0')
  59     install_requires.append('sphinx>=1.4.4')  # Value mirrored in doc/conf.py
  60 
  61 setup(
  62     name='luigi',
  63     version='2.8.3',
  64     description='Workflow mgmgt + task scheduling + dependency resolution',
  65     long_description=long_description,
  66     author='The Luigi Authors',
  67     url='https://github.com/spotify/luigi',
  68     license='Apache License 2.0',
  69     packages=[
  70         'luigi',
  71         'luigi.configuration',
  72         'luigi.contrib',
  73         'luigi.contrib.hdfs',
  74         'luigi.tools'
  75     ],
  76     package_data={
  77         'luigi': luigi_package_data
  78     },
  79     entry_points={
  80         'console_scripts': [
  81             'luigi = luigi.cmdline:luigi_run',
  82             'luigid = luigi.cmdline:luigid',
  83             'luigi-grep = luigi.tools.luigi_grep:main',
  84             'luigi-deps = luigi.tools.deps:main',
  85             'luigi-deps-tree = luigi.tools.deps_tree:main'
  86         ]
  87     },
  88     install_requires=install_requires,
  89     extras_require={
  90         'toml': ['toml<2.0.0'],
  91     },
  92     classifiers=[
  93         'Development Status :: 5 - Production/Stable',
  94         'Environment :: Console',
  95         'Environment :: Web Environment',
  96         'Intended Audience :: Developers',
  97         'Intended Audience :: System Administrators',
  98         'License :: OSI Approved :: Apache Software License',
  99         'Programming Language :: Python :: 2.7',
  100         'Programming Language :: Python :: 3.3',
  101         'Programming Language :: Python :: 3.4',
  102         'Programming Language :: Python :: 3.5',
  103         'Programming Language :: Python :: 3.6',
  104         'Programming Language :: Python :: 3.7',
  105         'Topic :: System :: Monitoring',
  106     ],
  107 )
  108
  [end of setup.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/setup.py b/setup.py
  --- a/setup.py
  +++ b/setup.py
  @@ -41,7 +41,7 @@
       'tornado>=4.0,<5',
       # https://pagure.io/python-daemon/issue/18
       'python-daemon<2.2.0',
  -    'python-dateutil==2.7.5',
  +    'python-dateutil>=2.7.5,<3',
   ]
   
   # Note: To support older versions of setuptools, we're explicitly not
  
verification_info: {"golden_diff": "diff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -41,7 +41,7 @@\n     'tornado>=4.0,<5',\n     # https://pagure.io/python-daemon/issue/18\n     'python-daemon<2.2.0',\n-    'python-dateutil==2.7.5',\n+    'python-dateutil>=2.7.5,<3',\n ]\n \n # Note: To support older versions of setuptools, we're explicitly not\n", "issue": "Is there a reason python-dateutil is pinned to v2.7.5?\nIn this [commit](https://github.com/spotify/luigi/commit/ca0aa9afedecda539339e51974ef38cecf180d4b), I can see that python-dateutil has been pinned to version 2.7.5 -  is this strictly necessary? Version 2.8.0 was released a couple of weeks ago and It's causing `ContextualVersionConflict` errors for us.\r\n\r\n\n", "before_files": [{"content": "# Copyright (c) 2012 Spotify AB\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not\n# use this file except in compliance with the License. You may obtain a copy of\n# the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n# License for the specific language governing permissions and limitations under\n# the License.\n\nimport os\nimport sys\n\nfrom setuptools import setup\n\n\ndef get_static_files(path):\n    return [os.path.join(dirpath.replace(\"luigi/\", \"\"), ext)\n            for (dirpath, dirnames, filenames) in os.walk(path)\n            for ext in [\"*.html\", \"*.js\", \"*.css\", \"*.png\",\n                        \"*.eot\", \"*.svg\", \"*.ttf\", \"*.woff\", \"*.woff2\"]]\n\n\nluigi_package_data = sum(map(get_static_files, [\"luigi/static\", \"luigi/templates\"]), [])\n\nreadme_note = \"\"\"\\\n.. note::\n\n   For the latest source, discussion, etc, please visit the\n   `GitHub repository <https://github.com/spotify/luigi>`_\\n\\n\n\"\"\"\n\nwith open('README.rst') as fobj:\n    long_description = readme_note + fobj.read()\n\ninstall_requires = [\n    'tornado>=4.0,<5',\n    # https://pagure.io/python-daemon/issue/18\n    'python-daemon<2.2.0',\n    'python-dateutil==2.7.5',\n]\n\n# Note: To support older versions of setuptools, we're explicitly not\n#   using conditional syntax (i.e. 'enum34>1.1.0;python_version<\"3.4\"').\n#   This syntax is a problem for setuptools as recent as `20.1.1`,\n#   published Feb 16, 2016.\nif sys.version_info[:2] < (3, 4):\n    install_requires.append('enum34>1.1.0')\n\nif os.environ.get('READTHEDOCS', None) == 'True':\n    # So that we can build documentation for luigi.db_task_history and luigi.contrib.sqla\n    install_requires.append('sqlalchemy')\n    # readthedocs don't like python-daemon, see #1342\n    install_requires.remove('python-daemon<2.2.0')\n    install_requires.append('sphinx>=1.4.4')  # Value mirrored in doc/conf.py\n\nsetup(\n    name='luigi',\n    version='2.8.3',\n    description='Workflow mgmgt + task scheduling + dependency resolution',\n    long_description=long_description,\n    author='The Luigi Authors',\n    url='https://github.com/spotify/luigi',\n    license='Apache License 2.0',\n    packages=[\n        'luigi',\n        'luigi.configuration',\n        'luigi.contrib',\n        'luigi.contrib.hdfs',\n        'luigi.tools'\n    ],\n    package_data={\n        'luigi': luigi_package_data\n    },\n    entry_points={\n        'console_scripts': [\n            'luigi = luigi.cmdline:luigi_run',\n            'luigid = luigi.cmdline:luigid',\n            'luigi-grep = luigi.tools.luigi_grep:main',\n            'luigi-deps = luigi.tools.deps:main',\n            'luigi-deps-tree = luigi.tools.deps_tree:main'\n        ]\n    },\n    install_requires=install_requires,\n    extras_require={\n        'toml': ['toml<2.0.0'],\n    },\n    classifiers=[\n        'Development Status :: 5 - Production/Stable',\n        'Environment :: Console',\n        'Environment :: Web Environment',\n        'Intended Audience :: Developers',\n        'Intended Audience :: System Administrators',\n        'License :: OSI Approved :: Apache Software License',\n        'Programming Language :: Python :: 2.7',\n        'Programming Language :: Python :: 3.3',\n        'Programming Language :: Python :: 3.4',\n        'Programming Language :: Python :: 3.5',\n        'Programming Language :: Python :: 3.6',\n        'Programming Language :: Python :: 3.7',\n        'Topic :: System :: Monitoring',\n    ],\n)\n", "path": "setup.py"}]}