Skip to content

Commit

Permalink
Merge pull request #70 from evo-company/refactor-types
Browse files Browse the repository at this point in the history
Refactor types
  • Loading branch information
kindermax committed Aug 2, 2022
2 parents 126acf4 + c730d61 commit 76de87c
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 63 deletions.
12 changes: 10 additions & 2 deletions examples/graphql_aiohttp.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import logging
from typing import Dict

from aiohttp import web

from hiku.types import String, Boolean, Integer, TypeRef, Record
from hiku.types import (
String,
Boolean,
Integer,
TypeRef,
Record,
RecordMeta,
)
from hiku.graph import Graph, Root, Field, Option
from hiku.engine import Engine
from hiku.endpoint.graphql import AsyncGraphQLEndpoint
Expand All @@ -24,7 +32,7 @@ async def action_func(fields):
return results


DATA_TYPES = {
DATA_TYPES: Dict[str, RecordMeta] = {
'Point': Record[{
'x': Integer,
'y': Integer,
Expand Down
8 changes: 7 additions & 1 deletion hiku/denormalize/graphql.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from collections import deque

from ..query import Field, Link
from ..types import TypeRefMeta, SequenceMeta, OptionalMeta
from ..types import (
TypeRefMeta,
SequenceMeta,
OptionalMeta,
GenericMeta,
)

from .base import Denormalize

Expand All @@ -20,6 +25,7 @@ def visit_field(self, obj: Field):

def visit_link(self, obj: Link):
type_ = self._type[-1].__field_types__[obj.name]
type_ref: GenericMeta
if isinstance(type_, TypeRefMeta):
type_ref = type_
elif isinstance(type_, SequenceMeta):
Expand Down
32 changes: 18 additions & 14 deletions hiku/edn.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ def start(*args, **kwargs):
@coroutine
def appender(lst):
while True:
lst.append((yield))
v = yield
lst.append(v)


def inst_handler(time_string):
Expand Down Expand Up @@ -140,15 +141,16 @@ def inst_handler(time_string):
@coroutine
def tag_handler(tag_name, tag_handlers):
while True:
c = (yield)
c = yield
if c in STOP_CHARS + '{"[(\\#':
break
tag_name += c
elements = []
handler = parser(appender(elements), tag_handlers)
handler.send(c)
while not elements:
handler.send((yield))
v = yield
handler.send(v)
if tag_name in tag_handlers:
yield tag_handlers[tag_name](elements[0]), True
else:
Expand All @@ -158,9 +160,9 @@ def tag_handler(tag_name, tag_handlers):

@coroutine
def character_handler():
r = (yield)
r = yield
while 1:
c = (yield)
c = yield
if not c.isalpha():
if len(r) == 1:
yield r, False
Expand All @@ -179,7 +181,7 @@ def parse_number(s):
@coroutine
def number_handler(s):
while 1:
c = (yield)
c = yield
if c in "0123456789+-eEMN.":
s += c
else:
Expand All @@ -189,7 +191,7 @@ def number_handler(s):
@coroutine
def symbol_handler(s):
while 1:
c = (yield)
c = yield
if c in '}])' + STOP_CHARS:
if s[0] == ':':
yield Keyword(s[1:]), False
Expand All @@ -209,7 +211,7 @@ def symbol_handler(s):
def parser(target, tag_handlers, stop=None):
handler = None
while True:
c = (yield)
c = yield
if handler:
v = handler.send(c)
if v is None:
Expand All @@ -229,14 +231,15 @@ def parser(target, tag_handlers, stop=None):
if c in STOP_CHARS:
continue
if c == ';':
while (yield) != '\n':
v = yield
while v != '\n':
pass
elif c == '"':
chars = []
while 1:
char = (yield)
char = yield
if char == '\\':
char = (yield)
char = yield
char2 = _CHAR_MAP.get(char)
if char2 is not None:
chars.append(char2)
Expand All @@ -252,7 +255,7 @@ def parser(target, tag_handlers, stop=None):
elif c in '0123456789':
handler = number_handler(c)
elif c in '-.':
c2 = (yield)
c2 = yield
if c2.isdigit(): # .5 should be an error
handler = number_handler(c + c2)
else:
Expand All @@ -261,7 +264,7 @@ def parser(target, tag_handlers, stop=None):
handler = symbol_handler(c)
elif c in '[({#':
if c == '#':
c2 = (yield)
c2 = yield
if c2 != '{':
handler = tag_handler(c2, tag_handlers)
continue
Expand All @@ -270,7 +273,8 @@ def parser(target, tag_handlers, stop=None):
p = parser(appender(lst), tag_handlers, stop=end_char)
try:
while 1:
p.send((yield))
v = yield
p.send(v)
except StopIteration:
pass
if c == '[':
Expand Down
70 changes: 37 additions & 33 deletions hiku/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
Record,
Any,
GenericMeta,
TypingMeta,
AnyMeta,
RecordMeta,
)
Expand Down Expand Up @@ -99,12 +100,24 @@ class AbstractField(AbstractBase, ABC):
pass


RootFieldFunc = t.Callable[[t.List['Field']], List[t.Any]]
NotRootFieldFunc = t.Callable[[t.List['Field'], List[t.Any]], List[List[t.Any]]]
R = t.TypeVar('R')

SyncAsync = t.Union[R, t.Awaitable[R]]

RootFieldFunc = t.Callable[
[t.List['Field']],
SyncAsync[List[t.Any]]
]
NotRootFieldFunc = t.Callable[
[t.List['Field'], List[t.Any]],
SyncAsync[List[List[t.Any]]]
]
NotRootFieldFuncInject = t.Callable[
[t.Any, t.List['Field'], List[t.Any]], List[List[t.Any]]
[t.Any, t.List['Field'], List[t.Any]],
SyncAsync[List[List[t.Any]]]
]


FieldType = t.Optional[GenericMeta]
FieldFunc = t.Union[
RootFieldFunc,
Expand Down Expand Up @@ -203,7 +216,7 @@ class AbstractLink(AbstractBase, ABC):
]


def get_type_enum(type_: LinkType) -> t.Tuple[Const, str]:
def get_type_enum(type_: TypingMeta) -> t.Tuple[Const, str]:
if isinstance(type_, TypeRefMeta):
return One, type_.__type_name__
elif isinstance(type_, OptionalMeta):
Expand All @@ -215,49 +228,40 @@ def get_type_enum(type_: LinkType) -> t.Tuple[Const, str]:
raise TypeError('Invalid type specified: {!r}'.format(type_))


LT = t.TypeVar('LT')
LR = t.TypeVar('LR')
LT = t.TypeVar('LT', bound=t.Hashable)
LR = t.TypeVar('LR', bound=t.Hashable)

RootLinkOne = t.Callable[[], LR]
RootLinkOneInject = t.Callable[[t.Any], LR]

RootLinkMaybe = t.Callable[[], t.Union[LR, NothingType]]
RootLinkMaybeInject = t.Callable[[t.Any], t.Union[LR, NothingType]]

RootLinkMany = t.Callable[[], t.List[LR]]
RootLinkManyInject = t.Callable[[t.Any], t.List[LR]]
MaybeLink = t.Union[LR, NothingType]
RootLinkT = t.Union[
t.Callable[[], SyncAsync[LR]],
t.Callable[[t.Any], SyncAsync[LR]]
]

LinkOne = t.Callable[[List[LT]], t.List[LR]]
LinkOneInject = t.Callable[[t.Any, List[LT]], t.List[LR]]
LinkT = t.Union[
t.Callable[[List[LT]], SyncAsync[LR]],
t.Callable[[t.Any, List[LT]], SyncAsync[LR]]
]

LinkMaybe = t.Callable[[List[LT]], t.List[t.Union[LR, NothingType]]]
LinkMaybeInject = t.Callable[
[t.Any, List[LT]], t.List[t.Union[LR, NothingType]]]
RootLinkOne = RootLinkT[LR]
RootLinkMaybe = RootLinkT[MaybeLink[LR]]
RootLinkMany = RootLinkT[t.List[LR]]

LinkMany = t.Callable[[List[LT]], t.List[t.List[LR]]]
LinkManyInject = t.Callable[[t.Any, List[LT]], t.List[t.List[LR]]]
LinkOne = LinkT[LT, t.List[LR]]
LinkMaybe = LinkT[LT, t.List[MaybeLink[LR]]]
LinkMany = LinkT[LT, t.List[t.List[LR]]]

LinkFunc = t.Union[
RootLinkOne,
RootLinkOneInject,
RootLinkMaybe,
RootLinkMaybeInject,
RootLinkMany,
RootLinkManyInject,
LinkOne,
LinkOneInject,
LinkMaybe,
LinkMaybeInject,
LinkMany,
LinkManyInject
]

LinkOneFunc = t.Union[
RootLinkOne, RootLinkOneInject, LinkOne, LinkOneInject]
LinkMaybeFunc = t.Union[
RootLinkMaybe, RootLinkMaybeInject, LinkMaybe, LinkMaybeInject]
LinkManyFunc = t.Union[
RootLinkMany, RootLinkManyInject, LinkMany, LinkManyInject]
LinkOneFunc = t.Union[RootLinkOne, LinkOne]
LinkMaybeFunc = t.Union[RootLinkMaybe, LinkMaybe]
LinkManyFunc = t.Union[RootLinkMany, LinkMany]


class Link(AbstractLink):
Expand Down
34 changes: 22 additions & 12 deletions hiku/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ def __repr__(self):
return super(TypingMeta, self).__repr__()


TR = t.TypeVar('TR', 'TypingMeta', 'TypeRefMeta', str)
T = t.TypeVar('T', bound='GenericMeta')


class OptionalMeta(TypingMeta, t.Generic[TR]):
class OptionalMeta(TypingMeta, t.Generic[T]):

def __cls_init__(cls, type_: TR):
cls.__type__ = _maybe_typeref(type_)
def __cls_init__(cls, type_: T):
cls.__type__: GenericMeta = _maybe_typeref(type_)

def __cls_repr__(self):
return '{}[{!r}]'.format(self.__name__, self.__type__)
Expand All @@ -113,10 +113,10 @@ class Optional(metaclass=OptionalMeta):
pass


class SequenceMeta(TypingMeta, t.Generic[TR]):
class SequenceMeta(TypingMeta, t.Generic[T]):

def __cls_init__(cls, item_type: TR):
cls.__item_type__ = _maybe_typeref(item_type)
def __cls_init__(cls, item_type: T):
cls.__item_type__: GenericMeta = _maybe_typeref(item_type)

def __cls_repr__(self):
return '{}[{!r}]'.format(self.__name__, self.__item_type__)
Expand Down Expand Up @@ -154,13 +154,13 @@ class RecordMeta(TypingMeta):
def __cls_init__(
cls,
field_types: t.Union[
t.Dict[str, TR],
t.List[t.Tuple[str, TR]]
t.Dict[str, T],
t.List[t.Tuple[str, T]]
]
):
items: t.Iterable
if hasattr(field_types, 'items'):
field_types = t.cast(t.Dict[str, TR], field_types)
field_types = t.cast(t.Dict[str, T], field_types)
items = list(field_types.items())
else:
items = list(field_types)
Expand Down Expand Up @@ -214,7 +214,17 @@ class TypeRef(metaclass=TypeRefMeta):
pass


def _maybe_typeref(typ: TR) -> TypeRefMeta:
@t.overload
def _maybe_typeref(typ: str) -> TypeRefMeta:
...


@t.overload
def _maybe_typeref(typ: GenericMeta) -> GenericMeta:
...


def _maybe_typeref(typ: t.Union[str, GenericMeta]) -> GenericMeta:
return TypeRef[typ] if isinstance(typ, str) else typ


Expand Down Expand Up @@ -307,7 +317,7 @@ def visit_callable(self, obj):
self.visit(arg_type)


def get_type(types: t.Dict[str, TypingMeta], typ: TypingMeta) -> TypingMeta:
def get_type(types: t.Dict[str, GenericMeta], typ: GenericMeta) -> GenericMeta:
if isinstance(typ, TypeRefMeta):
return types[typ.__type_name__]
else:
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ deps = -r requirements-tox.txt

[testenv:flake8]
commands = flake8
deps = flake8
deps = flake8==5.0.3

[flake8]
max-line-length = 80
Expand Down

0 comments on commit 76de87c

Please sign in to comment.