mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 01:47:45 +03:00 
			
		
		
		
	Merge branch 'refs/heads/master' into docs-playground
This commit is contained in:
		
						commit
						4e258b5def
					
				
							
								
								
									
										31
									
								
								examples/complex_example.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								examples/complex_example.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					import graphene
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GeoInput(graphene.InputObjectType):
 | 
				
			||||||
 | 
					    lat = graphene.Float(required=True)
 | 
				
			||||||
 | 
					    lng = graphene.Float(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Address(graphene.ObjectType):
 | 
				
			||||||
 | 
					    latlng = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
 | 
					    address = graphene.Field(Address, geo=graphene.Argument(GeoInput))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_address(self, args, info):
 | 
				
			||||||
 | 
					        geo = args.get('geo')
 | 
				
			||||||
 | 
					        return Address(latlng="({},{})".format(geo.get('lat'), geo.get('lng')))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = graphene.Schema(query=Query)
 | 
				
			||||||
 | 
					query = '''
 | 
				
			||||||
 | 
					    query something{
 | 
				
			||||||
 | 
					      address(geo: {lat:32.2, lng:12}) {
 | 
				
			||||||
 | 
					        latlng
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					result = schema.execute(query)
 | 
				
			||||||
 | 
					print(result.data['address']['latlng'])
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ query = '''
 | 
				
			||||||
        id
 | 
					        id
 | 
				
			||||||
        name
 | 
					        name
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
}
 | 
					    }
 | 
				
			||||||
'''
 | 
					'''
 | 
				
			||||||
result = schema.execute(query)
 | 
					result = schema.execute(query)
 | 
				
			||||||
print(result.data['patron'])
 | 
					print(result.data['patron'])
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
from graphene.contrib.django.types import (
 | 
					from graphene.contrib.django.types import (
 | 
				
			||||||
 | 
					    DjangoConnection,
 | 
				
			||||||
    DjangoObjectType,
 | 
					    DjangoObjectType,
 | 
				
			||||||
    DjangoInterface,
 | 
					    DjangoInterface,
 | 
				
			||||||
    DjangoNode
 | 
					    DjangoNode
 | 
				
			||||||
| 
						 | 
					@ -9,4 +10,4 @@ from graphene.contrib.django.fields import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ['DjangoObjectType', 'DjangoInterface', 'DjangoNode',
 | 
					__all__ = ['DjangoObjectType', 'DjangoInterface', 'DjangoNode',
 | 
				
			||||||
           'DjangoConnectionField', 'DjangoModelField']
 | 
					           'DjangoConnection', 'DjangoConnectionField', 'DjangoModelField']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,26 +1,22 @@
 | 
				
			||||||
 | 
					import warnings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ...core.exceptions import SkipField
 | 
					from ...core.exceptions import SkipField
 | 
				
			||||||
from ...core.fields import Field
 | 
					from ...core.fields import Field
 | 
				
			||||||
from ...core.types.base import FieldType
 | 
					from ...core.types.base import FieldType
 | 
				
			||||||
from ...core.types.definitions import List
 | 
					from ...core.types.definitions import List
 | 
				
			||||||
from ...relay import ConnectionField
 | 
					from ...relay import ConnectionField
 | 
				
			||||||
from ...relay.utils import is_node
 | 
					from ...relay.utils import is_node
 | 
				
			||||||
from .utils import get_type_for_model, lazy_map
 | 
					from .utils import get_type_for_model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoConnectionField(ConnectionField):
 | 
					class DjangoConnectionField(ConnectionField):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def wrap_resolved(self, value, instance, args, info):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        return lazy_map(value, self.type)
 | 
					        cls = self.__class__
 | 
				
			||||||
 | 
					        warnings.warn("Using {} will be not longer supported."
 | 
				
			||||||
 | 
					                      " Use relay.ConnectionField instead".format(cls.__name__),
 | 
				
			||||||
class LazyListField(Field):
 | 
					                      FutureWarning)
 | 
				
			||||||
 | 
					        return super(DjangoConnectionField, self).__init__(*args, **kwargs)
 | 
				
			||||||
    def get_type(self, schema):
 | 
					 | 
				
			||||||
        return List(self.type)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def resolver(self, instance, args, info):
 | 
					 | 
				
			||||||
        resolved = super(LazyListField, self).resolver(instance, args, info)
 | 
					 | 
				
			||||||
        return lazy_map(resolved, self.type)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConnectionOrListField(Field):
 | 
					class ConnectionOrListField(Field):
 | 
				
			||||||
| 
						 | 
					@ -33,8 +29,8 @@ class ConnectionOrListField(Field):
 | 
				
			||||||
        if is_node(field_object_type):
 | 
					        if is_node(field_object_type):
 | 
				
			||||||
            field = DjangoConnectionField(field_object_type)
 | 
					            field = DjangoConnectionField(field_object_type)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            field = LazyListField(field_object_type)
 | 
					            field = Field(List(field_object_type))
 | 
				
			||||||
        field.contribute_to_class(self.object_type, self.name)
 | 
					        field.contribute_to_class(self.object_type, self.attname)
 | 
				
			||||||
        return schema.T(field)
 | 
					        return schema.T(field)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,7 +69,7 @@ def test_node_replacedfield():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_interface_resolve_type():
 | 
					def test_interface_resolve_type():
 | 
				
			||||||
    resolve_type = Character.resolve_type(schema, Human())
 | 
					    resolve_type = Character._resolve_type(schema, Human())
 | 
				
			||||||
    assert isinstance(resolve_type, GraphQLObjectType)
 | 
					    assert isinstance(resolve_type, GraphQLObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,10 @@ import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ...core.types import BaseObjectType, ObjectTypeMeta
 | 
					from ...core.types import BaseObjectType, ObjectTypeMeta
 | 
				
			||||||
from ...relay.fields import GlobalIDField
 | 
					from ...relay.fields import GlobalIDField
 | 
				
			||||||
from ...relay.types import BaseNode
 | 
					from ...relay.types import BaseNode, Connection
 | 
				
			||||||
from .converter import convert_django_field
 | 
					from .converter import convert_django_field
 | 
				
			||||||
from .options import DjangoOptions
 | 
					from .options import DjangoOptions
 | 
				
			||||||
from .utils import get_reverse_fields
 | 
					from .utils import get_reverse_fields, maybe_queryset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
					class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
				
			||||||
            is_excluded = field.name in cls._meta.exclude_fields or is_already_created
 | 
					            is_excluded = field.name in cls._meta.exclude_fields or is_already_created
 | 
				
			||||||
            if is_not_in_only or is_excluded:
 | 
					            if is_not_in_only or is_excluded:
 | 
				
			||||||
                # We skip this field if we specify only_fields and is not
 | 
					                # We skip this field if we specify only_fields and is not
 | 
				
			||||||
                # in there. Or when we excldue this field in exclude_fields
 | 
					                # in there. Or when we exclude this field in exclude_fields
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            converted_field = convert_django_field(field)
 | 
					            converted_field = convert_django_field(field)
 | 
				
			||||||
            cls.add_to_class(field.name, converted_field)
 | 
					            cls.add_to_class(field.name, converted_field)
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,14 @@ class DjangoInterface(six.with_metaclass(
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DjangoConnection(Connection):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def from_list(cls, iterable, *args, **kwargs):
 | 
				
			||||||
 | 
					        iterable = maybe_queryset(iterable)
 | 
				
			||||||
 | 
					        return super(DjangoConnection, cls).from_list(iterable, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoNode(BaseNode, DjangoInterface):
 | 
					class DjangoNode(BaseNode, DjangoInterface):
 | 
				
			||||||
    id = GlobalIDField()
 | 
					    id = GlobalIDField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,3 +89,5 @@ class DjangoNode(BaseNode, DjangoInterface):
 | 
				
			||||||
            return cls(instance)
 | 
					            return cls(instance)
 | 
				
			||||||
        except cls._meta.model.DoesNotExist:
 | 
					        except cls._meta.model.DoesNotExist:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    connection_type = DjangoConnection
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,5 @@
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from django.db.models.manager import Manager
 | 
					from django.db.models.manager import Manager
 | 
				
			||||||
from django.db.models.query import QuerySet
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from ...utils import LazyMap
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_type_for_model(schema, model):
 | 
					def get_type_for_model(schema, model):
 | 
				
			||||||
| 
						 | 
					@ -22,9 +19,7 @@ def get_reverse_fields(model):
 | 
				
			||||||
            yield related
 | 
					            yield related
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def lazy_map(value, func):
 | 
					def maybe_queryset(value):
 | 
				
			||||||
    if isinstance(value, Manager):
 | 
					    if isinstance(value, Manager):
 | 
				
			||||||
        value = value.get_queryset()
 | 
					        value = value.get_queryset()
 | 
				
			||||||
    if isinstance(value, QuerySet):
 | 
					 | 
				
			||||||
        return LazyMap(value, func)
 | 
					 | 
				
			||||||
    return value
 | 
					    return value
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,10 @@ class Character(Interface):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pet(ObjectType):
 | 
					class Pet(ObjectType):
 | 
				
			||||||
    type = String(resolver=lambda *_: 'Dog')
 | 
					    type = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_type(self, args, info):
 | 
				
			||||||
 | 
					        return 'Dog'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Human(Character):
 | 
					class Human(Character):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ class BaseObjectType(BaseType):
 | 
				
			||||||
        signals.post_init.send(self.__class__, instance=self)
 | 
					        signals.post_init.send(self.__class__, instance=self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def resolve_type(cls, schema, instance, *args):
 | 
					    def _resolve_type(cls, schema, instance, *args):
 | 
				
			||||||
        return schema.T(instance.__class__)
 | 
					        return schema.T(instance.__class__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					@ -191,7 +191,7 @@ class BaseObjectType(BaseType):
 | 
				
			||||||
            return GraphQLInterfaceType(
 | 
					            return GraphQLInterfaceType(
 | 
				
			||||||
                cls._meta.type_name,
 | 
					                cls._meta.type_name,
 | 
				
			||||||
                description=cls._meta.description,
 | 
					                description=cls._meta.description,
 | 
				
			||||||
                resolve_type=partial(cls.resolve_type, schema),
 | 
					                resolve_type=partial(cls._resolve_type, schema),
 | 
				
			||||||
                fields=partial(cls.get_fields, schema)
 | 
					                fields=partial(cls.get_fields, schema)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        elif cls._meta.is_union:
 | 
					        elif cls._meta.is_union:
 | 
				
			||||||
| 
						 | 
					@ -219,6 +219,10 @@ class BaseObjectType(BaseType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return OrderedDict(fields)
 | 
					        return OrderedDict(fields)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def wrap(cls, instance, args, info):
 | 
				
			||||||
 | 
					        return cls(_root=instance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
					class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ def test_union_cannot_initialize():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_interface_resolve_type():
 | 
					def test_interface_resolve_type():
 | 
				
			||||||
    resolve_type = Character.resolve_type(schema, Human(object()))
 | 
					    resolve_type = Character._resolve_type(schema, Human(object()))
 | 
				
			||||||
    assert isinstance(resolve_type, GraphQLObjectType)
 | 
					    assert isinstance(resolve_type, GraphQLObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,3 @@
 | 
				
			||||||
from collections import Iterable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from graphql_relay.connection.arrayconnection import connection_from_list
 | 
					 | 
				
			||||||
from graphql_relay.node.node import from_global_id
 | 
					from graphql_relay.node.node import from_global_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..core.fields import Field
 | 
					from ..core.fields import Field
 | 
				
			||||||
| 
						 | 
					@ -30,24 +27,12 @@ class ConnectionField(Field):
 | 
				
			||||||
        return value
 | 
					        return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolver(self, instance, args, info):
 | 
					    def resolver(self, instance, args, info):
 | 
				
			||||||
        from graphene.relay.types import PageInfo
 | 
					 | 
				
			||||||
        schema = info.schema.graphene_schema
 | 
					        schema = info.schema.graphene_schema
 | 
				
			||||||
 | 
					        connection_type = self.get_type(schema)
 | 
				
			||||||
        resolved = super(ConnectionField, self).resolver(instance, args, info)
 | 
					        resolved = super(ConnectionField, self).resolver(instance, args, info)
 | 
				
			||||||
        if resolved:
 | 
					        if isinstance(resolved, connection_type):
 | 
				
			||||||
            resolved = self.wrap_resolved(resolved, instance, args, info)
 | 
					            return resolved
 | 
				
			||||||
            assert isinstance(
 | 
					        return connection_type.from_list(resolved, args, info)
 | 
				
			||||||
                resolved, Iterable), 'Resolved value from the connection field have to be iterable'
 | 
					 | 
				
			||||||
            type = schema.T(self.type)
 | 
					 | 
				
			||||||
            node = schema.objecttype(type)
 | 
					 | 
				
			||||||
            connection_type = self.get_connection_type(node)
 | 
					 | 
				
			||||||
            edge_type = self.get_edge_type(node)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            connection = connection_from_list(
 | 
					 | 
				
			||||||
                resolved, args, connection_type=connection_type,
 | 
					 | 
				
			||||||
                edge_type=edge_type, pageinfo_type=PageInfo)
 | 
					 | 
				
			||||||
            connection.set_connection_data(resolved)
 | 
					 | 
				
			||||||
            return connection
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_connection_type(self, node):
 | 
					    def get_connection_type(self, node):
 | 
				
			||||||
        connection_type = self.connection_type or node.get_connection_type()
 | 
					        connection_type = self.connection_type or node.get_connection_type()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
import inspect
 | 
					import inspect
 | 
				
			||||||
import warnings
 | 
					import warnings
 | 
				
			||||||
 | 
					from collections import Iterable
 | 
				
			||||||
from functools import wraps
 | 
					from functools import wraps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql_relay.connection.arrayconnection import connection_from_list
 | 
				
			||||||
from graphql_relay.node.node import to_global_id
 | 
					from graphql_relay.node.node import to_global_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..core.types import (Boolean, Field, InputObjectType, Interface, List,
 | 
					from ..core.types import (Boolean, Field, InputObjectType, Interface, List,
 | 
				
			||||||
| 
						 | 
					@ -63,6 +66,16 @@ class Connection(ObjectType):
 | 
				
			||||||
            (cls,),
 | 
					            (cls,),
 | 
				
			||||||
            {'edge_type': edge_type, 'edges': edges})
 | 
					            {'edge_type': edge_type, 'edges': edges})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def from_list(cls, iterable, args, info):
 | 
				
			||||||
 | 
					        assert isinstance(
 | 
				
			||||||
 | 
					            iterable, Iterable), 'Resolved value from the connection field have to be iterable'
 | 
				
			||||||
 | 
					        connection = connection_from_list(
 | 
				
			||||||
 | 
					            iterable, args, connection_type=cls,
 | 
				
			||||||
 | 
					            edge_type=cls.edge_type, pageinfo_type=PageInfo)
 | 
				
			||||||
 | 
					        connection.set_connection_data(iterable)
 | 
				
			||||||
 | 
					        return connection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_connection_data(self, data):
 | 
					    def set_connection_data(self, data):
 | 
				
			||||||
        self._connection_data = data
 | 
					        self._connection_data = data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,9 @@
 | 
				
			||||||
from blinker import Signal
 | 
					try:
 | 
				
			||||||
 | 
					    from blinker import Signal
 | 
				
			||||||
 | 
					except ImportError:
 | 
				
			||||||
 | 
					    class Signal(object):
 | 
				
			||||||
 | 
					        def send(self, *args, **kwargs):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
init_schema = Signal()
 | 
					init_schema = Signal()
 | 
				
			||||||
class_prepared = Signal()
 | 
					class_prepared = Signal()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,10 @@
 | 
				
			||||||
from .str_converters import to_camel_case, to_snake_case
 | 
					from .str_converters import to_camel_case, to_snake_case
 | 
				
			||||||
from .proxy_snake_dict import ProxySnakeDict
 | 
					from .proxy_snake_dict import ProxySnakeDict
 | 
				
			||||||
from .caching import cached_property, memoize
 | 
					from .caching import cached_property, memoize
 | 
				
			||||||
from .lazymap import LazyMap
 | 
					 | 
				
			||||||
from .misc import enum_to_graphql_enum
 | 
					from .misc import enum_to_graphql_enum
 | 
				
			||||||
from .resolve_only_args import resolve_only_args
 | 
					from .resolve_only_args import resolve_only_args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
 | 
					__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
 | 
				
			||||||
           'cached_property', 'memoize', 'LazyMap', 'enum_to_graphql_enum',
 | 
					           'cached_property', 'memoize', 'enum_to_graphql_enum',
 | 
				
			||||||
           'resolve_only_args']
 | 
					           'resolve_only_args']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,43 +0,0 @@
 | 
				
			||||||
class LazyMap(object):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, origin, _map, state=None):
 | 
					 | 
				
			||||||
        self._origin = origin
 | 
					 | 
				
			||||||
        self._origin_iter = origin.__iter__()
 | 
					 | 
				
			||||||
        self._state = state or []
 | 
					 | 
				
			||||||
        self._finished = False
 | 
					 | 
				
			||||||
        self._map = _map
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __iter__(self):
 | 
					 | 
				
			||||||
        return self if not self._finished else iter(self._state)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def iter(self):
 | 
					 | 
				
			||||||
        return self.__iter__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __len__(self):
 | 
					 | 
				
			||||||
        return self._origin.__len__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __next__(self):
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            n = next(self._origin_iter)
 | 
					 | 
				
			||||||
            n = self._map(n)
 | 
					 | 
				
			||||||
        except StopIteration as e:
 | 
					 | 
				
			||||||
            self._finished = True
 | 
					 | 
				
			||||||
            raise e
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            self._state.append(n)
 | 
					 | 
				
			||||||
            return n
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def next(self):
 | 
					 | 
				
			||||||
        return self.__next__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getitem__(self, key):
 | 
					 | 
				
			||||||
        item = self._origin[key]
 | 
					 | 
				
			||||||
        if isinstance(key, slice):
 | 
					 | 
				
			||||||
            return LazyMap(item, self._map)
 | 
					 | 
				
			||||||
        return self._map(item)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getattr__(self, name):
 | 
					 | 
				
			||||||
        return getattr(self._origin, name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __repr__(self):
 | 
					 | 
				
			||||||
        return "<LazyMap %s>" % repr(self._origin)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,23 +0,0 @@
 | 
				
			||||||
from py.test import raises
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from ..lazymap import LazyMap
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lazymap():
 | 
					 | 
				
			||||||
    data = list(range(10))
 | 
					 | 
				
			||||||
    lm = LazyMap(data, lambda x: 2 * x)
 | 
					 | 
				
			||||||
    assert len(lm) == 10
 | 
					 | 
				
			||||||
    assert lm[1] == 2
 | 
					 | 
				
			||||||
    assert isinstance(lm[1:4], LazyMap)
 | 
					 | 
				
			||||||
    assert lm.append == data.append
 | 
					 | 
				
			||||||
    assert repr(lm) == '<LazyMap [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lazymap_iter():
 | 
					 | 
				
			||||||
    data = list(range(2))
 | 
					 | 
				
			||||||
    lm = LazyMap(data, lambda x: 2 * x)
 | 
					 | 
				
			||||||
    iter_lm = iter(lm)
 | 
					 | 
				
			||||||
    assert iter_lm.next() == 0
 | 
					 | 
				
			||||||
    assert iter_lm.next() == 2
 | 
					 | 
				
			||||||
    with raises(StopIteration):
 | 
					 | 
				
			||||||
        iter_lm.next()
 | 
					 | 
				
			||||||
| 
						 | 
					@ -4,3 +4,6 @@ max-line-length = 120
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[coverage:run]
 | 
					[coverage:run]
 | 
				
			||||||
omit = core/ntypes/tests/*
 | 
					omit = core/ntypes/tests/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[isort]
 | 
				
			||||||
 | 
					known_first_party=graphene
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										3
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.py
									
									
									
									
									
								
							| 
						 | 
					@ -24,7 +24,7 @@ class PyTest(TestCommand):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
setup(
 | 
					setup(
 | 
				
			||||||
    name='graphene',
 | 
					    name='graphene',
 | 
				
			||||||
    version='0.4.1.1',
 | 
					    version='0.4.2',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    description='Graphene: Python DSL for GraphQL',
 | 
					    description='Graphene: Python DSL for GraphQL',
 | 
				
			||||||
    long_description=open('README.rst').read(),
 | 
					    long_description=open('README.rst').read(),
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,6 @@ setup(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    install_requires=[
 | 
					    install_requires=[
 | 
				
			||||||
        'six>=1.10.0',
 | 
					        'six>=1.10.0',
 | 
				
			||||||
        'blinker',
 | 
					 | 
				
			||||||
        'graphql-core==0.4.9',
 | 
					        'graphql-core==0.4.9',
 | 
				
			||||||
        'graphql-relay==0.3.3'
 | 
					        'graphql-relay==0.3.3'
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user