Skip to content

Commit

Permalink
Merge pull request #78 from evo-company/fix-some-typings
Browse files Browse the repository at this point in the history
fix typings
  • Loading branch information
kindermax committed Aug 18, 2022
2 parents 25c7e25 + 186b07b commit 257f470
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 105 deletions.
3 changes: 2 additions & 1 deletion hiku/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import ast as _ast
from typing import Any

PY38 = sys.version_info >= (3, 8)
PY38: bool = sys.version_info >= (3, 8)
PY310: bool = sys.version_info >= (3, 10)


class _AST:
Expand Down
2 changes: 1 addition & 1 deletion hiku/endpoint/graphql.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from ..introspection.graphql import GraphQLIntrospection, MUTATION_ROOT_NAME


_type_names = {
_type_names: t.Dict[OperationType, str] = {
OperationType.QUERY: QUERY_ROOT_NAME,
OperationType.MUTATION: MUTATION_ROOT_NAME,
}
Expand Down
17 changes: 2 additions & 15 deletions hiku/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,14 @@
List,
NoReturn,
Optional,
overload,
DefaultDict,
Awaitable,
)
from functools import partial
from itertools import chain, repeat
from collections import defaultdict
from collections.abc import Sequence, Mapping, Hashable
from typing_extensions import (
ParamSpec,
Concatenate,
)
from typing_extensions import Concatenate, ParamSpec

from .executors.base import SyncAsyncExecutor
from .query import (
Expand All @@ -44,7 +40,6 @@
Field,
Graph,
Node,
NothingType,
)
from .result import Proxy, Index, ROOT, Reference
from .executors.queue import (
Expand Down Expand Up @@ -267,15 +262,7 @@ def link_reqs(
return index.root[link.requires]


@overload
def link_ref_maybe(graph_link: Link, ident: NothingType) -> None: ... # type: ignore[misc] # noqa: E501


@overload
def link_ref_maybe(graph_link: Link, ident: Any) -> Reference: ...


def link_ref_maybe(graph_link, ident): # type: ignore[no-untyped-def]
def link_ref_maybe(graph_link: Link, ident: Any) -> Optional[Reference]:
if ident is Nothing:
return None
else:
Expand Down
10 changes: 4 additions & 6 deletions hiku/executors/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
TypeVar,
Callable,
TYPE_CHECKING,
Any,
)

from typing_extensions import ParamSpec

from hiku.executors.base import BaseSyncExecutor
from hiku.result import Proxy

Expand All @@ -17,7 +16,6 @@


T = TypeVar('T')
P = ParamSpec('P')


class FutureLike:
Expand All @@ -33,9 +31,9 @@ class SyncExecutor(BaseSyncExecutor):

def submit(
self,
fn: Callable[P, T],
*args: P.args,
**kwargs: P.kwargs
fn: Callable,
*args: Any,
**kwargs: Any
) -> FutureLike:
return FutureLike(fn(*args, **kwargs))

Expand Down
89 changes: 57 additions & 32 deletions hiku/expr/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,91 @@
Expression building blocks
"""
import typing as t

from functools import wraps
from itertools import chain
from collections import namedtuple
from typing_extensions import ParamSpec

from ..edn import loads
from ..query import Node, Link, Field
from ..types import Record, Callable, Any
from ..query import Node as QueryNode, Link, Field
from ..types import (
Record,
Callable,
Any,
GenericMeta,
)
from ..readers.simple import transform

from .nodes import Symbol, Tuple, List, Keyword, Dict
from .nodes import Symbol, Tuple, List, Keyword, Dict, Node


THIS = 'this'

_Func = namedtuple('_Func', 'expr, args')


class _DotHandler:
class DotHandler:

def __init__(self, obj):
def __init__(self, obj: t.Union[Symbol, Tuple]) -> None:
self.obj = obj

def __repr__(self):
def __repr__(self) -> str:
return repr(self.obj)

def __getattr__(self, name):
return _DotHandler(Tuple([Symbol('get'), self.obj, Symbol(name)]))
def __getattr__(self, name: str) -> 'DotHandler':
return DotHandler(Tuple([Symbol('get'), self.obj, Symbol(name)]))


# for backward compatibility
_DotHandler = DotHandler


class _S:

def __getattr__(self, name):
return _DotHandler(Symbol(name))
def __getattr__(self, name: str) -> DotHandler:
return DotHandler(Symbol(name))


#: Helper object to represent symbols in expressions. ``S.foo.bar`` in
#: expressions is equivalent to ``foo.bar`` in the regular Python.
S = _S()


def _to_expr(obj, fn_reg):
if isinstance(obj, _DotHandler):
def _to_expr(
obj: t.Union[DotHandler, _Func, t.List, t.Dict, Node],
fn_reg: t.Set[t.Callable]
) -> Node:
if isinstance(obj, DotHandler):
return obj.obj
elif isinstance(obj, _Func):
fn_reg.add(obj.expr)
return Tuple([Symbol(obj.expr.__def_name__)] +
[_to_expr(arg, fn_reg) for arg in obj.args])
values: t.List[Node] = [Symbol(obj.expr.__def_name__)]
values.extend(_to_expr(arg, fn_reg) for arg in obj.args)
return Tuple(values)
elif isinstance(obj, list):
return List(_to_expr(v, fn_reg) for v in obj)
return List([_to_expr(v, fn_reg) for v in obj])
elif isinstance(obj, dict):
values = chain.from_iterable((Keyword(k), _to_expr(v, fn_reg))
for k, v in obj.items())
values = list(chain.from_iterable((Keyword(k), _to_expr(v, fn_reg))
for k, v in obj.items()))
return Dict(values)
else:
return obj


def to_expr(obj):
functions = set([])
def to_expr(
obj: t.Union[DotHandler, _Func]
) -> t.Tuple[Node, t.Tuple[t.Callable, ...]]:
functions: t.Set[t.Callable] = set([])
node = _to_expr(obj, functions)
return node, tuple(functions)


def _query_to_types(obj):
if isinstance(obj, Node):
def _query_to_types(
obj: t.Union[QueryNode, Field, Link],
) -> t.Union[t.Type[Any], t.Type[Record]]:
if isinstance(obj, QueryNode):
return Record[[(f.name, _query_to_types(f)) for f in obj.fields]]
elif isinstance(obj, Link):
return _query_to_types(obj.node)
Expand All @@ -79,7 +99,13 @@ def _query_to_types(obj):
raise TypeError(type(obj))


def define(*types, **kwargs):
T = t.TypeVar('T')
P = ParamSpec('P')


def define(
*types: GenericMeta, **kwargs: str
) -> t.Callable[[t.Callable[P, T]], t.Callable[P, _Func]]:
"""Annotates function arguments with types.
These annotations are used to type-check expressions and to analyze,
Expand All @@ -102,33 +128,32 @@ def image_url(image):
This annotation also gives ability for Hiku to build a query for low-level
graph.
"""
def decorator(fn):
def decorator(fn: t.Callable[P, T]) -> t.Callable[P, _Func]:
_name = kwargs.pop('_name', None)
assert not kwargs, repr(kwargs)

name = _name or '{}/{}_{}'.format(fn.__module__, fn.__name__, id(fn))

@wraps(fn)
def expr(*args):
def expr(*args: P.args, **kw: P.kwargs) -> _Func:
return _Func(expr, args)

expr.__def_name__ = name
expr.__def_body__ = fn
expr.__def_name__ = name # type: ignore[attr-defined]
expr.__def_body__ = fn # type: ignore[attr-defined]

if len(types) == 1 and isinstance(types[0], str):
reqs_list = loads(str(types[0]))
expr.__def_type__ = Callable[[(_query_to_types(transform(r))
expr.__def_type__ = Callable[[(_query_to_types(transform(r)) # type: ignore[attr-defined] # noqa: E501
if r is not None else Any)
for r in reqs_list]]
else:
expr.__def_type__ = Callable[types]

expr.__def_type__ = Callable[types] # type: ignore[attr-defined]
return expr
return decorator


@define(Any, Any, Any, _name='each')
def each(var, col, expr):
def each(var: DotHandler, col: DotHandler, expr: DotHandler) -> None:
"""Returns a list of the results of the expression evaluation for every
item of the sequence provided.
Expand All @@ -148,7 +173,7 @@ def each(var, col, expr):


@define(Any, Any, Any, _name='if')
def if_(test, then, else_):
def if_(test: t.Any, then: t.Any, else_: t.Any) -> None:
"""Checks condition and continues to evaluate one of the two expressions
provided.
Expand All @@ -171,7 +196,7 @@ def if_(test, then, else_):


@define(Any, Any, Any, _name='if_some')
def if_some(bind, then, else_):
def if_some(bind: t.List, then: _Func, else_: t.Any) -> None:
"""Used to unpack values with ``Optional`` types and using them safely in
expressions.
Expand Down

0 comments on commit 257f470

Please sign in to comment.