prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Locally hosted RTD instance doesn't allow git file:/// URLs
  ## Details
  I installed a local RTD instance according to the Installation guide and imported test project. Now, I want to import my git project manually, 
  ## Expected Result
  
  I expected that the instance should accept all valid Git URLs.
  
  ## Actual Result
  
  When I enter file:///.../../x.git URL, the manual import page shows "Invalid scheme for URL" error. I checked that I can clone this URL from a terminal.
  
  
  </issue>
  <code>
  [start of readthedocs/projects/validators.py]
  1 """Validators for projects app."""
  2 
  3 # From https://github.com/django/django/pull/3477/files
  4 from __future__ import absolute_import
  5 import re
  6 
  7 from django.conf import settings
  8 from django.core.exceptions import ValidationError
  9 from django.utils.deconstruct import deconstructible
  10 from django.utils.translation import ugettext_lazy as _
  11 from django.core.validators import RegexValidator
  12 from future.backports.urllib.parse import urlparse
  13 
  14 
  15 domain_regex = (
  16     r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}(?<!-)\.?)|'
  17     r'localhost|'  # localhost...
  18     r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|'  # ...or ipv4
  19     r'\[?[A-F0-9]*:[A-F0-9:]+\]?)'  # ...or ipv6
  20 )
  21 
  22 
  23 @deconstructible
  24 class DomainNameValidator(RegexValidator):
  25     message = _('Enter a valid plain or internationalized domain name value')
  26     regex = re.compile(domain_regex, re.IGNORECASE)
  27 
  28     def __init__(self, accept_idna=True, **kwargs):
  29         message = kwargs.get('message')
  30         self.accept_idna = accept_idna
  31         super(DomainNameValidator, self).__init__(**kwargs)
  32         if not self.accept_idna and message is None:
  33             self.message = _('Enter a valid domain name value')
  34 
  35     def __call__(self, value):
  36         try:
  37             super(DomainNameValidator, self).__call__(value)
  38         except ValidationError as exc:
  39             if not self.accept_idna:
  40                 raise
  41             if not value:
  42                 raise
  43             try:
  44                 idnavalue = value.encode('idna')
  45             except UnicodeError:
  46                 raise exc
  47             super(DomainNameValidator, self).__call__(idnavalue)
  48 
  49 
  50 validate_domain_name = DomainNameValidator()
  51 
  52 
  53 @deconstructible
  54 class RepositoryURLValidator(object):
  55 
  56     disallow_relative_url = True
  57 
  58     # Pattern for ``git@github.com:user/repo`` pattern
  59     re_git_user = re.compile(r'^[\w]+@.+')
  60 
  61     def __call__(self, value):
  62         allow_private_repos = getattr(settings, 'ALLOW_PRIVATE_REPOS', False)
  63         public_schemes = ['https', 'http', 'git', 'ftps', 'ftp']
  64         private_schemes = ['ssh', 'ssh+git']
  65         valid_schemes = public_schemes
  66         if allow_private_repos:
  67             valid_schemes += private_schemes
  68         url = urlparse(value)
  69 
  70         # Malicious characters go first
  71         if '&&' in value or '|' in value:
  72             raise ValidationError(_('Invalid character in the URL'))
  73         elif url.scheme in valid_schemes:
  74             return value
  75 
  76         # Repo URL is not a supported scheme at this point, but there are
  77         # several cases where we might support it
  78         # Launchpad
  79         elif value.startswith('lp:'):
  80             return value
  81         # Relative paths are conditionally supported
  82         elif value.startswith('.') and not self.disallow_relative_url:
  83             return value
  84         # SSH cloning and ``git@github.com:user/project.git``
  85         elif self.re_git_user.search(value) or url.scheme in private_schemes:
  86             if allow_private_repos:
  87                 return value
  88 
  89             # Throw a more helpful error message
  90             raise ValidationError('Manual cloning via SSH is not supported')
  91 
  92         # No more valid URLs without supported URL schemes
  93         raise ValidationError(_('Invalid scheme for URL'))
  94 
  95 
  96 class SubmoduleURLValidator(RepositoryURLValidator):
  97 
  98     """
  99     A URL validator for repository submodules
  100 
  101     If a repository has a relative submodule, the URL path is effectively the
  102     supermodule's remote ``origin`` URL with the relative path applied.
  103 
  104     From the git docs::
  105 
  106         ``<repository>`` is the URL of the new submodule's origin repository.
  107         This may be either an absolute URL, or (if it begins with ``./`` or
  108         ``../``), the location relative to the superproject's default remote
  109         repository
  110     """
  111 
  112     disallow_relative_url = False
  113 
  114 
  115 validate_repository_url = RepositoryURLValidator()
  116 validate_submodule_url = SubmoduleURLValidator()
  117
  [end of readthedocs/projects/validators.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/readthedocs/projects/validators.py b/readthedocs/projects/validators.py
  --- a/readthedocs/projects/validators.py
  +++ b/readthedocs/projects/validators.py
  @@ -62,9 +62,12 @@
           allow_private_repos = getattr(settings, 'ALLOW_PRIVATE_REPOS', False)
           public_schemes = ['https', 'http', 'git', 'ftps', 'ftp']
           private_schemes = ['ssh', 'ssh+git']
  +        local_schemes = ['file']
           valid_schemes = public_schemes
           if allow_private_repos:
               valid_schemes += private_schemes
  +        if getattr(settings, 'DEBUG'):  # allow `file://` urls in dev
  +            valid_schemes += local_schemes
           url = urlparse(value)
   
           # Malicious characters go first
  
verification_info: {"golden_diff": "diff --git a/readthedocs/projects/validators.py b/readthedocs/projects/validators.py\n--- a/readthedocs/projects/validators.py\n+++ b/readthedocs/projects/validators.py\n@@ -62,9 +62,12 @@\n         allow_private_repos = getattr(settings, 'ALLOW_PRIVATE_REPOS', False)\n         public_schemes = ['https', 'http', 'git', 'ftps', 'ftp']\n         private_schemes = ['ssh', 'ssh+git']\n+        local_schemes = ['file']\n         valid_schemes = public_schemes\n         if allow_private_repos:\n             valid_schemes += private_schemes\n+        if getattr(settings, 'DEBUG'):  # allow `file://` urls in dev\n+            valid_schemes += local_schemes\n         url = urlparse(value)\n \n         # Malicious characters go first\n", "issue": "Locally hosted RTD instance doesn't allow git file:/// URLs\n## Details\r\nI installed a local RTD instance according to the Installation guide and imported test project. Now, I want to import my git project manually, \r\n## Expected Result\r\n\r\nI expected that the instance should accept all valid Git URLs.\r\n\r\n## Actual Result\r\n\r\nWhen I enter file:///.../../x.git URL, the manual import page shows \"Invalid scheme for URL\" error. I checked that I can clone this URL from a terminal.\r\n\n", "before_files": [{"content": "\"\"\"Validators for projects app.\"\"\"\n\n# From https://github.com/django/django/pull/3477/files\nfrom __future__ import absolute_import\nimport re\n\nfrom django.conf import settings\nfrom django.core.exceptions import ValidationError\nfrom django.utils.deconstruct import deconstructible\nfrom django.utils.translation import ugettext_lazy as _\nfrom django.core.validators import RegexValidator\nfrom future.backports.urllib.parse import urlparse\n\n\ndomain_regex = (\n    r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\\.)+(?:[A-Z]{2,6}\\.?|[A-Z0-9-]{2,}(?<!-)\\.?)|'\n    r'localhost|'  # localhost...\n    r'\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|'  # ...or ipv4\n    r'\\[?[A-F0-9]*:[A-F0-9:]+\\]?)'  # ...or ipv6\n)\n\n\n@deconstructible\nclass DomainNameValidator(RegexValidator):\n    message = _('Enter a valid plain or internationalized domain name value')\n    regex = re.compile(domain_regex, re.IGNORECASE)\n\n    def __init__(self, accept_idna=True, **kwargs):\n        message = kwargs.get('message')\n        self.accept_idna = accept_idna\n        super(DomainNameValidator, self).__init__(**kwargs)\n        if not self.accept_idna and message is None:\n            self.message = _('Enter a valid domain name value')\n\n    def __call__(self, value):\n        try:\n            super(DomainNameValidator, self).__call__(value)\n        except ValidationError as exc:\n            if not self.accept_idna:\n                raise\n            if not value:\n                raise\n            try:\n                idnavalue = value.encode('idna')\n            except UnicodeError:\n                raise exc\n            super(DomainNameValidator, self).__call__(idnavalue)\n\n\nvalidate_domain_name = DomainNameValidator()\n\n\n@deconstructible\nclass RepositoryURLValidator(object):\n\n    disallow_relative_url = True\n\n    # Pattern for ``git@github.com:user/repo`` pattern\n    re_git_user = re.compile(r'^[\\w]+@.+')\n\n    def __call__(self, value):\n        allow_private_repos = getattr(settings, 'ALLOW_PRIVATE_REPOS', False)\n        public_schemes = ['https', 'http', 'git', 'ftps', 'ftp']\n        private_schemes = ['ssh', 'ssh+git']\n        valid_schemes = public_schemes\n        if allow_private_repos:\n            valid_schemes += private_schemes\n        url = urlparse(value)\n\n        # Malicious characters go first\n        if '&&' in value or '|' in value:\n            raise ValidationError(_('Invalid character in the URL'))\n        elif url.scheme in valid_schemes:\n            return value\n\n        # Repo URL is not a supported scheme at this point, but there are\n        # several cases where we might support it\n        # Launchpad\n        elif value.startswith('lp:'):\n            return value\n        # Relative paths are conditionally supported\n        elif value.startswith('.') and not self.disallow_relative_url:\n            return value\n        # SSH cloning and ``git@github.com:user/project.git``\n        elif self.re_git_user.search(value) or url.scheme in private_schemes:\n            if allow_private_repos:\n                return value\n\n            # Throw a more helpful error message\n            raise ValidationError('Manual cloning via SSH is not supported')\n\n        # No more valid URLs without supported URL schemes\n        raise ValidationError(_('Invalid scheme for URL'))\n\n\nclass SubmoduleURLValidator(RepositoryURLValidator):\n\n    \"\"\"\n    A URL validator for repository submodules\n\n    If a repository has a relative submodule, the URL path is effectively the\n    supermodule's remote ``origin`` URL with the relative path applied.\n\n    From the git docs::\n\n        ``<repository>`` is the URL of the new submodule's origin repository.\n        This may be either an absolute URL, or (if it begins with ``./`` or\n        ``../``), the location relative to the superproject's default remote\n        repository\n    \"\"\"\n\n    disallow_relative_url = False\n\n\nvalidate_repository_url = RepositoryURLValidator()\nvalidate_submodule_url = SubmoduleURLValidator()\n", "path": "readthedocs/projects/validators.py"}]}