diff --git a/graphene_django/converter.py b/graphene_django/converter.py index 4d0b45f95..191a2c3d4 100644 --- a/graphene_django/converter.py +++ b/graphene_django/converter.py @@ -28,8 +28,31 @@ singledispatch = import_single_dispatch() +def _is_dunder(name): + """Returns True if a __dunder__ name, False otherwise.""" + return ( + len(name) > 4 + and name[:2] == name[-2:] == "__" + and name[2:3] != "_" + and name[-3:-2] != "_" + ) + + +def _is_sunder(name): + """Returns True if a _sunder_ name, False otherwise.""" + return ( + len(name) > 2 + and name[0] == name[-1] == "_" + and name[1:2] != "_" + and name[-2:-1] != "_" + ) + + def convert_choice_name(name): - name = to_const(force_text(name)) + name = force_text(name).encode("utf8").decode("ascii", "ignore") + name = to_const(name) + if _is_sunder(name) or _is_dunder(name): + name = "A%s" % name try: assert_valid_name(name) except AssertionError: diff --git a/graphene_django/tests/models.py b/graphene_django/tests/models.py index b4eb3ce8a..f7a4cf0f3 100644 --- a/graphene_django/tests/models.py +++ b/graphene_django/tests/models.py @@ -1,9 +1,16 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import from django.db import models from django.utils.translation import ugettext_lazy as _ -CHOICES = ((1, "this"), (2, _("that"))) +CHOICES = ( + (1, u"this"), + ("2", _(u"that")), + (u"_3漢", "nonascii"), + ("__dunder__", "dunder"), + ("_sunder_", "sunder"), +) class Pet(models.Model): diff --git a/graphene_django/tests/test_converter.py b/graphene_django/tests/test_converter.py index 5542c90a7..9ea8dc919 100644 --- a/graphene_django/tests/test_converter.py +++ b/graphene_django/tests/test_converter.py @@ -196,6 +196,27 @@ class Meta: convert_django_field_with_choices(field) +def test_field_with_choices_underscore(): + field = models.CharField( + choices=( + ("_amount_", "Amount"), + ("__percentage__", "Percentage"), + ("_not_sunder__", "Not Single Underscore"), + ("__not_dunder", "Not Double Underscore"), + ) + ) + + class UnderscoreChoicesModel(models.Model): + ourfield = field + + graphene_type = convert_django_field_with_choices(field) + assert len(graphene_type._meta.enum.__members__) == 4 + assert "A_AMOUNT_" in graphene_type._meta.enum.__members__ + assert "A__PERCENTAGE__" in graphene_type._meta.enum.__members__ + assert "_NOT_SUNDER__" in graphene_type._meta.enum.__members__ + assert "__NOT_DUNDER" in graphene_type._meta.enum.__members__ + + def test_field_with_choices_convert_enum_false(): field = models.CharField( help_text="Language", choices=(("es", "Spanish"), ("en", "English")) diff --git a/graphene_django/tests/test_types.py b/graphene_django/tests/test_types.py index c1ac6c2bc..3dd0c618b 100644 --- a/graphene_django/tests/test_types.py +++ b/graphene_django/tests/test_types.py @@ -179,6 +179,9 @@ def test_schema_representation(): enum ReporterAChoice { A_1 A_2 + _3 + A__DUNDER__ + A_SUNDER_ } enum ReporterReporterType {