prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  `::1/128` is not a valid prefix
  <!--
      NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.
  
      This form is only for reporting reproducible bugs. If you need assistance
      with Nautobot installation, or if you have a general question, please start a
      discussion instead: https://github.com/nautobot/nautobot/discussions
  
      Please describe the environment in which you are running Nautobot. Be sure
      that you are running an unmodified instance of the latest stable release
      before submitting a bug report, and that any plugins have been disabled.
  -->
  ### Environment
  * Python version: 3.6
  * Nautobot version: 1.1.3
  
  <!--
      Describe in detail the exact steps that someone else can take to reproduce
      this bug using the current stable release of Nautobot. Begin with the
      creation of any necessary database objects and call out every operation
      being performed explicitly. If reporting a bug in the REST API, be sure to
      reconstruct the raw HTTP request(s) being made: Don't rely on a client
      library such as pynautobot.
  -->
  
  When trying to create the prefix `::1/128` I get the following error:
  
  ```no-highlight
  <class 'netaddr.core.AddrFormatError'>
  
  invalid IPNetwork 0.0.0.1/128
  ```
  
  Both Python netaddr and ipaddress modules see this as a valid IPNetwork.  
  
  ### Steps to Reproduce
  1.  Create a prefix or aggregate using the prefix `::1/128`
  
  <!-- What did you expect to happen? -->
  ### Expected Behavior
  
  Prefix created
  
  <!-- What happened instead? -->
  ### Observed Behavior
  
  ```
  invalid IPNetwork 0.0.0.1/128
  ```
  
  </issue>
  <code>
  [start of nautobot/ipam/fields.py]
  1 from django.core.exceptions import ValidationError
  2 from django.db import models
  3 from django.utils.datastructures import DictWrapper
  4 import netaddr
  5 
  6 from .formfields import IPNetworkFormField
  7 
  8 
  9 class VarbinaryIPField(models.BinaryField):
  10     """
  11     IP network address
  12     """
  13 
  14     description = "IP network address"
  15 
  16     def __init__(self, **kwargs):
  17         super().__init__(**kwargs)
  18 
  19     def db_type(self, connection):
  20         """Returns the correct field type for a given database vendor."""
  21 
  22         # Use 'bytea' type for PostgreSQL.
  23         if connection.vendor == "postgresql":
  24             return "bytea"
  25 
  26         # Or 'varbinary' for everyone else.
  27         return "varbinary(16)"
  28 
  29     def value_to_string(self, obj):
  30         """IPField is serialized as str(IPAddress())"""
  31         value = self.value_from_object(obj)
  32         if not value:
  33             return value
  34 
  35         return str(self._parse_address(value))
  36 
  37     def _parse_address(self, value):
  38         """
  39         Parse `str`, `bytes` (varbinary), or `netaddr.IPAddress to `netaddr.IPAddress`.
  40         """
  41         try:
  42             value = int.from_bytes(value, "big")
  43         except TypeError:
  44             pass  # It's a string
  45 
  46         try:
  47             return netaddr.IPAddress(value)
  48         except netaddr.AddrFormatError:
  49             raise ValidationError("Invalid IP address format: {}".format(value))
  50         except (TypeError, ValueError) as e:
  51             raise ValidationError(e)
  52 
  53     def from_db_value(self, value, expression, connection):
  54         """Converts DB (varbinary) to Python (str)."""
  55         return self.to_python(value)
  56 
  57     def to_python(self, value):
  58         """Converts `value` to Python (str)."""
  59         if isinstance(value, netaddr.IPAddress):
  60             return str(value)
  61 
  62         if value is None:
  63             return value
  64 
  65         return str(self._parse_address(value))
  66 
  67     def get_db_prep_value(self, value, connection, prepared=False):
  68         """Converts Python (str) to DB (varbinary)."""
  69         if value is None:
  70             return value
  71 
  72         # Parse the address and then pack it to binary.
  73         value = self._parse_address(value).packed
  74 
  75         # Use defaults for PostgreSQL
  76         if connection.vendor == "postgresql":
  77             return super().get_db_prep_value(value, connection, prepared)
  78 
  79         return value
  80 
  81     def form_class(self):
  82         return IPNetworkFormField
  83 
  84     def formfield(self, **kwargs):
  85         defaults = {"form_class": self.form_class()}
  86         defaults.update(kwargs)
  87         return super().formfield(**defaults)
  88
  [end of nautobot/ipam/fields.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/nautobot/ipam/fields.py b/nautobot/ipam/fields.py
  --- a/nautobot/ipam/fields.py
  +++ b/nautobot/ipam/fields.py
  @@ -39,12 +39,17 @@
           Parse `str`, `bytes` (varbinary), or `netaddr.IPAddress to `netaddr.IPAddress`.
           """
           try:
  -            value = int.from_bytes(value, "big")
  +            int_value = int.from_bytes(value, "big")
  +            # Distinguish between
  +            # \x00\x00\x00\x01 (IPv4 0.0.0.1) and
  +            # \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01 (IPv6 ::1), among other cases
  +            version = 4 if len(value) == 4 else 6
  +            value = int_value
           except TypeError:
  -            pass  # It's a string
  +            version = None  # It's a string, IP version should be self-evident
   
           try:
  -            return netaddr.IPAddress(value)
  +            return netaddr.IPAddress(value, version=version)
           except netaddr.AddrFormatError:
               raise ValidationError("Invalid IP address format: {}".format(value))
           except (TypeError, ValueError) as e:
  
verification_info: {"golden_diff": "diff --git a/nautobot/ipam/fields.py b/nautobot/ipam/fields.py\n--- a/nautobot/ipam/fields.py\n+++ b/nautobot/ipam/fields.py\n@@ -39,12 +39,17 @@\n         Parse `str`, `bytes` (varbinary), or `netaddr.IPAddress to `netaddr.IPAddress`.\n         \"\"\"\n         try:\n-            value = int.from_bytes(value, \"big\")\n+            int_value = int.from_bytes(value, \"big\")\n+            # Distinguish between\n+            # \\x00\\x00\\x00\\x01 (IPv4 0.0.0.1) and\n+            # \\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01 (IPv6 ::1), among other cases\n+            version = 4 if len(value) == 4 else 6\n+            value = int_value\n         except TypeError:\n-            pass  # It's a string\n+            version = None  # It's a string, IP version should be self-evident\n \n         try:\n-            return netaddr.IPAddress(value)\n+            return netaddr.IPAddress(value, version=version)\n         except netaddr.AddrFormatError:\n             raise ValidationError(\"Invalid IP address format: {}\".format(value))\n         except (TypeError, ValueError) as e:\n", "issue": "`::1/128` is not a valid prefix\n<!--\r\n    NOTE: IF YOUR ISSUE DOES NOT FOLLOW THIS TEMPLATE, IT WILL BE CLOSED.\r\n\r\n    This form is only for reporting reproducible bugs. If you need assistance\r\n    with Nautobot installation, or if you have a general question, please start a\r\n    discussion instead: https://github.com/nautobot/nautobot/discussions\r\n\r\n    Please describe the environment in which you are running Nautobot. Be sure\r\n    that you are running an unmodified instance of the latest stable release\r\n    before submitting a bug report, and that any plugins have been disabled.\r\n-->\r\n### Environment\r\n* Python version: 3.6\r\n* Nautobot version: 1.1.3\r\n\r\n<!--\r\n    Describe in detail the exact steps that someone else can take to reproduce\r\n    this bug using the current stable release of Nautobot. Begin with the\r\n    creation of any necessary database objects and call out every operation\r\n    being performed explicitly. If reporting a bug in the REST API, be sure to\r\n    reconstruct the raw HTTP request(s) being made: Don't rely on a client\r\n    library such as pynautobot.\r\n-->\r\n\r\nWhen trying to create the prefix `::1/128` I get the following error:\r\n\r\n```no-highlight\r\n<class 'netaddr.core.AddrFormatError'>\r\n\r\ninvalid IPNetwork 0.0.0.1/128\r\n```\r\n\r\nBoth Python netaddr and ipaddress modules see this as a valid IPNetwork.  \r\n\r\n### Steps to Reproduce\r\n1.  Create a prefix or aggregate using the prefix `::1/128`\r\n\r\n<!-- What did you expect to happen? -->\r\n### Expected Behavior\r\n\r\nPrefix created\r\n\r\n<!-- What happened instead? -->\r\n### Observed Behavior\r\n\r\n```\r\ninvalid IPNetwork 0.0.0.1/128\r\n```\n", "before_files": [{"content": "from django.core.exceptions import ValidationError\nfrom django.db import models\nfrom django.utils.datastructures import DictWrapper\nimport netaddr\n\nfrom .formfields import IPNetworkFormField\n\n\nclass VarbinaryIPField(models.BinaryField):\n    \"\"\"\n    IP network address\n    \"\"\"\n\n    description = \"IP network address\"\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n\n    def db_type(self, connection):\n        \"\"\"Returns the correct field type for a given database vendor.\"\"\"\n\n        # Use 'bytea' type for PostgreSQL.\n        if connection.vendor == \"postgresql\":\n            return \"bytea\"\n\n        # Or 'varbinary' for everyone else.\n        return \"varbinary(16)\"\n\n    def value_to_string(self, obj):\n        \"\"\"IPField is serialized as str(IPAddress())\"\"\"\n        value = self.value_from_object(obj)\n        if not value:\n            return value\n\n        return str(self._parse_address(value))\n\n    def _parse_address(self, value):\n        \"\"\"\n        Parse `str`, `bytes` (varbinary), or `netaddr.IPAddress to `netaddr.IPAddress`.\n        \"\"\"\n        try:\n            value = int.from_bytes(value, \"big\")\n        except TypeError:\n            pass  # It's a string\n\n        try:\n            return netaddr.IPAddress(value)\n        except netaddr.AddrFormatError:\n            raise ValidationError(\"Invalid IP address format: {}\".format(value))\n        except (TypeError, ValueError) as e:\n            raise ValidationError(e)\n\n    def from_db_value(self, value, expression, connection):\n        \"\"\"Converts DB (varbinary) to Python (str).\"\"\"\n        return self.to_python(value)\n\n    def to_python(self, value):\n        \"\"\"Converts `value` to Python (str).\"\"\"\n        if isinstance(value, netaddr.IPAddress):\n            return str(value)\n\n        if value is None:\n            return value\n\n        return str(self._parse_address(value))\n\n    def get_db_prep_value(self, value, connection, prepared=False):\n        \"\"\"Converts Python (str) to DB (varbinary).\"\"\"\n        if value is None:\n            return value\n\n        # Parse the address and then pack it to binary.\n        value = self._parse_address(value).packed\n\n        # Use defaults for PostgreSQL\n        if connection.vendor == \"postgresql\":\n            return super().get_db_prep_value(value, connection, prepared)\n\n        return value\n\n    def form_class(self):\n        return IPNetworkFormField\n\n    def formfield(self, **kwargs):\n        defaults = {\"form_class\": self.form_class()}\n        defaults.update(kwargs)\n        return super().formfield(**defaults)\n", "path": "nautobot/ipam/fields.py"}]}