Skip to content

Commit

Permalink
Resolve import cycle by moving TypeInfoVisitor to utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
Cito committed Jan 25, 2020
1 parent b634fa2 commit 1a42027
Show file tree
Hide file tree
Showing 13 changed files with 275 additions and 253 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The current stable version 3.0.1 of GraphQL-core is up-to-date
with GraphQL.js version 14.5.8.

All parts of the API are covered by an extensive test suite
of currently 2039 unit tests.
of currently 2040 unit tests.


## Documentation
Expand Down
1 change: 0 additions & 1 deletion docs/modules/language.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ Visitor
.. autofunction:: visit
.. autoclass:: Visitor
.. autoclass:: ParallelVisitor
.. autoclass:: TypeInfoVisitor

The module also exports the following special symbols which can be used as
return values in the :class:`Visitor` methods to signal particular actions:
Expand Down
1 change: 1 addition & 0 deletions docs/modules/utilities.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ A helper to use within recursive-descent visitors which need to be aware of the
type system:

.. autoclass:: TypeInfo
.. autoclass:: TypeInfoVisitor

Coerce a Python value to a GraphQL type, or produce errors:

Expand Down
2 changes: 1 addition & 1 deletion src/graphql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@
# Visit
visit,
ParallelVisitor,
TypeInfoVisitor,
Visitor,
BREAK,
SKIP,
Expand Down Expand Up @@ -362,6 +361,7 @@
# A helper to use within recursive-descent visitors which need to be aware of the
# GraphQL type system.
TypeInfo,
TypeInfoVisitor,
# Coerce a Python value to a GraphQL type, or produce errors.
coerce_input_value,
# Concatenates multiple ASTs together.
Expand Down
2 changes: 0 additions & 2 deletions src/graphql/language/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
visit,
Visitor,
ParallelVisitor,
TypeInfoVisitor,
BREAK,
SKIP,
REMOVE,
Expand Down Expand Up @@ -116,7 +115,6 @@
"visit",
"Visitor",
"ParallelVisitor",
"TypeInfoVisitor",
"BREAK",
"SKIP",
"REMOVE",
Expand Down
30 changes: 0 additions & 30 deletions src/graphql/language/visitor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from copy import copy
from typing import (
TYPE_CHECKING,
Any,
Callable,
Collection,
Expand All @@ -16,13 +15,9 @@

from .ast import Node

if TYPE_CHECKING: # pragma: no cover
from ..utilities import TypeInfo # noqa: F401

__all__ = [
"Visitor",
"ParallelVisitor",
"TypeInfoVisitor",
"visit",
"BREAK",
"SKIP",
Expand Down Expand Up @@ -378,28 +373,3 @@ def leave(self, node, *args):
return result
elif skipping[i] is node:
skipping[i] = None


class TypeInfoVisitor(Visitor):
"""A visitor which maintains a provided TypeInfo."""

def __init__(self, type_info: "TypeInfo", visitor: Visitor) -> None:
self.type_info = type_info
self.visitor = visitor

def enter(self, node, *args):
self.type_info.enter(node)
fn = self.visitor.get_visit_fn(node.kind)
if fn:
result = fn(self.visitor, node, *args)
if result is not None:
self.type_info.leave(node)
if isinstance(result, ast.Node):
self.type_info.enter(result)
return result

def leave(self, node, *args):
fn = self.visitor.get_visit_fn(node.kind, is_leaving=True)
result = fn(self.visitor, node, *args) if fn else None
self.type_info.leave(node)
return result
3 changes: 2 additions & 1 deletion src/graphql/utilities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

# A helper to use within recursive-descent visitors which need to be aware of
# the GraphQL type system
from .type_info import TypeInfo
from .type_info import TypeInfo, TypeInfoVisitor

# Coerce a Python value to a GraphQL type, or produce errors.
from .coerce_input_value import coerce_input_value
Expand Down Expand Up @@ -90,6 +90,7 @@
"DangerousChange",
"DangerousChangeType",
"TypeInfo",
"TypeInfoVisitor",
"assert_valid_name",
"ast_from_value",
"build_ast_schema",
Expand Down
4 changes: 2 additions & 2 deletions src/graphql/utilities/find_deprecated_usages.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from typing import List

from ..error import GraphQLError
from ..language import DocumentNode, TypeInfoVisitor, Visitor, visit
from ..language import DocumentNode, Visitor, visit
from ..type import GraphQLSchema, get_named_type
from .type_info import TypeInfo
from .type_info import TypeInfo, TypeInfoVisitor


__all__ = ["find_deprecated_usages"]
Expand Down
28 changes: 27 additions & 1 deletion src/graphql/utilities/type_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
OperationType,
SelectionSetNode,
VariableDefinitionNode,
Visitor,
)
from ..type import (
GraphQLArgument,
Expand Down Expand Up @@ -43,7 +44,7 @@
)
from .type_from_ast import type_from_ast

__all__ = ["TypeInfo"]
__all__ = ["TypeInfo", "TypeInfoVisitor"]


GetFieldDefType = Callable[
Expand Down Expand Up @@ -282,3 +283,28 @@ def get_field_def(
parent_type = cast(Union[GraphQLObjectType, GraphQLInterfaceType], parent_type)
return parent_type.fields.get(name)
return None


class TypeInfoVisitor(Visitor):
"""A visitor which maintains a provided TypeInfo."""

def __init__(self, type_info: "TypeInfo", visitor: Visitor) -> None:
self.type_info = type_info
self.visitor = visitor

def enter(self, node, *args):
self.type_info.enter(node)
fn = self.visitor.get_visit_fn(node.kind)
if fn:
result = fn(self.visitor, node, *args)
if result is not None:
self.type_info.leave(node)
if isinstance(result, Node):
self.type_info.enter(result)
return result

def leave(self, node, *args):
fn = self.visitor.get_visit_fn(node.kind, is_leaving=True)
result = fn(self.visitor, node, *args) if fn else None
self.type_info.leave(node)
return result
4 changes: 2 additions & 2 deletions src/graphql/validation/validate.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from typing import Collection, List

from ..error import GraphQLError
from ..language import DocumentNode, ParallelVisitor, TypeInfoVisitor, visit
from ..language import DocumentNode, ParallelVisitor, visit
from ..type import GraphQLSchema, assert_valid_schema
from ..pyutils import inspect
from ..utilities import TypeInfo
from ..utilities import TypeInfo, TypeInfoVisitor
from .rules import RuleType
from .specified_rules import specified_rules, specified_sdl_rules
from .validation_context import SDLValidationContext, ValidationContext
Expand Down
3 changes: 1 addition & 2 deletions src/graphql/validation/validation_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
FragmentSpreadNode,
OperationDefinitionNode,
SelectionSetNode,
TypeInfoVisitor,
VariableNode,
Visitor,
visit,
)
from ..type import GraphQLSchema, GraphQLInputType
from ..utilities import TypeInfo
from ..utilities import TypeInfo, TypeInfoVisitor

__all__ = [
"ASTValidationContext",
Expand Down
Loading

0 comments on commit 1a42027

Please sign in to comment.