Change code with black

This commit is contained in:
ariel1899 2020-04-16 17:03:33 -04:00
parent 96361fc6e7
commit a644d03c5e
9 changed files with 169 additions and 79 deletions

View File

@ -205,7 +205,9 @@ class DjangoConnectionField(ConnectionField):
class DjangoField(Field):
"""Class to manage permission for fields"""
def __init__(self, type, permissions=(), permissions_resolver=auth_resolver, *args, **kwargs):
def __init__(
self, type, permissions=(), permissions_resolver=auth_resolver, *args, **kwargs
):
"""Get permissions to access a field"""
super(DjangoField, self).__init__(type, *args, **kwargs)
self.permissions = permissions
@ -215,15 +217,23 @@ class DjangoField(Field):
"""Intercept resolver to analyse permissions"""
parent_resolver = super(DjangoField, self).get_resolver(parent_resolver)
if self.permissions:
return partial(get_unbound_function(self.permissions_resolver), parent_resolver, self.permissions, None,
None, True)
return partial(
get_unbound_function(self.permissions_resolver),
parent_resolver,
self.permissions,
None,
None,
True,
)
return parent_resolver
class DataLoaderField(DjangoField):
"""Class to manage access to data-loader when resolve the field"""
def __init__(self, type, data_loader, source_loader, load_many=False, *args, **kwargs):
def __init__(
self, type, data_loader, source_loader, load_many=False, *args, **kwargs
):
"""
Initialization of data-loader to resolve field
:param data_loader: data-loader to resolve field
@ -243,7 +253,9 @@ class DataLoaderField(DjangoField):
def resolver_data_loader(self, root, info, *args, **kwargs):
"""Resolve field through dataloader"""
if root:
source_loader = reduce(lambda x, y: getattr(x, y), self.source_loader.split('.'), root)
source_loader = reduce(
lambda x, y: getattr(x, y), self.source_loader.split("."), root
)
else:
source_loader = kwargs.get(self.source_loader)

View File

@ -1,7 +1,19 @@
from django import forms
from django.core.exceptions import ImproperlyConfigured
from graphene import ID, Boolean, Float, Int, List, String, UUID, Date, DateTime, Time, Enum
from graphene import (
ID,
Boolean,
Float,
Int,
List,
String,
UUID,
Date,
DateTime,
Time,
Enum,
)
from graphene.utils.str_converters import to_camel_case
from graphene_django.converter import get_choices
@ -87,7 +99,7 @@ def convert_form_field_to_id(field):
def get_form_name(form):
"""Get form name"""
class_name = str(form.__class__).split('.')[-1]
class_name = str(form.__class__).split(".")[-1]
return class_name[:-2]
@ -99,15 +111,20 @@ def convert_form_field_with_choices(field, name=None, form=None):
:param form: field's form
:return: graphene Field
"""
choices = getattr(field, 'choices', None)
choices = getattr(field, "choices", None)
# If is a choice field, but not depends on models
if not isinstance(field, (forms.ModelMultipleChoiceField, forms.ModelChoiceField)) and choices:
if (
not isinstance(field, (forms.ModelMultipleChoiceField, forms.ModelChoiceField))
and choices
):
if form:
name = to_camel_case("{}_{}".format(get_form_name(form), field.label or name))
name = to_camel_case(
"{}_{}".format(get_form_name(form), field.label or name)
)
else:
name = field.label or name
name = to_camel_case(name.replace(' ', '_'))
name = to_camel_case(name.replace(" ", "_"))
choices = list(get_choices(choices))
named_choices = [(c[0], c[1]) for c in choices]
named_choices_descriptions = {c[0]: c[2] for c in choices}
@ -122,5 +139,7 @@ def convert_form_field_with_choices(field, name=None, form=None):
return named_choices_descriptions[self.name]
enum = Enum(name, list(named_choices), type=EnumWithDescriptionsType)
return enum(description=field.help_text, required=field.required) # pylint: disable=E1102
return enum(
description=field.help_text, required=field.required
) # pylint: disable=E1102
return convert_form_field(field)

View File

@ -22,8 +22,8 @@ def fields_for_form(form, only_fields, exclude_fields):
for name, field in form.fields.items():
is_not_in_only = only_fields and name not in only_fields
is_excluded = (
name
in exclude_fields # or
name
in exclude_fields # or
# name in already_created_fields
)
@ -46,7 +46,10 @@ class BaseDjangoFormMutation(ClientIDMutation):
return cls.perform_mutate(form, info)
else:
errors = [
ErrorType(field=to_camel_case(key) if key != '__all__' else key, messages=value)
ErrorType(
field=to_camel_case(key) if key != "__all__" else key,
messages=value,
)
for key, value in form.errors.items()
]
@ -81,7 +84,12 @@ class DjangoFormMutation(BaseDjangoFormMutation):
@classmethod
def __init_subclass_with_meta__(
cls, form_class=None, mirror_input=False, only_fields=(), exclude_fields=(), **options
cls,
form_class=None,
mirror_input=False,
only_fields=(),
exclude_fields=(),
**options
):
if not form_class:
@ -122,13 +130,13 @@ class DjangoModelFormMutation(BaseDjangoFormMutation):
@classmethod
def __init_subclass_with_meta__(
cls,
form_class=None,
model=None,
return_field_name=None,
only_fields=(),
exclude_fields=(),
**options
cls,
form_class=None,
model=None,
return_field_name=None,
only_fields=(),
exclude_fields=(),
**options
):
if not form_class:

View File

@ -115,6 +115,8 @@ def test_should_manytoone_convert_connectionorlist():
def test_should_typed_choice_convert_enum():
field = forms.TypedChoiceField(choices=(('A', 'Choice A'), ('B', 'Choice B')), label='field')
graphene_type = convert_form_field_with_choices(field, name='field_name')
field = forms.TypedChoiceField(
choices=(("A", "Choice A"), ("B", "Choice B")), label="field"
)
graphene_type = convert_form_field_with_choices(field, name="field_name")
assert isinstance(graphene_type, Enum)

View File

@ -52,6 +52,7 @@ class FilmType(DjangoObjectType):
def test_needs_form_class():
with raises(Exception) as exc:
class MyMutation(DjangoFormMutation):
pass
@ -180,7 +181,7 @@ class FormMutationTests(TestCase):
class MyMutation(DjangoFormMutation):
class Meta:
form_class = MyForm
exclude_fields = ['text']
exclude_fields = ["text"]
self.assertNotIn("text", MyMutation.Input._meta.fields)
self.assertIn("client_mutation_id", MyMutation.Input._meta.fields)
@ -331,7 +332,7 @@ class ModelFormMutationTests(TestCase):
self.assertEqual(result.data["petMutation"]["pet"], None)
self.assertEqual(
result.data["petMutation"]["errors"],
[{"field": "age", "messages": ["Too old"], }],
[{"field": "age", "messages": ["Too old"],}],
)
self.assertEqual(Pet.objects.count(), 0)
@ -341,7 +342,7 @@ class ModelFormMutationTests(TestCase):
class Meta:
form_class = PetForm
result = PetMutation.mutate_and_get_payload(None, None, test_camel='text')
result = PetMutation.mutate_and_get_payload(None, None, test_camel="text")
# A pet was not created
self.assertEqual(Pet.objects.count(), 0)
@ -349,8 +350,8 @@ class ModelFormMutationTests(TestCase):
fields_w_error = {e.field: e.messages for e in result.errors}
self.assertEqual(len(result.errors), 3)
self.assertIn("test_camel", fields_w_error)
self.assertEqual(fields_w_error['test_camel'], ["Enter a whole number."])
self.assertEqual(fields_w_error["test_camel"], ["Enter a whole number."])
self.assertIn("name", fields_w_error)
self.assertEqual(fields_w_error['name'], ["This field is required."])
self.assertEqual(fields_w_error["name"], ["This field is required."])
self.assertIn("age", fields_w_error)
self.assertEqual(fields_w_error['age'], ["This field is required."])
self.assertEqual(fields_w_error["age"], ["This field is required."])

View File

@ -231,15 +231,14 @@ data_loader = DataLoader(batch_load_fn=batch_load_fn)
class PermissionFieldTests(TestCase):
def test_permission_field(self):
MyType = object()
field = DjangoField(MyType, permissions=['perm1', 'perm2'], source='resolver')
field = DjangoField(MyType, permissions=["perm1", "perm2"], source="resolver")
resolver = field.get_resolver(None)
class Viewer(object):
def has_perm(self, perm):
return perm == 'perm2'
return perm == "perm2"
info = mock.Mock(context=mock.Mock(user=Viewer()))
@ -247,7 +246,7 @@ class PermissionFieldTests(TestCase):
def test_permission_field_without_permission(self):
MyType = object()
field = DjangoField(MyType, permissions=['perm1', 'perm2'], source='resolver')
field = DjangoField(MyType, permissions=["perm1", "perm2"], source="resolver")
resolver = field.get_resolver(field.resolver)
class Viewer(object):
@ -261,10 +260,11 @@ class PermissionFieldTests(TestCase):
class DataLoaderFieldTests(TestCase):
def test_dataloaderfield(self):
MyType = object()
data_loader_field = DataLoaderField(data_loader=data_loader, source_loader='key', type=MyType)
data_loader_field = DataLoaderField(
data_loader=data_loader, source_loader="key", type=MyType
)
resolver = data_loader_field.get_resolver(None)
instance = MyInstance()
@ -273,7 +273,9 @@ class DataLoaderFieldTests(TestCase):
def test_dataloaderfield_many(self):
MyType = object()
data_loader_field = DataLoaderField(data_loader=data_loader, source_loader='keys', type=MyType, load_many=True)
data_loader_field = DataLoaderField(
data_loader=data_loader, source_loader="keys", type=MyType, load_many=True
)
resolver = data_loader_field.get_resolver(None)
instance = MyInstance()
@ -282,7 +284,9 @@ class DataLoaderFieldTests(TestCase):
def test_dataloaderfield_inner_prop(self):
MyType = object()
data_loader_field = DataLoaderField(data_loader=data_loader, source_loader='InnerClass.key', type=MyType)
data_loader_field = DataLoaderField(
data_loader=data_loader, source_loader="InnerClass.key", type=MyType
)
resolver = data_loader_field.get_resolver(None)
instance = MyInstance()
@ -291,8 +295,12 @@ class DataLoaderFieldTests(TestCase):
def test_dataloaderfield_many_inner_prop(self):
MyType = object()
data_loader_field = DataLoaderField(data_loader=data_loader, source_loader='InnerClass.keys', type=MyType,
load_many=True)
data_loader_field = DataLoaderField(
data_loader=data_loader,
source_loader="InnerClass.keys",
type=MyType,
load_many=True,
)
resolver = data_loader_field.get_resolver(None)
instance = MyInstance()
@ -301,15 +309,19 @@ class DataLoaderFieldTests(TestCase):
def test_dataloaderfield_permissions(self):
MyType = object()
data_loader_field = DataLoaderField(data_loader=data_loader, source_loader='key', type=MyType,
permissions=['perm1', 'perm2'])
data_loader_field = DataLoaderField(
data_loader=data_loader,
source_loader="key",
type=MyType,
permissions=["perm1", "perm2"],
)
resolver = data_loader_field.get_resolver(None)
instance = MyInstance()
class Viewer(object):
def has_perm(self, perm):
return perm == 'perm2'
return perm == "perm2"
info = mock.Mock(context=mock.Mock(user=Viewer()))
@ -317,8 +329,12 @@ class DataLoaderFieldTests(TestCase):
def test_dataloaderfield_without_permissions(self):
MyType = object()
data_loader_field = DataLoaderField(data_loader=data_loader, source_loader='key', type=MyType,
permissions=['perm1', 'perm2'])
data_loader_field = DataLoaderField(
data_loader=data_loader,
source_loader="key",
type=MyType,
permissions=["perm1", "perm2"],
)
resolver = data_loader_field.get_resolver(None)
instance = MyInstance()

View File

@ -213,6 +213,7 @@ def with_local_registry(func):
@with_local_registry
def test_django_objecttype_only_fields():
with pytest.warns(PendingDeprecationWarning):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
@ -236,6 +237,7 @@ def test_django_objecttype_fields():
@with_local_registry
def test_django_objecttype_only_fields_and_fields():
with pytest.raises(Exception):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
@ -257,6 +259,7 @@ def test_django_objecttype_all_fields():
@with_local_registry
def test_django_objecttype_exclude_fields():
with pytest.warns(PendingDeprecationWarning):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
@ -280,6 +283,7 @@ def test_django_objecttype_exclude():
@with_local_registry
def test_django_objecttype_exclude_fields_and_exclude():
with pytest.raises(Exception):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
@ -290,6 +294,7 @@ def test_django_objecttype_exclude_fields_and_exclude():
@with_local_registry
def test_django_objecttype_exclude_and_only():
with pytest.raises(AssertionError):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
@ -300,12 +305,14 @@ def test_django_objecttype_exclude_and_only():
@with_local_registry
def test_django_objecttype_fields_exclude_type_checking():
with pytest.raises(TypeError):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
fields = "foo"
with pytest.raises(TypeError):
class Reporter2(DjangoObjectType):
class Meta:
model = ReporterModel
@ -315,15 +322,17 @@ def test_django_objecttype_fields_exclude_type_checking():
@with_local_registry
def test_django_objecttype_fields_exist_on_model():
with pytest.warns(UserWarning, match=r"Field name .* doesn't exist"):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
fields = ["first_name", "foo", "email"]
with pytest.warns(
UserWarning,
match=r"Field name .* matches an attribute on Django model .* but it's not a model field",
UserWarning,
match=r"Field name .* matches an attribute on Django model .* but it's not a model field",
) as record:
class Reporter2(DjangoObjectType):
class Meta:
model = ReporterModel
@ -331,6 +340,7 @@ def test_django_objecttype_fields_exist_on_model():
# Don't warn if selecting a custom field
with pytest.warns(None) as record:
class Reporter3(DjangoObjectType):
custom_field = String()
@ -344,9 +354,10 @@ def test_django_objecttype_fields_exist_on_model():
@with_local_registry
def test_django_objecttype_exclude_fields_exist_on_model():
with pytest.warns(
UserWarning,
match=r"Django model .* does not have a field or attribute named .*",
UserWarning,
match=r"Django model .* does not have a field or attribute named .*",
):
class Reporter(DjangoObjectType):
class Meta:
model = ReporterModel
@ -354,9 +365,10 @@ def test_django_objecttype_exclude_fields_exist_on_model():
# Don't warn if selecting a custom field
with pytest.warns(
UserWarning,
match=r"Excluding the custom field .* on DjangoObjectType .* has no effect.",
UserWarning,
match=r"Excluding the custom field .* on DjangoObjectType .* has no effect.",
):
class Reporter3(DjangoObjectType):
custom_field = String()
@ -366,6 +378,7 @@ def test_django_objecttype_exclude_fields_exist_on_model():
# Don't warn on exclude fields
with pytest.warns(None) as record:
class Reporter4(DjangoObjectType):
class Meta:
model = ReporterModel
@ -562,7 +575,7 @@ class TestDjangoObjectType:
def extra_field_resolver(root, info, **kwargs):
return 'extra field'
return "extra field"
class PermissionArticle(DjangoObjectType):
@ -570,27 +583,28 @@ class PermissionArticle(DjangoObjectType):
class Meta(object):
"""Meta Class"""
field_to_permission = {
'headline': ('content_type.permission1',),
'pub_date': ('content_type.permission2',)
"headline": ("content_type.permission1",),
"pub_date": ("content_type.permission2",),
}
permission_to_field = {
'content_type.permission3': ('headline', 'reporter', 'extra_field',)
"content_type.permission3": ("headline", "reporter", "extra_field",)
}
model = ArticleModel
extra_field = Field(String, resolver=extra_field_resolver)
def resolve_headline(self, info, **kwargs):
return 'headline'
return "headline"
def test_django_permissions():
expected = {
'headline': ('content_type.permission1', 'content_type.permission3'),
'pub_date': ('content_type.permission2',),
'reporter': ('content_type.permission3',),
'extra_field': ('content_type.permission3',),
"headline": ("content_type.permission1", "content_type.permission3"),
"pub_date": ("content_type.permission2",),
"reporter": ("content_type.permission3",),
"extra_field": ("content_type.permission3",),
}
assert PermissionArticle.field_permissions == expected
@ -600,7 +614,7 @@ def test_permission_resolver():
class Viewer(object):
def has_perm(self, perm):
return perm == 'content_type.permission3'
return perm == "content_type.permission3"
class Info(object):
class Context(object):
@ -609,7 +623,7 @@ def test_permission_resolver():
context = Context()
resolved = PermissionArticle.resolve_headline(MyType, Info())
assert resolved == 'headline'
assert resolved == "headline"
def test_resolver_without_permission():
@ -634,7 +648,7 @@ def test_permission_resolver_to_field():
class Viewer(object):
def has_perm(self, perm):
return perm == 'content_type.permission3'
return perm == "content_type.permission3"
class Info(object):
class Context(object):
@ -643,7 +657,7 @@ def test_permission_resolver_to_field():
context = Context()
resolved = PermissionArticle.resolve_extra_field(MyType, Info())
assert resolved == 'extra field'
assert resolved == "extra field"
def test_resolver_to_field_without_permission():
@ -651,7 +665,7 @@ def test_resolver_to_field_without_permission():
class Viewer(object):
def has_perm(self, perm):
return perm != 'content_type.permission3'
return perm != "content_type.permission3"
class Info(object):
class Context(object):

View File

@ -3,7 +3,6 @@ from collections import OrderedDict
from functools import partial
import six
from django.db.models import Model
from django.utils.functional import SimpleLazyObject
import graphene
@ -76,7 +75,8 @@ def validate_fields(type_, model, fields, only_fields, exclude_fields):
(
'Field name "{field_name}" matches an attribute on Django model "{app_label}.{object_name}" '
"but it's not a model field so Graphene cannot determine what type it should be. "
'Either define the type of the field on DjangoObjectType "{type_}" or remove it from the "fields" list.'
'Either define the type of the field on DjangoObjectType "{type_}" or remove it from the "fields" '
"list. "
).format(
field_name=name,
app_label=model._meta.app_label,
@ -89,7 +89,8 @@ def validate_fields(type_, model, fields, only_fields, exclude_fields):
warnings.warn(
(
'Field name "{field_name}" doesn\'t exist on Django model "{app_label}.{object_name}". '
'Consider removing the field from the "fields" list of DjangoObjectType "{type_}" because it has no effect.'
'Consider removing the field from the "fields" list of DjangoObjectType "{type_}" because it has '
"no effect. "
).format(
field_name=name,
app_label=model._meta.app_label,
@ -117,8 +118,10 @@ def validate_fields(type_, model, fields, only_fields, exclude_fields):
if not hasattr(model, name):
warnings.warn(
(
'Django model "{app_label}.{object_name}" does not have a field or attribute named "{field_name}". '
'Consider removing the field from the "exclude" list of DjangoObjectType "{type_}" because it has no effect'
'Django model "{app_label}.{object_name}" does not have a field or attribute named "{'
'field_name}". '
'Consider removing the field from the "exclude" list of DjangoObjectType "{type_}" because it '
"has no effect "
).format(
field_name=name,
app_label=model._meta.app_label,
@ -268,7 +271,9 @@ class DjangoObjectType(ObjectType):
_meta.fields = django_fields
_meta.connection = connection
field_permissions = cls.__get_field_permissions__(field_to_permission, permission_to_field)
field_permissions = cls.__get_field_permissions__(
field_to_permission, permission_to_field
)
if field_permissions:
cls.__set_as_nullable__(field_permissions, model, registry)
@ -323,13 +328,17 @@ class DjangoObjectType(ObjectType):
def __set_permissions_resolvers__(cls, permissions):
"""Set permission resolvers"""
for field_name, field_permissions in permissions.items():
attr = 'resolve_{}'.format(field_name)
resolver = getattr(cls._meta.fields[field_name], 'resolver', None) or getattr(cls, attr, None)
attr = "resolve_{}".format(field_name)
resolver = getattr(
cls._meta.fields[field_name], "resolver", None
) or getattr(cls, attr, None)
if not hasattr(field_permissions, '__iter__'):
if not hasattr(field_permissions, "__iter__"):
field_permissions = tuple(field_permissions)
setattr(cls, attr, get_auth_resolver(field_name, field_permissions, resolver))
setattr(
cls, attr, get_auth_resolver(field_name, field_permissions, resolver)
)
@classmethod
def __set_as_nullable__(cls, field_permissions, model, registry):
@ -339,7 +348,7 @@ class DjangoObjectType(ObjectType):
_as=Field,
)
for name, field in django_fields.items():
if hasattr(field, '_type') and isinstance(field._type, NonNull):
if hasattr(field, "_type") and isinstance(field._type, NonNull):
field._type = field._type._of_type
setattr(cls, name, field)

View File

@ -132,7 +132,16 @@ def resolve_bound_resolver(resolver, root, info, **args):
return resolver(root, info, **args)
def auth_resolver(parent_resolver, permissions, attname, default_value, raise_exception, root, info, **args):
def auth_resolver(
parent_resolver,
permissions,
attname,
default_value,
raise_exception,
root,
info,
**args
):
"""
Middleware resolver to check viewer's permissions
:param parent_resolver: Field resolver
@ -146,7 +155,7 @@ def auth_resolver(parent_resolver, permissions, attname, default_value, raise_ex
:return: Resolved field. None if the viewer does not have permission to access the field.
"""
# Get viewer from context
if not hasattr(info.context, 'user'):
if not hasattr(info.context, "user"):
raise PermissionDenied()
user = info.context.user