From 6f93f472323159aa4b8f4764eeae7bcba3d733cb Mon Sep 17 00:00:00 2001 From: Fabien BOURGEOIS Date: Fri, 9 Dec 2022 11:12:59 +0100 Subject: [PATCH] [MIG]Yaltik DSL : from coconut to pure py2 --- yaltik_dsl/src/__coconut__.py | 1576 --------------------------- yaltik_dsl/src/__init__.coco | 18 - yaltik_dsl/src/__init__.py | 35 - yaltik_dsl/src/odoo_dsl.coco | 139 --- yaltik_dsl/src/odoo_dsl.py | 81 +- yaltik_dsl/src/xml_base.coco | 75 -- yaltik_dsl/src/xml_base.py | 48 +- yaltik_dsl/tests/__coconut__.py | 1576 --------------------------- yaltik_dsl/tests/test_odoo.coco | 247 ----- yaltik_dsl/tests/test_odoo.py | 84 +- yaltik_dsl/tests/test_xml_base.coco | 129 --- yaltik_dsl/tests/test_xml_base.py | 76 +- 12 files changed, 59 insertions(+), 4025 deletions(-) delete mode 100644 yaltik_dsl/src/__coconut__.py delete mode 100644 yaltik_dsl/src/__init__.coco delete mode 100644 yaltik_dsl/src/odoo_dsl.coco delete mode 100644 yaltik_dsl/src/xml_base.coco delete mode 100644 yaltik_dsl/tests/__coconut__.py delete mode 100644 yaltik_dsl/tests/test_odoo.coco delete mode 100644 yaltik_dsl/tests/test_xml_base.coco diff --git a/yaltik_dsl/src/__coconut__.py b/yaltik_dsl/src/__coconut__.py deleted file mode 100644 index ee2c2e8..0000000 --- a/yaltik_dsl/src/__coconut__.py +++ /dev/null @@ -1,1576 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# type: ignore - -# Compiled with Coconut version 2.1.1 [The Spanish Inquisition] - -"""Built-in Coconut utilities.""" - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys -from __builtin__ import chr, hex, input, int, map, object, oct, open, print, range, str, super, zip, filter, reversed, enumerate, raw_input, xrange, repr, long -py_chr, py_hex, py_input, py_int, py_map, py_object, py_oct, py_open, py_print, py_range, py_str, py_super, py_zip, py_filter, py_reversed, py_enumerate, py_raw_input, py_xrange, py_repr = chr, hex, input, int, map, object, oct, open, print, range, str, super, zip, filter, reversed, enumerate, raw_input, xrange, repr -_coconut_py_raw_input, _coconut_py_xrange, _coconut_py_int, _coconut_py_long, _coconut_py_print, _coconut_py_str, _coconut_py_super, _coconut_py_unicode, _coconut_py_repr = raw_input, xrange, int, long, print, str, super, unicode, repr -from functools import wraps as _coconut_wraps -from future_builtins import * -chr, str = unichr, unicode -from io import open -class object(object): - __slots__ = () - def __ne__(self, other): - eq = self == other - return _coconut.NotImplemented if eq is _coconut.NotImplemented else not eq -class int(_coconut_py_int): - __slots__ = () - if hasattr(_coconut_py_int, "__doc__"): - __doc__ = _coconut_py_int.__doc__ - class __metaclass__(type): - def __instancecheck__(cls, inst): - return _coconut.isinstance(inst, (_coconut_py_int, _coconut_py_long)) - def __subclasscheck__(cls, subcls): - return _coconut.issubclass(subcls, (_coconut_py_int, _coconut_py_long)) -class range(object): - __slots__ = ("_xrange",) - if hasattr(_coconut_py_xrange, "__doc__"): - __doc__ = _coconut_py_xrange.__doc__ - def __init__(self, *args): - self._xrange = _coconut_py_xrange(*args) - def __iter__(self): - return _coconut.iter(self._xrange) - def __reversed__(self): - return _coconut.reversed(self._xrange) - def __len__(self): - return _coconut.len(self._xrange) - def __contains__(self, elem): - return elem in self._xrange - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - args = _coconut.slice(*self._args) - start, stop, step = (args.start if args.start is not None else 0), args.stop, (args.step if args.step is not None else 1) - if index.start is None: - new_start = start if index.step is None or index.step >= 0 else stop - step - elif index.start >= 0: - new_start = start + step * index.start - if (step >= 0 and new_start >= stop) or (step < 0 and new_start <= stop): - new_start = stop - else: - new_start = stop + step * index.start - if (step >= 0 and new_start <= start) or (step < 0 and new_start >= start): - new_start = start - if index.stop is None: - new_stop = stop if index.step is None or index.step >= 0 else start - step - elif index.stop >= 0: - new_stop = start + step * index.stop - if (step >= 0 and new_stop >= stop) or (step < 0 and new_stop <= stop): - new_stop = stop - else: - new_stop = stop + step * index.stop - if (step >= 0 and new_stop <= start) or (step < 0 and new_stop >= start): - new_stop = start - new_step = step if index.step is None else step * index.step - return self.__class__(new_start, new_stop, new_step) - else: - return self._xrange[index] - def count(self, elem): - """Count the number of times elem appears in the range.""" - return _coconut_py_int(elem in self._xrange) - def index(self, elem): - """Find the index of elem in the range.""" - if elem not in self._xrange: raise _coconut.ValueError(_coconut.repr(elem) + " is not in range") - start, _, step = self._xrange.__reduce_ex__(2)[1] - return (elem - start) // step - def __repr__(self): - return _coconut.repr(self._xrange)[1:] - @property - def _args(self): - return self._xrange.__reduce__()[1] - def __reduce_ex__(self, protocol): - return (self.__class__, self._xrange.__reduce_ex__(protocol)[1]) - def __reduce__(self): - return self.__reduce_ex__(_coconut.pickle.DEFAULT_PROTOCOL) - def __hash__(self): - return _coconut.hash(self._args) - def __copy__(self): - return self.__class__(*self._args) - def __eq__(self, other): - return self.__class__ is other.__class__ and self._args == other._args -from collections import Sequence as _coconut_Sequence -_coconut_Sequence.register(range) -@_coconut_wraps(_coconut_py_print) -def print(*args, **kwargs): - file = kwargs.get("file", _coconut_sys.stdout) - if "flush" in kwargs: - flush = kwargs["flush"] - del kwargs["flush"] - else: - flush = False - if _coconut.getattr(file, "encoding", None) is not None: - _coconut_py_print(*(_coconut_py_unicode(x).encode(file.encoding) for x in args), **kwargs) - else: - _coconut_py_print(*args, **kwargs) - if flush: - file.flush() -@_coconut_wraps(_coconut_py_raw_input) -def input(*args, **kwargs): - if _coconut.getattr(_coconut_sys.stdout, "encoding", None) is not None: - return _coconut_py_raw_input(*args, **kwargs).decode(_coconut_sys.stdout.encoding) - return _coconut_py_raw_input(*args, **kwargs).decode() -@_coconut_wraps(_coconut_py_repr) -def repr(obj): - import __builtin__ - try: - __builtin__.repr = _coconut_repr - if isinstance(obj, _coconut_py_unicode): - return _coconut_py_unicode(_coconut_py_repr(obj)[1:]) - if isinstance(obj, _coconut_py_str): - return "b" + _coconut_py_unicode(_coconut_py_repr(obj)) - return _coconut_py_unicode(_coconut_py_repr(obj)) - finally: - __builtin__.repr = _coconut_py_repr -ascii = _coconut_repr = repr -def raw_input(*args): - """Coconut uses Python 3 'input' instead of Python 2 'raw_input'.""" - raise _coconut.NameError("Coconut uses Python 3 'input' instead of Python 2 'raw_input'") -def xrange(*args): - """Coconut uses Python 3 'range' instead of Python 2 'xrange'.""" - raise _coconut.NameError("Coconut uses Python 3 'range' instead of Python 2 'xrange'") -def _coconut_exec(obj, globals=None, locals=None): - """Execute the given source in the context of globals and locals.""" - if locals is None: - locals = _coconut_sys._getframe(1).f_locals if globals is None else globals - if globals is None: - globals = _coconut_sys._getframe(1).f_globals - exec(obj, globals, locals) -def _coconut_default_breakpointhook(*args, **kwargs): - hookname = _coconut.os.getenv("PYTHONBREAKPOINT") - if hookname != "0": - if not hookname: - hookname = "pdb.set_trace" - modname, dot, funcname = hookname.rpartition(".") - if not dot: - modname = "builtins" if _coconut_sys.version_info >= (3,) else "__builtin__" - if _coconut_sys.version_info >= (2, 7): - import importlib - module = importlib.import_module(modname) - else: - import imp - module = imp.load_module(modname, *imp.find_module(modname)) - hook = _coconut.getattr(module, funcname) - return hook(*args, **kwargs) -if not hasattr(_coconut_sys, "__breakpointhook__"): - _coconut_sys.__breakpointhook__ = _coconut_default_breakpointhook -def breakpoint(*args, **kwargs): - return _coconut.getattr(_coconut_sys, "breakpointhook", _coconut_default_breakpointhook)(*args, **kwargs) -@_coconut_wraps(_coconut_py_super) -def _coconut_super(type=None, object_or_type=None): - if type is None: - if object_or_type is not None: - raise _coconut.TypeError("invalid use of super()") - frame = _coconut_sys._getframe(1) - try: - cls = frame.f_locals["__class__"] - except _coconut.AttributeError: - raise _coconut.RuntimeError("super(): __class__ cell not found") - self = frame.f_locals[frame.f_code.co_varnames[0]] - return _coconut_py_super(cls, self) - return _coconut_py_super(type, object_or_type) -super = _coconut_super -class _coconut(object): - import collections, copy, functools, types, itertools, operator, threading, os, warnings, contextlib, traceback, weakref, multiprocessing, math - from multiprocessing import dummy as multiprocessing_dummy - try: - from backports.functools_lru_cache import lru_cache - functools.lru_cache = lru_cache - except ImportError: - class you_need_to_install_backports_functools_lru_cache(object): - __slots__ = () - functools.lru_cache = you_need_to_install_backports_functools_lru_cache() - import copy_reg as copyreg - try: - import trollius as asyncio - except ImportError: - class you_need_to_install_trollius(object): - __slots__ = () - asyncio = you_need_to_install_trollius() - import cPickle as pickle - OrderedDict = collections.OrderedDict - abc = collections - class typing_mock(object): - TYPE_CHECKING = False - def __getattr__(self, name): - raise _coconut.ImportError("the typing module is not available at runtime in Python 3.4 or earlier; try hiding your typedefs behind an 'if TYPE_CHECKING:' block") - typing = typing_mock() - def NamedTuple(name, fields): - return _coconut.collections.namedtuple(name, [x for x, t in fields]) - typing.NamedTuple = NamedTuple - NamedTuple = staticmethod(NamedTuple) - try: - from typing_extensions import TypeAlias, ParamSpec, Concatenate - except ImportError: - class you_need_to_install_typing_extensions(object): - __slots__ = () - TypeAlias = ParamSpec = Concatenate = you_need_to_install_typing_extensions() - typing.TypeAlias = TypeAlias - typing.ParamSpec = ParamSpec - typing.Concatenate = Concatenate - try: - from typing_extensions import TypeVarTuple, Unpack - except ImportError: - class you_need_to_install_typing_extensions(object): - __slots__ = () - TypeVarTuple = Unpack = you_need_to_install_typing_extensions() - typing.TypeVarTuple = TypeVarTuple - typing.Unpack = Unpack - zip_longest = itertools.izip_longest - try: - import numpy - except ImportError: - class you_need_to_install_numpy(object): - __slots__ = () - numpy = you_need_to_install_numpy() - else: - abc.Sequence.register(numpy.ndarray) - numpy_modules = ('numpy', 'pandas', 'jaxlib.xla_extension') - jax_numpy_modules = ('jaxlib.xla_extension',) - abc.Sequence.register(collections.deque) - Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, slice, str, sum, super, tuple, type, vars, zip, repr, print, bytearray = Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, slice, str, sum, staticmethod(super), tuple, type, vars, zip, staticmethod(repr), staticmethod(print), bytearray -class _coconut_sentinel(object): - __slots__ = () -class _coconut_base_hashable(object): - __slots__ = () - def __reduce_ex__(self, _): - return self.__reduce__() - def __eq__(self, other): - return self.__class__ is other.__class__ and self.__reduce__() == other.__reduce__() - def __hash__(self): - return _coconut.hash(self.__reduce__()) -class MatchError(_coconut_base_hashable, Exception): - """Pattern-matching error. Has attributes .pattern, .value, and .message.""" - __slots__ = ("pattern", "value", "_message") - max_val_repr_len = 500 - def __init__(self, pattern=None, value=None): - self.pattern = pattern - self.value = value - self._message = None - @property - def message(self): - if self._message is None: - value_repr = _coconut.repr(self.value) - self._message = "pattern-matching failed for %s in %s" % (_coconut.repr(self.pattern), value_repr if _coconut.len(value_repr) <= self.max_val_repr_len else value_repr[:self.max_val_repr_len] + "...") - Exception.__init__(self, self._message) - return self._message - def __repr__(self): - self.message - return Exception.__repr__(self) - def __str__(self): - self.message - return Exception.__str__(self) - def __unicode__(self): - self.message - return Exception.__unicode__(self) - def __reduce__(self): - return (self.__class__, (self.pattern, self.value)) -class _coconut_tail_call(object): - __slots__ = ("func", "args", "kwargs") - def __init__(self, _coconut_func, *args, **kwargs): - self.func = _coconut_func - self.args = args - self.kwargs = kwargs -_coconut_tco_func_dict = {} -def _coconut_tco(func): - @_coconut.functools.wraps(func) - def tail_call_optimized_func(*args, **kwargs): - call_func = func - while True: - if _coconut.isinstance(call_func, _coconut_base_pattern_func): - call_func = call_func._coconut_tco_func - elif _coconut.isinstance(call_func, _coconut.types.MethodType): - wkref = _coconut_tco_func_dict.get(_coconut.id(call_func.__func__)) - wkref_func = None if wkref is None else wkref() - if wkref_func is call_func.__func__: - if call_func.__self__ is None: - call_func = call_func._coconut_tco_func - else: - call_func = _coconut.functools.partial(call_func._coconut_tco_func, call_func.__self__) - else: - wkref = _coconut_tco_func_dict.get(_coconut.id(call_func)) - wkref_func = None if wkref is None else wkref() - if wkref_func is call_func: - call_func = call_func._coconut_tco_func - result = call_func(*args, **kwargs) # use coconut --no-tco to clean up your traceback - if not isinstance(result, _coconut_tail_call): - return result - call_func, args, kwargs = result.func, result.args, result.kwargs - tail_call_optimized_func._coconut_tco_func = func - tail_call_optimized_func.__module__ = _coconut.getattr(func, "__module__", None) - tail_call_optimized_func.__name__ = _coconut.getattr(func, "__name__", None) - tail_call_optimized_func.__qualname__ = _coconut.getattr(func, "__qualname__", None) - _coconut_tco_func_dict[_coconut.id(tail_call_optimized_func)] = _coconut.weakref.ref(tail_call_optimized_func) - return tail_call_optimized_func -def _coconut_iter_getitem_special_case(iterable, start, stop, step): - iterable = _coconut.itertools.islice(iterable, start, None) - cache = _coconut.collections.deque(_coconut.itertools.islice(iterable, -stop), maxlen=-stop) - for index, item in _coconut.enumerate(iterable): - cached_item = cache.popleft() - if index % step == 0: - yield cached_item - cache.append(item) -def _coconut_iter_getitem(iterable, index): - """Iterator slicing works just like sequence slicing, including support for negative indices and slices, and support for `slice` objects in the same way as can be done with normal slicing. - - Coconut's iterator slicing is very similar to Python's `itertools.islice`, but unlike `itertools.islice`, Coconut's iterator slicing supports negative indices, and will preferentially call an object's `__iter_getitem__` (Coconut-specific magic method, preferred) or `__getitem__` (general Python magic method), if they exist. Coconut's iterator slicing is also optimized to work well with all of Coconut's built-in objects, only computing the elements of each that are actually necessary to extract the desired slice. - - Some code taken from more_itertools under the terms of its MIT license. - """ - obj_iter_getitem = _coconut.getattr(iterable, "__iter_getitem__", None) - if obj_iter_getitem is None: - obj_iter_getitem = _coconut.getattr(iterable, "__getitem__", None) - if obj_iter_getitem is not None: - try: - result = obj_iter_getitem(index) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if not _coconut.isinstance(index, _coconut.slice): - index = _coconut.operator.index(index) - if index < 0: - return _coconut.collections.deque(iterable, maxlen=-index)[0] - result = _coconut.next(_coconut.itertools.islice(iterable, index, index + 1), _coconut_sentinel) - if result is _coconut_sentinel: - raise _coconut.IndexError("$[] index out of range") - return result - start = _coconut.operator.index(index.start) if index.start is not None else None - stop = _coconut.operator.index(index.stop) if index.stop is not None else None - step = _coconut.operator.index(index.step) if index.step is not None else 1 - if step == 0: - raise _coconut.ValueError("slice step cannot be zero") - if start is None and stop is None and step == -1: - obj_reversed = _coconut.getattr(iterable, "__reversed__", None) - if obj_reversed is not None: - try: - result = obj_reversed() - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if step >= 0: - start = 0 if start is None else start - if start < 0: - cache = _coconut.collections.deque(_coconut.enumerate(iterable, 1), maxlen=-start) - len_iter = cache[-1][0] if cache else 0 - i = _coconut.max(len_iter + start, 0) - if stop is None: - j = len_iter - elif stop >= 0: - j = _coconut.min(stop, len_iter) - else: - j = _coconut.max(len_iter + stop, 0) - n = j - i - if n <= 0: - return () - if n < -start or step != 1: - cache = _coconut.itertools.islice(cache, 0, n, step) - return _coconut_map(_coconut.operator.itemgetter(1), cache) - elif stop is None or stop >= 0: - return _coconut.itertools.islice(iterable, start, stop, step) - else: - return _coconut_iter_getitem_special_case(iterable, start, stop, step) - else: - start = -1 if start is None else start - if stop is not None and stop < 0: - n = -stop - 1 - cache = _coconut.collections.deque(_coconut.enumerate(iterable, 1), maxlen=n) - len_iter = cache[-1][0] if cache else 0 - if start < 0: - i, j = start, stop - else: - i, j = _coconut.min(start - len_iter, -1), None - return _coconut_map(_coconut.operator.itemgetter(1), _coconut.tuple(cache)[i:j:step]) - else: - if stop is not None: - m = stop + 1 - iterable = _coconut.itertools.islice(iterable, m, None) - if start < 0: - i = start - n = None - elif stop is None: - i = None - n = start + 1 - else: - i = None - n = start - stop - if n is not None: - if n <= 0: - return () - iterable = _coconut.itertools.islice(iterable, 0, n) - return _coconut.tuple(iterable)[i::step] -class _coconut_base_compose(_coconut_base_hashable): - __slots__ = ("func", "funcstars") - def __init__(self, func, *funcstars): - self.func = func - self.funcstars = [] - for f, stars in funcstars: - if _coconut.isinstance(f, _coconut_base_compose): - self.funcstars.append((f.func, stars)) - self.funcstars += f.funcstars - else: - self.funcstars.append((f, stars)) - self.funcstars = _coconut.tuple(self.funcstars) - def __call__(self, *args, **kwargs): - arg = self.func(*args, **kwargs) - for f, stars in self.funcstars: - if stars == 0: - arg = f(arg) - elif stars == 1: - arg = f(*arg) - elif stars == 2: - arg = f(**arg) - else: - raise _coconut.ValueError("invalid arguments to " + _coconut.repr(self)) - return arg - def __repr__(self): - return _coconut.repr(self.func) + " " + " ".join(("..*> " if star == 1 else "..**>" if star == 2 else "..> ") + _coconut.repr(f) for f, star in self.funcstars) - def __reduce__(self): - return (self.__class__, (self.func,) + self.funcstars) - def __get__(self, obj, objtype=None): - if obj is None: - return self - return _coconut.types.MethodType(self, obj, objtype) -def _coconut_forward_compose(func, *funcs): - """Forward composition operator (..>). - - (..>)(f, g) is effectively equivalent to (*args, **kwargs) -> g(f(*args, **kwargs)).""" - return _coconut_base_compose(func, *((f, 0) for f in funcs)) -def _coconut_back_compose(*funcs): - """Backward composition operator (<..). - - (<..)(f, g) is effectively equivalent to (*args, **kwargs) -> f(g(*args, **kwargs)).""" - return _coconut_forward_compose(*_coconut.reversed(funcs)) -def _coconut_forward_star_compose(func, *funcs): - """Forward star composition operator (..*>). - - (..*>)(f, g) is effectively equivalent to (*args, **kwargs) -> g(*f(*args, **kwargs)).""" - return _coconut_base_compose(func, *((f, 1) for f in funcs)) -def _coconut_back_star_compose(*funcs): - """Backward star composition operator (<*..). - - (<*..)(f, g) is effectively equivalent to (*args, **kwargs) -> f(*g(*args, **kwargs)).""" - return _coconut_forward_star_compose(*_coconut.reversed(funcs)) -def _coconut_forward_dubstar_compose(func, *funcs): - """Forward double star composition operator (..**>). - - (..**>)(f, g) is effectively equivalent to (*args, **kwargs) -> g(**f(*args, **kwargs)).""" - return _coconut_base_compose(func, *((f, 2) for f in funcs)) -def _coconut_back_dubstar_compose(*funcs): - """Backward double star composition operator (<**..). - - (<**..)(f, g) is effectively equivalent to (*args, **kwargs) -> f(**g(*args, **kwargs)).""" - return _coconut_forward_dubstar_compose(*_coconut.reversed(funcs)) -def _coconut_pipe(x, f): - """Pipe operator (|>). Equivalent to (x, f) -> f(x).""" - return f(x) -def _coconut_star_pipe(xs, f): - """Star pipe operator (*|>). Equivalent to (xs, f) -> f(*xs).""" - return f(*xs) -def _coconut_dubstar_pipe(kws, f): - """Double star pipe operator (**|>). Equivalent to (kws, f) -> f(**kws).""" - return f(**kws) -def _coconut_back_pipe(f, x): - """Backward pipe operator (<|). Equivalent to (f, x) -> f(x).""" - return f(x) -def _coconut_back_star_pipe(f, xs): - """Backward star pipe operator (<*|). Equivalent to (f, xs) -> f(*xs).""" - return f(*xs) -def _coconut_back_dubstar_pipe(f, kws): - """Backward double star pipe operator (<**|). Equivalent to (f, kws) -> f(**kws).""" - return f(**kws) -def _coconut_none_pipe(x, f): - """Nullable pipe operator (|?>). Equivalent to (x, f) -> f(x) if x is not None else None.""" - return None if x is None else f(x) -def _coconut_none_star_pipe(xs, f): - """Nullable star pipe operator (|?*>). Equivalent to (xs, f) -> f(*xs) if xs is not None else None.""" - return None if xs is None else f(*xs) -def _coconut_none_dubstar_pipe(kws, f): - """Nullable double star pipe operator (|?**>). Equivalent to (kws, f) -> f(**kws) if kws is not None else None.""" - return None if kws is None else f(**kws) -def _coconut_assert(cond, msg=None): - """Assert operator (assert). Asserts condition with optional message.""" - if not cond: - assert False, msg if msg is not None else "(assert) got falsey value " + _coconut.repr(cond) -def _coconut_raise(exc=None, from_exc=None): - """Raise operator (raise). Raises exception with optional cause.""" - if exc is None: - raise - if from_exc is not None: - exc.__cause__ = from_exc - raise exc -def _coconut_bool_and(a, b): - """Boolean and operator (and). Equivalent to (a, b) -> a and b.""" - return a and b -def _coconut_bool_or(a, b): - """Boolean or operator (or). Equivalent to (a, b) -> a or b.""" - return a or b -def _coconut_none_coalesce(a, b): - """None coalescing operator (??). Equivalent to (a, b) -> a if a is not None else b.""" - return b if a is None else a -def _coconut_minus(a, b=_coconut_sentinel): - """Minus operator (-). Effectively equivalent to (a, b=None) -> a - b if b is not None else -a.""" - if b is _coconut_sentinel: - return -a - return a - b -def _coconut_comma_op(*args): - """Comma operator (,). Equivalent to (*args) -> args.""" - return args -def _coconut_matmul(a, b, **kwargs): - """Matrix multiplication operator (@). Implements operator.matmul on any Python version.""" - in_place = kwargs.pop("in_place", False) - if kwargs: - raise _coconut.TypeError("_coconut_matmul() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if in_place and _coconut.hasattr(a, "__imatmul__"): - try: - result = a.__imatmul__(b) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if _coconut.hasattr(a, "__matmul__"): - try: - result = a.__matmul__(b) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if _coconut.hasattr(b, "__rmatmul__"): - try: - result = b.__rmatmul__(a) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if "numpy" in (a.__class__.__module__, b.__class__.__module__): - from numpy import matmul - return matmul(a, b) - raise _coconut.TypeError("unsupported operand type(s) for @: " + _coconut.repr(_coconut.type(a)) + " and " + _coconut.repr(_coconut.type(b))) -@_coconut.functools.wraps(_coconut.itertools.tee) -def tee(iterable, n=2): - if n >= 0 and _coconut.isinstance(iterable, (_coconut.tuple, _coconut.frozenset)): - return (iterable,) * n - if n > 0 and (_coconut.isinstance(iterable, _coconut.abc.Sequence) or _coconut.getattr(iterable, "__copy__", None) is not None): - return (iterable,) + _coconut.tuple(_coconut.copy.copy(iterable) for _ in _coconut.range(n - 1)) - return _coconut.itertools.tee(iterable, n) -class reiterable(_coconut_base_hashable): - """Allow an iterator to be iterated over multiple times with the same results.""" - __slots__ = ("lock", "iter") - def __new__(cls, iterable): - if _coconut.isinstance(iterable, _coconut_reiterable): - return iterable - self = _coconut.object.__new__(cls) - self.lock = _coconut.threading.Lock() - self.iter = iterable - return self - def get_new_iter(self): - with self.lock: - self.iter, new_iter = _coconut_tee(self.iter) - return new_iter - def __iter__(self): - return _coconut.iter(self.get_new_iter()) - def __getitem__(self, index): - return _coconut_iter_getitem(self.get_new_iter(), index) - def __reversed__(self): - return _coconut_reversed(self.get_new_iter()) - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "reiterable(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.iter,)) - def __copy__(self): - return self.__class__(self.get_new_iter()) - def __fmap__(self, func): - return _coconut_map(func, self) -class scan(_coconut_base_hashable): - """Reduce func over iterable, yielding intermediate results, - optionally starting from initial.""" - __slots__ = ("func", "iter", "initial") - def __init__(self, function, iterable, initial=_coconut_sentinel): - self.func = function - self.iter = iterable - self.initial = initial - def __iter__(self): - acc = self.initial - if acc is not _coconut_sentinel: - yield acc - for item in self.iter: - if acc is _coconut_sentinel: - acc = item - else: - acc = self.func(acc, item) - yield acc - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "scan(%r, %s%s)" % (self.func, _coconut.repr(self.iter), "" if self.initial is _coconut_sentinel else ", " + _coconut.repr(self.initial)) - def __reduce__(self): - return (self.__class__, (self.func, self.iter, self.initial)) - def __fmap__(self, func): - return _coconut_map(func, self) -class reversed(_coconut_base_hashable): - __slots__ = ("iter",) - if hasattr(_coconut.map, "__doc__"): - __doc__ = _coconut.reversed.__doc__ - def __new__(cls, iterable): - if _coconut.isinstance(iterable, _coconut.range): - return iterable[::-1] - if not _coconut.hasattr(iterable, "__reversed__") or _coconut.isinstance(iterable, (_coconut.list, _coconut.tuple)): - return _coconut.object.__new__(cls) - return _coconut.reversed(iterable) - def __init__(self, iterable): - self.iter = iterable - def __iter__(self): - return _coconut.iter(_coconut.reversed(self.iter)) - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return _coconut_iter_getitem(self.iter, _coconut.slice(-(index.start + 1) if index.start is not None else None, -(index.stop + 1) if index.stop else None, -(index.step if index.step is not None else 1))) - return _coconut_iter_getitem(self.iter, -(index + 1)) - def __reversed__(self): - return self.iter - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "reversed(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.iter,)) - def __contains__(self, elem): - return elem in self.iter - def count(self, elem): - """Count the number of times elem appears in the reversed iterable.""" - return self.iter.count(elem) - def index(self, elem): - """Find the index of elem in the reversed iterable.""" - return _coconut.len(self.iter) - self.iter.index(elem) - 1 - def __fmap__(self, func): - return self.__class__(_coconut_map(func, self.iter)) -class flatten(_coconut_base_hashable): - """Flatten an iterable of iterables into a single iterable.""" - __slots__ = ("iter",) - def __init__(self, iterable): - self.iter = iterable - def __iter__(self): - return _coconut.itertools.chain.from_iterable(self.iter) - def __reversed__(self): - return self.__class__(_coconut_reversed(_coconut_map(_coconut_reversed, self.iter))) - def __repr__(self): - return "flatten(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.iter,)) - def __contains__(self, elem): - self.iter, new_iter = _coconut_tee(self.iter) - return _coconut.any(elem in it for it in new_iter) - def count(self, elem): - """Count the number of times elem appears in the flattened iterable.""" - self.iter, new_iter = _coconut_tee(self.iter) - return _coconut.sum(it.count(elem) for it in new_iter) - def index(self, elem): - self.iter, new_iter = _coconut_tee(self.iter) - ind = 0 - for it in new_iter: - try: - return ind + it.index(elem) - except _coconut.ValueError: - ind += _coconut.len(it) - raise ValueError("%r not in %r" % (elem, self)) - def __fmap__(self, func): - return self.__class__(_coconut_map(_coconut.functools.partial(_coconut_map, func), self.iter)) -class map(_coconut_base_hashable, _coconut.map): - __slots__ = ("func", "iters") - if hasattr(_coconut.map, "__doc__"): - __doc__ = _coconut.map.__doc__ - def __new__(cls, function, *iterables): - new_map = _coconut.map.__new__(cls, function, *iterables) - new_map.func = function - new_map.iters = iterables - return new_map - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(self.func, *(_coconut_iter_getitem(i, index) for i in self.iters)) - return self.func(*(_coconut_iter_getitem(i, index) for i in self.iters)) - def __reversed__(self): - return self.__class__(self.func, *(_coconut_reversed(i) for i in self.iters)) - def __len__(self): - return _coconut.min(_coconut.len(i) for i in self.iters) - def __repr__(self): - return "map(%r, %s)" % (self.func, ", ".join((_coconut.repr(i) for i in self.iters))) - def __reduce__(self): - return (self.__class__, (self.func,) + self.iters) - def __iter__(self): - return _coconut.iter(_coconut.map(self.func, *self.iters)) - def __fmap__(self, func): - return self.__class__(_coconut_forward_compose(self.func, func), *self.iters) -class _coconut_parallel_concurrent_map_func_wrapper(_coconut_base_hashable): - __slots__ = ("map_cls", "func", "star") - def __init__(self, map_cls, func, star): - self.map_cls = map_cls - self.func = func - self.star = star - def __reduce__(self): - return (self.__class__, (self.map_cls, self.func, self.star)) - def __call__(self, *args, **kwargs): - self.map_cls.get_pool_stack().append(None) - try: - if self.star: - assert _coconut.len(args) == 1, "internal parallel/concurrent map error (you should report this at https://github.com/evhub/coconut/issues/new)" - return self.func(*args[0], **kwargs) - else: - return self.func(*args, **kwargs) - except: - _coconut.print(self.map_cls.__name__ + " error:") - _coconut.traceback.print_exc() - raise - finally: - assert self.map_cls.get_pool_stack().pop() is None, "internal parallel/concurrent map error (you should report this at https://github.com/evhub/coconut/issues/new)" -class _coconut_base_parallel_concurrent_map(map): - __slots__ = ("result", "chunksize") - @classmethod - def get_pool_stack(cls): - return cls.threadlocal_ns.__dict__.setdefault("pool_stack", [None]) - def __new__(cls, function, *iterables, **kwargs): - self = _coconut_map.__new__(cls, function, *iterables) - self.result = None - self.chunksize = kwargs.pop("chunksize", 1) - if kwargs: - raise _coconut.TypeError(cls.__name__ + "() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if cls.get_pool_stack()[-1] is not None: - return self.get_list() - return self - @classmethod - @_coconut.contextlib.contextmanager - def multiple_sequential_calls(cls, max_workers=None): - """Context manager that causes nested calls to use the same pool.""" - if cls.get_pool_stack()[-1] is None: - cls.get_pool_stack()[-1] = cls.make_pool(max_workers) - try: - yield - finally: - cls.get_pool_stack()[-1].terminate() - cls.get_pool_stack()[-1] = None - else: - yield - def get_list(self): - if self.result is None: - with self.multiple_sequential_calls(): - if _coconut.len(self.iters) == 1: - self.result = _coconut.list(self.get_pool_stack()[-1].imap(_coconut_parallel_concurrent_map_func_wrapper(self.__class__, self.func, False), self.iters[0], self.chunksize)) - else: - self.result = _coconut.list(self.get_pool_stack()[-1].imap(_coconut_parallel_concurrent_map_func_wrapper(self.__class__, self.func, True), _coconut.zip(*self.iters), self.chunksize)) - return self.result - def __iter__(self): - return _coconut.iter(self.get_list()) -class parallel_map(_coconut_base_parallel_concurrent_map): - """Multi-process implementation of map. Requires arguments to be pickleable. - - For multiple sequential calls, use: - with parallel_map.multiple_sequential_calls(): - ... - """ - __slots__ = () - threadlocal_ns = _coconut.threading.local() - @staticmethod - def make_pool(max_workers=None): - return _coconut.multiprocessing.Pool(max_workers) - def __repr__(self): - return "parallel_" + _coconut_map.__repr__(self) -class concurrent_map(_coconut_base_parallel_concurrent_map): - """Multi-thread implementation of map. - - For multiple sequential calls, use: - with concurrent_map.multiple_sequential_calls(): - ... - """ - __slots__ = () - threadlocal_ns = _coconut.threading.local() - @staticmethod - def make_pool(max_workers=None): - return _coconut.multiprocessing_dummy.Pool(_coconut.multiprocessing.cpu_count() * 5 if max_workers is None else max_workers) - def __repr__(self): - return "concurrent_" + _coconut_map.__repr__(self) -class filter(_coconut_base_hashable, _coconut.filter): - __slots__ = ("func", "iter") - if hasattr(_coconut.filter, "__doc__"): - __doc__ = _coconut.filter.__doc__ - def __new__(cls, function, iterable): - new_filter = _coconut.filter.__new__(cls, function, iterable) - new_filter.func = function - new_filter.iter = iterable - return new_filter - def __reversed__(self): - return self.__class__(self.func, _coconut_reversed(self.iter)) - def __repr__(self): - return "filter(%r, %s)" % (self.func, _coconut.repr(self.iter)) - def __reduce__(self): - return (self.__class__, (self.func, self.iter)) - def __iter__(self): - return _coconut.iter(_coconut.filter(self.func, self.iter)) - def __fmap__(self, func): - return _coconut_map(func, self) -class zip(_coconut_base_hashable, _coconut.zip): - __slots__ = ("iters", "strict") - if hasattr(_coconut.zip, "__doc__"): - __doc__ = _coconut.zip.__doc__ - def __new__(cls, *iterables, **kwargs): - new_zip = _coconut.zip.__new__(cls, *iterables) - new_zip.iters = iterables - new_zip.strict = kwargs.pop("strict", False) - if kwargs: - raise _coconut.TypeError("zip() got unexpected keyword arguments " + _coconut.repr(kwargs)) - return new_zip - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(*(_coconut_iter_getitem(i, index) for i in self.iters), strict=self.strict) - return _coconut.tuple(_coconut_iter_getitem(i, index) for i in self.iters) - def __reversed__(self): - return self.__class__(*(_coconut_reversed(i) for i in self.iters), strict=self.strict) - def __len__(self): - return _coconut.min(_coconut.len(i) for i in self.iters) - def __repr__(self): - return "zip(%s%s)" % (", ".join((_coconut.repr(i) for i in self.iters)), ", strict=True" if self.strict else "") - def __reduce__(self): - return (self.__class__, self.iters, self.strict) - def __setstate__(self, strict): - self.strict = strict - def __iter__(self): - for items in _coconut.iter(_coconut.zip_longest(*self.iters, fillvalue=_coconut_sentinel) if self.strict else _coconut.zip(*self.iters)): - if self.strict and _coconut.any(x is _coconut_sentinel for x in items): - raise _coconut.ValueError("zip(..., strict=True) arguments have mismatched lengths") - yield items - def __fmap__(self, func): - return _coconut_map(func, self) -class zip_longest(zip): - __slots__ = ("fillvalue",) - if hasattr(_coconut.zip_longest, "__doc__"): - __doc__ = (_coconut.zip_longest).__doc__ - def __new__(cls, *iterables, **kwargs): - self = _coconut_zip.__new__(cls, *iterables, strict=False) - self.fillvalue = kwargs.pop("fillvalue", None) - if kwargs: - raise _coconut.TypeError("zip_longest() got unexpected keyword arguments " + _coconut.repr(kwargs)) - return self - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - new_ind = _coconut.slice(index.start + self.__len__() if index.start is not None and index.start < 0 else index.start, index.stop + self.__len__() if index.stop is not None and index.stop < 0 else index.stop, index.step) - return self.__class__(*(_coconut_iter_getitem(i, new_ind) for i in self.iters)) - if index < 0: - index += self.__len__() - result = [] - got_non_default = False - for it in self.iters: - try: - result.append(_coconut_iter_getitem(it, index)) - except _coconut.IndexError: - result.append(self.fillvalue) - else: - got_non_default = True - if not got_non_default: - raise _coconut.IndexError("zip_longest index out of range") - return _coconut.tuple(result) - def __len__(self): - return _coconut.max(_coconut.len(i) for i in self.iters) - def __repr__(self): - return "zip_longest(%s, fillvalue=%s)" % (", ".join((_coconut.repr(i) for i in self.iters)), _coconut.repr(self.fillvalue)) - def __reduce__(self): - return (self.__class__, self.iters, self.fillvalue) - def __setstate__(self, fillvalue): - self.fillvalue = fillvalue - def __iter__(self): - return _coconut.iter(_coconut.zip_longest(*self.iters, fillvalue=self.fillvalue)) -class enumerate(_coconut_base_hashable, _coconut.enumerate): - __slots__ = ("iter", "start") - if hasattr(_coconut.enumerate, "__doc__"): - __doc__ = _coconut.enumerate.__doc__ - def __new__(cls, iterable, start=0): - new_enumerate = _coconut.enumerate.__new__(cls, iterable, start) - new_enumerate.iter = iterable - new_enumerate.start = start - return new_enumerate - def __repr__(self): - return "enumerate(%s, %r)" % (_coconut.repr(self.iter), self.start) - def __fmap__(self, func): - return _coconut_map(func, self) - def __reduce__(self): - return (self.__class__, (self.iter, self.start)) - def __iter__(self): - return _coconut.iter(_coconut.enumerate(self.iter, self.start)) - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(_coconut_iter_getitem(self.iter, index), self.start + (0 if index.start is None else index.start if index.start >= 0 else _coconut.len(self.iter) + index.start)) - return (self.start + index, _coconut_iter_getitem(self.iter, index)) - def __len__(self): - return _coconut.len(self.iter) -class multi_enumerate(_coconut_base_hashable): - """Enumerate an iterable of iterables. Works like enumerate, but indexes - through inner iterables and produces a tuple index representing the index - in each inner iterable. Supports indexing. - - For numpy arrays, effectively equivalent to: - it = np.nditer(iterable, flags=["multi_index"]) - for x in it: - yield it.multi_index, x - - Also supports len for numpy arrays. - """ - __slots__ = ("iter",) - def __init__(self, iterable): - self.iter = iterable - def __repr__(self): - return "multi_enumerate(%s)" % (_coconut.repr(self.iter),) - def __fmap__(self, func): - return _coconut_map(func, self) - def __reduce__(self): - return (self.__class__, (self.iter,)) - @property - def is_numpy(self): - return self.iter.__class__.__module__ in _coconut.numpy_modules - def __iter__(self): - if self.is_numpy: - it = _coconut.numpy.nditer(self.iter, flags=["multi_index"]) - for x in it: - yield it.multi_index, x - else: - ind = [-1] - its = [_coconut.iter(self.iter)] - while its: - ind[-1] += 1 - try: - x = _coconut.next(its[-1]) - except _coconut.StopIteration: - ind.pop() - its.pop() - else: - if _coconut.isinstance(x, _coconut.abc.Iterable): - ind.append(-1) - its.append(_coconut.iter(x)) - else: - yield _coconut.tuple(ind), x - def __getitem__(self, index): - if self.is_numpy and not _coconut.isinstance(index, _coconut.slice): - multi_ind = [] - for i in _coconut.reversed(self.iter.shape): - multi_ind.append(index % i) - index //= i - multi_ind = _coconut.tuple(_coconut.reversed(multi_ind)) - return multi_ind, self.iter[multi_ind] - return _coconut_iter_getitem(_coconut.iter(self), index) - def __len__(self): - if self.is_numpy: - return self.iter.size - return _coconut.NotImplemented -class count(_coconut_base_hashable): - """count(start, step) returns an infinite iterator starting at start and increasing by step. - - If step is set to 0, count will infinitely repeat its first argument. - """ - __slots__ = ("start", "step") - def __init__(self, start=0, step=1): - self.start = start - self.step = step - def __iter__(self): - while True: - yield self.start - if self.step: - self.start += self.step - def __contains__(self, elem): - if not self.step: - return elem == self.start - if self.step > 0 and elem < self.start or self.step < 0 and elem > self.start: - return False - return (elem - self.start) % self.step == 0 - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - if (index.start is None or index.start >= 0) and (index.stop is None or index.stop >= 0): - new_start, new_step = self.start, self.step - if self.step and index.start is not None: - new_start += self.step * index.start - if self.step and index.step is not None: - new_step *= index.step - if index.stop is None: - return self.__class__(new_start, new_step) - if self.step and _coconut.isinstance(self.start, _coconut.int) and _coconut.isinstance(self.step, _coconut.int): - return _coconut.range(new_start, self.start + self.step * index.stop, new_step) - return _coconut_map(self.__getitem__, _coconut.range(index.start if index.start is not None else 0, index.stop, index.step if index.step is not None else 1)) - raise _coconut.IndexError("count() indices must be positive") - if index < 0: - raise _coconut.IndexError("count() indices must be positive") - return self.start + self.step * index if self.step else self.start - def count(self, elem): - """Count the number of times elem appears in the count.""" - if not self.step: - return _coconut.float("inf") if elem == self.start else 0 - return _coconut.int(elem in self) - def index(self, elem): - """Find the index of elem in the count.""" - if elem not in self: - raise _coconut.ValueError(_coconut.repr(elem) + " not in " + _coconut.repr(self)) - return (elem - self.start) // self.step if self.step else 0 - def __reversed__(self): - if not self.step: - return self - raise _coconut.TypeError(_coconut.repr(self) + " object is not reversible") - def __repr__(self): - return "count(%s, %s)" % (_coconut.repr(self.start), _coconut.repr(self.step)) - def __reduce__(self): - return (self.__class__, (self.start, self.step)) - def __copy__(self): - return self.__class__(self.start, self.step) - def __fmap__(self, func): - return _coconut_map(func, self) -class groupsof(_coconut_base_hashable): - """groupsof(n, iterable) splits iterable into groups of size n. - - If the length of the iterable is not divisible by n, the last group will be of size < n. - """ - __slots__ = ("group_size", "iter") - def __init__(self, n, iterable): - self.group_size = _coconut.operator.index(n) - if self.group_size <= 0: - raise _coconut.ValueError("group size must be > 0; not %r" % (self.group_size,)) - self.iter = iterable - def __iter__(self): - iterator = _coconut.iter(self.iter) - loop = True - while loop: - group = [] - for _ in _coconut.range(self.group_size): - try: - group.append(_coconut.next(iterator)) - except _coconut.StopIteration: - loop = False - break - if group: - yield _coconut.tuple(group) - def __len__(self): - return _coconut.int(_coconut.math.ceil(_coconut.len(self.iter) / self.group_size)) - def __repr__(self): - return "groupsof(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.group_size, self.iter)) - def __fmap__(self, func): - return _coconut_map(func, self) -class recursive_iterator(_coconut_base_hashable): - """Decorator that optimizes a recursive function that returns an iterator (e.g. a recursive generator).""" - __slots__ = ("func", "tee_store", "backup_tee_store") - def __init__(self, func): - self.func = func - self.tee_store = {} - self.backup_tee_store = [] - def __call__(self, *args, **kwargs): - key = (args, _coconut.frozenset(kwargs.items())) - use_backup = False - try: - _coconut.hash(key) - except _coconut.Exception: - try: - key = _coconut.pickle.dumps(key, -1) - except _coconut.Exception: - use_backup = True - if use_backup: - for i, (k, v) in _coconut.enumerate(self.backup_tee_store): - if k == key: - to_tee, store_pos = v, i - break - else: - to_tee = self.func(*args, **kwargs) - store_pos = None - to_store, to_return = _coconut_tee(to_tee) - if store_pos is None: - self.backup_tee_store.append([key, to_store]) - else: - self.backup_tee_store[store_pos][1] = to_store - else: - it = self.tee_store.get(key) - if it is None: - it = self.func(*args, **kwargs) - self.tee_store[key], to_return = _coconut_tee(it) - return to_return - def __repr__(self): - return "recursive_iterator(%r)" % (self.func,) - def __reduce__(self): - return (self.__class__, (self.func,)) - def __get__(self, obj, objtype=None): - if obj is None: - return self - return _coconut.types.MethodType(self, obj, objtype) -class _coconut_FunctionMatchErrorContext(object): - __slots__ = ("exc_class", "taken") - threadlocal_ns = _coconut.threading.local() - def __init__(self, exc_class): - self.exc_class = exc_class - self.taken = False - @classmethod - def get_contexts(cls): - try: - return cls.threadlocal_ns.contexts - except _coconut.AttributeError: - cls.threadlocal_ns.contexts = [] - return cls.threadlocal_ns.contexts - def __enter__(self): - self.get_contexts().append(self) - def __exit__(self, type, value, traceback): - self.get_contexts().pop() -def _coconut_get_function_match_error(): - try: - ctx = _coconut_FunctionMatchErrorContext.get_contexts()[-1] - except _coconut.IndexError: - return _coconut_MatchError - if ctx.taken: - return _coconut_MatchError - ctx.taken = True - return ctx.exc_class -class _coconut_base_pattern_func(_coconut_base_hashable): - __slots__ = ("FunctionMatchError", "patterns", "__doc__", "__name__") - _coconut_is_match = True - def __init__(self, *funcs): - self.FunctionMatchError = _coconut.type(_coconut_py_str("MatchError"), (_coconut_MatchError,), {}) - self.patterns = [] - self.__doc__ = None - self.__name__ = None - - for func in funcs: - self.add_pattern(func) - def add_pattern(self, func): - if _coconut.isinstance(func, _coconut_base_pattern_func): - self.patterns += func.patterns - else: - self.patterns.append(func) - self.__doc__ = _coconut.getattr(func, "__doc__", self.__doc__) - self.__name__ = _coconut.getattr(func, "__name__", self.__name__) - - def __call__(self, *args, **kwargs): - for func in self.patterns[:-1]: - try: - with _coconut_FunctionMatchErrorContext(self.FunctionMatchError): - return func(*args, **kwargs) - except self.FunctionMatchError: - pass - return self.patterns[-1](*args, **kwargs) - def _coconut_tco_func(self, *args, **kwargs): - for func in self.patterns[:-1]: - try: - with _coconut_FunctionMatchErrorContext(self.FunctionMatchError): - return func(*args, **kwargs) - except self.FunctionMatchError: - pass - return _coconut_tail_call(self.patterns[-1], *args, **kwargs) - def __repr__(self): - return "addpattern(%r)(*%r)" % (self.patterns[0], self.patterns[1:]) - def __reduce__(self): - return (self.__class__, _coconut.tuple(self.patterns)) - def __get__(self, obj, objtype=None): - if obj is None: - return self - return _coconut.types.MethodType(self, obj, objtype) -def _coconut_mark_as_match(base_func): - base_func._coconut_is_match = True - return base_func -def addpattern(base_func, new_pattern=None, **kwargs): - """Decorator to add a new case to a pattern-matching function (where the new case is checked last). - - Pass allow_any_func=True to allow any object as the base_func rather than just pattern-matching functions. - If new_pattern is passed, addpattern(base_func, new_pattern) is equivalent to addpattern(base_func)(new_pattern). - """ - allow_any_func = kwargs.pop("allow_any_func", False) - if not allow_any_func and not _coconut.getattr(base_func, "_coconut_is_match", False): - _coconut.warnings.warn("Possible misuse of addpattern with non-pattern-matching function " + _coconut.repr(base_func) + " (pass allow_any_func=True to dismiss)", stacklevel=2) - if kwargs: - raise _coconut.TypeError("addpattern() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if new_pattern is not None: - return _coconut_base_pattern_func(base_func, new_pattern) - return _coconut.functools.partial(_coconut_base_pattern_func, base_func) -_coconut_addpattern = addpattern -def prepattern(base_func, **kwargs): - """DEPRECATED: use addpattern instead.""" - def pattern_prepender(func): - return addpattern(func, **kwargs)(base_func) - return pattern_prepender -class _coconut_partial(_coconut_base_hashable): - __slots__ = ("func", "_argdict", "_arglen", "_pos_kwargs", "_stargs", "keywords") - if hasattr(_coconut.functools.partial, "__doc__"): - __doc__ = _coconut.functools.partial.__doc__ - def __init__(self, _coconut_func, _coconut_argdict, _coconut_arglen, _coconut_pos_kwargs, *args, **kwargs): - self.func = _coconut_func - self._argdict = _coconut_argdict - self._arglen = _coconut_arglen - self._pos_kwargs = _coconut_pos_kwargs - self._stargs = args - self.keywords = kwargs - def __reduce__(self): - return (self.__class__, (self.func, self._argdict, self._arglen, self._pos_kwargs) + self._stargs, self.keywords) - def __setstate__(self, keywords): - self.keywords = keywords - @property - def args(self): - return _coconut.tuple(self._argdict.get(i) for i in _coconut.range(self._arglen)) + self._stargs - @property - def required_nargs(self): - return self._arglen - _coconut.len(self._argdict) + len(self._pos_kwargs) - def __call__(self, *args, **kwargs): - callargs = [] - argind = 0 - for i in _coconut.range(self._arglen): - if i in self._argdict: - callargs.append(self._argdict[i]) - elif argind >= _coconut.len(args): - raise _coconut.TypeError("expected at least " + _coconut.str(self.required_nargs) + " argument(s) to " + _coconut.repr(self)) - else: - callargs.append(args[argind]) - argind += 1 - for k in self._pos_kwargs: - if k in kwargs: - raise _coconut.TypeError(_coconut.repr(k) + " is an invalid keyword argument for " + _coconut.repr(self)) - elif argind >= _coconut.len(args): - raise _coconut.TypeError("expected at least " + _coconut.str(self.required_nargs) + " argument(s) to " + _coconut.repr(self)) - else: - kwargs[k] = args[argind] - argind += 1 - callargs += self._stargs - callargs += args[argind:] - callkwargs = self.keywords.copy() - callkwargs.update(kwargs) - return self.func(*callargs, **callkwargs) - def __repr__(self): - args = [] - for i in _coconut.range(self._arglen): - if i in self._argdict: - args.append(_coconut.repr(self._argdict[i])) - else: - args.append("?") - for arg in self._stargs: - args.append(_coconut.repr(arg)) - for k in self._pos_kwargs: - args.append(k + "=?") - for k, v in self.keywords.items(): - args.append(k + "=" + _coconut.repr(v)) - return "%r$(%s)" % (self.func, ", ".join(args)) -def consume(iterable, keep_last=0): - """consume(iterable, keep_last) fully exhausts iterable and returns the last keep_last elements.""" - return _coconut.collections.deque(iterable, maxlen=keep_last) -class starmap(_coconut_base_hashable, _coconut.itertools.starmap): - __slots__ = ("func", "iter") - if hasattr(_coconut.itertools.starmap, "__doc__"): - __doc__ = _coconut.itertools.starmap.__doc__ - def __new__(cls, function, iterable): - new_map = _coconut.itertools.starmap.__new__(cls, function, iterable) - new_map.func = function - new_map.iter = iterable - return new_map - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(self.func, _coconut_iter_getitem(self.iter, index)) - return self.func(*_coconut_iter_getitem(self.iter, index)) - def __reversed__(self): - return self.__class__(self.func, *_coconut_reversed(self.iter)) - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "starmap(%r, %s)" % (self.func, _coconut.repr(self.iter)) - def __reduce__(self): - return (self.__class__, (self.func, self.iter)) - def __iter__(self): - return _coconut.iter(_coconut.itertools.starmap(self.func, self.iter)) - def __fmap__(self, func): - return self.__class__(_coconut_forward_compose(self.func, func), self.iter) -def _coconut_base_makedata(data_type, args): - if _coconut.hasattr(data_type, "_make") and _coconut.issubclass(data_type, _coconut.tuple): - return data_type._make(args) - if _coconut.issubclass(data_type, (_coconut.range, _coconut.abc.Iterator)): - return args - if _coconut.issubclass(data_type, _coconut.str): - return "".join(args) - return data_type(args) -def makedata(data_type, *args): - """Construct an object of the given data_type containing the given arguments.""" - return _coconut_base_makedata(data_type, args) -def datamaker(data_type): - """DEPRECATED: use makedata instead.""" - return _coconut.functools.partial(makedata, data_type) -_coconut_amap = None -def fmap(func, obj, **kwargs): - """fmap(func, obj) creates a copy of obj with func applied to its contents. - Supports asynchronous iterables, mappings (maps over .items()), and numpy arrays (uses np.vectorize). - - Override by defining obj.__fmap__(func). - """ - starmap_over_mappings = kwargs.pop("starmap_over_mappings", False) - if kwargs: - raise _coconut.TypeError("fmap() got unexpected keyword arguments " + _coconut.repr(kwargs)) - obj_fmap = _coconut.getattr(obj, "__fmap__", None) - if obj_fmap is not None: - try: - result = obj_fmap(func) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if obj.__class__.__module__ in _coconut.jax_numpy_modules: - import jax.numpy as jnp - return jnp.vectorize(func)(obj) - if obj.__class__.__module__ in _coconut.numpy_modules: - return _coconut.numpy.vectorize(func)(obj) - obj_aiter = _coconut.getattr(obj, "__aiter__", None) - if obj_aiter is not None and _coconut_amap is not None: - try: - aiter = obj_aiter() - except _coconut.NotImplementedError: - pass - else: - if aiter is not _coconut.NotImplemented: - return _coconut_amap(func, aiter) - if starmap_over_mappings: - return _coconut_base_makedata(obj.__class__, _coconut_starmap(func, obj.items()) if _coconut.isinstance(obj, _coconut.abc.Mapping) else _coconut_map(func, obj)) - else: - return _coconut_base_makedata(obj.__class__, _coconut_map(func, obj.items() if _coconut.isinstance(obj, _coconut.abc.Mapping) else obj)) -def memoize(maxsize=None, *args, **kwargs): - """Decorator that memoizes a function, preventing it from being recomputed - if it is called multiple times with the same arguments.""" - return _coconut.functools.lru_cache(maxsize, *args, **kwargs) -def _coconut_call_set_names(cls): - for k, v in _coconut.vars(cls).items(): - set_name = _coconut.getattr(v, "__set_name__", None) - if set_name is not None: - set_name(cls, k) -class override(_coconut_base_hashable): - __slots__ = ("func",) - def __init__(self, func): - self.func = func - def __get__(self, obj, objtype=None): - if obj is None: - return self.func - return _coconut.types.MethodType(self.func, obj, objtype) - def __set_name__(self, obj, name): - if not _coconut.hasattr(_coconut.super(obj, obj), name): - raise _coconut.RuntimeError(obj.__name__ + "." + name + " marked with @override but not overriding anything") - def __reduce__(self): - return (self.__class__, (self.func,)) -def reveal_type(obj): - """Special function to get MyPy to print the type of the given expression. - At runtime, reveal_type is the identity function.""" - return obj -def reveal_locals(): - """Special function to get MyPy to print the type of the current locals. - At runtime, reveal_locals always returns None.""" - pass -def _coconut_handle_cls_kwargs(**kwargs): - """Some code taken from six under the terms of its MIT license.""" - metaclass = kwargs.pop("metaclass", None) - if kwargs and metaclass is None: - raise _coconut.TypeError("unexpected keyword argument(s) in class definition: %r" % (kwargs,)) - def coconut_handle_cls_kwargs_wrapper(cls): - if metaclass is None: - return cls - orig_vars = cls.__dict__.copy() - slots = orig_vars.get("__slots__") - if slots is not None: - if _coconut.isinstance(slots, _coconut.str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop("__dict__", None) - orig_vars.pop("__weakref__", None) - if _coconut.hasattr(cls, "__qualname__"): - orig_vars["__qualname__"] = cls.__qualname__ - return metaclass(cls.__name__, cls.__bases__, orig_vars, **kwargs) - return coconut_handle_cls_kwargs_wrapper -def _coconut_handle_cls_stargs(*args): - temp_names = ["_coconut_base_cls_%s" % (i,) for i in _coconut.range(_coconut.len(args))] - ns = _coconut.dict(_coconut.zip(temp_names, args)) - _coconut_exec("class _coconut_cls_stargs_base(" + ", ".join(temp_names) + "): pass", ns) - return ns["_coconut_cls_stargs_base"] -def _coconut_dict_merge(*dicts, **kwargs): - for_func = kwargs.pop("for_func", False) - assert not kwargs, "error with internal Coconut function _coconut_dict_merge (you should report this at https://github.com/evhub/coconut/issues/new)" - newdict = {} - prevlen = 0 - for d in dicts: - newdict.update(d) - if for_func: - if _coconut.len(newdict) != prevlen + _coconut.len(d): - raise _coconut.TypeError("multiple values for the same keyword argument") - prevlen = _coconut.len(newdict) - return newdict -def ident(x, **kwargs): - """The identity function. Generally equivalent to x -> x. Useful in point-free programming. - Accepts one keyword-only argument, side_effect, which specifies a function to call on the argument before it is returned.""" - side_effect = kwargs.pop("side_effect", None) - if kwargs: - raise _coconut.TypeError("ident() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if side_effect is not None: - side_effect(x) - return x -def of(_coconut_f, *args, **kwargs): - """Function application operator function. - - Equivalent to: - def of(f, *args, **kwargs) = f(*args, **kwargs). - """ - return _coconut_f(*args, **kwargs) -class flip(_coconut_base_hashable): - """Given a function, return a new function with inverse argument order. - If nargs is passed, only the first nargs arguments are reversed.""" - __slots__ = ("func", "nargs") - def __init__(self, func, nargs=None): - self.func = func - self.nargs = nargs - def __reduce__(self): - return (self.__class__, (self.func, self.nargs)) - def __call__(self, *args, **kwargs): - return self.func(*args[::-1], **kwargs) if self.nargs is None else self.func(*(args[self.nargs-1::-1] + args[self.nargs:]), **kwargs) - def __repr__(self): - return "flip(%r%s)" % (self.func, "" if self.nargs is None else ", " + _coconut.repr(self.nargs)) -class const(_coconut_base_hashable): - """Create a function that, whatever its arguments, just returns the given value.""" - __slots__ = ("value",) - def __init__(self, value): - self.value = value - def __reduce__(self): - return (self.__class__, (self.value,)) - def __call__(self, *args, **kwargs): - return self.value - def __repr__(self): - return "const(%s)" % (_coconut.repr(self.value),) -class _coconut_lifted(_coconut_base_hashable): - __slots__ = ("func", "func_args", "func_kwargs") - def __init__(self, _coconut_func, *func_args, **func_kwargs): - self.func = _coconut_func - self.func_args = func_args - self.func_kwargs = func_kwargs - def __reduce__(self): - return (self.__class__, (self.func,) + self.func_args, self.func_kwargs) - def __setstate__(self, func_kwargs): - self.func_kwargs = func_kwargs - def __call__(self, *args, **kwargs): - return self.func(*(g(*args, **kwargs) for g in self.func_args), **_coconut.dict((k, h(*args, **kwargs)) for k, h in self.func_kwargs.items())) - def __repr__(self): - return "lift(%r)(%s%s)" % (self.func, ", ".join(_coconut.repr(g) for g in self.func_args), ", ".join(k + "=" + _coconut.repr(h) for k, h in self.func_kwargs.items())) -class lift(_coconut_base_hashable): - """Lifts a function up so that all of its arguments are functions. - - For a binary function f(x, y) and two unary functions g(z) and h(z), lift works as the S' combinator: - lift(f)(g, h)(z) == f(g(z), h(z)) - - In general, lift is requivalent to: - def lift(f) = ((*func_args, **func_kwargs) -> (*args, **kwargs) -> - f(*(g(*args, **kwargs) for g in func_args), **{k: h(*args, **kwargs) for k, h in func_kwargs.items()})) - - lift also supports a shortcut form such that lift(f, *func_args, **func_kwargs) is equivalent to lift(f)(*func_args, **func_kwargs). - """ - __slots__ = ("func",) - def __new__(cls, func, *func_args, **func_kwargs): - self = _coconut.object.__new__(cls) - self.func = func - if func_args or func_kwargs: - self = self(*func_args, **func_kwargs) - return self - def __reduce__(self): - return (self.__class__, (self.func,)) - def __call__(self, *func_args, **func_kwargs): - return _coconut_lifted(self.func, *func_args, **func_kwargs) - def __repr__(self): - return "lift(%r)" % (self.func,) -def all_equal(iterable): - """For a given iterable, check whether all elements in that iterable are equal to each other. - - Assumes transitivity and 'x != y' being equivalent to 'not (x == y)'. - """ - first_item = _coconut_sentinel - for item in iterable: - if first_item is _coconut_sentinel: - first_item = item - elif first_item != item: - return False - return True -def collectby(key_func, iterable, value_func=None, reduce_func=None): - """Collect the items in iterable into a dictionary of lists keyed by key_func(item). - - if value_func is passed, collect value_func(item) into each list instead of item. - - If reduce_func is passed, instead of collecting the items into lists, reduce over - the items of each key with reduce_func, effectively implementing a MapReduce operation. - """ - collection = _coconut.collections.defaultdict(_coconut.list) if reduce_func is None else {} - for item in iterable: - key = key_func(item) - if value_func is not None: - item = value_func(item) - if reduce_func is None: - collection[key].append(item) - else: - old_item = collection.get(key, _coconut_sentinel) - if old_item is not _coconut_sentinel: - item = reduce_func(old_item, item) - collection[key] = item - return collection -def _namedtuple_of(**kwargs): - """Construct an anonymous namedtuple of the given keyword arguments.""" - raise _coconut.RuntimeError("_namedtuple_of is not available on Python < 3.6 (use anonymous namedtuple literals instead)") -def _coconut_mk_anon_namedtuple(fields, types=None, of_kwargs=None): - if types is None: - NT = _coconut.collections.namedtuple("_namedtuple_of", fields) - else: - NT = _coconut.typing.NamedTuple("_namedtuple_of", [(f, t) for f, t in _coconut.zip(fields, types)]) - _coconut.copyreg.pickle(NT, lambda nt: (_coconut_mk_anon_namedtuple, (nt._fields, types, nt._asdict()))) - if of_kwargs is None: - return NT - return NT(**of_kwargs) -def _coconut_ndim(arr): - if (arr.__class__.__module__ in _coconut.numpy_modules or _coconut.hasattr(arr.__class__, "__matconcat__")) and _coconut.hasattr(arr, "ndim"): - return arr.ndim - if not _coconut.isinstance(arr, _coconut.abc.Sequence): - return 0 - if _coconut.len(arr) == 0: - return 1 - arr_dim = 1 - inner_arr = arr[0] - while _coconut.isinstance(inner_arr, _coconut.abc.Sequence): - arr_dim += 1 - if _coconut.len(inner_arr) < 1: - break - inner_arr = inner_arr[0] - return arr_dim -def _coconut_expand_arr(arr, new_dims): - if (arr.__class__.__module__ in _coconut.numpy_modules or _coconut.hasattr(arr.__class__, "__matconcat__")) and _coconut.hasattr(arr, "reshape"): - return arr.reshape((1,) * new_dims + arr.shape) - for _ in _coconut.range(new_dims): - arr = [arr] - return arr -def _coconut_concatenate(arrs, axis): - matconcat = None - for a in arrs: - if a.__class__.__module__ in _coconut.jax_numpy_modules: - from jax.numpy import concatenate as matconcat - break - if a.__class__.__module__ in _coconut.numpy_modules: - matconcat = _coconut.numpy.concatenate - break - if _coconut.hasattr(a.__class__, "__matconcat__"): - matconcat = a.__class__.__matconcat__ - break - if matconcat is not None: - return matconcat(arrs, axis) - if not axis: - return _coconut.list(_coconut.itertools.chain.from_iterable(arrs)) - return [_coconut_concatenate(rows, axis - 1) for rows in _coconut.zip(*arrs)] -def _coconut_multi_dim_arr(arrs, dim): - arr_dims = [_coconut_ndim(a) for a in arrs] - arrs = [_coconut_expand_arr(a, dim - d) if d < dim else a for a, d in _coconut.zip(arrs, arr_dims)] - arr_dims.append(dim) - max_arr_dim = _coconut.max(arr_dims) - return _coconut_concatenate(arrs, max_arr_dim - dim) -_coconut_self_match_types = (bool, bytearray, bytes, dict, float, frozenset, int, py_int, list, set, str, py_str, tuple) -_coconut_MatchError, _coconut_count, _coconut_enumerate, _coconut_filter, _coconut_map, _coconut_reiterable, _coconut_reversed, _coconut_starmap, _coconut_tee, _coconut_zip, TYPE_CHECKING, reduce, takewhile, dropwhile = MatchError, count, enumerate, filter, map, reiterable, reversed, starmap, tee, zip, False, _coconut.functools.reduce, _coconut.itertools.takewhile, _coconut.itertools.dropwhile diff --git a/yaltik_dsl/src/__init__.coco b/yaltik_dsl/src/__init__.coco deleted file mode 100644 index b0fa7d4..0000000 --- a/yaltik_dsl/src/__init__.coco +++ /dev/null @@ -1,18 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright 2020 Fabien Bourgeois -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -from . import odoo_dsl diff --git a/yaltik_dsl/src/__init__.py b/yaltik_dsl/src/__init__.py index 091e4f2..b0fa7d4 100644 --- a/yaltik_dsl/src/__init__.py +++ b/yaltik_dsl/src/__init__.py @@ -1,38 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0x620e4294 - -# Compiled with Coconut version 2.1.1 [The Spanish Inquisition] - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os as _coconut_os -_coconut_file_dir = _coconut_os.path.dirname(_coconut_os.path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os.path.dirname(_coconut_cached_module.__file__) != _coconut_file_dir: # type: ignore - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_dir) -_coconut_module_name = _coconut_os.path.splitext(_coconut_os.path.basename(_coconut_file_dir))[0] -if _coconut_module_name and _coconut_module_name[0].isalpha() and all(c.isalpha() or c.isdigit() for c in _coconut_module_name) and "__init__.py" in _coconut_os.listdir(_coconut_file_dir): - _coconut_full_module_name = str(_coconut_module_name + ".__coconut__") - import __coconut__ as _coconut__coconut__ - _coconut__coconut__.__name__ = _coconut_full_module_name - for _coconut_v in vars(_coconut__coconut__).values(): - if getattr(_coconut_v, "__module__", None) == b"__coconut__": - try: - _coconut_v.__module__ = _coconut_full_module_name - except AttributeError: - _coconut_v_type = type(_coconut_v) - if getattr(_coconut_v_type, "__module__", None) == b"__coconut__": - _coconut_v_type.__module__ = _coconut_full_module_name - _coconut_sys.modules[_coconut_full_module_name] = _coconut__coconut__ -from __coconut__ import * -from __coconut__ import _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_super, _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_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_multi_dim_arr, _coconut_mk_anon_namedtuple, _coconut_matmul -_coconut_sys.path.pop(0) - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # Copyright 2020 Fabien Bourgeois diff --git a/yaltik_dsl/src/odoo_dsl.coco b/yaltik_dsl/src/odoo_dsl.coco deleted file mode 100644 index 8e258a0..0000000 --- a/yaltik_dsl/src/odoo_dsl.coco +++ /dev/null @@ -1,139 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019-2020 Fabien Bourgeois -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -""" Odoo XML DSL """ - -from .xml_base import xmlroot, xmln - -# XML helpers functions and macros - -# Odoo root XML Node -odoo = lambda children: xmlroot({'tag': 'odoo', 'attrs': {}, 'children': children}) -openerp = lambda children: xmlroot({'tag': 'openerp', 'attrs': {}, 'children': children}) - -# Special data Node -def data(*args): - """ Allow optional args on data tag """ - if len(args) == 1: - args = list(args) - args.insert(0, {}) - return xmln('data', *args) - -# Aliases -function = lambda *args: xmln('function', *args) -record = lambda *args: xmln('record', *args) -form = lambda *args: xmln('form', *args) -tree = lambda *args: xmln('tree', *args) -search = lambda *args: xmln('search', *args) - -# Actions -act_window = lambda *args: xmln('act_window', *args) -def act_window_model(model, attrs): - """ Build new act_window from model and args """ - xmlid = '%s_view_action' % (model.replace('.', '_')) - name = '%s Action' % ' '.join(map(lambda w: w.capitalize(), model.split('.'))) - attrs_clone = attrs.copy() # Avoid side-effect - attrs_clone.update({'id': xmlid, 'name': name, 'res_model': model}) - return act_window(attrs_clone) - -def action_server_code(xmlid, name, modelref, code): - """ Server actions of type code """ - children = [field_name(name), - field({'name': 'model_id', 'ref': modelref}, []), - field({'name': 'state'}, ['code']), - field({'name': 'code'}, [code])] - return record({'id': xmlid, 'model': 'ir.actions.server'}, children) - -def client_action_multi(xmlid, name, model, action): - """ Client action multi (ir.values), with own xmlid, name, targeted model - and action """ - action = "'ir.actions.server,%d'%{}".format(action) - children = [field_name(name), - field({'name': 'key2', 'eval': "'client_action_multi'"}), - field({'name': 'model', 'eval': "'%s'" % model}), - field({'name': 'value', 'eval': action})] - return record({'id': xmlid, 'model': 'ir.values'}, children) - -# Menus -menuitem = lambda *args: xmln('menuitem', *args) -def menuitem_model(model, attrs): - """ Build new menuitem from model and attrs """ - model_und = model.replace('.', '_') - xmlid = '%s_menu' % model_und - actionid = '%s_view_action' % model_und - attrs_clone = attrs.copy() # Avoid side-effect - attrs_clone.update({'id': xmlid, 'action': actionid}) - return menuitem(attrs_clone) - -# Form aliases -group = lambda *args: xmln('group', *args) -header = lambda *args: xmln('header', *args) -footer = lambda *args: xmln('footer', *args) -sheet = lambda *args: xmln('sheet', *args) -button = lambda *args: xmln('button', *args) -p = lambda *args: xmln('p', *args) -xpath = lambda *args: xmln('xpath', *args) -attribute = lambda name, value: xmln('attribute', {'name': name}, [value]) - -# Fields -field = lambda *args: xmln('field', *args) -field_name = lambda name: field({'name': 'name'}, [name]) -field_nval = lambda name, value: field({'name': name}, [value]) -field_model = lambda model: field({'name': 'model'}, [model]) -field_inherit = lambda xmlid: field({'name': 'inherit_id', 'ref': xmlid}, []) -field_arch = lambda *args: field({'name': 'arch', 'type': 'xml'}, *args) - -# Search -filter = lambda *args: xmln('filter', *args) -separator = lambda *args: xmln('separator', *args) - -def filter_yes_no(field, str_yes=False, str_no=False): - """ Double filter for boolean : True and False """ - res = [] - if str_yes: - res.append(filter({'name': f'{field}_yes', 'string': str_yes, - 'domain': f"[('{field}', '=', True)]"})) - if str_no: - res.append(filter({'name': f'{field}_no', 'string': str_no, - 'domain': f"[('{field}', '=', False)]"})) - return res - -# Views -view = lambda xmlid, children: record({'id': xmlid, 'model': 'ir.ui.view'}, children) - -def view_def(xmlid, name, model, arch): - """ Shortcut for new view """ - return view(xmlid, [field_name(name), field_model(model), field_arch(arch)]) - -def view_new(view_type, model, arch): - """ View : new view definition, based on type (form, tree, ...) and model ID """ - model_und = model.replace('.', '_') - model_cap = ' '.join(map(lambda w: w.capitalize(), model.split('.'))) - xmlid = "%s_view_%s" % (model_und, view_type) - name = ' '.join([model_cap, view_type.capitalize()]) - return view_def(xmlid, name, model, arch) - -def view_inherit(filename, model, inherit, arch): - """ Inherited View simplification with name of the record, xmlid for model - and inherited view """ - module = filename.split('.')[2] - inherited = inherit.split('.')[1] - xmlid = '%s_inherit_%s' % (inherited, module) - model_cap = ' '.join(map(lambda w: w.capitalize(), model.split('.'))) - name = '%s Adaptations' % model_cap - return view(xmlid, [field_name(name), field_model(model), - field_inherit(inherit), field_arch(arch)]) diff --git a/yaltik_dsl/src/odoo_dsl.py b/yaltik_dsl/src/odoo_dsl.py index 800bfca..114e775 100644 --- a/yaltik_dsl/src/odoo_dsl.py +++ b/yaltik_dsl/src/odoo_dsl.py @@ -1,40 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0xf27e8c67 - -# Compiled with Coconut version 2.1.1 [The Spanish Inquisition] - -""" Odoo XML DSL """ - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os as _coconut_os -_coconut_file_dir = _coconut_os.path.dirname(_coconut_os.path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os.path.dirname(_coconut_cached_module.__file__) != _coconut_file_dir: # type: ignore - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_dir) -_coconut_module_name = _coconut_os.path.splitext(_coconut_os.path.basename(_coconut_file_dir))[0] -if _coconut_module_name and _coconut_module_name[0].isalpha() and all(c.isalpha() or c.isdigit() for c in _coconut_module_name) and "__init__.py" in _coconut_os.listdir(_coconut_file_dir): - _coconut_full_module_name = str(_coconut_module_name + ".__coconut__") - import __coconut__ as _coconut__coconut__ - _coconut__coconut__.__name__ = _coconut_full_module_name - for _coconut_v in vars(_coconut__coconut__).values(): - if getattr(_coconut_v, "__module__", None) == b"__coconut__": - try: - _coconut_v.__module__ = _coconut_full_module_name - except AttributeError: - _coconut_v_type = type(_coconut_v) - if getattr(_coconut_v_type, "__module__", None) == b"__coconut__": - _coconut_v_type.__module__ = _coconut_full_module_name - _coconut_sys.modules[_coconut_full_module_name] = _coconut__coconut__ -from __coconut__ import * -from __coconut__ import _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_super, _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_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_multi_dim_arr, _coconut_mk_anon_namedtuple, _coconut_matmul -_coconut_sys.path.pop(0) - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # # Copyright 2019-2020 Fabien Bourgeois @@ -52,10 +15,9 @@ _coconut_sys.path.pop(0) # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . +""" Odoo XML DSL """ - -from .xml_base import xmlroot -from .xml_base import xmln +from .xml_base import xmlroot, xmln # XML helpers functions and macros @@ -72,7 +34,6 @@ def data(*args): return xmln('data', *args) # Aliases - function = lambda *args: xmln('function', *args) record = lambda *args: xmln('record', *args) form = lambda *args: xmln('form', *args) @@ -85,38 +46,40 @@ def act_window_model(model, attrs): """ Build new act_window from model and args """ xmlid = '%s_view_action' % (model.replace('.', '_')) name = '%s Action' % ' '.join(map(lambda w: w.capitalize(), model.split('.'))) - attrs_clone = attrs.copy() # Avoid side-effect + attrs_clone = attrs.copy() # Avoid side-effect attrs_clone.update({'id': xmlid, 'name': name, 'res_model': model}) return act_window(attrs_clone) - def action_server_code(xmlid, name, modelref, code): """ Server actions of type code """ - children = [field_name(name), field({'name': 'model_id', 'ref': modelref}, []), field({'name': 'state'}, ['code',]), field({'name': 'code'}, [code,])] + children = [field_name(name), + field({'name': 'model_id', 'ref': modelref}, []), + field({'name': 'state'}, ['code']), + field({'name': 'code'}, [code])] return record({'id': xmlid, 'model': 'ir.actions.server'}, children) - def client_action_multi(xmlid, name, model, action): """ Client action multi (ir.values), with own xmlid, name, targeted model and action """ action = "'ir.actions.server,%d'%{}".format(action) - children = [field_name(name), field({'name': 'key2', 'eval': "'client_action_multi'"}), field({'name': 'model', 'eval': "'%s'" % model}), field({'name': 'value', 'eval': action})] + children = [field_name(name), + field({'name': 'key2', 'eval': "'client_action_multi'"}), + field({'name': 'model', 'eval': "'%s'" % model}), + field({'name': 'value', 'eval': action})] return record({'id': xmlid, 'model': 'ir.values'}, children) # Menus - menuitem = lambda *args: xmln('menuitem', *args) def menuitem_model(model, attrs): """ Build new menuitem from model and attrs """ model_und = model.replace('.', '_') xmlid = '%s_menu' % model_und actionid = '%s_view_action' % model_und - attrs_clone = attrs.copy() # Avoid side-effect + attrs_clone = attrs.copy() # Avoid side-effect attrs_clone.update({'id': xmlid, 'action': actionid}) return menuitem(attrs_clone) # Form aliases - group = lambda *args: xmln('group', *args) header = lambda *args: xmln('header', *args) footer = lambda *args: xmln('footer', *args) @@ -124,13 +87,13 @@ sheet = lambda *args: xmln('sheet', *args) button = lambda *args: xmln('button', *args) p = lambda *args: xmln('p', *args) xpath = lambda *args: xmln('xpath', *args) -attribute = lambda name, value: xmln('attribute', {'name': name}, [value,]) +attribute = lambda name, value: xmln('attribute', {'name': name}, [value]) # Fields field = lambda *args: xmln('field', *args) -field_name = lambda name: field({'name': 'name'}, [name,]) -field_nval = lambda name, value: field({'name': name}, [value,]) -field_model = lambda model: field({'name': 'model'}, [model,]) +field_name = lambda name: field({'name': 'name'}, [name]) +field_nval = lambda name, value: field({'name': name}, [value]) +field_model = lambda model: field({'name': 'model'}, [model]) field_inherit = lambda xmlid: field({'name': 'inherit_id', 'ref': xmlid}, []) field_arch = lambda *args: field({'name': 'arch', 'type': 'xml'}, *args) @@ -142,20 +105,20 @@ def filter_yes_no(field, str_yes=False, str_no=False): """ Double filter for boolean : True and False """ res = [] if str_yes: - res.append(filter({'name': '{_coconut_format_0}_yes'.format(_coconut_format_0=(field)), 'string': str_yes, 'domain': "[('{_coconut_format_0}', '=', True)]".format(_coconut_format_0=(field))})) + res.append(filter({'name': '%s_yes' % field, 'string': str_yes, + 'domain': "[('%s', '=', True)]" % field})) if str_no: - res.append(filter({'name': '{_coconut_format_0}_no'.format(_coconut_format_0=(field)), 'string': str_no, 'domain': "[('{_coconut_format_0}', '=', False)]".format(_coconut_format_0=(field))})) + res.append(filter({'name': '%s_no' % field, 'string': str_no, + 'domain': "[('%s', '=', False)]" % field})) return res # Views - view = lambda xmlid, children: record({'id': xmlid, 'model': 'ir.ui.view'}, children) def view_def(xmlid, name, model, arch): """ Shortcut for new view """ return view(xmlid, [field_name(name), field_model(model), field_arch(arch)]) - def view_new(view_type, model, arch): """ View : new view definition, based on type (form, tree, ...) and model ID """ model_und = model.replace('.', '_') @@ -164,7 +127,6 @@ def view_new(view_type, model, arch): name = ' '.join([model_cap, view_type.capitalize()]) return view_def(xmlid, name, model, arch) - def view_inherit(filename, model, inherit, arch): """ Inherited View simplification with name of the record, xmlid for model and inherited view """ @@ -173,4 +135,5 @@ def view_inherit(filename, model, inherit, arch): xmlid = '%s_inherit_%s' % (inherited, module) model_cap = ' '.join(map(lambda w: w.capitalize(), model.split('.'))) name = '%s Adaptations' % model_cap - return view(xmlid, [field_name(name), field_model(model), field_inherit(inherit), field_arch(arch)]) + return view(xmlid, [field_name(name), field_model(model), + field_inherit(inherit), field_arch(arch)]) diff --git a/yaltik_dsl/src/xml_base.coco b/yaltik_dsl/src/xml_base.coco deleted file mode 100644 index 854d282..0000000 --- a/yaltik_dsl/src/xml_base.coco +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2019-2020 Fabien Bourgeois -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -""" XML helpers and macros """ - -from os import path -import xml.etree.ElementTree as ET -from xml.dom import minidom -from collections import namedtuple -from functools import partial - -XMLDictElement = namedtuple('XMLDictElement', ['tag', 'attrs', 'children']) - - -def xmlroot(tree): - """ Special process for root XML Node """ - rootel = ET.Element(tree['tag'], tree['attrs']) - if 'children' in tree: - xmlchild(rootel, tree['children']) - return rootel - -def xmlchild(parent, children): - """ Handling of children (ie non root) XML Nodes with/o text and - subchildren (recursive) """ - if isinstance(children, basestring): - parent.text = children - elif isinstance(children, XMLDictElement): - attrs = {str(k): str(v) for [k, v] in children.attrs.items()} - new_parent = ET.SubElement(parent, children.tag, attrs) - subchildren = children.children - if subchildren: - xmlchild(new_parent, subchildren) - elif isinstance(children, list): - list(map(partial(xmlchild, parent), children)) - else: - raise TypeError('Invalid arguments for xmlchild') - -def xmln(tag='', attrs={}, children=[]): - """ XMLDictElement building from dict object, with defaults """ - if isinstance(attrs, list): - children = attrs - attrs = {} - xmldictel = partial(XMLDictElement, tag, attrs) - if isinstance(children, basestring): - return xmldictel([children]) - if isinstance(children, list): - return xmldictel(children) - raise TypeError('Invalid arguments for xmln') - - -def xml_write(filepath, tree, pretty=True, suffix='_views'): - """ Write XML file according to filename and given tree """ - if filepath.endswith('.py'): # if .pyc, no need to generate XML - output_xml = ET.tostring(tree) - if pretty: - output_xml = minidom.parseString(output_xml).toprettyxml(indent=' ') - output_path = path.abspath(filepath).split('/') - output_path[-1] = output_path[-1].replace('.py', '%s.xml' % suffix) - output_path = '/'.join(output_path) - with open(output_path, 'w') as output_file: - output_file.write(output_xml) diff --git a/yaltik_dsl/src/xml_base.py b/yaltik_dsl/src/xml_base.py index 80a0dc7..854d282 100644 --- a/yaltik_dsl/src/xml_base.py +++ b/yaltik_dsl/src/xml_base.py @@ -1,40 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0x37b96b63 - -# Compiled with Coconut version 2.1.1 [The Spanish Inquisition] - -""" XML helpers and macros """ - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os as _coconut_os -_coconut_file_dir = _coconut_os.path.dirname(_coconut_os.path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os.path.dirname(_coconut_cached_module.__file__) != _coconut_file_dir: # type: ignore - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_dir) -_coconut_module_name = _coconut_os.path.splitext(_coconut_os.path.basename(_coconut_file_dir))[0] -if _coconut_module_name and _coconut_module_name[0].isalpha() and all(c.isalpha() or c.isdigit() for c in _coconut_module_name) and "__init__.py" in _coconut_os.listdir(_coconut_file_dir): - _coconut_full_module_name = str(_coconut_module_name + ".__coconut__") - import __coconut__ as _coconut__coconut__ - _coconut__coconut__.__name__ = _coconut_full_module_name - for _coconut_v in vars(_coconut__coconut__).values(): - if getattr(_coconut_v, "__module__", None) == b"__coconut__": - try: - _coconut_v.__module__ = _coconut_full_module_name - except AttributeError: - _coconut_v_type = type(_coconut_v) - if getattr(_coconut_v_type, "__module__", None) == b"__coconut__": - _coconut_v_type.__module__ = _coconut_full_module_name - _coconut_sys.modules[_coconut_full_module_name] = _coconut__coconut__ -from __coconut__ import * -from __coconut__ import _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_super, _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_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_multi_dim_arr, _coconut_mk_anon_namedtuple, _coconut_matmul -_coconut_sys.path.pop(0) - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # # Copyright 2019-2020 Fabien Bourgeois @@ -52,7 +15,7 @@ _coconut_sys.path.pop(0) # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - +""" XML helpers and macros """ from os import path import xml.etree.ElementTree as ET @@ -70,14 +33,13 @@ def xmlroot(tree): xmlchild(rootel, tree['children']) return rootel - def xmlchild(parent, children): """ Handling of children (ie non root) XML Nodes with/o text and subchildren (recursive) """ if isinstance(children, basestring): parent.text = children elif isinstance(children, XMLDictElement): - attrs = dict(((str(k)), (str(v))) for [k, v] in children.attrs.items()) + attrs = {str(k): str(v) for [k, v] in children.attrs.items()} new_parent = ET.SubElement(parent, children.tag, attrs) subchildren = children.children if subchildren: @@ -87,7 +49,6 @@ def xmlchild(parent, children): else: raise TypeError('Invalid arguments for xmlchild') - def xmln(tag='', attrs={}, children=[]): """ XMLDictElement building from dict object, with defaults """ if isinstance(attrs, list): @@ -95,16 +56,15 @@ def xmln(tag='', attrs={}, children=[]): attrs = {} xmldictel = partial(XMLDictElement, tag, attrs) if isinstance(children, basestring): - return xmldictel([children,]) + return xmldictel([children]) if isinstance(children, list): return xmldictel(children) raise TypeError('Invalid arguments for xmln') - def xml_write(filepath, tree, pretty=True, suffix='_views'): """ Write XML file according to filename and given tree """ - if filepath.endswith('.py'): # if .pyc, no need to generate XML + if filepath.endswith('.py'): # if .pyc, no need to generate XML output_xml = ET.tostring(tree) if pretty: output_xml = minidom.parseString(output_xml).toprettyxml(indent=' ') diff --git a/yaltik_dsl/tests/__coconut__.py b/yaltik_dsl/tests/__coconut__.py deleted file mode 100644 index ee2c2e8..0000000 --- a/yaltik_dsl/tests/__coconut__.py +++ /dev/null @@ -1,1576 +0,0 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# type: ignore - -# Compiled with Coconut version 2.1.1 [The Spanish Inquisition] - -"""Built-in Coconut utilities.""" - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys -from __builtin__ import chr, hex, input, int, map, object, oct, open, print, range, str, super, zip, filter, reversed, enumerate, raw_input, xrange, repr, long -py_chr, py_hex, py_input, py_int, py_map, py_object, py_oct, py_open, py_print, py_range, py_str, py_super, py_zip, py_filter, py_reversed, py_enumerate, py_raw_input, py_xrange, py_repr = chr, hex, input, int, map, object, oct, open, print, range, str, super, zip, filter, reversed, enumerate, raw_input, xrange, repr -_coconut_py_raw_input, _coconut_py_xrange, _coconut_py_int, _coconut_py_long, _coconut_py_print, _coconut_py_str, _coconut_py_super, _coconut_py_unicode, _coconut_py_repr = raw_input, xrange, int, long, print, str, super, unicode, repr -from functools import wraps as _coconut_wraps -from future_builtins import * -chr, str = unichr, unicode -from io import open -class object(object): - __slots__ = () - def __ne__(self, other): - eq = self == other - return _coconut.NotImplemented if eq is _coconut.NotImplemented else not eq -class int(_coconut_py_int): - __slots__ = () - if hasattr(_coconut_py_int, "__doc__"): - __doc__ = _coconut_py_int.__doc__ - class __metaclass__(type): - def __instancecheck__(cls, inst): - return _coconut.isinstance(inst, (_coconut_py_int, _coconut_py_long)) - def __subclasscheck__(cls, subcls): - return _coconut.issubclass(subcls, (_coconut_py_int, _coconut_py_long)) -class range(object): - __slots__ = ("_xrange",) - if hasattr(_coconut_py_xrange, "__doc__"): - __doc__ = _coconut_py_xrange.__doc__ - def __init__(self, *args): - self._xrange = _coconut_py_xrange(*args) - def __iter__(self): - return _coconut.iter(self._xrange) - def __reversed__(self): - return _coconut.reversed(self._xrange) - def __len__(self): - return _coconut.len(self._xrange) - def __contains__(self, elem): - return elem in self._xrange - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - args = _coconut.slice(*self._args) - start, stop, step = (args.start if args.start is not None else 0), args.stop, (args.step if args.step is not None else 1) - if index.start is None: - new_start = start if index.step is None or index.step >= 0 else stop - step - elif index.start >= 0: - new_start = start + step * index.start - if (step >= 0 and new_start >= stop) or (step < 0 and new_start <= stop): - new_start = stop - else: - new_start = stop + step * index.start - if (step >= 0 and new_start <= start) or (step < 0 and new_start >= start): - new_start = start - if index.stop is None: - new_stop = stop if index.step is None or index.step >= 0 else start - step - elif index.stop >= 0: - new_stop = start + step * index.stop - if (step >= 0 and new_stop >= stop) or (step < 0 and new_stop <= stop): - new_stop = stop - else: - new_stop = stop + step * index.stop - if (step >= 0 and new_stop <= start) or (step < 0 and new_stop >= start): - new_stop = start - new_step = step if index.step is None else step * index.step - return self.__class__(new_start, new_stop, new_step) - else: - return self._xrange[index] - def count(self, elem): - """Count the number of times elem appears in the range.""" - return _coconut_py_int(elem in self._xrange) - def index(self, elem): - """Find the index of elem in the range.""" - if elem not in self._xrange: raise _coconut.ValueError(_coconut.repr(elem) + " is not in range") - start, _, step = self._xrange.__reduce_ex__(2)[1] - return (elem - start) // step - def __repr__(self): - return _coconut.repr(self._xrange)[1:] - @property - def _args(self): - return self._xrange.__reduce__()[1] - def __reduce_ex__(self, protocol): - return (self.__class__, self._xrange.__reduce_ex__(protocol)[1]) - def __reduce__(self): - return self.__reduce_ex__(_coconut.pickle.DEFAULT_PROTOCOL) - def __hash__(self): - return _coconut.hash(self._args) - def __copy__(self): - return self.__class__(*self._args) - def __eq__(self, other): - return self.__class__ is other.__class__ and self._args == other._args -from collections import Sequence as _coconut_Sequence -_coconut_Sequence.register(range) -@_coconut_wraps(_coconut_py_print) -def print(*args, **kwargs): - file = kwargs.get("file", _coconut_sys.stdout) - if "flush" in kwargs: - flush = kwargs["flush"] - del kwargs["flush"] - else: - flush = False - if _coconut.getattr(file, "encoding", None) is not None: - _coconut_py_print(*(_coconut_py_unicode(x).encode(file.encoding) for x in args), **kwargs) - else: - _coconut_py_print(*args, **kwargs) - if flush: - file.flush() -@_coconut_wraps(_coconut_py_raw_input) -def input(*args, **kwargs): - if _coconut.getattr(_coconut_sys.stdout, "encoding", None) is not None: - return _coconut_py_raw_input(*args, **kwargs).decode(_coconut_sys.stdout.encoding) - return _coconut_py_raw_input(*args, **kwargs).decode() -@_coconut_wraps(_coconut_py_repr) -def repr(obj): - import __builtin__ - try: - __builtin__.repr = _coconut_repr - if isinstance(obj, _coconut_py_unicode): - return _coconut_py_unicode(_coconut_py_repr(obj)[1:]) - if isinstance(obj, _coconut_py_str): - return "b" + _coconut_py_unicode(_coconut_py_repr(obj)) - return _coconut_py_unicode(_coconut_py_repr(obj)) - finally: - __builtin__.repr = _coconut_py_repr -ascii = _coconut_repr = repr -def raw_input(*args): - """Coconut uses Python 3 'input' instead of Python 2 'raw_input'.""" - raise _coconut.NameError("Coconut uses Python 3 'input' instead of Python 2 'raw_input'") -def xrange(*args): - """Coconut uses Python 3 'range' instead of Python 2 'xrange'.""" - raise _coconut.NameError("Coconut uses Python 3 'range' instead of Python 2 'xrange'") -def _coconut_exec(obj, globals=None, locals=None): - """Execute the given source in the context of globals and locals.""" - if locals is None: - locals = _coconut_sys._getframe(1).f_locals if globals is None else globals - if globals is None: - globals = _coconut_sys._getframe(1).f_globals - exec(obj, globals, locals) -def _coconut_default_breakpointhook(*args, **kwargs): - hookname = _coconut.os.getenv("PYTHONBREAKPOINT") - if hookname != "0": - if not hookname: - hookname = "pdb.set_trace" - modname, dot, funcname = hookname.rpartition(".") - if not dot: - modname = "builtins" if _coconut_sys.version_info >= (3,) else "__builtin__" - if _coconut_sys.version_info >= (2, 7): - import importlib - module = importlib.import_module(modname) - else: - import imp - module = imp.load_module(modname, *imp.find_module(modname)) - hook = _coconut.getattr(module, funcname) - return hook(*args, **kwargs) -if not hasattr(_coconut_sys, "__breakpointhook__"): - _coconut_sys.__breakpointhook__ = _coconut_default_breakpointhook -def breakpoint(*args, **kwargs): - return _coconut.getattr(_coconut_sys, "breakpointhook", _coconut_default_breakpointhook)(*args, **kwargs) -@_coconut_wraps(_coconut_py_super) -def _coconut_super(type=None, object_or_type=None): - if type is None: - if object_or_type is not None: - raise _coconut.TypeError("invalid use of super()") - frame = _coconut_sys._getframe(1) - try: - cls = frame.f_locals["__class__"] - except _coconut.AttributeError: - raise _coconut.RuntimeError("super(): __class__ cell not found") - self = frame.f_locals[frame.f_code.co_varnames[0]] - return _coconut_py_super(cls, self) - return _coconut_py_super(type, object_or_type) -super = _coconut_super -class _coconut(object): - import collections, copy, functools, types, itertools, operator, threading, os, warnings, contextlib, traceback, weakref, multiprocessing, math - from multiprocessing import dummy as multiprocessing_dummy - try: - from backports.functools_lru_cache import lru_cache - functools.lru_cache = lru_cache - except ImportError: - class you_need_to_install_backports_functools_lru_cache(object): - __slots__ = () - functools.lru_cache = you_need_to_install_backports_functools_lru_cache() - import copy_reg as copyreg - try: - import trollius as asyncio - except ImportError: - class you_need_to_install_trollius(object): - __slots__ = () - asyncio = you_need_to_install_trollius() - import cPickle as pickle - OrderedDict = collections.OrderedDict - abc = collections - class typing_mock(object): - TYPE_CHECKING = False - def __getattr__(self, name): - raise _coconut.ImportError("the typing module is not available at runtime in Python 3.4 or earlier; try hiding your typedefs behind an 'if TYPE_CHECKING:' block") - typing = typing_mock() - def NamedTuple(name, fields): - return _coconut.collections.namedtuple(name, [x for x, t in fields]) - typing.NamedTuple = NamedTuple - NamedTuple = staticmethod(NamedTuple) - try: - from typing_extensions import TypeAlias, ParamSpec, Concatenate - except ImportError: - class you_need_to_install_typing_extensions(object): - __slots__ = () - TypeAlias = ParamSpec = Concatenate = you_need_to_install_typing_extensions() - typing.TypeAlias = TypeAlias - typing.ParamSpec = ParamSpec - typing.Concatenate = Concatenate - try: - from typing_extensions import TypeVarTuple, Unpack - except ImportError: - class you_need_to_install_typing_extensions(object): - __slots__ = () - TypeVarTuple = Unpack = you_need_to_install_typing_extensions() - typing.TypeVarTuple = TypeVarTuple - typing.Unpack = Unpack - zip_longest = itertools.izip_longest - try: - import numpy - except ImportError: - class you_need_to_install_numpy(object): - __slots__ = () - numpy = you_need_to_install_numpy() - else: - abc.Sequence.register(numpy.ndarray) - numpy_modules = ('numpy', 'pandas', 'jaxlib.xla_extension') - jax_numpy_modules = ('jaxlib.xla_extension',) - abc.Sequence.register(collections.deque) - Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, slice, str, sum, super, tuple, type, vars, zip, repr, print, bytearray = Ellipsis, NotImplemented, NotImplementedError, Exception, AttributeError, ImportError, IndexError, NameError, TypeError, ValueError, StopIteration, RuntimeError, all, any, bytes, classmethod, dict, enumerate, filter, float, frozenset, getattr, hasattr, hash, id, int, isinstance, issubclass, iter, len, list, locals, map, min, max, next, object, property, range, reversed, set, slice, str, sum, staticmethod(super), tuple, type, vars, zip, staticmethod(repr), staticmethod(print), bytearray -class _coconut_sentinel(object): - __slots__ = () -class _coconut_base_hashable(object): - __slots__ = () - def __reduce_ex__(self, _): - return self.__reduce__() - def __eq__(self, other): - return self.__class__ is other.__class__ and self.__reduce__() == other.__reduce__() - def __hash__(self): - return _coconut.hash(self.__reduce__()) -class MatchError(_coconut_base_hashable, Exception): - """Pattern-matching error. Has attributes .pattern, .value, and .message.""" - __slots__ = ("pattern", "value", "_message") - max_val_repr_len = 500 - def __init__(self, pattern=None, value=None): - self.pattern = pattern - self.value = value - self._message = None - @property - def message(self): - if self._message is None: - value_repr = _coconut.repr(self.value) - self._message = "pattern-matching failed for %s in %s" % (_coconut.repr(self.pattern), value_repr if _coconut.len(value_repr) <= self.max_val_repr_len else value_repr[:self.max_val_repr_len] + "...") - Exception.__init__(self, self._message) - return self._message - def __repr__(self): - self.message - return Exception.__repr__(self) - def __str__(self): - self.message - return Exception.__str__(self) - def __unicode__(self): - self.message - return Exception.__unicode__(self) - def __reduce__(self): - return (self.__class__, (self.pattern, self.value)) -class _coconut_tail_call(object): - __slots__ = ("func", "args", "kwargs") - def __init__(self, _coconut_func, *args, **kwargs): - self.func = _coconut_func - self.args = args - self.kwargs = kwargs -_coconut_tco_func_dict = {} -def _coconut_tco(func): - @_coconut.functools.wraps(func) - def tail_call_optimized_func(*args, **kwargs): - call_func = func - while True: - if _coconut.isinstance(call_func, _coconut_base_pattern_func): - call_func = call_func._coconut_tco_func - elif _coconut.isinstance(call_func, _coconut.types.MethodType): - wkref = _coconut_tco_func_dict.get(_coconut.id(call_func.__func__)) - wkref_func = None if wkref is None else wkref() - if wkref_func is call_func.__func__: - if call_func.__self__ is None: - call_func = call_func._coconut_tco_func - else: - call_func = _coconut.functools.partial(call_func._coconut_tco_func, call_func.__self__) - else: - wkref = _coconut_tco_func_dict.get(_coconut.id(call_func)) - wkref_func = None if wkref is None else wkref() - if wkref_func is call_func: - call_func = call_func._coconut_tco_func - result = call_func(*args, **kwargs) # use coconut --no-tco to clean up your traceback - if not isinstance(result, _coconut_tail_call): - return result - call_func, args, kwargs = result.func, result.args, result.kwargs - tail_call_optimized_func._coconut_tco_func = func - tail_call_optimized_func.__module__ = _coconut.getattr(func, "__module__", None) - tail_call_optimized_func.__name__ = _coconut.getattr(func, "__name__", None) - tail_call_optimized_func.__qualname__ = _coconut.getattr(func, "__qualname__", None) - _coconut_tco_func_dict[_coconut.id(tail_call_optimized_func)] = _coconut.weakref.ref(tail_call_optimized_func) - return tail_call_optimized_func -def _coconut_iter_getitem_special_case(iterable, start, stop, step): - iterable = _coconut.itertools.islice(iterable, start, None) - cache = _coconut.collections.deque(_coconut.itertools.islice(iterable, -stop), maxlen=-stop) - for index, item in _coconut.enumerate(iterable): - cached_item = cache.popleft() - if index % step == 0: - yield cached_item - cache.append(item) -def _coconut_iter_getitem(iterable, index): - """Iterator slicing works just like sequence slicing, including support for negative indices and slices, and support for `slice` objects in the same way as can be done with normal slicing. - - Coconut's iterator slicing is very similar to Python's `itertools.islice`, but unlike `itertools.islice`, Coconut's iterator slicing supports negative indices, and will preferentially call an object's `__iter_getitem__` (Coconut-specific magic method, preferred) or `__getitem__` (general Python magic method), if they exist. Coconut's iterator slicing is also optimized to work well with all of Coconut's built-in objects, only computing the elements of each that are actually necessary to extract the desired slice. - - Some code taken from more_itertools under the terms of its MIT license. - """ - obj_iter_getitem = _coconut.getattr(iterable, "__iter_getitem__", None) - if obj_iter_getitem is None: - obj_iter_getitem = _coconut.getattr(iterable, "__getitem__", None) - if obj_iter_getitem is not None: - try: - result = obj_iter_getitem(index) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if not _coconut.isinstance(index, _coconut.slice): - index = _coconut.operator.index(index) - if index < 0: - return _coconut.collections.deque(iterable, maxlen=-index)[0] - result = _coconut.next(_coconut.itertools.islice(iterable, index, index + 1), _coconut_sentinel) - if result is _coconut_sentinel: - raise _coconut.IndexError("$[] index out of range") - return result - start = _coconut.operator.index(index.start) if index.start is not None else None - stop = _coconut.operator.index(index.stop) if index.stop is not None else None - step = _coconut.operator.index(index.step) if index.step is not None else 1 - if step == 0: - raise _coconut.ValueError("slice step cannot be zero") - if start is None and stop is None and step == -1: - obj_reversed = _coconut.getattr(iterable, "__reversed__", None) - if obj_reversed is not None: - try: - result = obj_reversed() - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if step >= 0: - start = 0 if start is None else start - if start < 0: - cache = _coconut.collections.deque(_coconut.enumerate(iterable, 1), maxlen=-start) - len_iter = cache[-1][0] if cache else 0 - i = _coconut.max(len_iter + start, 0) - if stop is None: - j = len_iter - elif stop >= 0: - j = _coconut.min(stop, len_iter) - else: - j = _coconut.max(len_iter + stop, 0) - n = j - i - if n <= 0: - return () - if n < -start or step != 1: - cache = _coconut.itertools.islice(cache, 0, n, step) - return _coconut_map(_coconut.operator.itemgetter(1), cache) - elif stop is None or stop >= 0: - return _coconut.itertools.islice(iterable, start, stop, step) - else: - return _coconut_iter_getitem_special_case(iterable, start, stop, step) - else: - start = -1 if start is None else start - if stop is not None and stop < 0: - n = -stop - 1 - cache = _coconut.collections.deque(_coconut.enumerate(iterable, 1), maxlen=n) - len_iter = cache[-1][0] if cache else 0 - if start < 0: - i, j = start, stop - else: - i, j = _coconut.min(start - len_iter, -1), None - return _coconut_map(_coconut.operator.itemgetter(1), _coconut.tuple(cache)[i:j:step]) - else: - if stop is not None: - m = stop + 1 - iterable = _coconut.itertools.islice(iterable, m, None) - if start < 0: - i = start - n = None - elif stop is None: - i = None - n = start + 1 - else: - i = None - n = start - stop - if n is not None: - if n <= 0: - return () - iterable = _coconut.itertools.islice(iterable, 0, n) - return _coconut.tuple(iterable)[i::step] -class _coconut_base_compose(_coconut_base_hashable): - __slots__ = ("func", "funcstars") - def __init__(self, func, *funcstars): - self.func = func - self.funcstars = [] - for f, stars in funcstars: - if _coconut.isinstance(f, _coconut_base_compose): - self.funcstars.append((f.func, stars)) - self.funcstars += f.funcstars - else: - self.funcstars.append((f, stars)) - self.funcstars = _coconut.tuple(self.funcstars) - def __call__(self, *args, **kwargs): - arg = self.func(*args, **kwargs) - for f, stars in self.funcstars: - if stars == 0: - arg = f(arg) - elif stars == 1: - arg = f(*arg) - elif stars == 2: - arg = f(**arg) - else: - raise _coconut.ValueError("invalid arguments to " + _coconut.repr(self)) - return arg - def __repr__(self): - return _coconut.repr(self.func) + " " + " ".join(("..*> " if star == 1 else "..**>" if star == 2 else "..> ") + _coconut.repr(f) for f, star in self.funcstars) - def __reduce__(self): - return (self.__class__, (self.func,) + self.funcstars) - def __get__(self, obj, objtype=None): - if obj is None: - return self - return _coconut.types.MethodType(self, obj, objtype) -def _coconut_forward_compose(func, *funcs): - """Forward composition operator (..>). - - (..>)(f, g) is effectively equivalent to (*args, **kwargs) -> g(f(*args, **kwargs)).""" - return _coconut_base_compose(func, *((f, 0) for f in funcs)) -def _coconut_back_compose(*funcs): - """Backward composition operator (<..). - - (<..)(f, g) is effectively equivalent to (*args, **kwargs) -> f(g(*args, **kwargs)).""" - return _coconut_forward_compose(*_coconut.reversed(funcs)) -def _coconut_forward_star_compose(func, *funcs): - """Forward star composition operator (..*>). - - (..*>)(f, g) is effectively equivalent to (*args, **kwargs) -> g(*f(*args, **kwargs)).""" - return _coconut_base_compose(func, *((f, 1) for f in funcs)) -def _coconut_back_star_compose(*funcs): - """Backward star composition operator (<*..). - - (<*..)(f, g) is effectively equivalent to (*args, **kwargs) -> f(*g(*args, **kwargs)).""" - return _coconut_forward_star_compose(*_coconut.reversed(funcs)) -def _coconut_forward_dubstar_compose(func, *funcs): - """Forward double star composition operator (..**>). - - (..**>)(f, g) is effectively equivalent to (*args, **kwargs) -> g(**f(*args, **kwargs)).""" - return _coconut_base_compose(func, *((f, 2) for f in funcs)) -def _coconut_back_dubstar_compose(*funcs): - """Backward double star composition operator (<**..). - - (<**..)(f, g) is effectively equivalent to (*args, **kwargs) -> f(**g(*args, **kwargs)).""" - return _coconut_forward_dubstar_compose(*_coconut.reversed(funcs)) -def _coconut_pipe(x, f): - """Pipe operator (|>). Equivalent to (x, f) -> f(x).""" - return f(x) -def _coconut_star_pipe(xs, f): - """Star pipe operator (*|>). Equivalent to (xs, f) -> f(*xs).""" - return f(*xs) -def _coconut_dubstar_pipe(kws, f): - """Double star pipe operator (**|>). Equivalent to (kws, f) -> f(**kws).""" - return f(**kws) -def _coconut_back_pipe(f, x): - """Backward pipe operator (<|). Equivalent to (f, x) -> f(x).""" - return f(x) -def _coconut_back_star_pipe(f, xs): - """Backward star pipe operator (<*|). Equivalent to (f, xs) -> f(*xs).""" - return f(*xs) -def _coconut_back_dubstar_pipe(f, kws): - """Backward double star pipe operator (<**|). Equivalent to (f, kws) -> f(**kws).""" - return f(**kws) -def _coconut_none_pipe(x, f): - """Nullable pipe operator (|?>). Equivalent to (x, f) -> f(x) if x is not None else None.""" - return None if x is None else f(x) -def _coconut_none_star_pipe(xs, f): - """Nullable star pipe operator (|?*>). Equivalent to (xs, f) -> f(*xs) if xs is not None else None.""" - return None if xs is None else f(*xs) -def _coconut_none_dubstar_pipe(kws, f): - """Nullable double star pipe operator (|?**>). Equivalent to (kws, f) -> f(**kws) if kws is not None else None.""" - return None if kws is None else f(**kws) -def _coconut_assert(cond, msg=None): - """Assert operator (assert). Asserts condition with optional message.""" - if not cond: - assert False, msg if msg is not None else "(assert) got falsey value " + _coconut.repr(cond) -def _coconut_raise(exc=None, from_exc=None): - """Raise operator (raise). Raises exception with optional cause.""" - if exc is None: - raise - if from_exc is not None: - exc.__cause__ = from_exc - raise exc -def _coconut_bool_and(a, b): - """Boolean and operator (and). Equivalent to (a, b) -> a and b.""" - return a and b -def _coconut_bool_or(a, b): - """Boolean or operator (or). Equivalent to (a, b) -> a or b.""" - return a or b -def _coconut_none_coalesce(a, b): - """None coalescing operator (??). Equivalent to (a, b) -> a if a is not None else b.""" - return b if a is None else a -def _coconut_minus(a, b=_coconut_sentinel): - """Minus operator (-). Effectively equivalent to (a, b=None) -> a - b if b is not None else -a.""" - if b is _coconut_sentinel: - return -a - return a - b -def _coconut_comma_op(*args): - """Comma operator (,). Equivalent to (*args) -> args.""" - return args -def _coconut_matmul(a, b, **kwargs): - """Matrix multiplication operator (@). Implements operator.matmul on any Python version.""" - in_place = kwargs.pop("in_place", False) - if kwargs: - raise _coconut.TypeError("_coconut_matmul() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if in_place and _coconut.hasattr(a, "__imatmul__"): - try: - result = a.__imatmul__(b) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if _coconut.hasattr(a, "__matmul__"): - try: - result = a.__matmul__(b) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if _coconut.hasattr(b, "__rmatmul__"): - try: - result = b.__rmatmul__(a) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if "numpy" in (a.__class__.__module__, b.__class__.__module__): - from numpy import matmul - return matmul(a, b) - raise _coconut.TypeError("unsupported operand type(s) for @: " + _coconut.repr(_coconut.type(a)) + " and " + _coconut.repr(_coconut.type(b))) -@_coconut.functools.wraps(_coconut.itertools.tee) -def tee(iterable, n=2): - if n >= 0 and _coconut.isinstance(iterable, (_coconut.tuple, _coconut.frozenset)): - return (iterable,) * n - if n > 0 and (_coconut.isinstance(iterable, _coconut.abc.Sequence) or _coconut.getattr(iterable, "__copy__", None) is not None): - return (iterable,) + _coconut.tuple(_coconut.copy.copy(iterable) for _ in _coconut.range(n - 1)) - return _coconut.itertools.tee(iterable, n) -class reiterable(_coconut_base_hashable): - """Allow an iterator to be iterated over multiple times with the same results.""" - __slots__ = ("lock", "iter") - def __new__(cls, iterable): - if _coconut.isinstance(iterable, _coconut_reiterable): - return iterable - self = _coconut.object.__new__(cls) - self.lock = _coconut.threading.Lock() - self.iter = iterable - return self - def get_new_iter(self): - with self.lock: - self.iter, new_iter = _coconut_tee(self.iter) - return new_iter - def __iter__(self): - return _coconut.iter(self.get_new_iter()) - def __getitem__(self, index): - return _coconut_iter_getitem(self.get_new_iter(), index) - def __reversed__(self): - return _coconut_reversed(self.get_new_iter()) - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "reiterable(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.iter,)) - def __copy__(self): - return self.__class__(self.get_new_iter()) - def __fmap__(self, func): - return _coconut_map(func, self) -class scan(_coconut_base_hashable): - """Reduce func over iterable, yielding intermediate results, - optionally starting from initial.""" - __slots__ = ("func", "iter", "initial") - def __init__(self, function, iterable, initial=_coconut_sentinel): - self.func = function - self.iter = iterable - self.initial = initial - def __iter__(self): - acc = self.initial - if acc is not _coconut_sentinel: - yield acc - for item in self.iter: - if acc is _coconut_sentinel: - acc = item - else: - acc = self.func(acc, item) - yield acc - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "scan(%r, %s%s)" % (self.func, _coconut.repr(self.iter), "" if self.initial is _coconut_sentinel else ", " + _coconut.repr(self.initial)) - def __reduce__(self): - return (self.__class__, (self.func, self.iter, self.initial)) - def __fmap__(self, func): - return _coconut_map(func, self) -class reversed(_coconut_base_hashable): - __slots__ = ("iter",) - if hasattr(_coconut.map, "__doc__"): - __doc__ = _coconut.reversed.__doc__ - def __new__(cls, iterable): - if _coconut.isinstance(iterable, _coconut.range): - return iterable[::-1] - if not _coconut.hasattr(iterable, "__reversed__") or _coconut.isinstance(iterable, (_coconut.list, _coconut.tuple)): - return _coconut.object.__new__(cls) - return _coconut.reversed(iterable) - def __init__(self, iterable): - self.iter = iterable - def __iter__(self): - return _coconut.iter(_coconut.reversed(self.iter)) - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return _coconut_iter_getitem(self.iter, _coconut.slice(-(index.start + 1) if index.start is not None else None, -(index.stop + 1) if index.stop else None, -(index.step if index.step is not None else 1))) - return _coconut_iter_getitem(self.iter, -(index + 1)) - def __reversed__(self): - return self.iter - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "reversed(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.iter,)) - def __contains__(self, elem): - return elem in self.iter - def count(self, elem): - """Count the number of times elem appears in the reversed iterable.""" - return self.iter.count(elem) - def index(self, elem): - """Find the index of elem in the reversed iterable.""" - return _coconut.len(self.iter) - self.iter.index(elem) - 1 - def __fmap__(self, func): - return self.__class__(_coconut_map(func, self.iter)) -class flatten(_coconut_base_hashable): - """Flatten an iterable of iterables into a single iterable.""" - __slots__ = ("iter",) - def __init__(self, iterable): - self.iter = iterable - def __iter__(self): - return _coconut.itertools.chain.from_iterable(self.iter) - def __reversed__(self): - return self.__class__(_coconut_reversed(_coconut_map(_coconut_reversed, self.iter))) - def __repr__(self): - return "flatten(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.iter,)) - def __contains__(self, elem): - self.iter, new_iter = _coconut_tee(self.iter) - return _coconut.any(elem in it for it in new_iter) - def count(self, elem): - """Count the number of times elem appears in the flattened iterable.""" - self.iter, new_iter = _coconut_tee(self.iter) - return _coconut.sum(it.count(elem) for it in new_iter) - def index(self, elem): - self.iter, new_iter = _coconut_tee(self.iter) - ind = 0 - for it in new_iter: - try: - return ind + it.index(elem) - except _coconut.ValueError: - ind += _coconut.len(it) - raise ValueError("%r not in %r" % (elem, self)) - def __fmap__(self, func): - return self.__class__(_coconut_map(_coconut.functools.partial(_coconut_map, func), self.iter)) -class map(_coconut_base_hashable, _coconut.map): - __slots__ = ("func", "iters") - if hasattr(_coconut.map, "__doc__"): - __doc__ = _coconut.map.__doc__ - def __new__(cls, function, *iterables): - new_map = _coconut.map.__new__(cls, function, *iterables) - new_map.func = function - new_map.iters = iterables - return new_map - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(self.func, *(_coconut_iter_getitem(i, index) for i in self.iters)) - return self.func(*(_coconut_iter_getitem(i, index) for i in self.iters)) - def __reversed__(self): - return self.__class__(self.func, *(_coconut_reversed(i) for i in self.iters)) - def __len__(self): - return _coconut.min(_coconut.len(i) for i in self.iters) - def __repr__(self): - return "map(%r, %s)" % (self.func, ", ".join((_coconut.repr(i) for i in self.iters))) - def __reduce__(self): - return (self.__class__, (self.func,) + self.iters) - def __iter__(self): - return _coconut.iter(_coconut.map(self.func, *self.iters)) - def __fmap__(self, func): - return self.__class__(_coconut_forward_compose(self.func, func), *self.iters) -class _coconut_parallel_concurrent_map_func_wrapper(_coconut_base_hashable): - __slots__ = ("map_cls", "func", "star") - def __init__(self, map_cls, func, star): - self.map_cls = map_cls - self.func = func - self.star = star - def __reduce__(self): - return (self.__class__, (self.map_cls, self.func, self.star)) - def __call__(self, *args, **kwargs): - self.map_cls.get_pool_stack().append(None) - try: - if self.star: - assert _coconut.len(args) == 1, "internal parallel/concurrent map error (you should report this at https://github.com/evhub/coconut/issues/new)" - return self.func(*args[0], **kwargs) - else: - return self.func(*args, **kwargs) - except: - _coconut.print(self.map_cls.__name__ + " error:") - _coconut.traceback.print_exc() - raise - finally: - assert self.map_cls.get_pool_stack().pop() is None, "internal parallel/concurrent map error (you should report this at https://github.com/evhub/coconut/issues/new)" -class _coconut_base_parallel_concurrent_map(map): - __slots__ = ("result", "chunksize") - @classmethod - def get_pool_stack(cls): - return cls.threadlocal_ns.__dict__.setdefault("pool_stack", [None]) - def __new__(cls, function, *iterables, **kwargs): - self = _coconut_map.__new__(cls, function, *iterables) - self.result = None - self.chunksize = kwargs.pop("chunksize", 1) - if kwargs: - raise _coconut.TypeError(cls.__name__ + "() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if cls.get_pool_stack()[-1] is not None: - return self.get_list() - return self - @classmethod - @_coconut.contextlib.contextmanager - def multiple_sequential_calls(cls, max_workers=None): - """Context manager that causes nested calls to use the same pool.""" - if cls.get_pool_stack()[-1] is None: - cls.get_pool_stack()[-1] = cls.make_pool(max_workers) - try: - yield - finally: - cls.get_pool_stack()[-1].terminate() - cls.get_pool_stack()[-1] = None - else: - yield - def get_list(self): - if self.result is None: - with self.multiple_sequential_calls(): - if _coconut.len(self.iters) == 1: - self.result = _coconut.list(self.get_pool_stack()[-1].imap(_coconut_parallel_concurrent_map_func_wrapper(self.__class__, self.func, False), self.iters[0], self.chunksize)) - else: - self.result = _coconut.list(self.get_pool_stack()[-1].imap(_coconut_parallel_concurrent_map_func_wrapper(self.__class__, self.func, True), _coconut.zip(*self.iters), self.chunksize)) - return self.result - def __iter__(self): - return _coconut.iter(self.get_list()) -class parallel_map(_coconut_base_parallel_concurrent_map): - """Multi-process implementation of map. Requires arguments to be pickleable. - - For multiple sequential calls, use: - with parallel_map.multiple_sequential_calls(): - ... - """ - __slots__ = () - threadlocal_ns = _coconut.threading.local() - @staticmethod - def make_pool(max_workers=None): - return _coconut.multiprocessing.Pool(max_workers) - def __repr__(self): - return "parallel_" + _coconut_map.__repr__(self) -class concurrent_map(_coconut_base_parallel_concurrent_map): - """Multi-thread implementation of map. - - For multiple sequential calls, use: - with concurrent_map.multiple_sequential_calls(): - ... - """ - __slots__ = () - threadlocal_ns = _coconut.threading.local() - @staticmethod - def make_pool(max_workers=None): - return _coconut.multiprocessing_dummy.Pool(_coconut.multiprocessing.cpu_count() * 5 if max_workers is None else max_workers) - def __repr__(self): - return "concurrent_" + _coconut_map.__repr__(self) -class filter(_coconut_base_hashable, _coconut.filter): - __slots__ = ("func", "iter") - if hasattr(_coconut.filter, "__doc__"): - __doc__ = _coconut.filter.__doc__ - def __new__(cls, function, iterable): - new_filter = _coconut.filter.__new__(cls, function, iterable) - new_filter.func = function - new_filter.iter = iterable - return new_filter - def __reversed__(self): - return self.__class__(self.func, _coconut_reversed(self.iter)) - def __repr__(self): - return "filter(%r, %s)" % (self.func, _coconut.repr(self.iter)) - def __reduce__(self): - return (self.__class__, (self.func, self.iter)) - def __iter__(self): - return _coconut.iter(_coconut.filter(self.func, self.iter)) - def __fmap__(self, func): - return _coconut_map(func, self) -class zip(_coconut_base_hashable, _coconut.zip): - __slots__ = ("iters", "strict") - if hasattr(_coconut.zip, "__doc__"): - __doc__ = _coconut.zip.__doc__ - def __new__(cls, *iterables, **kwargs): - new_zip = _coconut.zip.__new__(cls, *iterables) - new_zip.iters = iterables - new_zip.strict = kwargs.pop("strict", False) - if kwargs: - raise _coconut.TypeError("zip() got unexpected keyword arguments " + _coconut.repr(kwargs)) - return new_zip - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(*(_coconut_iter_getitem(i, index) for i in self.iters), strict=self.strict) - return _coconut.tuple(_coconut_iter_getitem(i, index) for i in self.iters) - def __reversed__(self): - return self.__class__(*(_coconut_reversed(i) for i in self.iters), strict=self.strict) - def __len__(self): - return _coconut.min(_coconut.len(i) for i in self.iters) - def __repr__(self): - return "zip(%s%s)" % (", ".join((_coconut.repr(i) for i in self.iters)), ", strict=True" if self.strict else "") - def __reduce__(self): - return (self.__class__, self.iters, self.strict) - def __setstate__(self, strict): - self.strict = strict - def __iter__(self): - for items in _coconut.iter(_coconut.zip_longest(*self.iters, fillvalue=_coconut_sentinel) if self.strict else _coconut.zip(*self.iters)): - if self.strict and _coconut.any(x is _coconut_sentinel for x in items): - raise _coconut.ValueError("zip(..., strict=True) arguments have mismatched lengths") - yield items - def __fmap__(self, func): - return _coconut_map(func, self) -class zip_longest(zip): - __slots__ = ("fillvalue",) - if hasattr(_coconut.zip_longest, "__doc__"): - __doc__ = (_coconut.zip_longest).__doc__ - def __new__(cls, *iterables, **kwargs): - self = _coconut_zip.__new__(cls, *iterables, strict=False) - self.fillvalue = kwargs.pop("fillvalue", None) - if kwargs: - raise _coconut.TypeError("zip_longest() got unexpected keyword arguments " + _coconut.repr(kwargs)) - return self - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - new_ind = _coconut.slice(index.start + self.__len__() if index.start is not None and index.start < 0 else index.start, index.stop + self.__len__() if index.stop is not None and index.stop < 0 else index.stop, index.step) - return self.__class__(*(_coconut_iter_getitem(i, new_ind) for i in self.iters)) - if index < 0: - index += self.__len__() - result = [] - got_non_default = False - for it in self.iters: - try: - result.append(_coconut_iter_getitem(it, index)) - except _coconut.IndexError: - result.append(self.fillvalue) - else: - got_non_default = True - if not got_non_default: - raise _coconut.IndexError("zip_longest index out of range") - return _coconut.tuple(result) - def __len__(self): - return _coconut.max(_coconut.len(i) for i in self.iters) - def __repr__(self): - return "zip_longest(%s, fillvalue=%s)" % (", ".join((_coconut.repr(i) for i in self.iters)), _coconut.repr(self.fillvalue)) - def __reduce__(self): - return (self.__class__, self.iters, self.fillvalue) - def __setstate__(self, fillvalue): - self.fillvalue = fillvalue - def __iter__(self): - return _coconut.iter(_coconut.zip_longest(*self.iters, fillvalue=self.fillvalue)) -class enumerate(_coconut_base_hashable, _coconut.enumerate): - __slots__ = ("iter", "start") - if hasattr(_coconut.enumerate, "__doc__"): - __doc__ = _coconut.enumerate.__doc__ - def __new__(cls, iterable, start=0): - new_enumerate = _coconut.enumerate.__new__(cls, iterable, start) - new_enumerate.iter = iterable - new_enumerate.start = start - return new_enumerate - def __repr__(self): - return "enumerate(%s, %r)" % (_coconut.repr(self.iter), self.start) - def __fmap__(self, func): - return _coconut_map(func, self) - def __reduce__(self): - return (self.__class__, (self.iter, self.start)) - def __iter__(self): - return _coconut.iter(_coconut.enumerate(self.iter, self.start)) - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(_coconut_iter_getitem(self.iter, index), self.start + (0 if index.start is None else index.start if index.start >= 0 else _coconut.len(self.iter) + index.start)) - return (self.start + index, _coconut_iter_getitem(self.iter, index)) - def __len__(self): - return _coconut.len(self.iter) -class multi_enumerate(_coconut_base_hashable): - """Enumerate an iterable of iterables. Works like enumerate, but indexes - through inner iterables and produces a tuple index representing the index - in each inner iterable. Supports indexing. - - For numpy arrays, effectively equivalent to: - it = np.nditer(iterable, flags=["multi_index"]) - for x in it: - yield it.multi_index, x - - Also supports len for numpy arrays. - """ - __slots__ = ("iter",) - def __init__(self, iterable): - self.iter = iterable - def __repr__(self): - return "multi_enumerate(%s)" % (_coconut.repr(self.iter),) - def __fmap__(self, func): - return _coconut_map(func, self) - def __reduce__(self): - return (self.__class__, (self.iter,)) - @property - def is_numpy(self): - return self.iter.__class__.__module__ in _coconut.numpy_modules - def __iter__(self): - if self.is_numpy: - it = _coconut.numpy.nditer(self.iter, flags=["multi_index"]) - for x in it: - yield it.multi_index, x - else: - ind = [-1] - its = [_coconut.iter(self.iter)] - while its: - ind[-1] += 1 - try: - x = _coconut.next(its[-1]) - except _coconut.StopIteration: - ind.pop() - its.pop() - else: - if _coconut.isinstance(x, _coconut.abc.Iterable): - ind.append(-1) - its.append(_coconut.iter(x)) - else: - yield _coconut.tuple(ind), x - def __getitem__(self, index): - if self.is_numpy and not _coconut.isinstance(index, _coconut.slice): - multi_ind = [] - for i in _coconut.reversed(self.iter.shape): - multi_ind.append(index % i) - index //= i - multi_ind = _coconut.tuple(_coconut.reversed(multi_ind)) - return multi_ind, self.iter[multi_ind] - return _coconut_iter_getitem(_coconut.iter(self), index) - def __len__(self): - if self.is_numpy: - return self.iter.size - return _coconut.NotImplemented -class count(_coconut_base_hashable): - """count(start, step) returns an infinite iterator starting at start and increasing by step. - - If step is set to 0, count will infinitely repeat its first argument. - """ - __slots__ = ("start", "step") - def __init__(self, start=0, step=1): - self.start = start - self.step = step - def __iter__(self): - while True: - yield self.start - if self.step: - self.start += self.step - def __contains__(self, elem): - if not self.step: - return elem == self.start - if self.step > 0 and elem < self.start or self.step < 0 and elem > self.start: - return False - return (elem - self.start) % self.step == 0 - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - if (index.start is None or index.start >= 0) and (index.stop is None or index.stop >= 0): - new_start, new_step = self.start, self.step - if self.step and index.start is not None: - new_start += self.step * index.start - if self.step and index.step is not None: - new_step *= index.step - if index.stop is None: - return self.__class__(new_start, new_step) - if self.step and _coconut.isinstance(self.start, _coconut.int) and _coconut.isinstance(self.step, _coconut.int): - return _coconut.range(new_start, self.start + self.step * index.stop, new_step) - return _coconut_map(self.__getitem__, _coconut.range(index.start if index.start is not None else 0, index.stop, index.step if index.step is not None else 1)) - raise _coconut.IndexError("count() indices must be positive") - if index < 0: - raise _coconut.IndexError("count() indices must be positive") - return self.start + self.step * index if self.step else self.start - def count(self, elem): - """Count the number of times elem appears in the count.""" - if not self.step: - return _coconut.float("inf") if elem == self.start else 0 - return _coconut.int(elem in self) - def index(self, elem): - """Find the index of elem in the count.""" - if elem not in self: - raise _coconut.ValueError(_coconut.repr(elem) + " not in " + _coconut.repr(self)) - return (elem - self.start) // self.step if self.step else 0 - def __reversed__(self): - if not self.step: - return self - raise _coconut.TypeError(_coconut.repr(self) + " object is not reversible") - def __repr__(self): - return "count(%s, %s)" % (_coconut.repr(self.start), _coconut.repr(self.step)) - def __reduce__(self): - return (self.__class__, (self.start, self.step)) - def __copy__(self): - return self.__class__(self.start, self.step) - def __fmap__(self, func): - return _coconut_map(func, self) -class groupsof(_coconut_base_hashable): - """groupsof(n, iterable) splits iterable into groups of size n. - - If the length of the iterable is not divisible by n, the last group will be of size < n. - """ - __slots__ = ("group_size", "iter") - def __init__(self, n, iterable): - self.group_size = _coconut.operator.index(n) - if self.group_size <= 0: - raise _coconut.ValueError("group size must be > 0; not %r" % (self.group_size,)) - self.iter = iterable - def __iter__(self): - iterator = _coconut.iter(self.iter) - loop = True - while loop: - group = [] - for _ in _coconut.range(self.group_size): - try: - group.append(_coconut.next(iterator)) - except _coconut.StopIteration: - loop = False - break - if group: - yield _coconut.tuple(group) - def __len__(self): - return _coconut.int(_coconut.math.ceil(_coconut.len(self.iter) / self.group_size)) - def __repr__(self): - return "groupsof(%s)" % (_coconut.repr(self.iter),) - def __reduce__(self): - return (self.__class__, (self.group_size, self.iter)) - def __fmap__(self, func): - return _coconut_map(func, self) -class recursive_iterator(_coconut_base_hashable): - """Decorator that optimizes a recursive function that returns an iterator (e.g. a recursive generator).""" - __slots__ = ("func", "tee_store", "backup_tee_store") - def __init__(self, func): - self.func = func - self.tee_store = {} - self.backup_tee_store = [] - def __call__(self, *args, **kwargs): - key = (args, _coconut.frozenset(kwargs.items())) - use_backup = False - try: - _coconut.hash(key) - except _coconut.Exception: - try: - key = _coconut.pickle.dumps(key, -1) - except _coconut.Exception: - use_backup = True - if use_backup: - for i, (k, v) in _coconut.enumerate(self.backup_tee_store): - if k == key: - to_tee, store_pos = v, i - break - else: - to_tee = self.func(*args, **kwargs) - store_pos = None - to_store, to_return = _coconut_tee(to_tee) - if store_pos is None: - self.backup_tee_store.append([key, to_store]) - else: - self.backup_tee_store[store_pos][1] = to_store - else: - it = self.tee_store.get(key) - if it is None: - it = self.func(*args, **kwargs) - self.tee_store[key], to_return = _coconut_tee(it) - return to_return - def __repr__(self): - return "recursive_iterator(%r)" % (self.func,) - def __reduce__(self): - return (self.__class__, (self.func,)) - def __get__(self, obj, objtype=None): - if obj is None: - return self - return _coconut.types.MethodType(self, obj, objtype) -class _coconut_FunctionMatchErrorContext(object): - __slots__ = ("exc_class", "taken") - threadlocal_ns = _coconut.threading.local() - def __init__(self, exc_class): - self.exc_class = exc_class - self.taken = False - @classmethod - def get_contexts(cls): - try: - return cls.threadlocal_ns.contexts - except _coconut.AttributeError: - cls.threadlocal_ns.contexts = [] - return cls.threadlocal_ns.contexts - def __enter__(self): - self.get_contexts().append(self) - def __exit__(self, type, value, traceback): - self.get_contexts().pop() -def _coconut_get_function_match_error(): - try: - ctx = _coconut_FunctionMatchErrorContext.get_contexts()[-1] - except _coconut.IndexError: - return _coconut_MatchError - if ctx.taken: - return _coconut_MatchError - ctx.taken = True - return ctx.exc_class -class _coconut_base_pattern_func(_coconut_base_hashable): - __slots__ = ("FunctionMatchError", "patterns", "__doc__", "__name__") - _coconut_is_match = True - def __init__(self, *funcs): - self.FunctionMatchError = _coconut.type(_coconut_py_str("MatchError"), (_coconut_MatchError,), {}) - self.patterns = [] - self.__doc__ = None - self.__name__ = None - - for func in funcs: - self.add_pattern(func) - def add_pattern(self, func): - if _coconut.isinstance(func, _coconut_base_pattern_func): - self.patterns += func.patterns - else: - self.patterns.append(func) - self.__doc__ = _coconut.getattr(func, "__doc__", self.__doc__) - self.__name__ = _coconut.getattr(func, "__name__", self.__name__) - - def __call__(self, *args, **kwargs): - for func in self.patterns[:-1]: - try: - with _coconut_FunctionMatchErrorContext(self.FunctionMatchError): - return func(*args, **kwargs) - except self.FunctionMatchError: - pass - return self.patterns[-1](*args, **kwargs) - def _coconut_tco_func(self, *args, **kwargs): - for func in self.patterns[:-1]: - try: - with _coconut_FunctionMatchErrorContext(self.FunctionMatchError): - return func(*args, **kwargs) - except self.FunctionMatchError: - pass - return _coconut_tail_call(self.patterns[-1], *args, **kwargs) - def __repr__(self): - return "addpattern(%r)(*%r)" % (self.patterns[0], self.patterns[1:]) - def __reduce__(self): - return (self.__class__, _coconut.tuple(self.patterns)) - def __get__(self, obj, objtype=None): - if obj is None: - return self - return _coconut.types.MethodType(self, obj, objtype) -def _coconut_mark_as_match(base_func): - base_func._coconut_is_match = True - return base_func -def addpattern(base_func, new_pattern=None, **kwargs): - """Decorator to add a new case to a pattern-matching function (where the new case is checked last). - - Pass allow_any_func=True to allow any object as the base_func rather than just pattern-matching functions. - If new_pattern is passed, addpattern(base_func, new_pattern) is equivalent to addpattern(base_func)(new_pattern). - """ - allow_any_func = kwargs.pop("allow_any_func", False) - if not allow_any_func and not _coconut.getattr(base_func, "_coconut_is_match", False): - _coconut.warnings.warn("Possible misuse of addpattern with non-pattern-matching function " + _coconut.repr(base_func) + " (pass allow_any_func=True to dismiss)", stacklevel=2) - if kwargs: - raise _coconut.TypeError("addpattern() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if new_pattern is not None: - return _coconut_base_pattern_func(base_func, new_pattern) - return _coconut.functools.partial(_coconut_base_pattern_func, base_func) -_coconut_addpattern = addpattern -def prepattern(base_func, **kwargs): - """DEPRECATED: use addpattern instead.""" - def pattern_prepender(func): - return addpattern(func, **kwargs)(base_func) - return pattern_prepender -class _coconut_partial(_coconut_base_hashable): - __slots__ = ("func", "_argdict", "_arglen", "_pos_kwargs", "_stargs", "keywords") - if hasattr(_coconut.functools.partial, "__doc__"): - __doc__ = _coconut.functools.partial.__doc__ - def __init__(self, _coconut_func, _coconut_argdict, _coconut_arglen, _coconut_pos_kwargs, *args, **kwargs): - self.func = _coconut_func - self._argdict = _coconut_argdict - self._arglen = _coconut_arglen - self._pos_kwargs = _coconut_pos_kwargs - self._stargs = args - self.keywords = kwargs - def __reduce__(self): - return (self.__class__, (self.func, self._argdict, self._arglen, self._pos_kwargs) + self._stargs, self.keywords) - def __setstate__(self, keywords): - self.keywords = keywords - @property - def args(self): - return _coconut.tuple(self._argdict.get(i) for i in _coconut.range(self._arglen)) + self._stargs - @property - def required_nargs(self): - return self._arglen - _coconut.len(self._argdict) + len(self._pos_kwargs) - def __call__(self, *args, **kwargs): - callargs = [] - argind = 0 - for i in _coconut.range(self._arglen): - if i in self._argdict: - callargs.append(self._argdict[i]) - elif argind >= _coconut.len(args): - raise _coconut.TypeError("expected at least " + _coconut.str(self.required_nargs) + " argument(s) to " + _coconut.repr(self)) - else: - callargs.append(args[argind]) - argind += 1 - for k in self._pos_kwargs: - if k in kwargs: - raise _coconut.TypeError(_coconut.repr(k) + " is an invalid keyword argument for " + _coconut.repr(self)) - elif argind >= _coconut.len(args): - raise _coconut.TypeError("expected at least " + _coconut.str(self.required_nargs) + " argument(s) to " + _coconut.repr(self)) - else: - kwargs[k] = args[argind] - argind += 1 - callargs += self._stargs - callargs += args[argind:] - callkwargs = self.keywords.copy() - callkwargs.update(kwargs) - return self.func(*callargs, **callkwargs) - def __repr__(self): - args = [] - for i in _coconut.range(self._arglen): - if i in self._argdict: - args.append(_coconut.repr(self._argdict[i])) - else: - args.append("?") - for arg in self._stargs: - args.append(_coconut.repr(arg)) - for k in self._pos_kwargs: - args.append(k + "=?") - for k, v in self.keywords.items(): - args.append(k + "=" + _coconut.repr(v)) - return "%r$(%s)" % (self.func, ", ".join(args)) -def consume(iterable, keep_last=0): - """consume(iterable, keep_last) fully exhausts iterable and returns the last keep_last elements.""" - return _coconut.collections.deque(iterable, maxlen=keep_last) -class starmap(_coconut_base_hashable, _coconut.itertools.starmap): - __slots__ = ("func", "iter") - if hasattr(_coconut.itertools.starmap, "__doc__"): - __doc__ = _coconut.itertools.starmap.__doc__ - def __new__(cls, function, iterable): - new_map = _coconut.itertools.starmap.__new__(cls, function, iterable) - new_map.func = function - new_map.iter = iterable - return new_map - def __getitem__(self, index): - if _coconut.isinstance(index, _coconut.slice): - return self.__class__(self.func, _coconut_iter_getitem(self.iter, index)) - return self.func(*_coconut_iter_getitem(self.iter, index)) - def __reversed__(self): - return self.__class__(self.func, *_coconut_reversed(self.iter)) - def __len__(self): - return _coconut.len(self.iter) - def __repr__(self): - return "starmap(%r, %s)" % (self.func, _coconut.repr(self.iter)) - def __reduce__(self): - return (self.__class__, (self.func, self.iter)) - def __iter__(self): - return _coconut.iter(_coconut.itertools.starmap(self.func, self.iter)) - def __fmap__(self, func): - return self.__class__(_coconut_forward_compose(self.func, func), self.iter) -def _coconut_base_makedata(data_type, args): - if _coconut.hasattr(data_type, "_make") and _coconut.issubclass(data_type, _coconut.tuple): - return data_type._make(args) - if _coconut.issubclass(data_type, (_coconut.range, _coconut.abc.Iterator)): - return args - if _coconut.issubclass(data_type, _coconut.str): - return "".join(args) - return data_type(args) -def makedata(data_type, *args): - """Construct an object of the given data_type containing the given arguments.""" - return _coconut_base_makedata(data_type, args) -def datamaker(data_type): - """DEPRECATED: use makedata instead.""" - return _coconut.functools.partial(makedata, data_type) -_coconut_amap = None -def fmap(func, obj, **kwargs): - """fmap(func, obj) creates a copy of obj with func applied to its contents. - Supports asynchronous iterables, mappings (maps over .items()), and numpy arrays (uses np.vectorize). - - Override by defining obj.__fmap__(func). - """ - starmap_over_mappings = kwargs.pop("starmap_over_mappings", False) - if kwargs: - raise _coconut.TypeError("fmap() got unexpected keyword arguments " + _coconut.repr(kwargs)) - obj_fmap = _coconut.getattr(obj, "__fmap__", None) - if obj_fmap is not None: - try: - result = obj_fmap(func) - except _coconut.NotImplementedError: - pass - else: - if result is not _coconut.NotImplemented: - return result - if obj.__class__.__module__ in _coconut.jax_numpy_modules: - import jax.numpy as jnp - return jnp.vectorize(func)(obj) - if obj.__class__.__module__ in _coconut.numpy_modules: - return _coconut.numpy.vectorize(func)(obj) - obj_aiter = _coconut.getattr(obj, "__aiter__", None) - if obj_aiter is not None and _coconut_amap is not None: - try: - aiter = obj_aiter() - except _coconut.NotImplementedError: - pass - else: - if aiter is not _coconut.NotImplemented: - return _coconut_amap(func, aiter) - if starmap_over_mappings: - return _coconut_base_makedata(obj.__class__, _coconut_starmap(func, obj.items()) if _coconut.isinstance(obj, _coconut.abc.Mapping) else _coconut_map(func, obj)) - else: - return _coconut_base_makedata(obj.__class__, _coconut_map(func, obj.items() if _coconut.isinstance(obj, _coconut.abc.Mapping) else obj)) -def memoize(maxsize=None, *args, **kwargs): - """Decorator that memoizes a function, preventing it from being recomputed - if it is called multiple times with the same arguments.""" - return _coconut.functools.lru_cache(maxsize, *args, **kwargs) -def _coconut_call_set_names(cls): - for k, v in _coconut.vars(cls).items(): - set_name = _coconut.getattr(v, "__set_name__", None) - if set_name is not None: - set_name(cls, k) -class override(_coconut_base_hashable): - __slots__ = ("func",) - def __init__(self, func): - self.func = func - def __get__(self, obj, objtype=None): - if obj is None: - return self.func - return _coconut.types.MethodType(self.func, obj, objtype) - def __set_name__(self, obj, name): - if not _coconut.hasattr(_coconut.super(obj, obj), name): - raise _coconut.RuntimeError(obj.__name__ + "." + name + " marked with @override but not overriding anything") - def __reduce__(self): - return (self.__class__, (self.func,)) -def reveal_type(obj): - """Special function to get MyPy to print the type of the given expression. - At runtime, reveal_type is the identity function.""" - return obj -def reveal_locals(): - """Special function to get MyPy to print the type of the current locals. - At runtime, reveal_locals always returns None.""" - pass -def _coconut_handle_cls_kwargs(**kwargs): - """Some code taken from six under the terms of its MIT license.""" - metaclass = kwargs.pop("metaclass", None) - if kwargs and metaclass is None: - raise _coconut.TypeError("unexpected keyword argument(s) in class definition: %r" % (kwargs,)) - def coconut_handle_cls_kwargs_wrapper(cls): - if metaclass is None: - return cls - orig_vars = cls.__dict__.copy() - slots = orig_vars.get("__slots__") - if slots is not None: - if _coconut.isinstance(slots, _coconut.str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop("__dict__", None) - orig_vars.pop("__weakref__", None) - if _coconut.hasattr(cls, "__qualname__"): - orig_vars["__qualname__"] = cls.__qualname__ - return metaclass(cls.__name__, cls.__bases__, orig_vars, **kwargs) - return coconut_handle_cls_kwargs_wrapper -def _coconut_handle_cls_stargs(*args): - temp_names = ["_coconut_base_cls_%s" % (i,) for i in _coconut.range(_coconut.len(args))] - ns = _coconut.dict(_coconut.zip(temp_names, args)) - _coconut_exec("class _coconut_cls_stargs_base(" + ", ".join(temp_names) + "): pass", ns) - return ns["_coconut_cls_stargs_base"] -def _coconut_dict_merge(*dicts, **kwargs): - for_func = kwargs.pop("for_func", False) - assert not kwargs, "error with internal Coconut function _coconut_dict_merge (you should report this at https://github.com/evhub/coconut/issues/new)" - newdict = {} - prevlen = 0 - for d in dicts: - newdict.update(d) - if for_func: - if _coconut.len(newdict) != prevlen + _coconut.len(d): - raise _coconut.TypeError("multiple values for the same keyword argument") - prevlen = _coconut.len(newdict) - return newdict -def ident(x, **kwargs): - """The identity function. Generally equivalent to x -> x. Useful in point-free programming. - Accepts one keyword-only argument, side_effect, which specifies a function to call on the argument before it is returned.""" - side_effect = kwargs.pop("side_effect", None) - if kwargs: - raise _coconut.TypeError("ident() got unexpected keyword arguments " + _coconut.repr(kwargs)) - if side_effect is not None: - side_effect(x) - return x -def of(_coconut_f, *args, **kwargs): - """Function application operator function. - - Equivalent to: - def of(f, *args, **kwargs) = f(*args, **kwargs). - """ - return _coconut_f(*args, **kwargs) -class flip(_coconut_base_hashable): - """Given a function, return a new function with inverse argument order. - If nargs is passed, only the first nargs arguments are reversed.""" - __slots__ = ("func", "nargs") - def __init__(self, func, nargs=None): - self.func = func - self.nargs = nargs - def __reduce__(self): - return (self.__class__, (self.func, self.nargs)) - def __call__(self, *args, **kwargs): - return self.func(*args[::-1], **kwargs) if self.nargs is None else self.func(*(args[self.nargs-1::-1] + args[self.nargs:]), **kwargs) - def __repr__(self): - return "flip(%r%s)" % (self.func, "" if self.nargs is None else ", " + _coconut.repr(self.nargs)) -class const(_coconut_base_hashable): - """Create a function that, whatever its arguments, just returns the given value.""" - __slots__ = ("value",) - def __init__(self, value): - self.value = value - def __reduce__(self): - return (self.__class__, (self.value,)) - def __call__(self, *args, **kwargs): - return self.value - def __repr__(self): - return "const(%s)" % (_coconut.repr(self.value),) -class _coconut_lifted(_coconut_base_hashable): - __slots__ = ("func", "func_args", "func_kwargs") - def __init__(self, _coconut_func, *func_args, **func_kwargs): - self.func = _coconut_func - self.func_args = func_args - self.func_kwargs = func_kwargs - def __reduce__(self): - return (self.__class__, (self.func,) + self.func_args, self.func_kwargs) - def __setstate__(self, func_kwargs): - self.func_kwargs = func_kwargs - def __call__(self, *args, **kwargs): - return self.func(*(g(*args, **kwargs) for g in self.func_args), **_coconut.dict((k, h(*args, **kwargs)) for k, h in self.func_kwargs.items())) - def __repr__(self): - return "lift(%r)(%s%s)" % (self.func, ", ".join(_coconut.repr(g) for g in self.func_args), ", ".join(k + "=" + _coconut.repr(h) for k, h in self.func_kwargs.items())) -class lift(_coconut_base_hashable): - """Lifts a function up so that all of its arguments are functions. - - For a binary function f(x, y) and two unary functions g(z) and h(z), lift works as the S' combinator: - lift(f)(g, h)(z) == f(g(z), h(z)) - - In general, lift is requivalent to: - def lift(f) = ((*func_args, **func_kwargs) -> (*args, **kwargs) -> - f(*(g(*args, **kwargs) for g in func_args), **{k: h(*args, **kwargs) for k, h in func_kwargs.items()})) - - lift also supports a shortcut form such that lift(f, *func_args, **func_kwargs) is equivalent to lift(f)(*func_args, **func_kwargs). - """ - __slots__ = ("func",) - def __new__(cls, func, *func_args, **func_kwargs): - self = _coconut.object.__new__(cls) - self.func = func - if func_args or func_kwargs: - self = self(*func_args, **func_kwargs) - return self - def __reduce__(self): - return (self.__class__, (self.func,)) - def __call__(self, *func_args, **func_kwargs): - return _coconut_lifted(self.func, *func_args, **func_kwargs) - def __repr__(self): - return "lift(%r)" % (self.func,) -def all_equal(iterable): - """For a given iterable, check whether all elements in that iterable are equal to each other. - - Assumes transitivity and 'x != y' being equivalent to 'not (x == y)'. - """ - first_item = _coconut_sentinel - for item in iterable: - if first_item is _coconut_sentinel: - first_item = item - elif first_item != item: - return False - return True -def collectby(key_func, iterable, value_func=None, reduce_func=None): - """Collect the items in iterable into a dictionary of lists keyed by key_func(item). - - if value_func is passed, collect value_func(item) into each list instead of item. - - If reduce_func is passed, instead of collecting the items into lists, reduce over - the items of each key with reduce_func, effectively implementing a MapReduce operation. - """ - collection = _coconut.collections.defaultdict(_coconut.list) if reduce_func is None else {} - for item in iterable: - key = key_func(item) - if value_func is not None: - item = value_func(item) - if reduce_func is None: - collection[key].append(item) - else: - old_item = collection.get(key, _coconut_sentinel) - if old_item is not _coconut_sentinel: - item = reduce_func(old_item, item) - collection[key] = item - return collection -def _namedtuple_of(**kwargs): - """Construct an anonymous namedtuple of the given keyword arguments.""" - raise _coconut.RuntimeError("_namedtuple_of is not available on Python < 3.6 (use anonymous namedtuple literals instead)") -def _coconut_mk_anon_namedtuple(fields, types=None, of_kwargs=None): - if types is None: - NT = _coconut.collections.namedtuple("_namedtuple_of", fields) - else: - NT = _coconut.typing.NamedTuple("_namedtuple_of", [(f, t) for f, t in _coconut.zip(fields, types)]) - _coconut.copyreg.pickle(NT, lambda nt: (_coconut_mk_anon_namedtuple, (nt._fields, types, nt._asdict()))) - if of_kwargs is None: - return NT - return NT(**of_kwargs) -def _coconut_ndim(arr): - if (arr.__class__.__module__ in _coconut.numpy_modules or _coconut.hasattr(arr.__class__, "__matconcat__")) and _coconut.hasattr(arr, "ndim"): - return arr.ndim - if not _coconut.isinstance(arr, _coconut.abc.Sequence): - return 0 - if _coconut.len(arr) == 0: - return 1 - arr_dim = 1 - inner_arr = arr[0] - while _coconut.isinstance(inner_arr, _coconut.abc.Sequence): - arr_dim += 1 - if _coconut.len(inner_arr) < 1: - break - inner_arr = inner_arr[0] - return arr_dim -def _coconut_expand_arr(arr, new_dims): - if (arr.__class__.__module__ in _coconut.numpy_modules or _coconut.hasattr(arr.__class__, "__matconcat__")) and _coconut.hasattr(arr, "reshape"): - return arr.reshape((1,) * new_dims + arr.shape) - for _ in _coconut.range(new_dims): - arr = [arr] - return arr -def _coconut_concatenate(arrs, axis): - matconcat = None - for a in arrs: - if a.__class__.__module__ in _coconut.jax_numpy_modules: - from jax.numpy import concatenate as matconcat - break - if a.__class__.__module__ in _coconut.numpy_modules: - matconcat = _coconut.numpy.concatenate - break - if _coconut.hasattr(a.__class__, "__matconcat__"): - matconcat = a.__class__.__matconcat__ - break - if matconcat is not None: - return matconcat(arrs, axis) - if not axis: - return _coconut.list(_coconut.itertools.chain.from_iterable(arrs)) - return [_coconut_concatenate(rows, axis - 1) for rows in _coconut.zip(*arrs)] -def _coconut_multi_dim_arr(arrs, dim): - arr_dims = [_coconut_ndim(a) for a in arrs] - arrs = [_coconut_expand_arr(a, dim - d) if d < dim else a for a, d in _coconut.zip(arrs, arr_dims)] - arr_dims.append(dim) - max_arr_dim = _coconut.max(arr_dims) - return _coconut_concatenate(arrs, max_arr_dim - dim) -_coconut_self_match_types = (bool, bytearray, bytes, dict, float, frozenset, int, py_int, list, set, str, py_str, tuple) -_coconut_MatchError, _coconut_count, _coconut_enumerate, _coconut_filter, _coconut_map, _coconut_reiterable, _coconut_reversed, _coconut_starmap, _coconut_tee, _coconut_zip, TYPE_CHECKING, reduce, takewhile, dropwhile = MatchError, count, enumerate, filter, map, reiterable, reversed, starmap, tee, zip, False, _coconut.functools.reduce, _coconut.itertools.takewhile, _coconut.itertools.dropwhile diff --git a/yaltik_dsl/tests/test_odoo.coco b/yaltik_dsl/tests/test_odoo.coco deleted file mode 100644 index cc2ad07..0000000 --- a/yaltik_dsl/tests/test_odoo.coco +++ /dev/null @@ -1,247 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2020 Fabien Bourgeois -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -""" Odoo Helpers tests """ - -import unittest -import xml.etree.ElementTree as ET -from src.xml_base import XMLDictElement -import src.odoo_dsl as od - -class TestOdooBase(unittest.TestCase): - """ Odoo Helpers tests """ - - def test_odoo(self): - """ Test odoo function """ - element = od.odoo([]) - self.assertIsInstance(element, ET.Element) - self.assertEqual(element.tag, 'odoo') - - def test_data(self): - """ Test data function """ - element = od.data([]) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'data') - self.assertEqual(element.attrs, {}) - - element = od.data({"one": "attribute"}, []) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'data') - self.assertEqual(element.attrs, {"one": "attribute"}) - - def test_aliases(self): - """ Test simple aliases to xmln """ - element = od.record({"one": "attribute"}, 'A child') - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'record') - self.assertEqual(element.attrs, {"one": "attribute"}) - self.assertEqual(element.children, ['A child']) - - element = od.tree() - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'tree') - - def test_act_window_model(self): - """ Test act_window function """ - element = od.act_window_model('sample.model', {'view_type': 'form'}) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'act_window') - self.assertEqual(element.attrs['view_type'], 'form') - self.assertEqual(element.attrs['id'], 'sample_model_view_action') - self.assertEqual(element.attrs['res_model'], 'sample.model') - self.assertEqual(element.attrs['name'], 'Sample Model Action') - - def test_menunitem_model(self): - """ Test menuitem function """ - element = od.menuitem_model('sample.model', {'groups': 'base.user_employee'}) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'menuitem') - self.assertEqual(element.attrs['groups'], 'base.user_employee') - self.assertEqual(element.attrs['id'], 'sample_model_menu') - self.assertEqual(element.attrs['action'], 'sample_model_view_action') - - def test_attribute(self): - """ Test attribute function """ - element = od.attribute('invisible', "1") - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'attribute') - self.assertEqual(element.attrs['name'], 'invisible') - self.assertEqual(element.children, ["1"]) - - def test_fields(self): - """ Test fields function """ - element = od.field({"one": "attribute"}, 'A child') - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'field') - - element = od.field_name('A name') - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'field') - self.assertEqual(element.attrs['name'], 'name') - self.assertEqual(element.children, ['A name']) - - element = od.field_model('sample.model') - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'field') - self.assertEqual(element.attrs['name'], 'model') - self.assertEqual(element.children, ['sample.model']) - - element = od.field_inherit('module.xml_view') - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'field') - self.assertEqual(element.attrs['name'], 'inherit_id') - self.assertEqual(element.attrs['ref'], 'module.xml_view') - self.assertFalse(element.children) - - element = od.field_arch() - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'field') - self.assertEqual(element.attrs['name'], 'arch') - self.assertEqual(element.attrs['type'], 'xml') - self.assertFalse(element.children) - - def test_view(self): - """ Test view function """ - element = od.view('view_xmlid', []) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'record') - self.assertEqual(element.attrs['id'], 'view_xmlid') - self.assertEqual(element.attrs['model'], 'ir.ui.view') - self.assertFalse(element.children) - - def test_view_def(self): - """ Test view_def function """ - element = od.view_def('view_xmlid', 'View', 'sample.model', []) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'record') - self.assertEqual(element.attrs['id'], 'view_xmlid') - self.assertEqual(element.attrs['model'], 'ir.ui.view') - self.assertEqual((len(element.children)), 3) - self.assertIsInstance(element.children[0], XMLDictElement) - self.assertEqual(element.children[0].tag, 'field') - self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['View']) - self.assertIsInstance(element.children[1], XMLDictElement) - self.assertEqual(element.children[1].tag, 'field') - self.assertEqual(element.children[1].attrs['name'], 'model') - self.assertEqual(element.children[1].children, ['sample.model']) - self.assertIsInstance(element.children[2], XMLDictElement) - self.assertEqual(element.children[2].tag, 'field') - self.assertEqual(element.children[2].attrs['name'], 'arch') - self.assertEqual(element.children[2].attrs['type'], 'xml') - self.assertFalse(element.children[2].children) - - def test_view_new(self): - """ Test view_new function """ - element = od.view_new('tree', 'sample.model', []) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'record') - self.assertEqual(element.attrs['id'], 'sample_model_view_tree') - self.assertEqual(element.attrs['model'], 'ir.ui.view') - self.assertEqual((len(element.children)), 3) - self.assertIsInstance(element.children[0], XMLDictElement) - self.assertEqual(element.children[0].tag, 'field') - self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Sample Model Tree']) - self.assertIsInstance(element.children[1], XMLDictElement) - self.assertEqual(element.children[1].tag, 'field') - self.assertEqual(element.children[1].attrs['name'], 'model') - self.assertEqual(element.children[1].children, ['sample.model']) - self.assertIsInstance(element.children[2], XMLDictElement) - self.assertEqual(element.children[2].tag, 'field') - self.assertEqual(element.children[2].attrs['name'], 'arch') - self.assertEqual(element.children[2].attrs['type'], 'xml') - self.assertFalse(element.children[2].children) - - def test_view_inherit(self): - """ Test view_inherit function """ - element = od.view_inherit('odoo.addons.module', 'sample.model', 'parent.view', []) - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'record') - self.assertEqual(element.attrs['id'], 'view_inherit_module') - self.assertEqual(element.attrs['model'], 'ir.ui.view') - self.assertEqual((len(element.children)), 4) - self.assertIsInstance(element.children[0], XMLDictElement) - self.assertEqual(element.children[0].tag, 'field') - self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Sample Model Adaptations']) - self.assertIsInstance(element.children[1], XMLDictElement) - self.assertEqual(element.children[1].tag, 'field') - self.assertEqual(element.children[1].attrs['name'], 'model') - self.assertEqual(element.children[1].children, ['sample.model']) - self.assertIsInstance(element.children[2], XMLDictElement) - self.assertEqual(element.children[2].tag, 'field') - self.assertEqual(element.children[2].attrs['name'], 'inherit_id') - self.assertFalse(element.children[2].children) - self.assertIsInstance(element.children[3], XMLDictElement) - self.assertEqual(element.children[3].tag, 'field') - self.assertEqual(element.children[3].attrs['name'], 'arch') - self.assertEqual(element.children[3].attrs['type'], 'xml') - self.assertFalse(element.children[3].children) - - def test_action_server_code(self): - """ Test action_server_code function """ - element = od.action_server_code('sample.xmlid', 'Code', 'sample.model', - '''record.do_something()''') - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'record') - self.assertEqual(element.attrs['id'], 'sample.xmlid') - self.assertEqual(element.attrs['model'], 'ir.actions.server') - self.assertEqual((len(element.children)), 4) - self.assertIsInstance(element.children[0], XMLDictElement) - self.assertEqual(element.children[0].tag, 'field') - self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Code']) - self.assertIsInstance(element.children[1], XMLDictElement) - self.assertEqual(element.children[1].tag, 'field') - self.assertEqual(element.children[1].attrs['name'], 'model_id') - self.assertEqual(element.children[1].attrs['ref'], 'sample.model') - self.assertFalse(element.children[1].children) - self.assertEqual(element.children[2].tag, 'field') - self.assertEqual(element.children[2].attrs['name'], 'state') - self.assertEqual(element.children[2].children, ['code']) - self.assertEqual(element.children[3].tag, 'field') - self.assertEqual(element.children[3].attrs['name'], 'code') - self.assertEqual(element.children[3].children, ['record.do_something()']) - - def test_client_action_multi(self): - """ Test client_action_multi function """ - element = od.client_action_multi('sample.xmlid', 'Multi', 'sample.model', 'sample.action') - self.assertIsInstance(element, XMLDictElement) - self.assertEqual(element.tag, 'record') - self.assertEqual(element.attrs['id'], 'sample.xmlid') - self.assertEqual(element.attrs['model'], 'ir.values') - self.assertEqual((len(element.children)), 4) - self.assertIsInstance(element.children[0], XMLDictElement) - self.assertEqual(element.children[0].tag, 'field') - self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Multi']) - self.assertIsInstance(element.children[1], XMLDictElement) - self.assertEqual(element.children[1].tag, 'field') - self.assertEqual(element.children[1].attrs['name'], 'key2') - self.assertEqual(element.children[1].attrs['eval'], "'client_action_multi'") - self.assertFalse(element.children[1].children) - self.assertEqual(element.children[2].tag, 'field') - self.assertEqual(element.children[2].attrs['name'], 'model') - self.assertEqual(element.children[2].attrs['eval'], "'sample.model'") - self.assertEqual(element.children[3].tag, 'field') - self.assertEqual(element.children[3].attrs['name'], 'value') - self.assertEqual(element.children[3].attrs['eval'], "'ir.actions.server,%d'%sample.action") - - -if __name__ == '__main__': - unittest.main() diff --git a/yaltik_dsl/tests/test_odoo.py b/yaltik_dsl/tests/test_odoo.py index b255231..cc2ad07 100644 --- a/yaltik_dsl/tests/test_odoo.py +++ b/yaltik_dsl/tests/test_odoo.py @@ -1,40 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0xbf41493b - -# Compiled with Coconut version 2.1.1 [The Spanish Inquisition] - -""" Odoo Helpers tests """ - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os as _coconut_os -_coconut_file_dir = _coconut_os.path.dirname(_coconut_os.path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os.path.dirname(_coconut_cached_module.__file__) != _coconut_file_dir: # type: ignore - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_dir) -_coconut_module_name = _coconut_os.path.splitext(_coconut_os.path.basename(_coconut_file_dir))[0] -if _coconut_module_name and _coconut_module_name[0].isalpha() and all(c.isalpha() or c.isdigit() for c in _coconut_module_name) and "__init__.py" in _coconut_os.listdir(_coconut_file_dir): - _coconut_full_module_name = str(_coconut_module_name + ".__coconut__") - import __coconut__ as _coconut__coconut__ - _coconut__coconut__.__name__ = _coconut_full_module_name - for _coconut_v in vars(_coconut__coconut__).values(): - if getattr(_coconut_v, "__module__", None) == b"__coconut__": - try: - _coconut_v.__module__ = _coconut_full_module_name - except AttributeError: - _coconut_v_type = type(_coconut_v) - if getattr(_coconut_v_type, "__module__", None) == b"__coconut__": - _coconut_v_type.__module__ = _coconut_full_module_name - _coconut_sys.modules[_coconut_full_module_name] = _coconut__coconut__ -from __coconut__ import * -from __coconut__ import _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_super, _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_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_multi_dim_arr, _coconut_mk_anon_namedtuple, _coconut_matmul -_coconut_sys.path.pop(0) - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # # Copyright 2020 Fabien Bourgeois @@ -52,7 +15,7 @@ _coconut_sys.path.pop(0) # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - +""" Odoo Helpers tests """ import unittest import xml.etree.ElementTree as ET @@ -68,7 +31,6 @@ class TestOdooBase(unittest.TestCase): self.assertIsInstance(element, ET.Element) self.assertEqual(element.tag, 'odoo') - def test_data(self): """ Test data function """ element = od.data([]) @@ -81,20 +43,18 @@ class TestOdooBase(unittest.TestCase): self.assertEqual(element.tag, 'data') self.assertEqual(element.attrs, {"one": "attribute"}) - def test_aliases(self): """ Test simple aliases to xmln """ element = od.record({"one": "attribute"}, 'A child') self.assertIsInstance(element, XMLDictElement) self.assertEqual(element.tag, 'record') self.assertEqual(element.attrs, {"one": "attribute"}) - self.assertEqual(element.children, ['A child',]) + self.assertEqual(element.children, ['A child']) element = od.tree() self.assertIsInstance(element, XMLDictElement) self.assertEqual(element.tag, 'tree') - def test_act_window_model(self): """ Test act_window function """ element = od.act_window_model('sample.model', {'view_type': 'form'}) @@ -105,7 +65,6 @@ class TestOdooBase(unittest.TestCase): self.assertEqual(element.attrs['res_model'], 'sample.model') self.assertEqual(element.attrs['name'], 'Sample Model Action') - def test_menunitem_model(self): """ Test menuitem function """ element = od.menuitem_model('sample.model', {'groups': 'base.user_employee'}) @@ -115,15 +74,13 @@ class TestOdooBase(unittest.TestCase): self.assertEqual(element.attrs['id'], 'sample_model_menu') self.assertEqual(element.attrs['action'], 'sample_model_view_action') - def test_attribute(self): """ Test attribute function """ element = od.attribute('invisible', "1") self.assertIsInstance(element, XMLDictElement) self.assertEqual(element.tag, 'attribute') self.assertEqual(element.attrs['name'], 'invisible') - self.assertEqual(element.children, ["1",]) - + self.assertEqual(element.children, ["1"]) def test_fields(self): """ Test fields function """ @@ -135,13 +92,13 @@ class TestOdooBase(unittest.TestCase): self.assertIsInstance(element, XMLDictElement) self.assertEqual(element.tag, 'field') self.assertEqual(element.attrs['name'], 'name') - self.assertEqual(element.children, ['A name',]) + self.assertEqual(element.children, ['A name']) element = od.field_model('sample.model') self.assertIsInstance(element, XMLDictElement) self.assertEqual(element.tag, 'field') self.assertEqual(element.attrs['name'], 'model') - self.assertEqual(element.children, ['sample.model',]) + self.assertEqual(element.children, ['sample.model']) element = od.field_inherit('module.xml_view') self.assertIsInstance(element, XMLDictElement) @@ -157,7 +114,6 @@ class TestOdooBase(unittest.TestCase): self.assertEqual(element.attrs['type'], 'xml') self.assertFalse(element.children) - def test_view(self): """ Test view function """ element = od.view('view_xmlid', []) @@ -167,7 +123,6 @@ class TestOdooBase(unittest.TestCase): self.assertEqual(element.attrs['model'], 'ir.ui.view') self.assertFalse(element.children) - def test_view_def(self): """ Test view_def function """ element = od.view_def('view_xmlid', 'View', 'sample.model', []) @@ -179,18 +134,17 @@ class TestOdooBase(unittest.TestCase): self.assertIsInstance(element.children[0], XMLDictElement) self.assertEqual(element.children[0].tag, 'field') self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['View',]) + self.assertEqual(element.children[0].children, ['View']) self.assertIsInstance(element.children[1], XMLDictElement) self.assertEqual(element.children[1].tag, 'field') self.assertEqual(element.children[1].attrs['name'], 'model') - self.assertEqual(element.children[1].children, ['sample.model',]) + self.assertEqual(element.children[1].children, ['sample.model']) self.assertIsInstance(element.children[2], XMLDictElement) self.assertEqual(element.children[2].tag, 'field') self.assertEqual(element.children[2].attrs['name'], 'arch') self.assertEqual(element.children[2].attrs['type'], 'xml') self.assertFalse(element.children[2].children) - def test_view_new(self): """ Test view_new function """ element = od.view_new('tree', 'sample.model', []) @@ -202,18 +156,17 @@ class TestOdooBase(unittest.TestCase): self.assertIsInstance(element.children[0], XMLDictElement) self.assertEqual(element.children[0].tag, 'field') self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Sample Model Tree',]) + self.assertEqual(element.children[0].children, ['Sample Model Tree']) self.assertIsInstance(element.children[1], XMLDictElement) self.assertEqual(element.children[1].tag, 'field') self.assertEqual(element.children[1].attrs['name'], 'model') - self.assertEqual(element.children[1].children, ['sample.model',]) + self.assertEqual(element.children[1].children, ['sample.model']) self.assertIsInstance(element.children[2], XMLDictElement) self.assertEqual(element.children[2].tag, 'field') self.assertEqual(element.children[2].attrs['name'], 'arch') self.assertEqual(element.children[2].attrs['type'], 'xml') self.assertFalse(element.children[2].children) - def test_view_inherit(self): """ Test view_inherit function """ element = od.view_inherit('odoo.addons.module', 'sample.model', 'parent.view', []) @@ -225,11 +178,11 @@ class TestOdooBase(unittest.TestCase): self.assertIsInstance(element.children[0], XMLDictElement) self.assertEqual(element.children[0].tag, 'field') self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Sample Model Adaptations',]) + self.assertEqual(element.children[0].children, ['Sample Model Adaptations']) self.assertIsInstance(element.children[1], XMLDictElement) self.assertEqual(element.children[1].tag, 'field') self.assertEqual(element.children[1].attrs['name'], 'model') - self.assertEqual(element.children[1].children, ['sample.model',]) + self.assertEqual(element.children[1].children, ['sample.model']) self.assertIsInstance(element.children[2], XMLDictElement) self.assertEqual(element.children[2].tag, 'field') self.assertEqual(element.children[2].attrs['name'], 'inherit_id') @@ -240,10 +193,10 @@ class TestOdooBase(unittest.TestCase): self.assertEqual(element.children[3].attrs['type'], 'xml') self.assertFalse(element.children[3].children) - def test_action_server_code(self): """ Test action_server_code function """ - element = od.action_server_code('sample.xmlid', 'Code', 'sample.model', '''record.do_something()''') + element = od.action_server_code('sample.xmlid', 'Code', 'sample.model', + '''record.do_something()''') self.assertIsInstance(element, XMLDictElement) self.assertEqual(element.tag, 'record') self.assertEqual(element.attrs['id'], 'sample.xmlid') @@ -252,7 +205,7 @@ class TestOdooBase(unittest.TestCase): self.assertIsInstance(element.children[0], XMLDictElement) self.assertEqual(element.children[0].tag, 'field') self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Code',]) + self.assertEqual(element.children[0].children, ['Code']) self.assertIsInstance(element.children[1], XMLDictElement) self.assertEqual(element.children[1].tag, 'field') self.assertEqual(element.children[1].attrs['name'], 'model_id') @@ -260,11 +213,10 @@ class TestOdooBase(unittest.TestCase): self.assertFalse(element.children[1].children) self.assertEqual(element.children[2].tag, 'field') self.assertEqual(element.children[2].attrs['name'], 'state') - self.assertEqual(element.children[2].children, ['code',]) + self.assertEqual(element.children[2].children, ['code']) self.assertEqual(element.children[3].tag, 'field') self.assertEqual(element.children[3].attrs['name'], 'code') - self.assertEqual(element.children[3].children, ['record.do_something()',]) - + self.assertEqual(element.children[3].children, ['record.do_something()']) def test_client_action_multi(self): """ Test client_action_multi function """ @@ -277,7 +229,7 @@ class TestOdooBase(unittest.TestCase): self.assertIsInstance(element.children[0], XMLDictElement) self.assertEqual(element.children[0].tag, 'field') self.assertEqual(element.children[0].attrs['name'], 'name') - self.assertEqual(element.children[0].children, ['Multi',]) + self.assertEqual(element.children[0].children, ['Multi']) self.assertIsInstance(element.children[1], XMLDictElement) self.assertEqual(element.children[1].tag, 'field') self.assertEqual(element.children[1].attrs['name'], 'key2') @@ -291,7 +243,5 @@ class TestOdooBase(unittest.TestCase): self.assertEqual(element.children[3].attrs['eval'], "'ir.actions.server,%d'%sample.action") - -_coconut_call_set_names(TestOdooBase) if __name__ == '__main__': unittest.main() diff --git a/yaltik_dsl/tests/test_xml_base.coco b/yaltik_dsl/tests/test_xml_base.coco deleted file mode 100644 index 5d334ee..0000000 --- a/yaltik_dsl/tests/test_xml_base.coco +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright 2020 Fabien Bourgeois -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - -""" XML Helpers tests """ - -from functools import partial -import unittest -import xml.etree.ElementTree as ET -from os import unlink -from src.xml_base import xmln, xmlroot, xmlchild, xml_write - - -class TestXMLBase(unittest.TestCase): - """ XML Helpers tests """ - - def test_xmln(self): - """ Text xmln """ - # Tags - self.assertDictEqual(xmln()._asdict(), {'tag': '', 'attrs': {}, 'children': []}) - self.assertEqual(xmln('a tag').tag, 'a tag') - # Attrs - self.assertDictEqual(xmln(attrs={'a good': 'one'}).attrs, {'a good': 'one'}) - # Childrens - self.assertListEqual(xmln(children=[1, 2, 3]).children, [1, 2, 3]) - self.assertListEqual(xmln(children='Some text').children, ['Some text']) - - with self.assertRaisesRegexp(TypeError, 'Invalid arguments'): - xmln(children=False) - - # Ensure that only children after tags is managed - element = xmln('tag', {'something': 'inside'}) - self.assertIsInstance(element.attrs, dict) - self.assertIsInstance(element.children, list) - - element = xmln('tag', ['something', 'inside']) - self.assertIsInstance(element.attrs, dict) - self.assertIsInstance(element.children, list) - - - def test_xmlchild(self): - """ Test xmlchild """ - parent = xmlroot({'tag': 'root', 'attrs': {}, 'children': []}) - xmlc_par = partial(xmlchild, parent) - - # Bad arguments - with self.assertRaisesRegexp(TypeError, 'Invalid arguments for xmlchild'): - xmlc_par(False) - # Need XMLDictElement, not dict - with self.assertRaisesRegexp(TypeError, 'Invalid arguments for xmlchild'): - xmlc_par([{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}]) - - xmlc_par(['some text']) - self.assertEqual(parent.text, 'some text') - - xmlc_par([xmln('t', {'a': 'b'}, [])]) - child = parent.iter('t').next() - self.assertEqual(child.tag, 't') - self.assertDictEqual(child.attrib, {'a': 'b'}) - self.assertListEqual(list(child), []) - - xmlc_par([xmln('t2', {1: 2}, [])]) - child = parent.iter('t2').next() - self.assertDictEqual(child.attrib, {'1': '2'}) - - xmlc_par([xmln('tchildren', {}, [xmln('subchild', {}, [])])]) - child = parent.iter('tchildren').next() - subchildren = list(child) - self.assertEqual(len(subchildren), 1) - self.assertEqual(subchildren[0].tag, 'subchild') - - - def test_xmlroot(self): - """ Test xmlroot """ - root = xmlroot({'tag': 'root', 'attrs': {}, 'children': []}) - self.assertIsInstance(root, ET.Element) - - with self.assertRaisesRegexp(TypeError, 'no attribute'): - xmlroot(False) - with self.assertRaisesRegexp(KeyError, 'tag'): - xmlroot({}) - with self.assertRaisesRegexp(KeyError, 'attrs'): - xmlroot({'tag': 'root'}) - - - def test_xml_write(self): - """ test xml_write """ - children = [xmln('child1', {'attr': 'value'}, []), - xmln('child2', {}, "Some text")] - tree = xmlroot({'tag': 'root', 'attrs': {}, 'children': children}) - xmlw = lambda p: xml_write(p, tree) - - self.assertIsNone(xmlw('/badpath')) - self.assertIsNone(xmlw('/bad.ext')) - - xmlw(__file__) - filepath = __file__.replace('.py', '_views.xml') - with open(filepath, 'r') as output_file: - output_xml = output_file.read() - self.assertIn('', output_xml) - self.assertIn('', output_xml) - self.assertIn('Some text', output_xml) - unlink(filepath) - xml_write(__file__, tree, suffix='_data') - filepath = __file__.replace('.py', '_data.xml') - with open(filepath, 'r') as output_file: - output_xml = output_file.read() - self.assertIn('', output_xml) - self.assertIn('', output_xml) - self.assertIn('Some text', output_xml) - unlink(filepath) - -if __name__ == '__main__': - unittest.main() diff --git a/yaltik_dsl/tests/test_xml_base.py b/yaltik_dsl/tests/test_xml_base.py index 7f010be..5d334ee 100644 --- a/yaltik_dsl/tests/test_xml_base.py +++ b/yaltik_dsl/tests/test_xml_base.py @@ -1,40 +1,3 @@ -#!/usr/bin/env python2 -# -*- coding: utf-8 -*- -# __coconut_hash__ = 0x63b4cad9 - -# Compiled with Coconut version 2.1.1 [The Spanish Inquisition] - -""" XML Helpers tests """ - -# Coconut Header: ------------------------------------------------------------- - -from __future__ import print_function, absolute_import, unicode_literals, division -import sys as _coconut_sys, os as _coconut_os -_coconut_file_dir = _coconut_os.path.dirname(_coconut_os.path.abspath(__file__)) -_coconut_cached_module = _coconut_sys.modules.get(b"__coconut__") -if _coconut_cached_module is not None and _coconut_os.path.dirname(_coconut_cached_module.__file__) != _coconut_file_dir: # type: ignore - del _coconut_sys.modules[b"__coconut__"] -_coconut_sys.path.insert(0, _coconut_file_dir) -_coconut_module_name = _coconut_os.path.splitext(_coconut_os.path.basename(_coconut_file_dir))[0] -if _coconut_module_name and _coconut_module_name[0].isalpha() and all(c.isalpha() or c.isdigit() for c in _coconut_module_name) and "__init__.py" in _coconut_os.listdir(_coconut_file_dir): - _coconut_full_module_name = str(_coconut_module_name + ".__coconut__") - import __coconut__ as _coconut__coconut__ - _coconut__coconut__.__name__ = _coconut_full_module_name - for _coconut_v in vars(_coconut__coconut__).values(): - if getattr(_coconut_v, "__module__", None) == b"__coconut__": - try: - _coconut_v.__module__ = _coconut_full_module_name - except AttributeError: - _coconut_v_type = type(_coconut_v) - if getattr(_coconut_v_type, "__module__", None) == b"__coconut__": - _coconut_v_type.__module__ = _coconut_full_module_name - _coconut_sys.modules[_coconut_full_module_name] = _coconut__coconut__ -from __coconut__ import * -from __coconut__ import _coconut_call_set_names, _coconut_handle_cls_kwargs, _coconut_handle_cls_stargs, _namedtuple_of, _coconut, _coconut_super, _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_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_multi_dim_arr, _coconut_mk_anon_namedtuple, _coconut_matmul -_coconut_sys.path.pop(0) - -# Compiled Coconut: ----------------------------------------------------------- - # -*- coding: utf-8 -*- # # Copyright 2020 Fabien Bourgeois @@ -52,16 +15,13 @@ _coconut_sys.path.pop(0) # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - +""" XML Helpers tests """ from functools import partial import unittest import xml.etree.ElementTree as ET from os import unlink -from src.xml_base import xmln -from src.xml_base import xmlroot -from src.xml_base import xmlchild -from src.xml_base import xml_write +from src.xml_base import xmln, xmlroot, xmlchild, xml_write class TestXMLBase(unittest.TestCase): @@ -69,19 +29,19 @@ class TestXMLBase(unittest.TestCase): def test_xmln(self): """ Text xmln """ -# Tags + # Tags self.assertDictEqual(xmln()._asdict(), {'tag': '', 'attrs': {}, 'children': []}) self.assertEqual(xmln('a tag').tag, 'a tag') -# Attrs + # Attrs self.assertDictEqual(xmln(attrs={'a good': 'one'}).attrs, {'a good': 'one'}) -# Childrens + # Childrens self.assertListEqual(xmln(children=[1, 2, 3]).children, [1, 2, 3]) - self.assertListEqual(xmln(children='Some text').children, ['Some text',]) + self.assertListEqual(xmln(children='Some text').children, ['Some text']) with self.assertRaisesRegexp(TypeError, 'Invalid arguments'): xmln(children=False) -# Ensure that only children after tags is managed + # Ensure that only children after tags is managed element = xmln('tag', {'something': 'inside'}) self.assertIsInstance(element.attrs, dict) self.assertIsInstance(element.children, list) @@ -91,40 +51,38 @@ class TestXMLBase(unittest.TestCase): self.assertIsInstance(element.children, list) - def test_xmlchild(self): """ Test xmlchild """ parent = xmlroot({'tag': 'root', 'attrs': {}, 'children': []}) xmlc_par = partial(xmlchild, parent) -# Bad arguments + # Bad arguments with self.assertRaisesRegexp(TypeError, 'Invalid arguments for xmlchild'): xmlc_par(False) -# Need XMLDictElement, not dict + # Need XMLDictElement, not dict with self.assertRaisesRegexp(TypeError, 'Invalid arguments for xmlchild'): - xmlc_par([{'tag': 't', 'attrs': {'a': 'b'}, 'children': []},]) + xmlc_par([{'tag': 't', 'attrs': {'a': 'b'}, 'children': []}]) - xmlc_par(['some text',]) + xmlc_par(['some text']) self.assertEqual(parent.text, 'some text') - xmlc_par([xmln('t', {'a': 'b'}, []),]) + xmlc_par([xmln('t', {'a': 'b'}, [])]) child = parent.iter('t').next() self.assertEqual(child.tag, 't') self.assertDictEqual(child.attrib, {'a': 'b'}) self.assertListEqual(list(child), []) - xmlc_par([xmln('t2', {1: 2}, []),]) + xmlc_par([xmln('t2', {1: 2}, [])]) child = parent.iter('t2').next() self.assertDictEqual(child.attrib, {'1': '2'}) - xmlc_par([xmln('tchildren', {}, [xmln('subchild', {}, []),]),]) + xmlc_par([xmln('tchildren', {}, [xmln('subchild', {}, [])])]) child = parent.iter('tchildren').next() subchildren = list(child) self.assertEqual(len(subchildren), 1) self.assertEqual(subchildren[0].tag, 'subchild') - def test_xmlroot(self): """ Test xmlroot """ root = xmlroot({'tag': 'root', 'attrs': {}, 'children': []}) @@ -138,10 +96,10 @@ class TestXMLBase(unittest.TestCase): xmlroot({'tag': 'root'}) - def test_xml_write(self): """ test xml_write """ - children = [xmln('child1', {'attr': 'value'}, []), xmln('child2', {}, "Some text")] + children = [xmln('child1', {'attr': 'value'}, []), + xmln('child2', {}, "Some text")] tree = xmlroot({'tag': 'root', 'attrs': {}, 'children': children}) xmlw = lambda p: xml_write(p, tree) @@ -167,7 +125,5 @@ class TestXMLBase(unittest.TestCase): self.assertIn('Some text', output_xml) unlink(filepath) - -_coconut_call_set_names(TestXMLBase) if __name__ == '__main__': unittest.main()