Skip to content

Commit 9ceaf54

Browse files
committed
Fix lazy imports
1 parent 5434e9d commit 9ceaf54

File tree

9 files changed

+89
-39
lines changed

9 files changed

+89
-39
lines changed

__coconut__/__init__.pyi

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,6 @@ try:
8989
except ImportError:
9090
def _deprecated(message: _t.Text) -> _t.Callable[[_T], _T]: ... # type: ignore
9191

92-
import importlib as _importlib
93-
_coconut_lazy_module = _importlib.import_module
94-
9592
import _coconut as __coconut # we mock _coconut as a package since mypy doesn't handle namespace classes very well
9693
_coconut = __coconut
9794

@@ -205,6 +202,7 @@ _coconut_filter = filter
205202
_coconut_range = range
206203
_coconut_reversed = reversed
207204
_coconut_zip = zip
205+
_coconut_type = type
208206

209207

210208
zip_longest = _coconut.zip_longest
@@ -232,6 +230,12 @@ TYPE_CHECKING = _t.TYPE_CHECKING
232230
_coconut_sentinel: _t.Any = ...
233231

234232

233+
@_t.overload
234+
def _coconut_lazy_module(name: str) -> _coconut.types.ModuleType: ...
235+
@_t.overload
236+
def _coconut_lazy_module(name: str, *, attr: str) -> _t.Any: ...
237+
238+
235239
def scan(
236240
func: _t.Callable[[_T, _U], _T],
237241
iterable: _t.Iterable[_U],

_coconut/__init__.pyi

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ str = _builtins.str
181181
sum = _builtins.sum
182182
super = _builtins.super
183183
tuple = _builtins.tuple
184-
type = _builtins.type
185184
zip = _builtins.zip
186185
vars = _builtins.vars
187186
repr = _builtins.repr

coconut/__coconut__.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
from __coconut__ import *
2-
from __coconut__ import _coconut_tail_call, _coconut_tco, _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_Expected, _coconut_MatchError, _coconut_SupportsAdd, _coconut_SupportsMinus, _coconut_SupportsMul, _coconut_SupportsPow, _coconut_SupportsTruediv, _coconut_SupportsFloordiv, _coconut_SupportsMod, _coconut_SupportsAnd, _coconut_SupportsXor, _coconut_SupportsOr, _coconut_SupportsLshift, _coconut_SupportsRshift, _coconut_SupportsMatmul, _coconut_SupportsInv, _coconut_Expected, _coconut_MatchError, _coconut_iter_getitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_star_pipe, _coconut_dubstar_pipe, _coconut_back_pipe, _coconut_back_star_pipe, _coconut_back_dubstar_pipe, _coconut_none_pipe, _coconut_none_star_pipe, _coconut_none_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_complex_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_raise, _coconut_mark_as_match, _coconut_reiterable, _coconut_self_match_types, _coconut_dict_merge, _coconut_exec, _coconut_comma_op, _coconut_arr_concat_op, _coconut_mk_anon_namedtuple, _coconut_matmul, _coconut_py_str, _coconut_flatten, _coconut_multiset, _coconut_back_none_pipe, _coconut_back_none_star_pipe, _coconut_back_none_dubstar_pipe, _coconut_forward_none_compose, _coconut_back_none_compose, _coconut_forward_none_star_compose, _coconut_back_none_star_compose, _coconut_forward_none_dubstar_compose, _coconut_back_none_dubstar_compose, _coconut_call_or_coefficient, _coconut_in, _coconut_not_in, _coconut_attritemgetter, _coconut_if_op, _coconut_CoconutWarning, _coconut_lazy_module
2+
from __coconut__ import _coconut_tail_call, _coconut_tco, _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_Expected, _coconut_MatchError, _coconut_SupportsAdd, _coconut_SupportsMinus, _coconut_SupportsMul, _coconut_SupportsPow, _coconut_SupportsTruediv, _coconut_SupportsFloordiv, _coconut_SupportsMod, _coconut_SupportsAnd, _coconut_SupportsXor, _coconut_SupportsOr, _coconut_SupportsLshift, _coconut_SupportsRshift, _coconut_SupportsMatmul, _coconut_SupportsInv, _coconut_Expected, _coconut_MatchError, _coconut_iter_getitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_star_pipe, _coconut_dubstar_pipe, _coconut_back_pipe, _coconut_back_star_pipe, _coconut_back_dubstar_pipe, _coconut_none_pipe, _coconut_none_star_pipe, _coconut_none_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_complex_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_raise, _coconut_mark_as_match, _coconut_reiterable, _coconut_self_match_types, _coconut_dict_merge, _coconut_exec, _coconut_comma_op, _coconut_arr_concat_op, _coconut_mk_anon_namedtuple, _coconut_matmul, _coconut_py_str, _coconut_flatten, _coconut_multiset, _coconut_back_none_pipe, _coconut_back_none_star_pipe, _coconut_back_none_dubstar_pipe, _coconut_forward_none_compose, _coconut_back_none_compose, _coconut_forward_none_star_compose, _coconut_back_none_star_compose, _coconut_forward_none_dubstar_compose, _coconut_back_none_dubstar_compose, _coconut_call_or_coefficient, _coconut_in, _coconut_not_in, _coconut_attritemgetter, _coconut_if_op, _coconut_CoconutWarning, _coconut_lazy_module, _coconut_type

coconut/compiler/compiler.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4086,11 +4086,11 @@ def _make_import_stmt(self, imp_from, imp, imp_as, raw=False, lazy=False):
40864086
mod_name = ".".join(fake_mods[:i])
40874087
out_lines.append(self.ensure_module_or_create_fake(mod_name))
40884088
bind_to = imp_as if imp_as is not None else imp
4089-
out_lines.append('{bind_to} = _coconut_lazy_module("{module}"){attr} {type_ignore}'.format(
4089+
out_lines.append('{bind_to} = _coconut_lazy_module("{module}"{attr_param}) {type_ignore}'.format(
40904090
bind_to=bind_to,
40914091
module=imp_from if imp_from is not None else imp,
4092-
attr="." + imp if imp_from is not None else "",
4093-
type_ignore=self.type_ignore_comment() if "." in bind_to else "",
4092+
attr_param=', attr="' + imp + '"' if imp_from is not None else "",
4093+
type_ignore=self.type_ignore_comment(),
40944094
))
40954095
return "\n".join(out_lines)
40964096
else:
@@ -4257,7 +4257,7 @@ def complex_raise_stmt_handle(self, loc, tokens):
42574257
from_expr=from_expr,
42584258
)
42594259

4260-
def normal_dict_comp_handle(self, original, loc, tokens):
4260+
def normal_dict_comp_handle(self, tokens):
42614261
"""Process standard dictionary comprehension."""
42624262
key, val, comp = tokens
42634263
# on < 3.9 have to use _coconut.dict since it's different than py_dict

coconut/compiler/header.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ def _coconut_matmul(a, b, **kwargs):
525525
if "numpy" in (_coconut_get_base_module(a), _coconut_get_base_module(b)):
526526
from numpy import matmul
527527
return matmul(a, b)
528-
raise _coconut.TypeError("unsupported operand type(s) for @: " + _coconut.repr(_coconut.type(a)) + " and " + _coconut.repr(_coconut.type(b)))
528+
raise _coconut.TypeError("unsupported operand type(s) for @: " + _coconut.repr(_coconut_type(a)) + " and " + _coconut.repr(_coconut_type(b)))
529529
''',
530530
),
531531
def_total_and_comparisons=pycondition(
@@ -621,7 +621,7 @@ def __call__(self, *args, **kwargs):
621621
arg = f(arg)
622622
if await_f:
623623
arg = yield _coconut.asyncio.From(arg)
624-
raise _coconut.asyncio.Return(arg)
624+
raise _coconut.asyncio_Return(arg)
625625
''',
626626
),
627627
indent=1
@@ -666,7 +666,7 @@ def __anext__(self):
666666
# (extra_format_dict is to keep indentation levels matching)
667667
extra_format_dict = dict(
668668
# when anything is added to this list it must also be added to *both* __coconut__ stub files
669-
underscore_imports="{tco_comma}{call_set_names_comma}{handle_cls_args_comma}_namedtuple_of, _coconut, _coconut_Expected, _coconut_MatchError, _coconut_SupportsAdd, _coconut_SupportsMinus, _coconut_SupportsMul, _coconut_SupportsPow, _coconut_SupportsTruediv, _coconut_SupportsFloordiv, _coconut_SupportsMod, _coconut_SupportsAnd, _coconut_SupportsXor, _coconut_SupportsOr, _coconut_SupportsLshift, _coconut_SupportsRshift, _coconut_SupportsMatmul, _coconut_SupportsInv, _coconut_iter_getitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_star_pipe, _coconut_dubstar_pipe, _coconut_back_pipe, _coconut_back_star_pipe, _coconut_back_dubstar_pipe, _coconut_none_pipe, _coconut_none_star_pipe, _coconut_none_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_complex_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_raise, _coconut_mark_as_match, _coconut_reiterable, _coconut_self_match_types, _coconut_dict_merge, _coconut_exec, _coconut_comma_op, _coconut_arr_concat_op, _coconut_mk_anon_namedtuple, _coconut_matmul, _coconut_py_str, _coconut_flatten, _coconut_multiset, _coconut_back_none_pipe, _coconut_back_none_star_pipe, _coconut_back_none_dubstar_pipe, _coconut_forward_none_compose, _coconut_back_none_compose, _coconut_forward_none_star_compose, _coconut_back_none_star_compose, _coconut_forward_none_dubstar_compose, _coconut_back_none_dubstar_compose, _coconut_call_or_coefficient, _coconut_in, _coconut_not_in, _coconut_attritemgetter, _coconut_if_op, _coconut_CoconutWarning, _coconut_lazy_module".format(**format_dict),
669+
underscore_imports="{tco_comma}{call_set_names_comma}{handle_cls_args_comma}_namedtuple_of, _coconut, _coconut_Expected, _coconut_MatchError, _coconut_SupportsAdd, _coconut_SupportsMinus, _coconut_SupportsMul, _coconut_SupportsPow, _coconut_SupportsTruediv, _coconut_SupportsFloordiv, _coconut_SupportsMod, _coconut_SupportsAnd, _coconut_SupportsXor, _coconut_SupportsOr, _coconut_SupportsLshift, _coconut_SupportsRshift, _coconut_SupportsMatmul, _coconut_SupportsInv, _coconut_iter_getitem, _coconut_base_compose, _coconut_forward_compose, _coconut_back_compose, _coconut_forward_star_compose, _coconut_back_star_compose, _coconut_forward_dubstar_compose, _coconut_back_dubstar_compose, _coconut_pipe, _coconut_star_pipe, _coconut_dubstar_pipe, _coconut_back_pipe, _coconut_back_star_pipe, _coconut_back_dubstar_pipe, _coconut_none_pipe, _coconut_none_star_pipe, _coconut_none_dubstar_pipe, _coconut_bool_and, _coconut_bool_or, _coconut_none_coalesce, _coconut_minus, _coconut_map, _coconut_partial, _coconut_complex_partial, _coconut_get_function_match_error, _coconut_base_pattern_func, _coconut_addpattern, _coconut_sentinel, _coconut_assert, _coconut_raise, _coconut_mark_as_match, _coconut_reiterable, _coconut_self_match_types, _coconut_dict_merge, _coconut_exec, _coconut_comma_op, _coconut_arr_concat_op, _coconut_mk_anon_namedtuple, _coconut_matmul, _coconut_py_str, _coconut_flatten, _coconut_multiset, _coconut_back_none_pipe, _coconut_back_none_star_pipe, _coconut_back_none_dubstar_pipe, _coconut_forward_none_compose, _coconut_back_none_compose, _coconut_forward_none_star_compose, _coconut_back_none_star_compose, _coconut_forward_none_dubstar_compose, _coconut_back_none_dubstar_compose, _coconut_call_or_coefficient, _coconut_in, _coconut_not_in, _coconut_attritemgetter, _coconut_if_op, _coconut_CoconutWarning, _coconut_lazy_module, _coconut_type".format(**format_dict),
670670
import_typing=pycondition(
671671
(3, 5),
672672
if_ge='''
@@ -764,6 +764,15 @@ class you_need_to_install_typing_extensions{object}:
764764
(3, 4),
765765
if_lt='''
766766
asyncio = _coconut_lazy_module("trollius")
767+
def _coconut_trollius_coroutine(func):
768+
try:
769+
import trollius
770+
return trollius.coroutine(func)
771+
except ImportError as err:
772+
def raise_import_error(*args, **kwargs):
773+
raise err
774+
return raise_import_error
775+
asyncio.coroutine = _coconut_trollius_coroutine
767776
asyncio_Return = _coconut_lazy_module("trollius", attr="Return")
768777
''',
769778
if_ge='''

coconut/compiler/matching.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ def match_class(self, tokens, item):
11331133
self_match_matcher, other_cls_matcher = self.branches(2)
11341134

11351135
# handle instances of _coconut_self_match_types
1136-
self_match_matcher.add_check("_coconut.type(" + item + ") in _coconut_self_match_types")
1136+
self_match_matcher.add_check("_coconut_type(" + item + ") in _coconut_self_match_types")
11371137
if pos_matches:
11381138
if len(pos_matches) > 1:
11391139
self_match_matcher.add_def(
@@ -1150,7 +1150,7 @@ def match_class(self, tokens, item):
11501150
self_match_matcher.match(pos_matches[0], item)
11511151

11521152
# handle all other classes
1153-
other_cls_matcher.add_check("not _coconut.type(" + item + ") in _coconut_self_match_types")
1153+
other_cls_matcher.add_check("not _coconut_type(" + item + ") in _coconut_self_match_types")
11541154
match_args_var = other_cls_matcher.get_temp_var()
11551155
other_cls_matcher.add_def(
11561156
handle_indentation(

coconut/compiler/templates/header.py_template

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,30 @@ def _coconut_lazy_module(name, on_import=None, attr=None):
1616
return _coconut.getattr(state[0], attr)
1717
return state[0]
1818
if attr is None:
19-
from types import ModuleType
20-
class lazy_mod(ModuleType):
21-
def __getattr__(self, name):
22-
return _coconut.getattr(load(), name)
23-
def __dir__(self):
24-
return _coconut.dir(load())
25-
return lazy_mod(_coconut_py_str(name))
19+
from types import ModuleType as base
2620
else:
27-
class meta(type):
28-
def __getattr__(cls, name):
29-
return _coconut.getattr(load(), name)
30-
def __setattr__(cls, name, value):
31-
_coconut.setattr(load(), name, value)
32-
def __dir__(cls):
33-
return _coconut.dir(load())
34-
return meta(_coconut_py_str(name), (), {{}})
21+
base = _coconut_type
22+
class lazy_obj(base):
23+
def __getattr__(cls, name):
24+
return _coconut.getattr(load(), name)
25+
def __setattr__(cls, name, value):
26+
_coconut.setattr(load(), name, value)
27+
def __dir__(cls):
28+
return _coconut.dir(load())
29+
def __instancecheck__(cls, inst):
30+
return _coconut.isinstance(inst, load())
31+
def __subclasscheck__(cls, sub):
32+
return _coconut.issubclass(sub, load())
33+
def _coconut_make_lazy_dunder(_coconut_n):
34+
def _coconut_lazy_dunder(cls, *args, **kwargs):
35+
return _coconut.getattr(load(), _coconut_n)(*args, **kwargs)
36+
return _coconut_lazy_dunder
37+
for _coconut_dunder in ("__call__", "__hash__", "__repr__", "__str__", "__format__", "__bytes__", "__bool__", "__nonzero__", "__int__", "__float__", "__complex__", "__index__", "__round__", "__eq__", "__ne__", "__lt__", "__le__", "__gt__", "__ge__", "__len__", "__contains__", "__iter__", "__next__", "__reversed__", "__getitem__", "__setitem__", "__delitem__", "__missing__", "__add__", "__radd__", "__iadd__", "__sub__", "__rsub__", "__isub__", "__mul__", "__rmul__", "__imul__", "__floordiv__", "__rfloordiv__", "__ifloordiv__", "__truediv__", "__rtruediv__", "__itruediv__", "__mod__", "__rmod__", "__imod__", "__pow__", "__rpow__", "__ipow__", "__matmul__", "__rmatmul__", "__imatmul__", "__divmod__", "__rdivmod__", "__neg__", "__pos__", "__abs__", "__invert__", "__and__", "__rand__", "__iand__", "__or__", "__ror__", "__ior__", "__xor__", "__rxor__", "__ixor__", "__lshift__", "__rlshift__", "__ilshift__", "__rshift__", "__rrshift__", "__irshift__", "__enter__", "__exit__", "__aiter__", "__anext__", "__await__", "__aenter__", "__aexit__", "__reduce__", "__reduce_ex__", "__copy__", "__deepcopy__"):
38+
_coconut_type.__setattr__(lazy_obj, _coconut_dunder, _coconut_make_lazy_dunder(_coconut_dunder))
39+
if attr is None:
40+
return lazy_obj(_coconut_py_str(name))
41+
else:
42+
return lazy_obj(_coconut_py_str(name), (), {{}})
3543
@_coconut_wraps(_coconut_py_super)
3644
def _coconut_super(type=None, object_or_type=None):
3745
if type is None:
@@ -82,7 +90,7 @@ class _coconut{object}:{COMMENT.EVERYTHING_HERE_MUST_BE_COPIED_TO_STUB_FILE}
8290
reiterables = abc.Sequence, abc.Mapping, abc.Set
8391
fmappables = list, tuple, dict, set, frozenset, bytes, bytearray
8492
abc.Sequence.register(collections.deque)
85-
Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, KeyError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bool, bytes, callable, chr, classmethod, complex, dict, dir, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, globals, map, min, max, next, object, ord, property, range, reversed, set, setattr, slice, str, sum, super, tuple, type, vars, zip, repr, print{comma_bytearray} = Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, KeyError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bool, bytes, callable, chr, classmethod, complex, dict, dir, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, globals, map, {lstatic}min{rstatic}, {lstatic}max{rstatic}, next, object, ord, property, range, reversed, set, setattr, slice, str, sum, {lstatic}super{rstatic}, tuple, type, vars, zip, {lstatic}repr{rstatic}, {lstatic}print{rstatic}{comma_bytearray}
93+
Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, KeyError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bool, bytes, callable, chr, classmethod, complex, dict, dir, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, globals, map, min, max, next, object, ord, property, range, reversed, set, setattr, slice, str, sum, super, tuple, vars, zip, repr, print{comma_bytearray} = Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, KeyError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bool, bytes, callable, chr, classmethod, complex, dict, dir, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, globals, map, {lstatic}min{rstatic}, {lstatic}max{rstatic}, next, object, ord, property, range, reversed, set, setattr, slice, str, sum, {lstatic}super{rstatic}, tuple, vars, zip, {lstatic}repr{rstatic}, {lstatic}print{rstatic}{comma_bytearray}
8694
def _coconut_handle_cls_kwargs(**kwargs):
8795
"""Some code taken from six under the terms of its MIT license."""
8896
metaclass = kwargs.pop("metaclass", None)
@@ -1405,7 +1413,7 @@ def _coconut_get_function_match_error():
14051413
class _coconut_base_pattern_func(_coconut_base_callable):{COMMENT.no_slots_to_allow_func_attrs}
14061414
_coconut_is_match = True
14071415
def __init__(self, *funcs):
1408-
self.FunctionMatchError = _coconut.type({py_str_MatchError}, ({_coconut_}MatchError,), {empty_py_dict})
1416+
self.FunctionMatchError = _coconut_type({py_str_MatchError}, ({_coconut_}MatchError,), {empty_py_dict})
14091417
self.patterns = []
14101418
self.__doc__ = None
14111419
self.__name__ = None
@@ -1677,7 +1685,7 @@ def _coconut_memoize_helper(maxsize=None, typed=False):
16771685
@_coconut_wraps(func)
16781686
def memoized_func(*args, **kwargs):
16791687
if typed:
1680-
key = (_coconut.tuple((x, _coconut.type(x)) for x in args), _coconut.tuple((k, _coconut.type(k), v, _coconut.type(v)) for k, v in kwargs.items()))
1688+
key = (_coconut.tuple((x, _coconut_type(x)) for x in args), _coconut.tuple((k, _coconut_type(k), v, _coconut_type(v)) for k, v in kwargs.items()))
16811689
else:
16821690
key = (args, _coconut.tuple(kwargs.items()))
16831691
got = cache.get(key, _coconut_sentinel)

0 commit comments

Comments
 (0)