We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
1.1.0 not compatible with python 2
First of all, thanks a lot for your hard work! We've been using dj-stripe for a long time and it has served us well. Now we're ready to upgrade! Let the fun begin ;).

We're using python 2 and Django 1.11. I'm correct that 1.2 should support that right? Anyway we have to move to 1.1 first for the migrations. There is one problem though in the 1.1 release.

In commit https://github.com/dj-stripe/dj-stripe/commit/6a6f048a3a432a3ba40fba8bf90f8789139daec4 `StripeEnumField` was added with the non python 2 compatible `super()` call:

```name, path, args, kwargs = super().deconstruct()```

What do you guys think? Can we backport a hotfix fix to 1.1.1 or something?


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `djstripe/fields.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 """
3 .. module:: djstripe.fields.
4 
5    :synopsis: dj-stripe Custom Field Definitions
6 
7 .. moduleauthor:: Bill Huneke (@wahuneke)
8 """
9 from __future__ import absolute_import, division, print_function, unicode_literals
10 
11 import decimal
12 
13 from django.core.exceptions import FieldError, ImproperlyConfigured
14 from django.core.validators import MaxValueValidator, MinValueValidator
15 from django.db import models
16 
17 from .settings import USE_NATIVE_JSONFIELD
18 from .utils import convert_tstamp, dict_nested_accessor
19 
20 
21 if USE_NATIVE_JSONFIELD:
22     from django.contrib.postgres.fields import JSONField
23 else:
24     from jsonfield import JSONField
25 
26 
27 class PaymentMethodForeignKey(models.ForeignKey):
28     def __init__(self, **kwargs):
29         kwargs.setdefault("to", "PaymentMethod")
30         super(PaymentMethodForeignKey, self).__init__(**kwargs)
31 
32 
33 class StripeFieldMixin(object):
34     """
35     Custom fields for all Stripe data.
36 
37     This allows keeping track of which database fields are suitable for
38     sending to or receiving from Stripe. Also, allows a few handy extra parameters.
39     """
40 
41     # Used if the name at stripe is different from the name in our database
42     # Include a . in name if value is nested in dict in Stripe's object
43     # (e.g.  stripe_name = "data.id"  -->  obj["data"]["id"])
44     stripe_name = None
45 
46     # If stripe_name is None, this can also be used to specify a nested value, but
47     # the final value is assumed to be the database field name
48     # (e.g.    nested_name = "data"    -->  obj["data"][db_field_name]
49     nested_name = None
50 
51     # This indicates that this field will always appear in a stripe object. It will be
52     # an Exception if we try to parse a stripe object that does not include this field
53     # in the data. If set to False then null=True attribute will be automatically set
54     stripe_required = True
55 
56     # If a field was populated in previous API versions but we don't want to drop the old
57     # data for some reason, mark it as deprecated. This will make sure we never try to send
58     # it to Stripe or expect in Stripe data received
59     # This setting automatically implies Null=True
60     deprecated = False
61 
62     def __init__(self, *args, **kwargs):
63         """
64         Assign class instance variables based on kwargs.
65 
66         Assign extra class instance variables if stripe_required is defined or
67         if deprecated is defined.
68         """
69         self.stripe_name = kwargs.pop('stripe_name', self.stripe_name)
70         self.nested_name = kwargs.pop('nested_name', self.nested_name)
71         self.stripe_required = kwargs.pop('stripe_required', self.stripe_required)
72         self.deprecated = kwargs.pop('deprecated', self.deprecated)
73         if not self.stripe_required:
74             kwargs["null"] = True
75 
76         if self.deprecated:
77             kwargs["null"] = True
78             kwargs["default"] = None
79         super(StripeFieldMixin, self).__init__(*args, **kwargs)
80 
81     def stripe_to_db(self, data):
82         """Try converting stripe fields to defined database fields."""
83         if not self.deprecated:
84             try:
85                 if self.stripe_name:
86                     result = dict_nested_accessor(data, self.stripe_name)
87                 elif self.nested_name:
88                     result = dict_nested_accessor(data, self.nested_name + "." + self.name)
89                 else:
90                     result = data[self.name]
91             except (KeyError, TypeError):
92                 if self.stripe_required:
93                     model_name = self.model._meta.object_name if hasattr(self, "model") else ""
94                     raise FieldError("Required stripe field '{field_name}' was not"
95                                      " provided in {model_name} data object.".format(field_name=self.name,
96                                                                                      model_name=model_name))
97                 else:
98                     result = None
99 
100             return result
101 
102 
103 class StripePercentField(StripeFieldMixin, models.DecimalField):
104     """A field used to define a percent according to djstripe logic."""
105 
106     def __init__(self, *args, **kwargs):
107         """Assign default args to this field."""
108         defaults = {
109             'decimal_places': 2,
110             'max_digits': 5,
111             'validators': [MinValueValidator(1.00), MaxValueValidator(100.00)]
112         }
113         defaults.update(kwargs)
114         super(StripePercentField, self).__init__(*args, **defaults)
115 
116 
117 class StripeCurrencyField(StripeFieldMixin, models.DecimalField):
118     """
119     A field used to define currency according to djstripe logic.
120 
121     Stripe is always in cents. djstripe stores everything in dollars.
122     """
123 
124     def __init__(self, *args, **kwargs):
125         """Assign default args to this field."""
126         defaults = {
127             'decimal_places': 2,
128             'max_digits': 8,
129         }
130         defaults.update(kwargs)
131         super(StripeCurrencyField, self).__init__(*args, **defaults)
132 
133     def stripe_to_db(self, data):
134         """Convert the raw value to decimal representation."""
135         val = super(StripeCurrencyField, self).stripe_to_db(data)
136 
137         # Note: 0 is a possible return value, which is 'falseish'
138         if val is not None:
139             return val / decimal.Decimal("100")
140 
141 
142 class StripeBooleanField(StripeFieldMixin, models.BooleanField):
143     """A field used to define a boolean value according to djstripe logic."""
144 
145     def __init__(self, *args, **kwargs):
146         """Throw an error when a user tries to deprecate."""
147         if kwargs.get("deprecated", False):
148             raise ImproperlyConfigured("Boolean field cannot be deprecated. Change field type to "
149                                        "StripeNullBooleanField")
150         super(StripeBooleanField, self).__init__(*args, **kwargs)
151 
152 
153 class StripeNullBooleanField(StripeFieldMixin, models.NullBooleanField):
154     """A field used to define a NullBooleanField value according to djstripe logic."""
155 
156     pass
157 
158 
159 class StripeCharField(StripeFieldMixin, models.CharField):
160     """A field used to define a CharField value according to djstripe logic."""
161 
162     pass
163 
164 
165 class StripeEnumField(StripeCharField):
166     def __init__(self, enum, *args, **kwargs):
167         self.enum = enum
168         choices = enum.choices
169         defaults = {
170             "choices": choices,
171             "max_length": max(len(k) for k, v in choices)
172         }
173         defaults.update(kwargs)
174         super(StripeEnumField, self).__init__(*args, **defaults)
175 
176     def deconstruct(self):
177         name, path, args, kwargs = super().deconstruct()
178         kwargs["enum"] = self.enum
179         del kwargs["choices"]
180         return name, path, args, kwargs
181 
182 
183 class StripeIdField(StripeCharField):
184     """A field with enough space to hold any stripe ID."""
185 
186     def __init__(self, *args, **kwargs):
187         """
188         Assign default args to this field.
189 
190         As per: https://stripe.com/docs/upgrades
191         You can safely assume object IDs we generate will never exceed 255
192         characters, but you should be able to handle IDs of up to that
193         length.
194         """
195         defaults = {
196             'max_length': 255,
197             'blank': False,
198             'null': False,
199         }
200         defaults.update(kwargs)
201         super(StripeIdField, self).__init__(*args, **defaults)
202 
203 
204 class StripeTextField(StripeFieldMixin, models.TextField):
205     """A field used to define a TextField value according to djstripe logic."""
206 
207     pass
208 
209 
210 class StripeDateTimeField(StripeFieldMixin, models.DateTimeField):
211     """A field used to define a DateTimeField value according to djstripe logic."""
212 
213     def stripe_to_db(self, data):
214         """Convert the raw timestamp value to a DateTime representation."""
215         val = super(StripeDateTimeField, self).stripe_to_db(data)
216 
217         # Note: 0 is a possible return value, which is 'falseish'
218         if val is not None:
219             return convert_tstamp(val)
220 
221 
222 class StripeIntegerField(StripeFieldMixin, models.IntegerField):
223     """A field used to define a IntegerField value according to djstripe logic."""
224 
225     pass
226 
227 
228 class StripePositiveIntegerField(StripeFieldMixin, models.PositiveIntegerField):
229     """A field used to define a PositiveIntegerField value according to djstripe logic."""
230 
231     pass
232 
233 
234 class StripeJSONField(StripeFieldMixin, JSONField):
235     """A field used to define a JSONField value according to djstripe logic."""
236 
237     pass
238
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/djstripe/fields.py b/djstripe/fields.py
--- a/djstripe/fields.py
+++ b/djstripe/fields.py
@@ -174,7 +174,7 @@
         super(StripeEnumField, self).__init__(*args, **defaults)
 
     def deconstruct(self):
-        name, path, args, kwargs = super().deconstruct()
+        name, path, args, kwargs = super(StripeEnumField, self).deconstruct()
         kwargs["enum"] = self.enum
         del kwargs["choices"]
         return name, path, args, kwargs

{"golden_diff": "diff --git a/djstripe/fields.py b/djstripe/fields.py\n--- a/djstripe/fields.py\n+++ b/djstripe/fields.py\n@@ -174,7 +174,7 @@\n         super(StripeEnumField, self).__init__(*args, **defaults)\n \n     def deconstruct(self):\n-        name, path, args, kwargs = super().deconstruct()\n+        name, path, args, kwargs = super(StripeEnumField, self).deconstruct()\n         kwargs[\"enum\"] = self.enum\n         del kwargs[\"choices\"]\n         return name, path, args, kwargs\n", "issue": "1.1.0 not compatible with python 2\nFirst of all, thanks a lot for your hard work! We've been using dj-stripe for a long time and it has served us well. Now we're ready to upgrade! Let the fun begin ;).\r\n\r\nWe're using python 2 and Django 1.11. I'm correct that 1.2 should support that right? Anyway we have to move to 1.1 first for the migrations. There is one problem though in the 1.1 release.\r\n\r\nIn commit https://github.com/dj-stripe/dj-stripe/commit/6a6f048a3a432a3ba40fba8bf90f8789139daec4 `StripeEnumField` was added with the non python 2 compatible `super()` call:\r\n\r\n```name, path, args, kwargs = super().deconstruct()```\r\n\r\nWhat do you guys think? Can we backport a hotfix fix to 1.1.1 or something?\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\n.. module:: djstripe.fields.\n\n   :synopsis: dj-stripe Custom Field Definitions\n\n.. moduleauthor:: Bill Huneke (@wahuneke)\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport decimal\n\nfrom django.core.exceptions import FieldError, ImproperlyConfigured\nfrom django.core.validators import MaxValueValidator, MinValueValidator\nfrom django.db import models\n\nfrom .settings import USE_NATIVE_JSONFIELD\nfrom .utils import convert_tstamp, dict_nested_accessor\n\n\nif USE_NATIVE_JSONFIELD:\n    from django.contrib.postgres.fields import JSONField\nelse:\n    from jsonfield import JSONField\n\n\nclass PaymentMethodForeignKey(models.ForeignKey):\n    def __init__(self, **kwargs):\n        kwargs.setdefault(\"to\", \"PaymentMethod\")\n        super(PaymentMethodForeignKey, self).__init__(**kwargs)\n\n\nclass StripeFieldMixin(object):\n    \"\"\"\n    Custom fields for all Stripe data.\n\n    This allows keeping track of which database fields are suitable for\n    sending to or receiving from Stripe. Also, allows a few handy extra parameters.\n    \"\"\"\n\n    # Used if the name at stripe is different from the name in our database\n    # Include a . in name if value is nested in dict in Stripe's object\n    # (e.g.  stripe_name = \"data.id\"  -->  obj[\"data\"][\"id\"])\n    stripe_name = None\n\n    # If stripe_name is None, this can also be used to specify a nested value, but\n    # the final value is assumed to be the database field name\n    # (e.g.    nested_name = \"data\"    -->  obj[\"data\"][db_field_name]\n    nested_name = None\n\n    # This indicates that this field will always appear in a stripe object. It will be\n    # an Exception if we try to parse a stripe object that does not include this field\n    # in the data. If set to False then null=True attribute will be automatically set\n    stripe_required = True\n\n    # If a field was populated in previous API versions but we don't want to drop the old\n    # data for some reason, mark it as deprecated. This will make sure we never try to send\n    # it to Stripe or expect in Stripe data received\n    # This setting automatically implies Null=True\n    deprecated = False\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Assign class instance variables based on kwargs.\n\n        Assign extra class instance variables if stripe_required is defined or\n        if deprecated is defined.\n        \"\"\"\n        self.stripe_name = kwargs.pop('stripe_name', self.stripe_name)\n        self.nested_name = kwargs.pop('nested_name', self.nested_name)\n        self.stripe_required = kwargs.pop('stripe_required', self.stripe_required)\n        self.deprecated = kwargs.pop('deprecated', self.deprecated)\n        if not self.stripe_required:\n            kwargs[\"null\"] = True\n\n        if self.deprecated:\n            kwargs[\"null\"] = True\n            kwargs[\"default\"] = None\n        super(StripeFieldMixin, self).__init__(*args, **kwargs)\n\n    def stripe_to_db(self, data):\n        \"\"\"Try converting stripe fields to defined database fields.\"\"\"\n        if not self.deprecated:\n            try:\n                if self.stripe_name:\n                    result = dict_nested_accessor(data, self.stripe_name)\n                elif self.nested_name:\n                    result = dict_nested_accessor(data, self.nested_name + \".\" + self.name)\n                else:\n                    result = data[self.name]\n            except (KeyError, TypeError):\n                if self.stripe_required:\n                    model_name = self.model._meta.object_name if hasattr(self, \"model\") else \"\"\n                    raise FieldError(\"Required stripe field '{field_name}' was not\"\n                                     \" provided in {model_name} data object.\".format(field_name=self.name,\n                                                                                     model_name=model_name))\n                else:\n                    result = None\n\n            return result\n\n\nclass StripePercentField(StripeFieldMixin, models.DecimalField):\n    \"\"\"A field used to define a percent according to djstripe logic.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Assign default args to this field.\"\"\"\n        defaults = {\n            'decimal_places': 2,\n            'max_digits': 5,\n            'validators': [MinValueValidator(1.00), MaxValueValidator(100.00)]\n        }\n        defaults.update(kwargs)\n        super(StripePercentField, self).__init__(*args, **defaults)\n\n\nclass StripeCurrencyField(StripeFieldMixin, models.DecimalField):\n    \"\"\"\n    A field used to define currency according to djstripe logic.\n\n    Stripe is always in cents. djstripe stores everything in dollars.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Assign default args to this field.\"\"\"\n        defaults = {\n            'decimal_places': 2,\n            'max_digits': 8,\n        }\n        defaults.update(kwargs)\n        super(StripeCurrencyField, self).__init__(*args, **defaults)\n\n    def stripe_to_db(self, data):\n        \"\"\"Convert the raw value to decimal representation.\"\"\"\n        val = super(StripeCurrencyField, self).stripe_to_db(data)\n\n        # Note: 0 is a possible return value, which is 'falseish'\n        if val is not None:\n            return val / decimal.Decimal(\"100\")\n\n\nclass StripeBooleanField(StripeFieldMixin, models.BooleanField):\n    \"\"\"A field used to define a boolean value according to djstripe logic.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Throw an error when a user tries to deprecate.\"\"\"\n        if kwargs.get(\"deprecated\", False):\n            raise ImproperlyConfigured(\"Boolean field cannot be deprecated. Change field type to \"\n                                       \"StripeNullBooleanField\")\n        super(StripeBooleanField, self).__init__(*args, **kwargs)\n\n\nclass StripeNullBooleanField(StripeFieldMixin, models.NullBooleanField):\n    \"\"\"A field used to define a NullBooleanField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeCharField(StripeFieldMixin, models.CharField):\n    \"\"\"A field used to define a CharField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeEnumField(StripeCharField):\n    def __init__(self, enum, *args, **kwargs):\n        self.enum = enum\n        choices = enum.choices\n        defaults = {\n            \"choices\": choices,\n            \"max_length\": max(len(k) for k, v in choices)\n        }\n        defaults.update(kwargs)\n        super(StripeEnumField, self).__init__(*args, **defaults)\n\n    def deconstruct(self):\n        name, path, args, kwargs = super().deconstruct()\n        kwargs[\"enum\"] = self.enum\n        del kwargs[\"choices\"]\n        return name, path, args, kwargs\n\n\nclass StripeIdField(StripeCharField):\n    \"\"\"A field with enough space to hold any stripe ID.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Assign default args to this field.\n\n        As per: https://stripe.com/docs/upgrades\n        You can safely assume object IDs we generate will never exceed 255\n        characters, but you should be able to handle IDs of up to that\n        length.\n        \"\"\"\n        defaults = {\n            'max_length': 255,\n            'blank': False,\n            'null': False,\n        }\n        defaults.update(kwargs)\n        super(StripeIdField, self).__init__(*args, **defaults)\n\n\nclass StripeTextField(StripeFieldMixin, models.TextField):\n    \"\"\"A field used to define a TextField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeDateTimeField(StripeFieldMixin, models.DateTimeField):\n    \"\"\"A field used to define a DateTimeField value according to djstripe logic.\"\"\"\n\n    def stripe_to_db(self, data):\n        \"\"\"Convert the raw timestamp value to a DateTime representation.\"\"\"\n        val = super(StripeDateTimeField, self).stripe_to_db(data)\n\n        # Note: 0 is a possible return value, which is 'falseish'\n        if val is not None:\n            return convert_tstamp(val)\n\n\nclass StripeIntegerField(StripeFieldMixin, models.IntegerField):\n    \"\"\"A field used to define a IntegerField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripePositiveIntegerField(StripeFieldMixin, models.PositiveIntegerField):\n    \"\"\"A field used to define a PositiveIntegerField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeJSONField(StripeFieldMixin, JSONField):\n    \"\"\"A field used to define a JSONField value according to djstripe logic.\"\"\"\n\n    pass\n", "path": "djstripe/fields.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\"\"\"\n.. module:: djstripe.fields.\n\n   :synopsis: dj-stripe Custom Field Definitions\n\n.. moduleauthor:: Bill Huneke (@wahuneke)\n\"\"\"\nfrom __future__ import absolute_import, division, print_function, unicode_literals\n\nimport decimal\n\nfrom django.core.exceptions import FieldError, ImproperlyConfigured\nfrom django.core.validators import MaxValueValidator, MinValueValidator\nfrom django.db import models\n\nfrom .settings import USE_NATIVE_JSONFIELD\nfrom .utils import convert_tstamp, dict_nested_accessor\n\n\nif USE_NATIVE_JSONFIELD:\n    from django.contrib.postgres.fields import JSONField\nelse:\n    from jsonfield import JSONField\n\n\nclass PaymentMethodForeignKey(models.ForeignKey):\n    def __init__(self, **kwargs):\n        kwargs.setdefault(\"to\", \"PaymentMethod\")\n        super(PaymentMethodForeignKey, self).__init__(**kwargs)\n\n\nclass StripeFieldMixin(object):\n    \"\"\"\n    Custom fields for all Stripe data.\n\n    This allows keeping track of which database fields are suitable for\n    sending to or receiving from Stripe. Also, allows a few handy extra parameters.\n    \"\"\"\n\n    # Used if the name at stripe is different from the name in our database\n    # Include a . in name if value is nested in dict in Stripe's object\n    # (e.g.  stripe_name = \"data.id\"  -->  obj[\"data\"][\"id\"])\n    stripe_name = None\n\n    # If stripe_name is None, this can also be used to specify a nested value, but\n    # the final value is assumed to be the database field name\n    # (e.g.    nested_name = \"data\"    -->  obj[\"data\"][db_field_name]\n    nested_name = None\n\n    # This indicates that this field will always appear in a stripe object. It will be\n    # an Exception if we try to parse a stripe object that does not include this field\n    # in the data. If set to False then null=True attribute will be automatically set\n    stripe_required = True\n\n    # If a field was populated in previous API versions but we don't want to drop the old\n    # data for some reason, mark it as deprecated. This will make sure we never try to send\n    # it to Stripe or expect in Stripe data received\n    # This setting automatically implies Null=True\n    deprecated = False\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Assign class instance variables based on kwargs.\n\n        Assign extra class instance variables if stripe_required is defined or\n        if deprecated is defined.\n        \"\"\"\n        self.stripe_name = kwargs.pop('stripe_name', self.stripe_name)\n        self.nested_name = kwargs.pop('nested_name', self.nested_name)\n        self.stripe_required = kwargs.pop('stripe_required', self.stripe_required)\n        self.deprecated = kwargs.pop('deprecated', self.deprecated)\n        if not self.stripe_required:\n            kwargs[\"null\"] = True\n\n        if self.deprecated:\n            kwargs[\"null\"] = True\n            kwargs[\"default\"] = None\n        super(StripeFieldMixin, self).__init__(*args, **kwargs)\n\n    def stripe_to_db(self, data):\n        \"\"\"Try converting stripe fields to defined database fields.\"\"\"\n        if not self.deprecated:\n            try:\n                if self.stripe_name:\n                    result = dict_nested_accessor(data, self.stripe_name)\n                elif self.nested_name:\n                    result = dict_nested_accessor(data, self.nested_name + \".\" + self.name)\n                else:\n                    result = data[self.name]\n            except (KeyError, TypeError):\n                if self.stripe_required:\n                    model_name = self.model._meta.object_name if hasattr(self, \"model\") else \"\"\n                    raise FieldError(\"Required stripe field '{field_name}' was not\"\n                                     \" provided in {model_name} data object.\".format(field_name=self.name,\n                                                                                     model_name=model_name))\n                else:\n                    result = None\n\n            return result\n\n\nclass StripePercentField(StripeFieldMixin, models.DecimalField):\n    \"\"\"A field used to define a percent according to djstripe logic.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Assign default args to this field.\"\"\"\n        defaults = {\n            'decimal_places': 2,\n            'max_digits': 5,\n            'validators': [MinValueValidator(1.00), MaxValueValidator(100.00)]\n        }\n        defaults.update(kwargs)\n        super(StripePercentField, self).__init__(*args, **defaults)\n\n\nclass StripeCurrencyField(StripeFieldMixin, models.DecimalField):\n    \"\"\"\n    A field used to define currency according to djstripe logic.\n\n    Stripe is always in cents. djstripe stores everything in dollars.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Assign default args to this field.\"\"\"\n        defaults = {\n            'decimal_places': 2,\n            'max_digits': 8,\n        }\n        defaults.update(kwargs)\n        super(StripeCurrencyField, self).__init__(*args, **defaults)\n\n    def stripe_to_db(self, data):\n        \"\"\"Convert the raw value to decimal representation.\"\"\"\n        val = super(StripeCurrencyField, self).stripe_to_db(data)\n\n        # Note: 0 is a possible return value, which is 'falseish'\n        if val is not None:\n            return val / decimal.Decimal(\"100\")\n\n\nclass StripeBooleanField(StripeFieldMixin, models.BooleanField):\n    \"\"\"A field used to define a boolean value according to djstripe logic.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"Throw an error when a user tries to deprecate.\"\"\"\n        if kwargs.get(\"deprecated\", False):\n            raise ImproperlyConfigured(\"Boolean field cannot be deprecated. Change field type to \"\n                                       \"StripeNullBooleanField\")\n        super(StripeBooleanField, self).__init__(*args, **kwargs)\n\n\nclass StripeNullBooleanField(StripeFieldMixin, models.NullBooleanField):\n    \"\"\"A field used to define a NullBooleanField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeCharField(StripeFieldMixin, models.CharField):\n    \"\"\"A field used to define a CharField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeEnumField(StripeCharField):\n    def __init__(self, enum, *args, **kwargs):\n        self.enum = enum\n        choices = enum.choices\n        defaults = {\n            \"choices\": choices,\n            \"max_length\": max(len(k) for k, v in choices)\n        }\n        defaults.update(kwargs)\n        super(StripeEnumField, self).__init__(*args, **defaults)\n\n    def deconstruct(self):\n        name, path, args, kwargs = super(StripeEnumField, self).deconstruct()\n        kwargs[\"enum\"] = self.enum\n        del kwargs[\"choices\"]\n        return name, path, args, kwargs\n\n\nclass StripeIdField(StripeCharField):\n    \"\"\"A field with enough space to hold any stripe ID.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        \"\"\"\n        Assign default args to this field.\n\n        As per: https://stripe.com/docs/upgrades\n        You can safely assume object IDs we generate will never exceed 255\n        characters, but you should be able to handle IDs of up to that\n        length.\n        \"\"\"\n        defaults = {\n            'max_length': 255,\n            'blank': False,\n            'null': False,\n        }\n        defaults.update(kwargs)\n        super(StripeIdField, self).__init__(*args, **defaults)\n\n\nclass StripeTextField(StripeFieldMixin, models.TextField):\n    \"\"\"A field used to define a TextField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeDateTimeField(StripeFieldMixin, models.DateTimeField):\n    \"\"\"A field used to define a DateTimeField value according to djstripe logic.\"\"\"\n\n    def stripe_to_db(self, data):\n        \"\"\"Convert the raw timestamp value to a DateTime representation.\"\"\"\n        val = super(StripeDateTimeField, self).stripe_to_db(data)\n\n        # Note: 0 is a possible return value, which is 'falseish'\n        if val is not None:\n            return convert_tstamp(val)\n\n\nclass StripeIntegerField(StripeFieldMixin, models.IntegerField):\n    \"\"\"A field used to define a IntegerField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripePositiveIntegerField(StripeFieldMixin, models.PositiveIntegerField):\n    \"\"\"A field used to define a PositiveIntegerField value according to djstripe logic.\"\"\"\n\n    pass\n\n\nclass StripeJSONField(StripeFieldMixin, JSONField):\n    \"\"\"A field used to define a JSONField value according to djstripe logic.\"\"\"\n\n    pass\n", "path": "djstripe/fields.py"}]}