We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Some invalid phone numbers throw an exception and result in server error
### What I'm trying to achieve
Type in a fake number +1 123 456 7890, into the shipping form. Should fail gracefully with a red input box

### Steps to reproduce the problem
1. Type in a fake number +1 123 456 7890, into the shipping form
2. Receive ValueError at /en/checkout/shipping-address/ “+11234567890” is not a valid phone number.

### What I expected to happen
Should fail gracefully with a red input box

### What happens
500 Internal server error

**System information**
Operating system: Ubuntu 18.04
Browser: Firefox


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `saleor/account/validators.py`
Content:
```
1 from django.core.exceptions import ValidationError
2 from django.utils.translation import ugettext_lazy as _
3 from phonenumber_field.phonenumber import to_python
4 from phonenumbers.phonenumberutil import is_possible_number
5 
6 
7 def validate_possible_number(value, country=None):
8     phone_number = to_python(value, country)
9     if phone_number and not is_possible_number(phone_number):
10         raise ValidationError(
11             _("The phone number entered is not valid."), code="invalid_phone_number"
12         )
13
```

Path: `saleor/account/i18n.py`
Content:
```
1 from collections import defaultdict
2 
3 import i18naddress
4 from django import forms
5 from django.forms.forms import BoundField
6 from django.utils.translation import pgettext_lazy, ugettext_lazy as _
7 from django_countries import countries
8 from phonenumber_field.phonenumber import PhoneNumber
9 from phonenumbers import NumberParseException
10 from phonenumbers.phonenumberutil import is_possible_number
11 
12 from .models import Address
13 from .widgets import DatalistTextWidget, PhonePrefixWidget
14 
15 COUNTRY_FORMS = {}
16 UNKNOWN_COUNTRIES = set()
17 
18 AREA_TYPE_TRANSLATIONS = {
19     "area": pgettext_lazy("Address field", "Area"),
20     "county": pgettext_lazy("Address field", "County"),
21     "department": pgettext_lazy("Address field", "Department"),
22     "district": pgettext_lazy("Address field", "District"),
23     "do_si": pgettext_lazy("Address field", "Do/si"),
24     "eircode": pgettext_lazy("Address field", "Eircode"),
25     "emirate": pgettext_lazy("Address field", "Emirate"),
26     "island": pgettext_lazy("Address field", "Island"),
27     "neighborhood": pgettext_lazy("Address field", "Neighborhood"),
28     "oblast": pgettext_lazy("Address field", "Oblast"),
29     "parish": pgettext_lazy("Address field", "Parish"),
30     "pin": pgettext_lazy("Address field", "PIN"),
31     "postal": pgettext_lazy("Address field", "Postal code"),
32     "prefecture": pgettext_lazy("Address field", "Prefecture"),
33     "province": pgettext_lazy("Address field", "Province"),
34     "state": pgettext_lazy("Address field", "State"),
35     "suburb": pgettext_lazy("Address field", "Suburb"),
36     "townland": pgettext_lazy("Address field", "Townland"),
37     "village_township": pgettext_lazy("Address field", "Village/township"),
38     "zip": pgettext_lazy("Address field", "ZIP code"),
39 }
40 
41 
42 class PossiblePhoneNumberFormField(forms.CharField):
43     """A phone input field."""
44 
45     def __init__(self, *args, **kwargs):
46         super().__init__(*args, **kwargs)
47         self.widget.input_type = "tel"
48 
49 
50 class CountryAreaChoiceField(forms.ChoiceField):
51     widget = DatalistTextWidget
52 
53     def valid_value(self, value):
54         return True
55 
56 
57 class AddressMetaForm(forms.ModelForm):
58     # This field is never visible in UI
59     preview = forms.BooleanField(initial=False, required=False)
60 
61     class Meta:
62         model = Address
63         fields = ["country", "preview"]
64         labels = {"country": pgettext_lazy("Country", "Country")}
65 
66     def clean(self):
67         data = super().clean()
68         if data.get("preview"):
69             self.data = self.data.copy()
70             self.data["preview"] = False
71         return data
72 
73 
74 class AddressForm(forms.ModelForm):
75 
76     AUTOCOMPLETE_MAPPING = [
77         ("first_name", "given-name"),
78         ("last_name", "family-name"),
79         ("company_name", "organization"),
80         ("street_address_1", "address-line1"),
81         ("street_address_2", "address-line2"),
82         ("city", "address-level2"),
83         ("postal_code", "postal-code"),
84         ("country_area", "address-level1"),
85         ("country", "country"),
86         ("city_area", "address-level3"),
87         ("phone", "tel"),
88         ("email", "email"),
89     ]
90 
91     class Meta:
92         model = Address
93         exclude = []
94         labels = {
95             "first_name": pgettext_lazy("Personal name", "Given name"),
96             "last_name": pgettext_lazy("Personal name", "Family name"),
97             "company_name": pgettext_lazy(
98                 "Company or organization", "Company or organization"
99             ),
100             "street_address_1": pgettext_lazy("Address", "Address"),
101             "street_address_2": "",
102             "city": pgettext_lazy("City", "City"),
103             "city_area": pgettext_lazy("City area", "District"),
104             "postal_code": pgettext_lazy("Postal code", "Postal code"),
105             "country": pgettext_lazy("Country", "Country"),
106             "country_area": pgettext_lazy("Country area", "State or province"),
107             "phone": pgettext_lazy("Phone number", "Phone number"),
108         }
109         placeholders = {
110             "street_address_1": pgettext_lazy(
111                 "Address", "Street address, P.O. box, company name"
112             ),
113             "street_address_2": pgettext_lazy(
114                 "Address", "Apartment, suite, unit, building, floor, etc"
115             ),
116         }
117 
118     phone = PossiblePhoneNumberFormField(widget=PhonePrefixWidget, required=False)
119 
120     def __init__(self, *args, **kwargs):
121         autocomplete_type = kwargs.pop("autocomplete_type", None)
122         super().__init__(*args, **kwargs)
123         # countries order was taken as defined in the model,
124         # not being sorted accordingly to the selected language
125         self.fields["country"].choices = sorted(
126             COUNTRY_CHOICES, key=lambda choice: choice[1]
127         )
128         autocomplete_dict = defaultdict(lambda: "off", self.AUTOCOMPLETE_MAPPING)
129         for field_name, field in self.fields.items():
130             if autocomplete_type:
131                 autocomplete = "%s %s" % (
132                     autocomplete_type,
133                     autocomplete_dict[field_name],
134                 )
135             else:
136                 autocomplete = autocomplete_dict[field_name]
137             field.widget.attrs["autocomplete"] = autocomplete
138             field.widget.attrs["placeholder"] = (
139                 field.label if not hasattr(field, "placeholder") else field.placeholder
140             )
141 
142     def clean(self):
143         data = super().clean()
144         phone = data.get("phone")
145         country = data.get("country")
146         if phone:
147             try:
148                 data["phone"] = clean_phone_for_country(phone, country)
149             except forms.ValidationError as error:
150                 self.add_error("phone", error)
151         return data
152 
153 
154 def clean_phone_for_country(phone, country):
155     error = _("The phone number entered is not valid.")
156     error_code = "invalid_phone_number"
157     if phone:
158         try:
159             phone = PhoneNumber.from_string(phone, country)
160         except NumberParseException:
161             raise forms.ValidationError(error, code=error_code)
162         else:
163             if not is_possible_number(phone):
164                 raise forms.ValidationError(error, code=error_code)
165     return phone
166 
167 
168 class CountryAwareAddressForm(AddressForm):
169 
170     I18N_MAPPING = [
171         ("name", ["first_name", "last_name"]),
172         ("street_address", ["street_address_1", "street_address_2"]),
173         ("city_area", ["city_area"]),
174         ("country_area", ["country_area"]),
175         ("company_name", ["company_name"]),
176         ("postal_code", ["postal_code"]),
177         ("city", ["city"]),
178         ("sorting_code", []),
179         ("country_code", ["country"]),
180     ]
181 
182     class Meta:
183         model = Address
184         exclude = []
185 
186     def add_field_errors(self, errors):
187         field_mapping = dict(self.I18N_MAPPING)
188         for field_name, error_code in errors.items():
189             local_fields = field_mapping[field_name]
190             for field in local_fields:
191                 try:
192                     error_msg = self.fields[field].error_messages[error_code]
193                 except KeyError:
194                     error_msg = pgettext_lazy(
195                         "Address form", "This value is invalid for selected country"
196                     )
197                 self.add_error(field, error_msg)
198 
199     def validate_address(self, data):
200         try:
201             data["country_code"] = data.get("country", "")
202             if data["street_address_1"] or data["street_address_2"]:
203                 data["street_address"] = "%s\n%s" % (
204                     data["street_address_1"],
205                     data["street_address_2"],
206                 )
207             data = i18naddress.normalize_address(data)
208             del data["sorting_code"]
209         except i18naddress.InvalidAddress as exc:
210             self.add_field_errors(exc.errors)
211         return data
212 
213     def clean(self):
214         data = super().clean()
215         return self.validate_address(data)
216 
217 
218 def get_address_form_class(country_code):
219     return COUNTRY_FORMS[country_code]
220 
221 
222 def get_form_i18n_lines(form_instance):
223     country_code = form_instance.i18n_country_code
224     try:
225         fields_order = i18naddress.get_field_order({"country_code": country_code})
226     except ValueError:
227         fields_order = i18naddress.get_field_order({})
228     field_mapping = dict(form_instance.I18N_MAPPING)
229 
230     def _convert_to_bound_fields(form, i18n_field_names):
231         bound_fields = []
232         for field_name in i18n_field_names:
233             local_fields = field_mapping[field_name]
234             for local_name in local_fields:
235                 local_field = form_instance.fields[local_name]
236                 bound_field = BoundField(form, local_field, local_name)
237                 bound_fields.append(bound_field)
238         return bound_fields
239 
240     if fields_order:
241         return [_convert_to_bound_fields(form_instance, line) for line in fields_order]
242 
243 
244 def update_base_fields(form_class, i18n_rules):
245     for field_name, label_value in AddressForm.Meta.labels.items():
246         field = form_class.base_fields[field_name]
247         field.label = label_value
248 
249     for field_name, placeholder_value in AddressForm.Meta.placeholders.items():
250         field = form_class.base_fields[field_name]
251         field.placeholder = placeholder_value
252 
253     if i18n_rules.country_area_choices:
254         form_class.base_fields["country_area"] = CountryAreaChoiceField(
255             choices=i18n_rules.country_area_choices
256         )
257 
258     labels_map = {
259         "country_area": i18n_rules.country_area_type,
260         "postal_code": i18n_rules.postal_code_type,
261         "city_area": i18n_rules.city_area_type,
262     }
263 
264     for field_name, area_type in labels_map.items():
265         field = form_class.base_fields[field_name]
266         field.label = AREA_TYPE_TRANSLATIONS[area_type]
267 
268     hidden_fields = i18naddress.KNOWN_FIELDS - i18n_rules.allowed_fields
269     for field_name in hidden_fields:
270         if field_name in form_class.base_fields:
271             form_class.base_fields[field_name].widget = forms.HiddenInput()
272 
273     country_field = form_class.base_fields["country"]
274     country_field.choices = COUNTRY_CHOICES
275 
276 
277 def construct_address_form(country_code, i18n_rules):
278     class_name = "AddressForm%s" % country_code
279     base_class = CountryAwareAddressForm
280     form_kwargs = {
281         "Meta": type(str("Meta"), (base_class.Meta, object), {}),
282         "formfield_callback": None,
283     }
284     class_ = type(base_class)(str(class_name), (base_class,), form_kwargs)
285     update_base_fields(class_, i18n_rules)
286     class_.i18n_country_code = country_code
287     class_.i18n_fields_order = property(get_form_i18n_lines)
288     return class_
289 
290 
291 for country in countries.countries.keys():
292     try:
293         country_rules = i18naddress.get_validation_rules({"country_code": country})
294     except ValueError:
295         country_rules = i18naddress.get_validation_rules({})
296         UNKNOWN_COUNTRIES.add(country)
297 
298 COUNTRY_CHOICES = [
299     (code, label)
300     for code, label in countries.countries.items()
301     if code not in UNKNOWN_COUNTRIES
302 ]
303 # Sort choices list by country name
304 COUNTRY_CHOICES = sorted(COUNTRY_CHOICES, key=lambda choice: choice[1])
305 
306 for country, label in COUNTRY_CHOICES:
307     country_rules = i18naddress.get_validation_rules({"country_code": country})
308     COUNTRY_FORMS[country] = construct_address_form(country, country_rules)
309
```
--- 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/saleor/account/i18n.py b/saleor/account/i18n.py
--- a/saleor/account/i18n.py
+++ b/saleor/account/i18n.py
@@ -3,13 +3,11 @@
 import i18naddress
 from django import forms
 from django.forms.forms import BoundField
-from django.utils.translation import pgettext_lazy, ugettext_lazy as _
+from django.utils.translation import pgettext_lazy
 from django_countries import countries
-from phonenumber_field.phonenumber import PhoneNumber
-from phonenumbers import NumberParseException
-from phonenumbers.phonenumberutil import is_possible_number
 
 from .models import Address
+from .validators import validate_possible_number
 from .widgets import DatalistTextWidget, PhonePrefixWidget
 
 COUNTRY_FORMS = {}
@@ -145,26 +143,12 @@
         country = data.get("country")
         if phone:
             try:
-                data["phone"] = clean_phone_for_country(phone, country)
+                data["phone"] = validate_possible_number(phone, country)
             except forms.ValidationError as error:
                 self.add_error("phone", error)
         return data
 
 
-def clean_phone_for_country(phone, country):
-    error = _("The phone number entered is not valid.")
-    error_code = "invalid_phone_number"
-    if phone:
-        try:
-            phone = PhoneNumber.from_string(phone, country)
-        except NumberParseException:
-            raise forms.ValidationError(error, code=error_code)
-        else:
-            if not is_possible_number(phone):
-                raise forms.ValidationError(error, code=error_code)
-    return phone
-
-
 class CountryAwareAddressForm(AddressForm):
 
     I18N_MAPPING = [
diff --git a/saleor/account/validators.py b/saleor/account/validators.py
--- a/saleor/account/validators.py
+++ b/saleor/account/validators.py
@@ -4,9 +4,14 @@
 from phonenumbers.phonenumberutil import is_possible_number
 
 
-def validate_possible_number(value, country=None):
-    phone_number = to_python(value, country)
-    if phone_number and not is_possible_number(phone_number):
+def validate_possible_number(phone, country=None):
+    phone_number = to_python(phone, country)
+    if (
+        phone_number
+        and not is_possible_number(phone_number)
+        or not phone_number.is_valid()
+    ):
         raise ValidationError(
             _("The phone number entered is not valid."), code="invalid_phone_number"
         )
+    return phone_number

{"golden_diff": "diff --git a/saleor/account/i18n.py b/saleor/account/i18n.py\n--- a/saleor/account/i18n.py\n+++ b/saleor/account/i18n.py\n@@ -3,13 +3,11 @@\n import i18naddress\n from django import forms\n from django.forms.forms import BoundField\n-from django.utils.translation import pgettext_lazy, ugettext_lazy as _\n+from django.utils.translation import pgettext_lazy\n from django_countries import countries\n-from phonenumber_field.phonenumber import PhoneNumber\n-from phonenumbers import NumberParseException\n-from phonenumbers.phonenumberutil import is_possible_number\n \n from .models import Address\n+from .validators import validate_possible_number\n from .widgets import DatalistTextWidget, PhonePrefixWidget\n \n COUNTRY_FORMS = {}\n@@ -145,26 +143,12 @@\n         country = data.get(\"country\")\n         if phone:\n             try:\n-                data[\"phone\"] = clean_phone_for_country(phone, country)\n+                data[\"phone\"] = validate_possible_number(phone, country)\n             except forms.ValidationError as error:\n                 self.add_error(\"phone\", error)\n         return data\n \n \n-def clean_phone_for_country(phone, country):\n-    error = _(\"The phone number entered is not valid.\")\n-    error_code = \"invalid_phone_number\"\n-    if phone:\n-        try:\n-            phone = PhoneNumber.from_string(phone, country)\n-        except NumberParseException:\n-            raise forms.ValidationError(error, code=error_code)\n-        else:\n-            if not is_possible_number(phone):\n-                raise forms.ValidationError(error, code=error_code)\n-    return phone\n-\n-\n class CountryAwareAddressForm(AddressForm):\n \n     I18N_MAPPING = [\ndiff --git a/saleor/account/validators.py b/saleor/account/validators.py\n--- a/saleor/account/validators.py\n+++ b/saleor/account/validators.py\n@@ -4,9 +4,14 @@\n from phonenumbers.phonenumberutil import is_possible_number\n \n \n-def validate_possible_number(value, country=None):\n-    phone_number = to_python(value, country)\n-    if phone_number and not is_possible_number(phone_number):\n+def validate_possible_number(phone, country=None):\n+    phone_number = to_python(phone, country)\n+    if (\n+        phone_number\n+        and not is_possible_number(phone_number)\n+        or not phone_number.is_valid()\n+    ):\n         raise ValidationError(\n             _(\"The phone number entered is not valid.\"), code=\"invalid_phone_number\"\n         )\n+    return phone_number\n", "issue": "Some invalid phone numbers throw an exception and result in server error\n### What I'm trying to achieve\r\nType in a fake number +1 123 456 7890, into the shipping form. Should fail gracefully with a red input box\r\n\r\n### Steps to reproduce the problem\r\n1. Type in a fake number +1 123 456 7890, into the shipping form\r\n2. Receive ValueError at /en/checkout/shipping-address/ \u201c+11234567890\u201d is not a valid phone number.\r\n\r\n### What I expected to happen\r\nShould fail gracefully with a red input box\r\n\r\n### What happens\r\n500 Internal server error\r\n\r\n**System information**\r\nOperating system: Ubuntu 18.04\r\nBrowser: Firefox\r\n\n", "before_files": [{"content": "from django.core.exceptions import ValidationError\nfrom django.utils.translation import ugettext_lazy as _\nfrom phonenumber_field.phonenumber import to_python\nfrom phonenumbers.phonenumberutil import is_possible_number\n\n\ndef validate_possible_number(value, country=None):\n    phone_number = to_python(value, country)\n    if phone_number and not is_possible_number(phone_number):\n        raise ValidationError(\n            _(\"The phone number entered is not valid.\"), code=\"invalid_phone_number\"\n        )\n", "path": "saleor/account/validators.py"}, {"content": "from collections import defaultdict\n\nimport i18naddress\nfrom django import forms\nfrom django.forms.forms import BoundField\nfrom django.utils.translation import pgettext_lazy, ugettext_lazy as _\nfrom django_countries import countries\nfrom phonenumber_field.phonenumber import PhoneNumber\nfrom phonenumbers import NumberParseException\nfrom phonenumbers.phonenumberutil import is_possible_number\n\nfrom .models import Address\nfrom .widgets import DatalistTextWidget, PhonePrefixWidget\n\nCOUNTRY_FORMS = {}\nUNKNOWN_COUNTRIES = set()\n\nAREA_TYPE_TRANSLATIONS = {\n    \"area\": pgettext_lazy(\"Address field\", \"Area\"),\n    \"county\": pgettext_lazy(\"Address field\", \"County\"),\n    \"department\": pgettext_lazy(\"Address field\", \"Department\"),\n    \"district\": pgettext_lazy(\"Address field\", \"District\"),\n    \"do_si\": pgettext_lazy(\"Address field\", \"Do/si\"),\n    \"eircode\": pgettext_lazy(\"Address field\", \"Eircode\"),\n    \"emirate\": pgettext_lazy(\"Address field\", \"Emirate\"),\n    \"island\": pgettext_lazy(\"Address field\", \"Island\"),\n    \"neighborhood\": pgettext_lazy(\"Address field\", \"Neighborhood\"),\n    \"oblast\": pgettext_lazy(\"Address field\", \"Oblast\"),\n    \"parish\": pgettext_lazy(\"Address field\", \"Parish\"),\n    \"pin\": pgettext_lazy(\"Address field\", \"PIN\"),\n    \"postal\": pgettext_lazy(\"Address field\", \"Postal code\"),\n    \"prefecture\": pgettext_lazy(\"Address field\", \"Prefecture\"),\n    \"province\": pgettext_lazy(\"Address field\", \"Province\"),\n    \"state\": pgettext_lazy(\"Address field\", \"State\"),\n    \"suburb\": pgettext_lazy(\"Address field\", \"Suburb\"),\n    \"townland\": pgettext_lazy(\"Address field\", \"Townland\"),\n    \"village_township\": pgettext_lazy(\"Address field\", \"Village/township\"),\n    \"zip\": pgettext_lazy(\"Address field\", \"ZIP code\"),\n}\n\n\nclass PossiblePhoneNumberFormField(forms.CharField):\n    \"\"\"A phone input field.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.widget.input_type = \"tel\"\n\n\nclass CountryAreaChoiceField(forms.ChoiceField):\n    widget = DatalistTextWidget\n\n    def valid_value(self, value):\n        return True\n\n\nclass AddressMetaForm(forms.ModelForm):\n    # This field is never visible in UI\n    preview = forms.BooleanField(initial=False, required=False)\n\n    class Meta:\n        model = Address\n        fields = [\"country\", \"preview\"]\n        labels = {\"country\": pgettext_lazy(\"Country\", \"Country\")}\n\n    def clean(self):\n        data = super().clean()\n        if data.get(\"preview\"):\n            self.data = self.data.copy()\n            self.data[\"preview\"] = False\n        return data\n\n\nclass AddressForm(forms.ModelForm):\n\n    AUTOCOMPLETE_MAPPING = [\n        (\"first_name\", \"given-name\"),\n        (\"last_name\", \"family-name\"),\n        (\"company_name\", \"organization\"),\n        (\"street_address_1\", \"address-line1\"),\n        (\"street_address_2\", \"address-line2\"),\n        (\"city\", \"address-level2\"),\n        (\"postal_code\", \"postal-code\"),\n        (\"country_area\", \"address-level1\"),\n        (\"country\", \"country\"),\n        (\"city_area\", \"address-level3\"),\n        (\"phone\", \"tel\"),\n        (\"email\", \"email\"),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n        labels = {\n            \"first_name\": pgettext_lazy(\"Personal name\", \"Given name\"),\n            \"last_name\": pgettext_lazy(\"Personal name\", \"Family name\"),\n            \"company_name\": pgettext_lazy(\n                \"Company or organization\", \"Company or organization\"\n            ),\n            \"street_address_1\": pgettext_lazy(\"Address\", \"Address\"),\n            \"street_address_2\": \"\",\n            \"city\": pgettext_lazy(\"City\", \"City\"),\n            \"city_area\": pgettext_lazy(\"City area\", \"District\"),\n            \"postal_code\": pgettext_lazy(\"Postal code\", \"Postal code\"),\n            \"country\": pgettext_lazy(\"Country\", \"Country\"),\n            \"country_area\": pgettext_lazy(\"Country area\", \"State or province\"),\n            \"phone\": pgettext_lazy(\"Phone number\", \"Phone number\"),\n        }\n        placeholders = {\n            \"street_address_1\": pgettext_lazy(\n                \"Address\", \"Street address, P.O. box, company name\"\n            ),\n            \"street_address_2\": pgettext_lazy(\n                \"Address\", \"Apartment, suite, unit, building, floor, etc\"\n            ),\n        }\n\n    phone = PossiblePhoneNumberFormField(widget=PhonePrefixWidget, required=False)\n\n    def __init__(self, *args, **kwargs):\n        autocomplete_type = kwargs.pop(\"autocomplete_type\", None)\n        super().__init__(*args, **kwargs)\n        # countries order was taken as defined in the model,\n        # not being sorted accordingly to the selected language\n        self.fields[\"country\"].choices = sorted(\n            COUNTRY_CHOICES, key=lambda choice: choice[1]\n        )\n        autocomplete_dict = defaultdict(lambda: \"off\", self.AUTOCOMPLETE_MAPPING)\n        for field_name, field in self.fields.items():\n            if autocomplete_type:\n                autocomplete = \"%s %s\" % (\n                    autocomplete_type,\n                    autocomplete_dict[field_name],\n                )\n            else:\n                autocomplete = autocomplete_dict[field_name]\n            field.widget.attrs[\"autocomplete\"] = autocomplete\n            field.widget.attrs[\"placeholder\"] = (\n                field.label if not hasattr(field, \"placeholder\") else field.placeholder\n            )\n\n    def clean(self):\n        data = super().clean()\n        phone = data.get(\"phone\")\n        country = data.get(\"country\")\n        if phone:\n            try:\n                data[\"phone\"] = clean_phone_for_country(phone, country)\n            except forms.ValidationError as error:\n                self.add_error(\"phone\", error)\n        return data\n\n\ndef clean_phone_for_country(phone, country):\n    error = _(\"The phone number entered is not valid.\")\n    error_code = \"invalid_phone_number\"\n    if phone:\n        try:\n            phone = PhoneNumber.from_string(phone, country)\n        except NumberParseException:\n            raise forms.ValidationError(error, code=error_code)\n        else:\n            if not is_possible_number(phone):\n                raise forms.ValidationError(error, code=error_code)\n    return phone\n\n\nclass CountryAwareAddressForm(AddressForm):\n\n    I18N_MAPPING = [\n        (\"name\", [\"first_name\", \"last_name\"]),\n        (\"street_address\", [\"street_address_1\", \"street_address_2\"]),\n        (\"city_area\", [\"city_area\"]),\n        (\"country_area\", [\"country_area\"]),\n        (\"company_name\", [\"company_name\"]),\n        (\"postal_code\", [\"postal_code\"]),\n        (\"city\", [\"city\"]),\n        (\"sorting_code\", []),\n        (\"country_code\", [\"country\"]),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n\n    def add_field_errors(self, errors):\n        field_mapping = dict(self.I18N_MAPPING)\n        for field_name, error_code in errors.items():\n            local_fields = field_mapping[field_name]\n            for field in local_fields:\n                try:\n                    error_msg = self.fields[field].error_messages[error_code]\n                except KeyError:\n                    error_msg = pgettext_lazy(\n                        \"Address form\", \"This value is invalid for selected country\"\n                    )\n                self.add_error(field, error_msg)\n\n    def validate_address(self, data):\n        try:\n            data[\"country_code\"] = data.get(\"country\", \"\")\n            if data[\"street_address_1\"] or data[\"street_address_2\"]:\n                data[\"street_address\"] = \"%s\\n%s\" % (\n                    data[\"street_address_1\"],\n                    data[\"street_address_2\"],\n                )\n            data = i18naddress.normalize_address(data)\n            del data[\"sorting_code\"]\n        except i18naddress.InvalidAddress as exc:\n            self.add_field_errors(exc.errors)\n        return data\n\n    def clean(self):\n        data = super().clean()\n        return self.validate_address(data)\n\n\ndef get_address_form_class(country_code):\n    return COUNTRY_FORMS[country_code]\n\n\ndef get_form_i18n_lines(form_instance):\n    country_code = form_instance.i18n_country_code\n    try:\n        fields_order = i18naddress.get_field_order({\"country_code\": country_code})\n    except ValueError:\n        fields_order = i18naddress.get_field_order({})\n    field_mapping = dict(form_instance.I18N_MAPPING)\n\n    def _convert_to_bound_fields(form, i18n_field_names):\n        bound_fields = []\n        for field_name in i18n_field_names:\n            local_fields = field_mapping[field_name]\n            for local_name in local_fields:\n                local_field = form_instance.fields[local_name]\n                bound_field = BoundField(form, local_field, local_name)\n                bound_fields.append(bound_field)\n        return bound_fields\n\n    if fields_order:\n        return [_convert_to_bound_fields(form_instance, line) for line in fields_order]\n\n\ndef update_base_fields(form_class, i18n_rules):\n    for field_name, label_value in AddressForm.Meta.labels.items():\n        field = form_class.base_fields[field_name]\n        field.label = label_value\n\n    for field_name, placeholder_value in AddressForm.Meta.placeholders.items():\n        field = form_class.base_fields[field_name]\n        field.placeholder = placeholder_value\n\n    if i18n_rules.country_area_choices:\n        form_class.base_fields[\"country_area\"] = CountryAreaChoiceField(\n            choices=i18n_rules.country_area_choices\n        )\n\n    labels_map = {\n        \"country_area\": i18n_rules.country_area_type,\n        \"postal_code\": i18n_rules.postal_code_type,\n        \"city_area\": i18n_rules.city_area_type,\n    }\n\n    for field_name, area_type in labels_map.items():\n        field = form_class.base_fields[field_name]\n        field.label = AREA_TYPE_TRANSLATIONS[area_type]\n\n    hidden_fields = i18naddress.KNOWN_FIELDS - i18n_rules.allowed_fields\n    for field_name in hidden_fields:\n        if field_name in form_class.base_fields:\n            form_class.base_fields[field_name].widget = forms.HiddenInput()\n\n    country_field = form_class.base_fields[\"country\"]\n    country_field.choices = COUNTRY_CHOICES\n\n\ndef construct_address_form(country_code, i18n_rules):\n    class_name = \"AddressForm%s\" % country_code\n    base_class = CountryAwareAddressForm\n    form_kwargs = {\n        \"Meta\": type(str(\"Meta\"), (base_class.Meta, object), {}),\n        \"formfield_callback\": None,\n    }\n    class_ = type(base_class)(str(class_name), (base_class,), form_kwargs)\n    update_base_fields(class_, i18n_rules)\n    class_.i18n_country_code = country_code\n    class_.i18n_fields_order = property(get_form_i18n_lines)\n    return class_\n\n\nfor country in countries.countries.keys():\n    try:\n        country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    except ValueError:\n        country_rules = i18naddress.get_validation_rules({})\n        UNKNOWN_COUNTRIES.add(country)\n\nCOUNTRY_CHOICES = [\n    (code, label)\n    for code, label in countries.countries.items()\n    if code not in UNKNOWN_COUNTRIES\n]\n# Sort choices list by country name\nCOUNTRY_CHOICES = sorted(COUNTRY_CHOICES, key=lambda choice: choice[1])\n\nfor country, label in COUNTRY_CHOICES:\n    country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    COUNTRY_FORMS[country] = construct_address_form(country, country_rules)\n", "path": "saleor/account/i18n.py"}], "after_files": [{"content": "from django.core.exceptions import ValidationError\nfrom django.utils.translation import ugettext_lazy as _\nfrom phonenumber_field.phonenumber import to_python\nfrom phonenumbers.phonenumberutil import is_possible_number\n\n\ndef validate_possible_number(phone, country=None):\n    phone_number = to_python(phone, country)\n    if (\n        phone_number\n        and not is_possible_number(phone_number)\n        or not phone_number.is_valid()\n    ):\n        raise ValidationError(\n            _(\"The phone number entered is not valid.\"), code=\"invalid_phone_number\"\n        )\n    return phone_number\n", "path": "saleor/account/validators.py"}, {"content": "from collections import defaultdict\n\nimport i18naddress\nfrom django import forms\nfrom django.forms.forms import BoundField\nfrom django.utils.translation import pgettext_lazy\nfrom django_countries import countries\n\nfrom .models import Address\nfrom .validators import validate_possible_number\nfrom .widgets import DatalistTextWidget, PhonePrefixWidget\n\nCOUNTRY_FORMS = {}\nUNKNOWN_COUNTRIES = set()\n\nAREA_TYPE_TRANSLATIONS = {\n    \"area\": pgettext_lazy(\"Address field\", \"Area\"),\n    \"county\": pgettext_lazy(\"Address field\", \"County\"),\n    \"department\": pgettext_lazy(\"Address field\", \"Department\"),\n    \"district\": pgettext_lazy(\"Address field\", \"District\"),\n    \"do_si\": pgettext_lazy(\"Address field\", \"Do/si\"),\n    \"eircode\": pgettext_lazy(\"Address field\", \"Eircode\"),\n    \"emirate\": pgettext_lazy(\"Address field\", \"Emirate\"),\n    \"island\": pgettext_lazy(\"Address field\", \"Island\"),\n    \"neighborhood\": pgettext_lazy(\"Address field\", \"Neighborhood\"),\n    \"oblast\": pgettext_lazy(\"Address field\", \"Oblast\"),\n    \"parish\": pgettext_lazy(\"Address field\", \"Parish\"),\n    \"pin\": pgettext_lazy(\"Address field\", \"PIN\"),\n    \"postal\": pgettext_lazy(\"Address field\", \"Postal code\"),\n    \"prefecture\": pgettext_lazy(\"Address field\", \"Prefecture\"),\n    \"province\": pgettext_lazy(\"Address field\", \"Province\"),\n    \"state\": pgettext_lazy(\"Address field\", \"State\"),\n    \"suburb\": pgettext_lazy(\"Address field\", \"Suburb\"),\n    \"townland\": pgettext_lazy(\"Address field\", \"Townland\"),\n    \"village_township\": pgettext_lazy(\"Address field\", \"Village/township\"),\n    \"zip\": pgettext_lazy(\"Address field\", \"ZIP code\"),\n}\n\n\nclass PossiblePhoneNumberFormField(forms.CharField):\n    \"\"\"A phone input field.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.widget.input_type = \"tel\"\n\n\nclass CountryAreaChoiceField(forms.ChoiceField):\n    widget = DatalistTextWidget\n\n    def valid_value(self, value):\n        return True\n\n\nclass AddressMetaForm(forms.ModelForm):\n    # This field is never visible in UI\n    preview = forms.BooleanField(initial=False, required=False)\n\n    class Meta:\n        model = Address\n        fields = [\"country\", \"preview\"]\n        labels = {\"country\": pgettext_lazy(\"Country\", \"Country\")}\n\n    def clean(self):\n        data = super().clean()\n        if data.get(\"preview\"):\n            self.data = self.data.copy()\n            self.data[\"preview\"] = False\n        return data\n\n\nclass AddressForm(forms.ModelForm):\n\n    AUTOCOMPLETE_MAPPING = [\n        (\"first_name\", \"given-name\"),\n        (\"last_name\", \"family-name\"),\n        (\"company_name\", \"organization\"),\n        (\"street_address_1\", \"address-line1\"),\n        (\"street_address_2\", \"address-line2\"),\n        (\"city\", \"address-level2\"),\n        (\"postal_code\", \"postal-code\"),\n        (\"country_area\", \"address-level1\"),\n        (\"country\", \"country\"),\n        (\"city_area\", \"address-level3\"),\n        (\"phone\", \"tel\"),\n        (\"email\", \"email\"),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n        labels = {\n            \"first_name\": pgettext_lazy(\"Personal name\", \"Given name\"),\n            \"last_name\": pgettext_lazy(\"Personal name\", \"Family name\"),\n            \"company_name\": pgettext_lazy(\n                \"Company or organization\", \"Company or organization\"\n            ),\n            \"street_address_1\": pgettext_lazy(\"Address\", \"Address\"),\n            \"street_address_2\": \"\",\n            \"city\": pgettext_lazy(\"City\", \"City\"),\n            \"city_area\": pgettext_lazy(\"City area\", \"District\"),\n            \"postal_code\": pgettext_lazy(\"Postal code\", \"Postal code\"),\n            \"country\": pgettext_lazy(\"Country\", \"Country\"),\n            \"country_area\": pgettext_lazy(\"Country area\", \"State or province\"),\n            \"phone\": pgettext_lazy(\"Phone number\", \"Phone number\"),\n        }\n        placeholders = {\n            \"street_address_1\": pgettext_lazy(\n                \"Address\", \"Street address, P.O. box, company name\"\n            ),\n            \"street_address_2\": pgettext_lazy(\n                \"Address\", \"Apartment, suite, unit, building, floor, etc\"\n            ),\n        }\n\n    phone = PossiblePhoneNumberFormField(widget=PhonePrefixWidget, required=False)\n\n    def __init__(self, *args, **kwargs):\n        autocomplete_type = kwargs.pop(\"autocomplete_type\", None)\n        super().__init__(*args, **kwargs)\n        # countries order was taken as defined in the model,\n        # not being sorted accordingly to the selected language\n        self.fields[\"country\"].choices = sorted(\n            COUNTRY_CHOICES, key=lambda choice: choice[1]\n        )\n        autocomplete_dict = defaultdict(lambda: \"off\", self.AUTOCOMPLETE_MAPPING)\n        for field_name, field in self.fields.items():\n            if autocomplete_type:\n                autocomplete = \"%s %s\" % (\n                    autocomplete_type,\n                    autocomplete_dict[field_name],\n                )\n            else:\n                autocomplete = autocomplete_dict[field_name]\n            field.widget.attrs[\"autocomplete\"] = autocomplete\n            field.widget.attrs[\"placeholder\"] = (\n                field.label if not hasattr(field, \"placeholder\") else field.placeholder\n            )\n\n    def clean(self):\n        data = super().clean()\n        phone = data.get(\"phone\")\n        country = data.get(\"country\")\n        if phone:\n            try:\n                data[\"phone\"] = validate_possible_number(phone, country)\n            except forms.ValidationError as error:\n                self.add_error(\"phone\", error)\n        return data\n\n\nclass CountryAwareAddressForm(AddressForm):\n\n    I18N_MAPPING = [\n        (\"name\", [\"first_name\", \"last_name\"]),\n        (\"street_address\", [\"street_address_1\", \"street_address_2\"]),\n        (\"city_area\", [\"city_area\"]),\n        (\"country_area\", [\"country_area\"]),\n        (\"company_name\", [\"company_name\"]),\n        (\"postal_code\", [\"postal_code\"]),\n        (\"city\", [\"city\"]),\n        (\"sorting_code\", []),\n        (\"country_code\", [\"country\"]),\n    ]\n\n    class Meta:\n        model = Address\n        exclude = []\n\n    def add_field_errors(self, errors):\n        field_mapping = dict(self.I18N_MAPPING)\n        for field_name, error_code in errors.items():\n            local_fields = field_mapping[field_name]\n            for field in local_fields:\n                try:\n                    error_msg = self.fields[field].error_messages[error_code]\n                except KeyError:\n                    error_msg = pgettext_lazy(\n                        \"Address form\", \"This value is invalid for selected country\"\n                    )\n                self.add_error(field, error_msg)\n\n    def validate_address(self, data):\n        try:\n            data[\"country_code\"] = data.get(\"country\", \"\")\n            if data[\"street_address_1\"] or data[\"street_address_2\"]:\n                data[\"street_address\"] = \"%s\\n%s\" % (\n                    data[\"street_address_1\"],\n                    data[\"street_address_2\"],\n                )\n            data = i18naddress.normalize_address(data)\n            del data[\"sorting_code\"]\n        except i18naddress.InvalidAddress as exc:\n            self.add_field_errors(exc.errors)\n        return data\n\n    def clean(self):\n        data = super().clean()\n        return self.validate_address(data)\n\n\ndef get_address_form_class(country_code):\n    return COUNTRY_FORMS[country_code]\n\n\ndef get_form_i18n_lines(form_instance):\n    country_code = form_instance.i18n_country_code\n    try:\n        fields_order = i18naddress.get_field_order({\"country_code\": country_code})\n    except ValueError:\n        fields_order = i18naddress.get_field_order({})\n    field_mapping = dict(form_instance.I18N_MAPPING)\n\n    def _convert_to_bound_fields(form, i18n_field_names):\n        bound_fields = []\n        for field_name in i18n_field_names:\n            local_fields = field_mapping[field_name]\n            for local_name in local_fields:\n                local_field = form_instance.fields[local_name]\n                bound_field = BoundField(form, local_field, local_name)\n                bound_fields.append(bound_field)\n        return bound_fields\n\n    if fields_order:\n        return [_convert_to_bound_fields(form_instance, line) for line in fields_order]\n\n\ndef update_base_fields(form_class, i18n_rules):\n    for field_name, label_value in AddressForm.Meta.labels.items():\n        field = form_class.base_fields[field_name]\n        field.label = label_value\n\n    for field_name, placeholder_value in AddressForm.Meta.placeholders.items():\n        field = form_class.base_fields[field_name]\n        field.placeholder = placeholder_value\n\n    if i18n_rules.country_area_choices:\n        form_class.base_fields[\"country_area\"] = CountryAreaChoiceField(\n            choices=i18n_rules.country_area_choices\n        )\n\n    labels_map = {\n        \"country_area\": i18n_rules.country_area_type,\n        \"postal_code\": i18n_rules.postal_code_type,\n        \"city_area\": i18n_rules.city_area_type,\n    }\n\n    for field_name, area_type in labels_map.items():\n        field = form_class.base_fields[field_name]\n        field.label = AREA_TYPE_TRANSLATIONS[area_type]\n\n    hidden_fields = i18naddress.KNOWN_FIELDS - i18n_rules.allowed_fields\n    for field_name in hidden_fields:\n        if field_name in form_class.base_fields:\n            form_class.base_fields[field_name].widget = forms.HiddenInput()\n\n    country_field = form_class.base_fields[\"country\"]\n    country_field.choices = COUNTRY_CHOICES\n\n\ndef construct_address_form(country_code, i18n_rules):\n    class_name = \"AddressForm%s\" % country_code\n    base_class = CountryAwareAddressForm\n    form_kwargs = {\n        \"Meta\": type(str(\"Meta\"), (base_class.Meta, object), {}),\n        \"formfield_callback\": None,\n    }\n    class_ = type(base_class)(str(class_name), (base_class,), form_kwargs)\n    update_base_fields(class_, i18n_rules)\n    class_.i18n_country_code = country_code\n    class_.i18n_fields_order = property(get_form_i18n_lines)\n    return class_\n\n\nfor country in countries.countries.keys():\n    try:\n        country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    except ValueError:\n        country_rules = i18naddress.get_validation_rules({})\n        UNKNOWN_COUNTRIES.add(country)\n\nCOUNTRY_CHOICES = [\n    (code, label)\n    for code, label in countries.countries.items()\n    if code not in UNKNOWN_COUNTRIES\n]\n# Sort choices list by country name\nCOUNTRY_CHOICES = sorted(COUNTRY_CHOICES, key=lambda choice: choice[1])\n\nfor country, label in COUNTRY_CHOICES:\n    country_rules = i18naddress.get_validation_rules({\"country_code\": country})\n    COUNTRY_FORMS[country] = construct_address_form(country, country_rules)\n", "path": "saleor/account/i18n.py"}]}