def cons(o, seq) -> ISeq:
    """Creates a new sequence where o is the first element and seq is the rest.
    If seq is None, return a list containing o. If seq is not a ISeq, attempt
    to coerce it to a ISeq and then cons o onto the resulting sequence."""
    if seq is None:
        return llist.l(o)
    if isinstance(seq, ISeq):
        return seq.cons(o)
    return Maybe(to_seq(seq)).map(lambda s: s.cons(o)).or_else(lambda: llist.l(o))

def cons ( o , seq ) -> ISeq : if seq is None : return llist . l ( o ) if isinstance ( seq , ISeq ) : return seq . cons ( o ) return Maybe ( to_seq ( seq ) ) . map ( lambda s : s . cons ( o ) ) . or_else ( lambda : llist . l ( o ) )

Creates a new sequence where o is the first element and seq is the rest . If seq is None return a list containing o . If seq is not a ISeq attempt to coerce it to a ISeq and then cons o onto the resulting sequence .


def to_seq(o) -> Optional[ISeq]:
    """Coerce the argument o to a ISeq. If o is None, return None."""
    if o is None:
        return None
    if isinstance(o, ISeq):
        return _seq_or_nil(o)
    if isinstance(o, ISeqable):
        return _seq_or_nil(o.seq())
    return _seq_or_nil(lseq.sequence(o))

def to_seq ( o ) -> Optional [ ISeq ] : if o is None : return None if isinstance ( o , ISeq ) : return _seq_or_nil ( o ) if isinstance ( o , ISeqable ) : return _seq_or_nil ( o . seq ( ) ) return _seq_or_nil ( lseq . sequence ( o ) )

Coerce the argument o to a ISeq . If o is None return None .


def concat(*seqs) -> ISeq:
    """Concatenate the sequences given by seqs into a single ISeq."""
    allseqs = lseq.sequence(itertools.chain(*filter(None, map(to_seq, seqs))))
    if allseqs is None:
        return lseq.EMPTY
    return allseqs

def concat ( * seqs ) -> ISeq : allseqs = lseq . sequence ( itertools . chain ( * filter ( None , map ( to_seq , seqs ) ) ) ) if allseqs is None : return lseq . EMPTY return allseqs

Concatenate the sequences given by seqs into a single ISeq .


def assoc(m, *kvs):
    """Associate keys to values in associative data structure m. If m is None,
    returns a new Map with key-values kvs."""
    if m is None:
        return lmap.Map.empty().assoc(*kvs)
    if isinstance(m, IAssociative):
        return m.assoc(*kvs)
    raise TypeError(
        f"Object of type {type(m)} does not implement Associative interface"
    )

Associate keys to values in associative data structure m . If m is None returns a new Map with key - values kvs .


def conj(coll, *xs):
    """Conjoin xs to collection. New elements may be added in different positions
    depending on the type of coll. conj returns the same type as coll. If coll
    is None, return a list with xs conjoined."""
    if coll is None:
        l = llist.List.empty()
        return l.cons(*xs)
    if isinstance(coll, IPersistentCollection):
        return coll.cons(*xs)
    raise TypeError(
        f"Object of type {type(coll)} does not implement Collection interface"
    )

Conjoin xs to collection . New elements may be added in different positions depending on the type of coll . conj returns the same type as coll . If coll is None return a list with xs conjoined .


def partial(f, *args):
    """Return a function which is the partial application of f with args."""

    @functools.wraps(f)
    def partial_f(*inner_args):
        return f(*itertools.chain(args, inner_args))

    return partial_f

def partial ( f , * args ) : @ functools . wraps ( f ) def partial_f ( * inner_args ) : return f ( * itertools . chain ( args , inner_args ) ) return partial_f

Return a function which is the partial application of f with args .


def deref(o, timeout_s=None, timeout_val=None):
    """Dereference a Deref object and return its contents.

    If o is an object implementing IBlockingDeref and timeout_s and
    timeout_val are supplied, deref will wait at most timeout_s seconds,
    returning timeout_val if timeout_s seconds elapse and o has not
    returned."""
    if isinstance(o, IDeref):
        return o.deref()
    elif isinstance(o, IBlockingDeref):
        return o.deref(timeout_s, timeout_val)
    raise TypeError(f"Object of type {type(o)} cannot be dereferenced")

Dereference a Deref object and return its contents .


def equals(v1, v2) -> bool:
    """Compare two objects by value. Unlike the standard Python equality operator,
    this function does not consider 1 == True or 0 == False. All other equality
    operations are the same and performed using Python's equality operator."""
    if isinstance(v1, (bool, type(None))) or isinstance(v2, (bool, type(None))):
        return v1 is v2
    return v1 == v2

def equals ( v1 , v2 ) -> bool : if isinstance ( v1 , ( bool , type ( None ) ) ) or isinstance ( v2 , ( bool , type ( None ) ) ) : return v1 is v2 return v1 == v2

Compare two objects by value . Unlike the standard Python equality operator this function does not consider 1 == True or 0 == False . All other equality operations are the same and performed using Python s equality operator .


def divide(x: LispNumber, y: LispNumber) -> LispNumber:
    """Division reducer. If both arguments are integers, return a Fraction.
    Otherwise, return the true division of x and y."""
    if isinstance(x, int) and isinstance(y, int):
        return Fraction(x, y)
    return x / y

def divide ( x : LispNumber , y : LispNumber ) -> LispNumber : if isinstance ( x , int ) and isinstance ( y , int ) : return Fraction ( x , y ) return x / y

Division reducer . If both arguments are integers return a Fraction . Otherwise return the true division of x and y .


def sort(coll, f=None) -> Optional[ISeq]:
    """Return a sorted sequence of the elements in coll. If a comparator
    function f is provided, compare elements in coll using f."""
    return to_seq(sorted(coll, key=Maybe(f).map(functools.cmp_to_key).value))

def sort ( coll , f = None ) -> Optional [ ISeq ] : return to_seq ( sorted ( coll , key = Maybe ( f ) . map ( functools . cmp_to_key ) . value ) )

Return a sorted sequence of the elements in coll . If a comparator function f is provided compare elements in coll using f .


def contains(coll, k):
    """Return true if o contains the key k."""
    if isinstance(coll, IAssociative):
        return coll.contains(k)
    return k in coll

def contains ( coll , k ) : if isinstance ( coll , IAssociative ) : return coll . contains ( k ) return k in coll


def get(m, k, default=None):
    """Return the value of k in m. Return default if k not found in m."""
    if isinstance(m, IAssociative):
        return m.entry(k, default=default)

    try:
        return m[k]
    except (KeyError, IndexError, TypeError) as e:
        logger.debug("Ignored %s: %s", type(e).__name__, e)
        return default

def
get
(
m
,
k
,
default
=
)
:
if
isinstance
(
m
,
IAssociative
)
:
return
m
.
entry
(
k
,
default
=
default
)
try
:
return
m
[
k
]
except
(
KeyError
,
IndexError
,
TypeError
)
as
e
:
logger
.
debug
(
"Ignored %s: %s"
,
type
(
e
)
.
__name__
,
e
)
return
default

Return the value of k in m . Return default if k not found in m .


def to_lisp(o, keywordize_keys: bool = True):
    """Recursively convert Python collections into Lisp collections."""
    if not isinstance(o, (dict, frozenset, list, set, tuple)):
        return o
    else:  # pragma: no cover
        return _to_lisp_backup(o, keywordize_keys=keywordize_keys)

def
to_lisp
(
o
,
keywordize_keys
:
bool
=
True
)
:
if
not
isinstance
(
o
,
(
dict
,
frozenset
,
list
,
set
,
tuple
)
)
:
return
o
else
:
# pragma: no cover
return
_to_lisp_backup
(
o
,
keywordize_keys
=
keywordize_keys
)

Recursively convert Python collections into Lisp collections .


def to_py(o, keyword_fn: Callable[[kw.Keyword], Any] = _kw_name):
    """Recursively convert Lisp collections into Python collections."""
    if isinstance(o, ISeq):
        return _to_py_list(o, keyword_fn=keyword_fn)
    elif not isinstance(
        o, (IPersistentList, IPersistentMap, IPersistentSet, IPersistentVector)
    ):
        return o
    else:  # pragma: no cover
        return _to_py_backup(o, keyword_fn=keyword_fn)

def
to_py
(
o
,
keyword_fn
:
Callable
[
[
kw
.
Keyword
]
,
Any
]
=
_kw_name
)
:
if
isinstance
(
o
,
ISeq
)
:
return
_to_py_list
(
o
,
keyword_fn
=
keyword_fn
)
elif
not
isinstance
(
o
,
(
IPersistentList
,
IPersistentMap
,
IPersistentSet
,
IPersistentVector
)
)
:
return
o
else
:
# pragma: no cover
return
_to_py_backup
(
o
,
keyword_fn
=
keyword_fn
)

Recursively convert Lisp collections into Python collections .


def lrepr(o, human_readable: bool = False) -> str:
    """Produce a string representation of an object. If human_readable is False,
    the string representation of Lisp objects is something that can be read back
    in by the reader as the same object."""
    core_ns = Namespace.get(sym.symbol(CORE_NS))
    assert core_ns is not None
    return lobj.lrepr(
        o,
        human_readable=human_readable,
        print_dup=core_ns.find(sym.symbol(_PRINT_DUP_VAR_NAME)).value,  # type: ignore
        print_length=core_ns.find(  # type: ignore
            sym.symbol(_PRINT_LENGTH_VAR_NAME)
        ).value,
        print_level=core_ns.find(  # type: ignore
            sym.symbol(_PRINT_LEVEL_VAR_NAME)
        ).value,
        print_meta=core_ns.find(sym.symbol(_PRINT_META_VAR_NAME)).value,  # type: ignore
        print_readably=core_ns.find(  # type: ignore
            sym.symbol(_PRINT_READABLY_VAR_NAME)
        ).value,
    )

def
lrepr
(
o
,
human_readable
:
bool
=
False
)
->
str
:
core_ns
=
Namespace
.
get
(
sym
.
symbol
(
CORE_NS
)
)
assert
core_ns
is
not
return
lobj
.
lrepr
(
o
,
human_readable
=
human_readable
,
print_dup
=
core_ns
.
find
(
sym
.
symbol
(
_PRINT_DUP_VAR_NAME
)
)
.
value
,
# type: ignore
print_length
=
core_ns
.
find
(
# type: ignore
sym
.
symbol
(
_PRINT_LENGTH_VAR_NAME
)
)
.
value
,
print_level
=
core_ns
.
find
(
# type: ignore
sym
.
symbol
(
_PRINT_LEVEL_VAR_NAME
)
)
.
value
,
print_meta
=
core_ns
.
find
(
sym
.
symbol
(
_PRINT_META_VAR_NAME
)
)
.
value
,
# type: ignore
print_readably
=
core_ns
.
find
(
# type: ignore
sym
.
symbol
(
_PRINT_READABLY_VAR_NAME
)
)
.
value
,
)

Produce a string representation of an object . If human_readable is False the string representation of Lisp objects is something that can be read back in by the reader as the same object .


def _collect_args(args) -> ISeq:
    """Collect Python starred arguments into a Basilisp list."""
    if isinstance(args, tuple):
        return llist.list(args)
    raise TypeError("Python variadic arguments should always be a tuple")

Collect Python starred arguments into a Basilisp list .


def _trampoline(f):
    """Trampoline a function repeatedly until it is finished recurring to help
    avoid stack growth."""

    @functools.wraps(f)
    def trampoline(*args, **kwargs):
        while True:
            ret = f(*args, **kwargs)
            if isinstance(ret, _TrampolineArgs):
                args = ret.args
                kwargs = ret.kwargs
                continue
            return ret

    return trampoline

def _trampoline ( f ) : @ functools . wraps ( f ) def trampoline ( * args , * * kwargs ) : while True : ret = f ( * args , * * kwargs ) if isinstance ( ret , _TrampolineArgs ) : args = ret . args kwargs = ret . kwargs continue return ret return trampoline

Trampoline a function repeatedly until it is finished recurring to help avoid stack growth .


def _with_attrs(**kwargs):
    """Decorator to set attributes on a function. Returns the original
    function after setting the attributes named by the keyword arguments."""

    def decorator(f):
        for k, v in kwargs.items():
            setattr(f, k, v)
        return f

    return decorator

def _with_attrs ( * * kwargs ) : def decorator ( f ) : for k , v in kwargs . items ( ) : setattr ( f , k , v ) return f return decorator

Decorator to set attributes on a function . Returns the original function after setting the attributes named by the keyword arguments .


def _fn_with_meta(f, meta: Optional[lmap.Map]):
    """Return a new function with the given meta. If the function f already
    has a meta map, then merge the """

    if not isinstance(meta, lmap.Map):
        raise TypeError("meta must be a map")

    if inspect.iscoroutinefunction(f):

        @functools.wraps(f)
        async def wrapped_f(*args, **kwargs):
            return await f(*args, **kwargs)

    else:

        @functools.wraps(f)  # type: ignore
        def wrapped_f(*args, **kwargs):
            return f(*args, **kwargs)

    wrapped_f.meta = (  # type: ignore
        f.meta.update(meta)
        if hasattr(f, "meta") and isinstance(f.meta, lmap.Map)
        else meta
    )
    wrapped_f.with_meta = partial(_fn_with_meta, wrapped_f)  # type: ignore
    return wrapped_f

def
_fn_with_meta
(
f
,
meta
:
Optional
[
lmap
.
Map
]
)
:
if
not
isinstance
(
meta
,
lmap
.
Map
)
:
raise
TypeError
(
"meta must be a map"
)
if
inspect
.
iscoroutinefunction
(
f
)
:
@
functools
.
wraps
(
f
)
async
def
wrapped_f
(
*
args
,
*
*
kwargs
)
:
return
await
f
(
*
args
,
*
*
kwargs
)
else
:
@
functools
.
wraps
(
f
)
# type: ignore
def
wrapped_f
(
*
args
,
*
*
kwargs
)
:
return
f
(
*
args
,
*
*
kwargs
)
wrapped_f
.
meta
=
(
# type: ignore
f
.
meta
.
update
(
meta
)
if
hasattr
(
f
,
"meta"
)
and
isinstance
(
f
.
meta
,
lmap
.
Map
)
else
meta
)
wrapped_f
.
with_meta
=
partial
(
_fn_with_meta
,
wrapped_f
)
# type: ignore
return
wrapped_f

Return a new function with the given meta . If the function f already has a meta map then merge the


def _basilisp_fn(f):
    """Create a Basilisp function, setting meta and supplying a with_meta
    method implementation."""
    assert not hasattr(f, "meta")
    f._basilisp_fn = True
    f.meta = None
    f.with_meta = partial(_fn_with_meta, f)
    return f

def _basilisp_fn ( f ) : assert not hasattr ( f , "meta" ) f . _basilisp_fn = True f . meta = None f . with_meta = partial ( _fn_with_meta , f ) return f

Create a Basilisp function setting meta and supplying a with_meta method implementation .


def resolve_alias(s: sym.Symbol, ns: Optional[Namespace] = None) -> sym.Symbol:
    """Resolve the aliased symbol in the current namespace."""
    if s in _SPECIAL_FORMS:
        return s

    ns = Maybe(ns).or_else(get_current_ns)
    if s.ns is not None:
        aliased_ns = ns.get_alias(sym.symbol(s.ns))
        if aliased_ns is not None:
            return sym.symbol(s.name, aliased_ns.name)
        else:
            return s
    else:
        which_var = ns.find(sym.symbol(s.name))
        if which_var is not None:
            return sym.symbol(which_var.name.name, which_var.ns.name)
        else:
            return sym.symbol(s.name, ns=ns.name)

def resolve_alias ( s : sym . Symbol , ns : Optional [ Namespace ] = None ) -> sym . Symbol : if s in _SPECIAL_FORMS : return s ns = Maybe ( ns ) . or_else ( get_current_ns ) if s . ns is not None : aliased_ns = ns . get_alias ( sym . symbol ( s . ns ) ) if aliased_ns is not None : return sym . symbol ( s . name , aliased_ns . name ) else : return s else : which_var = ns . find ( sym . symbol ( s . name ) ) if which_var is not None : return sym . symbol ( which_var . name . name , which_var . ns . name ) else : return sym . symbol ( s . name , ns = ns . name )

Resolve the aliased symbol in the current namespace .


def resolve_var(s: sym.Symbol, ns: Optional[Namespace] = None) -> Optional[Var]:
    """Resolve the aliased symbol to a Var from the specified
    namespace, or the current namespace if none is specified."""
    return Var.find(resolve_alias(s, ns))

def resolve_var ( s : sym . Symbol , ns : Optional [ Namespace ] = None ) -> Optional [ Var ] : return Var . find ( resolve_alias ( s , ns ) )

Resolve the aliased symbol to a Var from the specified namespace or the current namespace if none is specified .


def add_generated_python(
    generated_python: str,
    var_name: str = _GENERATED_PYTHON_VAR_NAME,
    which_ns: Optional[str] = None,
) -> None:
    """Add generated Python code to a dynamic variable in which_ns."""
    if which_ns is None:
        which_ns = get_current_ns().name
    ns_sym = sym.Symbol(var_name, ns=which_ns)
    v = Maybe(Var.find(ns_sym)).or_else(
        lambda: Var.intern(
            sym.symbol(which_ns),  # type: ignore
            sym.symbol(var_name),
            "",
            dynamic=True,
            meta=lmap.map({_PRIVATE_META_KEY: True}),
        )
    )
    v.value = v.value + generated_python

def
add_generated_python
(
generated_python
:
str
,
var_name
:
str
=
_GENERATED_PYTHON_VAR_NAME
,
which_ns
:
Optional
[
str
]
=
,
)
->
:
if
which_ns
is
:
which_ns
=
get_current_ns
(
)
.
name
ns_sym
=
sym
.
Symbol
(
var_name
,
ns
=
which_ns
)
v
=
Maybe
(
Var
.
find
(
ns_sym
)
)
.
or_else
(
lambda
:
Var
.
intern
(
sym
.
symbol
(
which_ns
)
,
# type: ignore
sym
.
symbol
(
var_name
)
,
""
,
dynamic
=
True
,
meta
=
lmap
.
map
(
{
_PRIVATE_META_KEY
:
True
}
)
,
)
)
v
.
value
=
v
.
value
+
generated_python

Add generated Python code to a dynamic variable in which_ns .


def bootstrap(ns_var_name: str = NS_VAR_NAME, core_ns_name: str = CORE_NS) -> None:
    """Bootstrap the environment with functions that are are difficult to
    express with the very minimal lisp environment."""
    core_ns_sym = sym.symbol(core_ns_name)
    ns_var_sym = sym.symbol(ns_var_name, ns=core_ns_name)
    __NS = Maybe(Var.find(ns_var_sym)).or_else_raise(
        lambda: RuntimeException(f"Dynamic Var {ns_var_sym} not bound!")
    )

    def in_ns(s: sym.Symbol):
        ns = Namespace.get_or_create(s)
        __NS.value = ns
        return ns

    Var.intern_unbound(core_ns_sym, sym.symbol("unquote"))
    Var.intern_unbound(core_ns_sym, sym.symbol("unquote-splicing"))
    Var.intern(
        core_ns_sym, sym.symbol("in-ns"), in_ns, meta=lmap.map({_REDEF_META_KEY: True})
    )
    Var.intern(
        core_ns_sym,
        sym.symbol(_PRINT_GENERATED_PY_VAR_NAME),
        False,
        dynamic=True,
        meta=lmap.map({_PRIVATE_META_KEY: True}),
    )
    Var.intern(
        core_ns_sym,
        sym.symbol(_GENERATED_PYTHON_VAR_NAME),
        "",
        dynamic=True,
        meta=lmap.map({_PRIVATE_META_KEY: True}),
    )

    # Dynamic Vars for controlling printing
    Var.intern(
        core_ns_sym, sym.symbol(_PRINT_DUP_VAR_NAME), lobj.PRINT_DUP, dynamic=True
    )
    Var.intern(
        core_ns_sym, sym.symbol(_PRINT_LENGTH_VAR_NAME), lobj.PRINT_LENGTH, dynamic=True
    )
    Var.intern(
        core_ns_sym, sym.symbol(_PRINT_LEVEL_VAR_NAME), lobj.PRINT_LEVEL, dynamic=True
    )
    Var.intern(
        core_ns_sym, sym.symbol(_PRINT_META_VAR_NAME), lobj.PRINT_META, dynamic=True
    )
    Var.intern(
        core_ns_sym,
        sym.symbol(_PRINT_READABLY_VAR_NAME),
        lobj.PRINT_READABLY,
        dynamic=True,
    )

def
bootstrap
(
ns_var_name
:
str
=
NS_VAR_NAME
,
core_ns_name
:
str
=
CORE_NS
)
->
:
core_ns_sym
=
sym
.
symbol
(
core_ns_name
)
ns_var_sym
=
sym
.
symbol
(
ns_var_name
,
ns
=
core_ns_name
)
__NS
=
Maybe
(
Var
.
find
(
ns_var_sym
)
)
.
or_else_raise
(
lambda
:
RuntimeException
(
f"Dynamic Var {ns_var_sym} not bound!"
)
)
def
in_ns
(
s
:
sym
.
Symbol
)
:
ns
=
Namespace
.
get_or_create
(
s
)
__NS
.
value
=
ns
return
ns
Var
.
intern_unbound
(
core_ns_sym
,
sym
.
symbol
(
"unquote"
)
)
Var
.
intern_unbound
(
core_ns_sym
,
sym
.
symbol
(
"unquote-splicing"
)
)
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
"in-ns"
)
,
in_ns
,
meta
=
lmap
.
map
(
{
_REDEF_META_KEY
:
True
}
)
)
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
_PRINT_GENERATED_PY_VAR_NAME
)
,
False
,
dynamic
=
True
,
meta
=
lmap
.
map
(
{
_PRIVATE_META_KEY
:
True
}
)
,
)
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
_GENERATED_PYTHON_VAR_NAME
)
,
""
,
dynamic
=
True
,
meta
=
lmap
.
map
(
{
_PRIVATE_META_KEY
:
True
}
)
,
)
# Dynamic Vars for controlling printing
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
_PRINT_DUP_VAR_NAME
)
,
lobj
.
PRINT_DUP
,
dynamic
=
True
)
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
_PRINT_LENGTH_VAR_NAME
)
,
lobj
.
PRINT_LENGTH
,
dynamic
=
True
)
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
_PRINT_LEVEL_VAR_NAME
)
,
lobj
.
PRINT_LEVEL
,
dynamic
=
True
)
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
_PRINT_META_VAR_NAME
)
,
lobj
.
PRINT_META
,
dynamic
=
True
)
Var
.
intern
(
core_ns_sym
,
sym
.
symbol
(
_PRINT_READABLY_VAR_NAME
)
,
lobj
.
PRINT_READABLY
,
dynamic
=
True
,
)

Bootstrap the environment with functions that are are difficult to express with the very minimal lisp environment .


def intern(
        ns: sym.Symbol, name: sym.Symbol, val, dynamic: bool = False, meta=None
    ) -> "Var":
        """Intern the value bound to the symbol `name` in namespace `ns`."""
        var_ns = Namespace.get_or_create(ns)
        var = var_ns.intern(name, Var(var_ns, name, dynamic=dynamic, meta=meta))
        var.root = val
        return var

def intern ( ns : sym . Symbol , name : sym . Symbol , val , dynamic : bool = False , meta = None ) -> "Var" : var_ns = Namespace . get_or_create ( ns ) var = var_ns . intern ( name , Var ( var_ns , name , dynamic = dynamic , meta = meta ) ) var . root = val return var

Intern the value bound to the symbol name in namespace ns .


def intern_unbound(
        ns: sym.Symbol, name: sym.Symbol, dynamic: bool = False, meta=None
    ) -> "Var":
        """Create a new unbound `Var` instance to the symbol `name` in namespace `ns`."""
        var_ns = Namespace.get_or_create(ns)
        return var_ns.intern(name, Var(var_ns, name, dynamic=dynamic, meta=meta))

def intern_unbound ( ns : sym . Symbol , name : sym . Symbol , dynamic : bool = False , meta = None ) -> "Var" : var_ns = Namespace . get_or_create ( ns ) return var_ns . intern ( name , Var ( var_ns , name , dynamic = dynamic , meta = meta ) )

Create a new unbound Var instance to the symbol name in namespace ns .


def find_in_ns(ns_sym: sym.Symbol, name_sym: sym.Symbol) -> "Optional[Var]":
        """Return the value current bound to the name `name_sym` in the namespace
        specified by `ns_sym`."""
        ns = Namespace.get(ns_sym)
        if ns:
            return ns.find(name_sym)
        return None

def find_in_ns ( ns_sym : sym . Symbol , name_sym : sym . Symbol ) -> "Optional[Var]" : ns = Namespace . get ( ns_sym ) if ns : return ns . find ( name_sym ) return None

Return the value current bound to the name name_sym in the namespace specified by ns_sym .


def find(ns_qualified_sym: sym.Symbol) -> "Optional[Var]":
        """Return the value currently bound to the name in the namespace specified
        by `ns_qualified_sym`."""
        ns = Maybe(ns_qualified_sym.ns).or_else_raise(
            lambda: ValueError(
                f"Namespace must be specified in Symbol {ns_qualified_sym}"
            )
        )
        ns_sym = sym.symbol(ns)
        name_sym = sym.symbol(ns_qualified_sym.name)
        return Var.find_in_ns(ns_sym, name_sym)

Return the value currently bound to the name in the namespace specified by ns_qualified_sym .


def find_safe(ns_qualified_sym: sym.Symbol) -> "Var":
        """Return the Var currently bound to the name in the namespace specified
        by `ns_qualified_sym`. If no Var is bound to that name, raise an exception.

        This is a utility method to return useful debugging information when code
        refers to an invalid symbol at runtime."""
        v = Var.find(ns_qualified_sym)
        if v is None:
            raise RuntimeException(
                f"Unable to resolve symbol {ns_qualified_sym} in this context"
            )
        return v

Return the Var currently bound to the name in the namespace specified by ns_qualified_sym . If no Var is bound to that name raise an exception .


def add_default_import(cls, module: str):
        """Add a gated default import to the default imports.

        In particular, we need to avoid importing 'basilisp.core' before we have
        finished macro-expanding."""
        if module in cls.GATED_IMPORTS:
            cls.DEFAULT_IMPORTS.swap(lambda s: s.cons(sym.symbol(module)))

def add_default_import ( cls , module : str ) : if module in cls . GATED_IMPORTS : cls . DEFAULT_IMPORTS . swap ( lambda s : s . cons ( sym . symbol ( module ) ) )

Add a gated default import to the default imports .


def add_alias(self, alias: sym.Symbol, namespace: "Namespace") -> None:
        """Add a Symbol alias for the given Namespace."""
        self._aliases.swap(lambda m: m.assoc(alias, namespace))

def add_alias ( self , alias : sym . Symbol , namespace : "Namespace" ) -> None : self . _aliases . swap ( lambda m : m . assoc ( alias , namespace ) )

Add a Symbol alias for the given Namespace .


def intern(self, sym: sym.Symbol, var: Var, force: bool = False) -> Var:
        """Intern the Var given in this namespace mapped by the given Symbol.
        If the Symbol already maps to a Var, this method _will not overwrite_
        the existing Var mapping unless the force keyword argument is given
        and is True."""
        m: lmap.Map = self._interns.swap(Namespace._intern, sym, var, force=force)
        return m.entry(sym)

def intern ( self , sym : sym . Symbol , var : Var , force : bool = False ) -> Var : m : lmap . Map = self . _interns . swap ( Namespace . _intern , sym , var , force = force ) return m . entry ( sym )

Intern the Var given in this namespace mapped by the given Symbol . If the Symbol already maps to a Var this method _will not overwrite_ the existing Var mapping unless the force keyword argument is given and is True .


def _intern(
        m: lmap.Map, sym: sym.Symbol, new_var: Var, force: bool = False
    ) -> lmap.Map:
        """Swap function used by intern to atomically intern a new variable in
        the symbol mapping for this Namespace."""
        var = m.entry(sym, None)
        if var is None or force:
            return m.assoc(sym, new_var)
        return m

def _intern ( m : lmap . Map , sym : sym . Symbol , new_var : Var , force : bool = False ) -> lmap . Map : var = m . entry ( sym , None ) if var is None or force : return m . assoc ( sym , new_var ) return m

Swap function used by intern to atomically intern a new variable in the symbol mapping for this Namespace .


def find(self, sym: sym.Symbol) -> Optional[Var]:
        """Find Vars mapped by the given Symbol input or None if no Vars are
        mapped by that Symbol."""
        v = self.interns.entry(sym, None)
        if v is None:
            return self.refers.entry(sym, None)
        return v

def find ( self , sym : sym . Symbol ) -> Optional [ Var ] : v = self . interns . entry ( sym , None ) if v is None : return self . refers . entry ( sym , None ) return v

Find Vars mapped by the given Symbol input or None if no Vars are mapped by that Symbol .


def add_import(
        self, sym: sym.Symbol, module: types.ModuleType, *aliases: sym.Symbol
    ) -> None:
        """Add the Symbol as an imported Symbol in this Namespace. If aliases are given,
        the aliases will be applied to the """
        self._imports.swap(lambda m: m.assoc(sym, module))
        if aliases:
            self._import_aliases.swap(
                lambda m: m.assoc(
                    *itertools.chain.from_iterable([(alias, sym) for alias in aliases])
                )
            )

def add_import ( self , sym : sym . Symbol , module : types . ModuleType , * aliases : sym . Symbol ) -> None : self . _imports . swap ( lambda m : m . assoc ( sym , module ) ) if aliases : self . _import_aliases . swap ( lambda m : m . assoc ( * itertools . chain . from_iterable ( [ ( alias , sym ) for alias in aliases ] ) ) )

Add the Symbol as an imported Symbol in this Namespace . If aliases are given the aliases will be applied to the


def get_import(self, sym: sym.Symbol) -> Optional[types.ModuleType]:
        """Return the module if a moduled named by sym has been imported into
        this Namespace, None otherwise.

        First try to resolve a module directly with the given name. If no module
        can be resolved, attempt to resolve the module using import aliases."""
        mod = self.imports.entry(sym, None)
        if mod is None:
            alias = self.import_aliases.get(sym, None)
            if alias is None:
                return None
            return self.imports.entry(alias, None)
        return mod

def get_import ( self , sym : sym . Symbol ) -> Optional [ types . ModuleType ] : mod = self . imports . entry ( sym , None ) if mod is None : alias = self . import_aliases . get ( sym , None ) if alias is None : return None return self . imports . entry ( alias , None ) return mod

Return the module if a moduled named by sym has been imported into this Namespace None otherwise .


def add_refer(self, sym: sym.Symbol, var: Var) -> None:
        """Refer var in this namespace under the name sym."""
        if not var.is_private:
            self._refers.swap(lambda s: s.assoc(sym, var))

def add_refer ( self , sym : sym . Symbol , var : Var ) -> None : if not var . is_private : self . _refers . swap ( lambda s : s . assoc ( sym , var ) )

Refer var in this namespace under the name sym .


def get_refer(self, sym: sym.Symbol) -> Optional[Var]:
        """Get the Var referred by Symbol or None if it does not exist."""
        return self.refers.entry(sym, None)

def get_refer ( self , sym : sym . Symbol ) -> Optional [ Var ] : return self . refers . entry ( sym , None )

Get the Var referred by Symbol or None if it does not exist .


def __refer_all(cls, refers: lmap.Map, other_ns_interns: lmap.Map) -> lmap.Map:
        """Refer all _public_ interns from another namespace."""
        final_refers = refers
        for entry in other_ns_interns:
            s: sym.Symbol = entry.key
            var: Var = entry.value
            if not var.is_private:
                final_refers = final_refers.assoc(s, var)
        return final_refers

def __refer_all ( cls , refers : lmap . Map , other_ns_interns : lmap . Map ) -> lmap . Map : final_refers = refers for entry in other_ns_interns : s : sym . Symbol = entry . key var : Var = entry . value if not var . is_private : final_refers = final_refers . assoc ( s , var ) return final_refers

Refer all _public_ interns from another namespace .


def refer_all(self, other_ns: "Namespace"):
        """Refer all the Vars in the other namespace."""
        self._refers.swap(Namespace.__refer_all, other_ns.interns)

def refer_all ( self , other_ns : "Namespace" ) : self . _refers . swap ( Namespace . __refer_all , other_ns . interns )

Refer all the Vars in the other namespace .


def __get_or_create(
        ns_cache: NamespaceMap,
        name: sym.Symbol,
        module: types.ModuleType = None,
        core_ns_name=CORE_NS,
    ) -> lmap.Map:
        """Private swap function used by `get_or_create` to atomically swap
        the new namespace map into the global cache."""
        ns = ns_cache.entry(name, None)
        if ns is not None:
            return ns_cache
        new_ns = Namespace(name, module=module)
        if name.name != core_ns_name:
            core_ns = ns_cache.entry(sym.symbol(core_ns_name), None)
            assert core_ns is not None, "Core namespace not loaded yet!"
            new_ns.refer_all(core_ns)
        return ns_cache.assoc(name, new_ns)

def
__get_or_create
(
ns_cache
:
NamespaceMap
,
name
:
sym
.
Symbol
,
module
:
types
.
ModuleType
=
,
core_ns_name
=
CORE_NS
,
)
->
lmap
.
Map
:
ns
=
ns_cache
.
entry
(
name
,
)
if
ns
is
not
:
return
ns_cache
new_ns
=
Namespace
(
name
,
module
=
module
)
if
name
.
name
!=
core_ns_name
:
core_ns
=
ns_cache
.
entry
(
sym
.
symbol
(
core_ns_name
)
,
)
assert
core_ns
is
not
,
"Core namespace not loaded yet!"
new_ns
.
refer_all
(
core_ns
)
return
ns_cache
.
assoc
(
name
,
new_ns
)

Private swap function used by get_or_create to atomically swap the new namespace map into the global cache .


def get_or_create(
        cls, name: sym.Symbol, module: types.ModuleType = None
    ) -> "Namespace":
        """Get the namespace bound to the symbol `name` in the global namespace
        cache, creating it if it does not exist.
        Return the namespace."""
        return cls._NAMESPACES.swap(Namespace.__get_or_create, name, module=module)[
            name
        ]

def get_or_create ( cls , name : sym . Symbol , module : types . ModuleType = None ) -> "Namespace" : return cls . _NAMESPACES . swap ( Namespace . __get_or_create , name , module = module ) [ name ]

Get the namespace bound to the symbol name in the global namespace cache creating it if it does not exist . Return the namespace .


def get(cls, name: sym.Symbol) -> "Optional[Namespace]":
        """Get the namespace bound to the symbol `name` in the global namespace
        cache. Return the namespace if it exists or None otherwise.."""
        return cls._NAMESPACES.deref().entry(name, None)

def get ( cls , name : sym . Symbol ) -> "Optional[Namespace]" : return cls . _NAMESPACES . deref ( ) . entry ( name , None )

Get the namespace bound to the symbol name in the global namespace cache . Return the namespace if it exists or None otherwise ..


def remove(cls, name: sym.Symbol) -> Optional["Namespace"]:
        """Remove the namespace bound to the symbol `name` in the global
        namespace cache and return that namespace.
        Return None if the namespace did not exist in the cache."""
        while True:
            oldval: lmap.Map = cls._NAMESPACES.deref()
            ns: Optional[Namespace] = oldval.entry(name, None)
            newval = oldval
            if ns is not None:
                newval = oldval.dissoc(name)
            if cls._NAMESPACES.compare_and_set(oldval, newval):
                return ns

def remove ( cls , name : sym . Symbol ) -> Optional [ "Namespace" ] : while True : oldval : lmap . Map = cls . _NAMESPACES . deref ( ) ns : Optional [ Namespace ] = oldval . entry ( name , None ) newval = oldval if ns is not None : newval = oldval . dissoc ( name ) if cls . _NAMESPACES . compare_and_set ( oldval , newval ) : return ns

Remove the namespace bound to the symbol name in the global namespace cache and return that namespace . Return None if the namespace did not exist in the cache .


def __completion_matcher(text: str) -> CompletionMatcher:
        """Return a function which matches any symbol keys from map entries
        against the given text."""

        def is_match(entry: Tuple[sym.Symbol, Any]) -> bool:
            return entry[0].name.startswith(text)

        return is_match

def __completion_matcher ( text : str ) -> CompletionMatcher : def is_match ( entry : Tuple [ sym . Symbol , Any ] ) -> bool : return entry [ 0 ] . name . startswith ( text ) return is_match

Return a function which matches any symbol keys from map entries against the given text .


def __complete_alias(
        self, prefix: str, name_in_ns: Optional[str] = None
    ) -> Iterable[str]:
        """Return an iterable of possible completions matching the given
        prefix from the list of aliased namespaces. If name_in_ns is given,
        further attempt to refine the list to matching names in that namespace."""
        candidates = filter(
            Namespace.__completion_matcher(prefix), [(s, n) for s, n in self.aliases]
        )
        if name_in_ns is not None:
            for _, candidate_ns in candidates:
                for match in candidate_ns.__complete_interns(
                    name_in_ns, include_private_vars=False
                ):
                    yield f"{prefix}/{match}"
        else:
            for alias, _ in candidates:
                yield f"{alias}/"

def __complete_alias ( self , prefix : str , name_in_ns : Optional [ str ] = None ) -> Iterable [ str ] : candidates = filter ( Namespace . __completion_matcher ( prefix ) , [ ( s , n ) for s , n in self . aliases ] ) if name_in_ns is not None : for _ , candidate_ns in candidates : for match in candidate_ns . __complete_interns ( name_in_ns , include_private_vars = False ) : yield f"{prefix}/{match}" else : for alias , _ in candidates : yield f"{alias}/"

Return an iterable of possible completions matching the given prefix from the list of aliased namespaces . If name_in_ns is given further attempt to refine the list to matching names in that namespace .


def __complete_imports_and_aliases(
        self, prefix: str, name_in_module: Optional[str] = None
    ) -> Iterable[str]:
        """Return an iterable of possible completions matching the given
        prefix from the list of imports and aliased imports. If name_in_module
        is given, further attempt to refine the list to matching names in that
        namespace."""
        imports = self.imports
        aliases = lmap.map(
            {
                alias: imports.entry(import_name)
                for alias, import_name in self.import_aliases
            }
        )

        candidates = filter(
            Namespace.__completion_matcher(prefix), itertools.chain(aliases, imports)
        )
        if name_in_module is not None:
            for _, module in candidates:
                for name in module.__dict__:
                    if name.startswith(name_in_module):
                        yield f"{prefix}/{name}"
        else:
            for candidate_name, _ in candidates:
                yield f"{candidate_name}/"

def __complete_imports_and_aliases ( self , prefix : str , name_in_module : Optional [ str ] = None ) -> Iterable [ str ] : imports = self . imports aliases = lmap . map ( { alias : imports . entry ( import_name ) for alias , import_name in self . import_aliases } ) candidates = filter ( Namespace . __completion_matcher ( prefix ) , itertools . chain ( aliases , imports ) ) if name_in_module is not None : for _ , module in candidates : for name in module . __dict__ : if name . startswith ( name_in_module ) : yield f"{prefix}/{name}" else : for candidate_name , _ in candidates : yield f"{candidate_name}/"

Return an iterable of possible completions matching the given prefix from the list of imports and aliased imports . If name_in_module is given further attempt to refine the list to matching names in that namespace .


def __complete_interns(
        self, value: str, include_private_vars: bool = True
    ) -> Iterable[str]:
        """Return an iterable of possible completions matching the given
        prefix from the list of interned Vars."""
        if include_private_vars:
            is_match = Namespace.__completion_matcher(value)
        else:
            _is_match = Namespace.__completion_matcher(value)

            def is_match(entry: Tuple[sym.Symbol, Var]) -> bool:
                return _is_match(entry) and not entry[1].is_private

        return map(
            lambda entry: f"{entry[0].name}",
            filter(is_match, [(s, v) for s, v in self.interns]),
        )

def __complete_interns ( self , value : str , include_private_vars : bool = True ) -> Iterable [ str ] : if include_private_vars : is_match = Namespace . __completion_matcher ( value ) else : _is_match = Namespace . __completion_matcher ( value ) def is_match ( entry : Tuple [ sym . Symbol , Var ] ) -> bool : return _is_match ( entry ) and not entry [ 1 ] . is_private return map ( lambda entry : f"{entry[0].name}" , filter ( is_match , [ ( s , v ) for s , v in self . interns ] ) , )

Return an iterable of possible completions matching the given prefix from the list of interned Vars .


def __complete_refers(self, value: str) -> Iterable[str]:
        """Return an iterable of possible completions matching the given
        prefix from the list of referred Vars."""
        return map(
            lambda entry: f"{entry[0].name}",
            filter(
                Namespace.__completion_matcher(value), [(s, v) for s, v in self.refers]
            ),
        )

def __complete_refers ( self , value : str ) -> Iterable [ str ] : return map ( lambda entry : f"{entry[0].name}" , filter ( Namespace . __completion_matcher ( value ) , [ ( s , v ) for s , v in self . refers ] ) , )

Return an iterable of possible completions matching the given prefix from the list of referred Vars .


def complete(self, text: str) -> Iterable[str]:
        """Return an iterable of possible completions for the given text in
        this namespace."""
        assert not text.startswith(":")

        if "/" in text:
            prefix, suffix = text.split("/", maxsplit=1)
            results = itertools.chain(
                self.__complete_alias(prefix, name_in_ns=suffix),
                self.__complete_imports_and_aliases(prefix, name_in_module=suffix),
            )
        else:
            results = itertools.chain(
                self.__complete_alias(text),
                self.__complete_imports_and_aliases(text),
                self.__complete_interns(text),
                self.__complete_refers(text),
            )

        return results

def complete ( self , text : str ) -> Iterable [ str ] : assert not text . startswith ( ":" ) if "/" in text : prefix , suffix = text . split ( "/" , maxsplit = 1 ) results = itertools . chain ( self . __complete_alias ( prefix , name_in_ns = suffix ) , self . __complete_imports_and_aliases ( prefix , name_in_module = suffix ) , ) else : results = itertools . chain ( self . __complete_alias ( text ) , self . __complete_imports_and_aliases ( text ) , self . __complete_interns ( text ) , self . __complete_refers ( text ) , ) return results

Return an iterable of possible completions for the given text in this namespace .


def args(self) -> Tuple:
        """Return the arguments for a trampolined function. If the function
        that is being trampolined has varargs, unroll the final argument if
        it is a sequence."""
        if not self._has_varargs:
            return self._args

        try:
            final = self._args[-1]
            if isinstance(final, ISeq):
                inits = self._args[:-1]
                return tuple(itertools.chain(inits, final))
            return self._args
        except IndexError:
            return ()

def args ( self ) -> Tuple : if not self . _has_varargs : return self . _args try : final = self . _args [ - 1 ] if isinstance ( final , ISeq ) : inits = self . _args [ : - 1 ] return tuple ( itertools . chain ( inits , final ) ) return self . _args except IndexError : return ( )

Return the arguments for a trampolined function . If the function that is being trampolined has varargs unroll the final argument if it is a sequence .


def list(members, meta=None) -> List:  # pylint:disable=redefined-builtin
    """Creates a new list."""
    return List(  # pylint: disable=abstract-class-instantiated
        plist(iterable=members), meta=meta
    )


def l(*members, meta=None) -> List:
    """Creates a new list from members."""
    return List(  # pylint: disable=abstract-class-instantiated
        plist(iterable=members), meta=meta
    )


def change_style(style, representer):
    """
    This function is used to format the key value as a multi-line string maintaining the line breaks
    """

    def new_representer(dumper, data):
        scalar = representer(dumper, data)
        scalar.style = style
        return scalar

    return new_representer

def change_style ( style , representer ) : def new_representer ( dumper , data ) : scalar = representer ( dumper , data ) scalar . style = style return scalar return new_representer

This function is used to format the key value as a multi - line string maintaining the line breaks


def decrypt(token, key_store, key_purpose, leeway=120):
    """This decrypts the provided jwe token, then decodes resulting jwt token and returns
    the payload.

    :param str token: The jwe token.
    :param key_store: The key store.
    :param str key_purpose: Context for the key.
    :param int leeway: Extra allowed time in seconds after expiration to account for clock skew.
    :return: The decrypted payload.

    """
    tokens = token.split('.')
    if len(tokens) != 5:
        raise InvalidTokenException("Incorrect number of tokens")

    decrypted_token = JWEHelper.decrypt(token, key_store, key_purpose)

    payload = JWTHelper.decode(decrypted_token, key_store, key_purpose, leeway)

    return payload

def
decrypt
(
token
,
key_store
,
key_purpose
,
leeway
=
120
)
:
tokens
=
token
.
split
(
'.'
)
if
len
(
tokens
)
!=
5
:
raise
InvalidTokenException
(
"Incorrect number of tokens"
)
decrypted_token
=
JWEHelper
.
decrypt
(
token
,
key_store
,
key_purpose
)
payload
=
JWTHelper
.
decode
(
decrypted_token
,
key_store
,
key_purpose
,
leeway
)
return
payload

This decrypts the provided jwe token then decodes resulting jwt token and returns the payload .


def encrypt(json, key_store, key_purpose):
    """This encrypts the supplied json and returns a jwe token.

    :param str json: The json to be encrypted.
    :param key_store: The key store.
    :param str key_purpose: Context for the key.
    :return: A jwe token.

    """
    jwt_key = key_store.get_key_for_purpose_and_type(key_purpose, "private")

    payload = JWTHelper.encode(json, jwt_key.kid, key_store, key_purpose)

    jwe_key = key_store.get_key_for_purpose_and_type(key_purpose, "public")

    return JWEHelper.encrypt(payload, jwe_key.kid, key_store, key_purpose)

def encrypt ( json , key_store , key_purpose ) : jwt_key = key_store . get_key_for_purpose_and_type ( key_purpose , "private" ) payload = JWTHelper . encode ( json , jwt_key . kid , key_store , key_purpose ) jwe_key = key_store . get_key_for_purpose_and_type ( key_purpose , "public" ) return JWEHelper . encrypt ( payload , jwe_key . kid , key_store , key_purpose )

This encrypts the supplied json and returns a jwe token .


def delete(self, *args):
        """Remove the key from the request cache and from memcache."""
        cache = get_cache()
        key = self.get_cache_key(*args)
        if key in cache:
            del cache[key]

def delete ( self , * args ) : cache = get_cache ( ) key = self . get_cache_key ( * args ) if key in cache : del cache [ key ]

Remove the key from the request cache and from memcache .


def to_python(self):
        """Deconstruct the ``Constraint`` instance to a tuple.

        Returns:
            tuple: The deconstructed ``Constraint``.
        """
        return (
            self.selector,
            COMPARISON_MAP.get(self.comparison, self.comparison),
            self.argument
        )

def to_python ( self ) : return ( self . selector , COMPARISON_MAP . get ( self . comparison , self . comparison ) , self . argument )

Deconstruct the Constraint instance to a tuple .


def close(self):
        """Close stream."""
        if self.writer.can_write_eof():
            self.writer.write_eof()
        self.writer.close()

def close ( self ) : if self . writer . can_write_eof ( ) : self . writer . write_eof ( ) self . writer . close ( )


def parse_str_to_expression(fiql_str):
    """Parse a FIQL formatted string into an ``Expression``.

    Args:
        fiql_str (string): The FIQL formatted string we want to parse.

    Returns:
        Expression: An ``Expression`` object representing the parsed FIQL
        string.

    Raises:
        FiqlFormatException: Unable to parse string due to incorrect
            formatting.

    Example:

        >>> expression = parse_str_to_expression(
        ...         "name==bar,dob=gt=1990-01-01")

    """
    #pylint: disable=too-many-branches
    nesting_lvl = 0
    last_element = None
    expression = Expression()
    for (preamble, selector, comparison, argument) in iter_parse(fiql_str):
        if preamble:
            for char in preamble:
                if char == '(':
                    if isinstance(last_element, BaseExpression):
                        raise FiqlFormatException(
                            "%s can not be followed by %s" % (
                                last_element.__class__, Expression))
                    expression = expression.create_nested_expression()
                    nesting_lvl += 1
                elif char == ')':
                    expression = expression.get_parent()
                    last_element = expression
                    nesting_lvl -= 1
                else:
                    if not expression.has_constraint():
                        raise FiqlFormatException(
                            "%s proceeding initial %s" % (
                                Operator, Constraint))
                    if isinstance(last_element, Operator):
                        raise FiqlFormatException(
                            "%s can not be followed by %s" % (
                                Operator, Operator))
                    last_element = Operator(char)
                    expression = expression.add_operator(last_element)
        if selector:
            if isinstance(last_element, BaseExpression):
                raise FiqlFormatException("%s can not be followed by %s" % (
                    last_element.__class__, Constraint))
            last_element = Constraint(selector, comparison, argument)
            expression.add_element(last_element)
    if nesting_lvl != 0:
        raise FiqlFormatException(
            "At least one nested expression was not correctly closed")
    if not expression.has_constraint():
        raise FiqlFormatException(
            "Parsed string '%s' contained no constraint" % fiql_str)
    return expression

Parse a FIQL formatted string into an Expression .


def dump(ndb_model, fp, **kwargs):
  """Custom json dump using the custom encoder above."""
  for chunk in NdbEncoder(**kwargs).iterencode(ndb_model):
    fp.write(chunk)

def dump ( ndb_model , fp , * * kwargs ) : for chunk in NdbEncoder ( * * kwargs ) . iterencode ( ndb_model ) : fp . write ( chunk )

Custom json dump using the custom encoder above .


def object_hook_handler(self, val):
    """Handles decoding of nested date strings."""
    return {k: self.decode_date(v) for k, v in val.iteritems()}

def object_hook_handler ( self , val ) : return { k : self . decode_date ( v ) for k , v in val . iteritems ( ) }

Handles decoding of nested date strings .


def decode_date(self, val):
    """Tries to decode strings that look like dates into datetime objects."""
    if isinstance(val, basestring) and val.count('-') == 2 and len(val) > 9:
      try:
        dt = dateutil.parser.parse(val)
        # Check for UTC.
        if val.endswith(('+00:00', '-00:00', 'Z')):
          # Then remove tzinfo for gae, which is offset-naive.
          dt = dt.replace(tzinfo=None)
        return dt
      except (TypeError, ValueError):
        pass
    return val

Tries to decode strings that look like dates into datetime objects .


def decode(self, val):
    """Override of the default decode method that also uses decode_date."""
    # First try the date decoder.
    new_val = self.decode_date(val)
    if val != new_val:
      return new_val
    # Fall back to the default decoder.
    return json.JSONDecoder.decode(self, val)

def
decode
(
self
,
val
)
:
# First try the date decoder.
new_val
=
self
.
decode_date
(
val
)
if
val
!=
new_val
:
return
new_val
# Fall back to the default decoder.
return
json
.
JSONDecoder
.
decode
(
self
,
val
)

Override of the default decode method that also uses decode_date .


def default(self, obj):
    """Overriding the default JSONEncoder.default for NDB support."""
    obj_type = type(obj)
    # NDB Models return a repr to calls from type().
    if obj_type not in self._ndb_type_encoding:
      if hasattr(obj, '__metaclass__'):
        obj_type = obj.__metaclass__
      else:
        # Try to encode subclasses of types
        for ndb_type in NDB_TYPES:
          if isinstance(obj, ndb_type):
            obj_type = ndb_type
            break

    fn = self._ndb_type_encoding.get(obj_type)

    if fn:
      return fn(obj)

    return json.JSONEncoder.default(self, obj)

Overriding the default JSONEncoder . default for NDB support .


def validate_version():
    """Validate version before release."""
    import leicacam
    version_string = leicacam.__version__
    versions = version_string.split('.', 3)
    try:
        for ver in versions:
            int(ver)
    except ValueError:
        print(
            'Only integers are allowed in release version, '
            'please adjust current version {}'.format(version_string))
        return None
    return version_string


def generate():
    """Generate changelog."""
    old_dir = os.getcwd()
    proj_dir = os.path.join(os.path.dirname(__file__), os.pardir)
    os.chdir(proj_dir)
    version = validate_version()
    if not version:
        os.chdir(old_dir)
        return
    print('Generating changelog for version {}'.format(version))
    options = [
        '--user', 'arve0', '--project', 'leicacam', '-v', '--with-unreleased',
        '--future-release', version]
    generator = ChangelogGenerator(options)
    generator.run()
    os.chdir(old_dir)

def
generate
(
)
:
old_dir
=
os
.
getcwd
(
)
proj_dir
=
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
)
,
os
.
pardir
)
os
.
chdir
(
proj_dir
)
version
=
validate_version
(
)
if
not
version
:
os
.
chdir
(
old_dir
)
return
print
(
'Generating changelog for version {}'
.
format
(
version
)
)
options
=
[
'--user'
,
'arve0'
,
'--project'
,
'leicacam'
,
'-v'
,
'--with-unreleased'
,
'--future-release'
,
version
]
generator
=
ChangelogGenerator
(
options
)
generator
.
run
(
)
os
.
chdir
(
old_dir
)


def strongly_connected_components(graph: Graph) -> List:
	"""Find the strongly connected components in a graph using Tarjan's algorithm.

	The `graph` argument should be a dictionary mapping node names to sequences of successor nodes.
	"""

	assert check_argument_types()

	result = []
	stack = []
	low = {}

	def visit(node: str):
		if node in low: return

		num = len(low)
		low[node] = num
		stack_pos = len(stack)
		stack.append(node)

		for successor in graph[node]:
			visit(successor)
			low[node] = min(low[node], low[successor])

		if num == low[node]:
			component = tuple(stack[stack_pos:])
			del stack[stack_pos:]

			result.append(component)

			for item in component:
				low[item] = len(graph)

	for node in graph:
		visit(node)

	return result

def strongly_connected_components ( graph : Graph ) -> List : assert check_argument_types ( ) result = [ ] stack = [ ] low = { } def visit ( node : str ) : if node in low : return num = len ( low ) low [ node ] = num stack_pos = len ( stack ) stack . append ( node ) for successor in graph [ node ] : visit ( successor ) low [ node ] = min ( low [ node ] , low [ successor ] ) if num == low [ node ] : component = tuple ( stack [ stack_pos : ] ) del stack [ stack_pos : ] result . append ( component ) for item in component : low [ item ] = len ( graph ) for node in graph : visit ( node ) return result

Find the strongly connected components in a graph using Tarjan s algorithm . The graph argument should be a dictionary mapping node names to sequences of successor nodes .


def robust_topological_sort(graph: Graph) -> list:
	"""Identify strongly connected components then perform a topological sort of those components."""

	assert check_argument_types()

	components = strongly_connected_components(graph)

	node_component = {}
	for component in components:
		for node in component:
			node_component[node] = component

	component_graph = {}
	for component in components:
		component_graph[component] = []

	for node in graph:
		node_c = node_component[node]
		for successor in graph[node]:
			successor_c = node_component[successor]
			if node_c != successor_c:
				component_graph[node_c].append(successor_c)

	return topological_sort(component_graph)

def robust_topological_sort ( graph : Graph ) -> list : assert check_argument_types ( ) components = strongly_connected_components ( graph ) node_component = { } for component in components : for node in component : node_component [ node ] = component component_graph = { } for component in components : component_graph [ component ] = [ ] for node in graph : node_c = node_component [ node ] for successor in graph [ node ] : successor_c = node_component [ successor ] if node_c != successor_c : component_graph [ node_c ] . append ( successor_c ) return topological_sort ( component_graph )

Identify strongly connected components then perform a topological sort of those components .


def set_parent(self, parent):
        """Set parent ``Expression`` for this object.

        Args:
            parent (Expression): The ``Expression`` which contains this object.

        Raises:
            FiqlObjectException: Parent must be of type ``Expression``.
        """
        if not isinstance(parent, Expression):
            raise FiqlObjectException("Parent must be of %s not %s" % (
                Expression, type(parent)))
        self.parent = parent

def
set_parent
(
self
,
parent
)
:
if
not
isinstance
(
parent
,
Expression
)
:
raise
FiqlObjectException
(
"Parent must be of %s not %s"
%
(
Expression
,
type
(
parent
)
)
)
self
.
parent
=
parent


def get_parent(self):
        """Get the parent ``Expression`` for this object.

        Returns:
            Expression: The ``Expression`` which contains this object.

        Raises:
            FiqlObjectException: Parent is ``None``.
        """
        if not isinstance(self.parent, Expression):
            raise FiqlObjectException("Parent must be of %s not %s" % (
                Expression, type(self.parent)))
        return self.parent

def
get_parent
(
self
)
:
if
not
isinstance
(
self
.
parent
,
Expression
)
:
raise
FiqlObjectException
(
"Parent must be of %s not %s"
%
(
Expression
,
type
(
self
.
parent
)
)
)
return
self
.
parent

Get the parent Expression for this object .


def add_operator(self, operator):
        """Add an ``Operator`` to the ``Expression``.

        The ``Operator`` may result in a new ``Expression`` if an ``Operator``
        already exists and is of a different precedence.

        There are three possibilities when adding an ``Operator`` to an
        ``Expression`` depending on whether or not an ``Operator`` already
        exists:

          - No ``Operator`` on the working ``Expression``; Simply set the
            ``Operator`` and return ``self``.
          - ``Operator`` already exists and is higher in precedence; The
            ``Operator`` and last ``Constraint`` belong in a sub-expression of
            the working ``Expression``.
          - ``Operator`` already exists and is lower in precedence; The
            ``Operator`` belongs to the parent of the working ``Expression``
            whether one currently exists or not. To remain in the context of
            the top ``Expression``, this method will return the parent here
            rather than ``self``.

        Args:
            operator (Operator): What we are adding.

        Returns:
            Expression: ``self`` or related ``Expression``.

        Raises:
            FiqlObjectExpression: Operator is not a valid ``Operator``.
        """
        if not isinstance(operator, Operator):
            raise FiqlObjectException("%s is not a valid element type" % (
                operator.__class__))

        if not self._working_fragment.operator:
            self._working_fragment.operator = operator
        elif operator > self._working_fragment.operator:
            last_constraint = self._working_fragment.elements.pop()
            self._working_fragment = self._working_fragment \
                    .create_nested_expression()
            self._working_fragment.add_element(last_constraint)
            self._working_fragment.add_operator(operator)
        elif operator < self._working_fragment.operator:
            if self._working_fragment.parent:
                return self._working_fragment.parent.add_operator(operator)
            else:
                return Expression().add_element(self._working_fragment) \
                        .add_operator(operator)
        return self

def
add_operator
(
self
,
operator
)
:
if
not
isinstance
(
operator
,
Operator
)
:
raise
FiqlObjectException
(
"%s is not a valid element type"
%
(
operator
.
__class__
)
)
if
not
self
.
_working_fragment
.
operator
:
self
.
_working_fragment
.
operator
=
operator
elif
operator
>
self
.
_working_fragment
.
operator
:
last_constraint
=
self
.
_working_fragment
.
elements
.
pop
(
)
self
.
_working_fragment
=
self
.
_working_fragment
.
create_nested_expression
(
)
self
.
_working_fragment
.
add_element
(
last_constraint
)
self
.
_working_fragment
.
add_operator
(
operator
)
elif
operator
<
self
.
_working_fragment
.
operator
:
if
self
.
_working_fragment
.
parent
:
return
self
.
_working_fragment
.
parent
.
add_operator
(
operator
)
else
:
return
Expression
(
)
.
add_element
(
self
.
_working_fragment
)
.
add_operator
(
operator
)
return
self


def add_element(self, element):
        """Add an element of type ``Operator``, ``Constraint``, or
        ``Expression`` to the ``Expression``.

        Args:
            element: ``Constraint``, ``Expression``, or ``Operator``.

        Returns:
            Expression: ``self``

        Raises:
            FiqlObjectException: Element is not a valid type.
        """
        if isinstance(element, BaseExpression):
            element.set_parent(self._working_fragment)
            self._working_fragment.elements.append(element)
            return self
        else:
            return self.add_operator(element)

def add_element ( self , element ) : if isinstance ( element , BaseExpression ) : element . set_parent ( self . _working_fragment ) self . _working_fragment . elements . append ( element ) return self else : return self . add_operator ( element )

Add an element of type Operator Constraint or Expression to the Expression .


def op_and(self, *elements):
        """Update the ``Expression`` by joining the specified additional
        ``elements`` using an "AND" ``Operator``

        Args:
            *elements (BaseExpression): The ``Expression`` and/or
                ``Constraint`` elements which the "AND" ``Operator`` applies
                to.

        Returns:
            Expression: ``self`` or related ``Expression``.
        """
        expression = self.add_operator(Operator(';'))
        for element in elements:
            expression.add_element(element)
        return expression

def op_and ( self , * elements ) : expression = self . add_operator ( Operator ( ';' ) ) for element in elements : expression . add_element ( element ) return expression

Update the Expression by joining the specified additional elements using an AND Operator


def op_or(self, *elements):
        """Update the ``Expression`` by joining the specified additional
        ``elements`` using an "OR" ``Operator``

        Args:
            *elements (BaseExpression): The ``Expression`` and/or
                ``Constraint`` elements which the "OR" ``Operator`` applies
                to.

        Returns:
            Expression: ``self`` or related ``Expression``.
        """
        expression = self.add_operator(Operator(','))
        for element in elements:
            expression.add_element(element)
        return expression

def op_or ( self , * elements ) : expression = self . add_operator ( Operator ( ',' ) ) for element in elements : expression . add_element ( element ) return expression

Update the Expression by joining the specified additional elements using an OR Operator


def logger(function):
    """Decorate passed in function and log message to module logger."""
    @functools.wraps(function)
    def wrapper(*args, **kwargs):
        """Wrap function."""
        sep = kwargs.get('sep', ' ')
        end = kwargs.get('end', '')  # do not add newline by default
        out = sep.join([repr(x) for x in args])
        out = out + end
        _LOGGER.debug(out)
        return function(*args, **kwargs)
    return wrapper

def
logger
(
function
)
:
@
functools
.
wraps
(
function
)
def
wrapper
(
*
args
,
*
*
kwargs
)
:
"""Wrap function."""
sep
=
kwargs
.
get
(
'sep'
,
' '
)
end
=
kwargs
.
get
(
'end'
,
''
)
# do not add newline by default
out
=
sep
.
join
(
[
repr
(
x
)
for
x
in
args
]
)
out
=
out
+
end
_LOGGER
.
debug
(
out
)
return
function
(
*
args
,
*
*
kwargs
)
return
wrapper

Decorate passed in function and log message to module logger .


def _parse_receive(incomming):
    """Parse received response.

    Parameters
    ----------
    incomming : bytes string
        Incomming bytes from socket server.

    Returns
    -------
    list of OrderedDict
        Received message as a list of OrderedDict.

    """
    debug(b'< ' + incomming)
    # remove terminating null byte
    incomming = incomming.rstrip(b'\x00')
    # split received messages
    # return as list of several messages received
    msgs = incomming.splitlines()
    return [bytes_as_dict(msg) for msg in msgs]


def tuples_as_dict(_list):
    """Translate a list of tuples to OrderedDict with key and val as strings.

    Parameters
    ----------
    _list : list of tuples

    Returns
    -------
    collections.OrderedDict

    Example
    -------
    ::

        >>> tuples_as_dict([('cmd', 'val'), ('cmd2', 'val2')])
        OrderedDict([('cmd', 'val'), ('cmd2', 'val2')])

    """
    _dict = OrderedDict()
    for key, val in _list:
        key = str(key)
        val = str(val)
        _dict[key] = val
    return _dict

def tuples_as_dict ( _list ) : _dict = OrderedDict ( ) for key , val in _list : key = str ( key ) val = str ( val ) _dict [ key ] = val return _dict

Translate a list of tuples to OrderedDict with key and val as strings .


def check_messages(msgs, cmd, value=None):
    """Check if specific message is present.

    Parameters
    ----------
    cmd : string
        Command to check for in bytestring from microscope CAM interface. If
        ``value`` is falsey, value of received command does not matter.
    value : string
        Check if ``cmd:value`` is received.

    Returns
    -------
    collections.OrderedDict
        Correct messsage or None if no correct message if found.

    """
    for msg in msgs:
        if value and msg.get(cmd) == value:
            return msg
        if not value and msg.get(cmd):
            return msg
    return None

def check_messages ( msgs , cmd , value = None ) : for msg in msgs : if value and msg . get ( cmd ) == value : return msg if not value and msg . get ( cmd ) : return msg return None


def _prepare_send(self, commands):
        """Prepare message to be sent.

        Parameters
        ----------
        commands : list of tuples or bytes string
            Commands as a list of tuples or a bytes string. cam.prefix is
            allways prepended before sending.

        Returns
        -------
        string
            Message to be sent.

        """
        if isinstance(commands, bytes):
            msg = self.prefix_bytes + commands
        else:
            msg = tuples_as_bytes(self.prefix + commands)
        debug(b'> ' + msg)
        return msg

def
_prepare_send
(
self
,
commands
)
:
if
isinstance
(
commands
,
bytes
)
:
msg
=
self
.
prefix_bytes
+
commands
else
:
msg
=
tuples_as_bytes
(
self
.
prefix
+
commands
)
debug
(
b'> '
+
msg
)
return
msg


def flush(self):
        """Flush incomming socket messages."""
        debug('flushing incomming socket messages')
        try:
            while True:
                msg = self.socket.recv(self.buffer_size)
                debug(b'< ' + msg)
        except socket.error:
            pass

def
flush
(
self
)
:
debug
(
'flushing incomming socket messages'
)
try
:
while
True
:
msg
=
self
.
socket
.
recv
(
self
.
buffer_size
)
debug
(
b'< '
+
msg
)
except
socket
.
error
:
pass


def enable(self, slide=0, wellx=1, welly=1, fieldx=1, fieldy=1):
        """Enable a given scan field."""
        # pylint: disable=too-many-arguments
        cmd = [
            ('cmd', 'enable'),
            ('slide', str(slide)),
            ('wellx', str(wellx)),
            ('welly', str(welly)),
            ('fieldx', str(fieldx)),
            ('fieldy', str(fieldy)),
            ('value', 'true')
        ]
        self.send(cmd)
        return self.wait_for(*cmd[0])

def
enable
(
self
,
slide
=
0
,
wellx
=
1
,
welly
=
1
,
fieldx
=
1
,
fieldy
=
1
)
:
# pylint: disable=too-many-arguments
cmd
=
[
(
'cmd'
,
'enable'
)
,
(
'slide'
,
str
(
slide
)
)
,
(
'wellx'
,
str
(
wellx
)
)
,
(
'welly'
,
str
(
welly
)
)
,
(
'fieldx'
,
str
(
fieldx
)
)
,
(
'fieldy'
,
str
(
fieldy
)
)
,
(
'value'
,
'true'
)
]
self
.
send
(
cmd
)
return
self
.
wait_for
(
*
cmd
[
0
]
)


def save_template(self, filename="{ScanningTemplate}leicacam.xml"):
        """Save scanning template to filename."""
        cmd = [
            ('sys', '0'),
            ('cmd', 'save'),
            ('fil', str(filename))
        ]
        self.send(cmd)
        return self.wait_for(*cmd[0])

def save_template ( self , filename = "{ScanningTemplate}leicacam.xml" ) : cmd = [ ( 'sys' , '0' ) , ( 'cmd' , 'save' ) , ( 'fil' , str ( filename ) ) ] self . send ( cmd ) return self . wait_for ( * cmd [ 0 ] )


def load_template(self, filename="{ScanningTemplate}leicacam.xml"):
        """Load scanning template from filename.

        Template needs to exist in database, otherwise it will not load.

        Parameters
        ----------
        filename : str
            Filename to template to load. Filename may contain path also, in
            such case, the basename will be used. '.xml' will be stripped
            from the filename if it exists because of a bug; LASAF implicit
            add '.xml'. If '{ScanningTemplate}' is omitted, it will be added.

        Returns
        -------
        collections.OrderedDict
            Response from LASAF in an ordered dict.

        Example
        -------
        ::

            >>> # load {ScanningTemplate}leicacam.xml
            >>> cam.load_template('leicacam')

            >>> # load {ScanningTemplate}leicacam.xml
            >>> cam.load_template('{ScanningTemplate}leicacam')

            >>> # load {ScanningTemplate}leicacam.xml
            >>> cam.load_template('/path/to/{ScanningTemplate}leicacam.xml')

        """
        basename = os.path.basename(filename)
        if basename[-4:] == '.xml':
            basename = basename[:-4]
        if basename[:18] != '{ScanningTemplate}':
            basename = '{ScanningTemplate}' + basename
        cmd = [
            ('sys', '0'),
            ('cmd', 'load'),
            ('fil', str(basename))
        ]
        self.send(cmd)
        return self.wait_for(*cmd[1])

def load_template ( self , filename = "{ScanningTemplate}leicacam.xml" ) : basename = os . path . basename ( filename ) if basename [ - 4 : ] == '.xml' : basename = basename [ : - 4 ] if basename [ : 18 ] != '{ScanningTemplate}' : basename = '{ScanningTemplate}' + basename cmd = [ ( 'sys' , '0' ) , ( 'cmd' , 'load' ) , ( 'fil' , str ( basename ) ) ] self . send ( cmd ) return self . wait_for ( * cmd [ 1 ] )


def get_information(self, about='stage'):
        """Get information about given keyword. Defaults to stage."""
        cmd = [
            ('cmd', 'getinfo'),
            ('dev', str(about))
        ]
        self.send(cmd)
        return self.wait_for(*cmd[1])

def get_information ( self , about = 'stage' ) : cmd = [ ( 'cmd' , 'getinfo' ) , ( 'dev' , str ( about ) ) ] self . send ( cmd ) return self . wait_for ( * cmd [ 1 ] )

Get information about given keyword . Defaults to stage .


def incfile(fname, fpointer, lrange="1,6-", sdir=None):
    r"""
    Include a Python source file in a docstring formatted in reStructuredText.

    :param fname: File name, relative to environment variable
                  :bash:`${TRACER_DIR}`
    :type  fname: string

    :param fpointer: Output function pointer. Normally is :code:`cog.out` but
                     :code:`print` or other functions can be used for
                     debugging
    :type  fpointer: function object

    :param lrange: Line range to include, similar to Sphinx
                   `literalinclude <http://sphinx-doc.org/markup/code.html
                   #directive-literalinclude>`_ directive
    :type  lrange: string

    :param sdir: Source file directory. If None the :bash:`${TRACER_DIR}`
                 environment variable is used if it is defined, otherwise
                 the directory where the :code:`docs.support.incfile` module
                 is located is used
    :type  sdir: string

    For example:

    .. code-block:: python

        def func():
            \"\"\"
            This is a docstring. This file shows how to use it:

            .. =[=cog
            .. import docs.support.incfile
            .. docs.support.incfile.incfile('func_example.py', cog.out)
            .. =]=
            .. code-block:: python

                # func_example.py
                if __name__ == '__main__':
                    func()

            .. =[=end=]=
            \"\"\"
            return 'This is func output'
    """
    # Read file
    file_dir = (
        sdir
        if sdir
        else os.environ.get("TRACER_DIR", os.path.abspath(os.path.dirname(__file__)))
    )
    fname = os.path.join(file_dir, fname)
    with open(fname) as fobj:
        lines = fobj.readlines()
    # Parse line specification
    tokens = [item.strip() for item in lrange.split(",")]
    inc_lines = []
    for token in tokens:
        if "-" in token:
            subtokens = token.split("-")
            lmin, lmax = (
                int(subtokens[0]),
                int(subtokens[1]) if subtokens[1] else len(lines),
            )
            for num in range(lmin, lmax + 1):
                inc_lines.append(num)
        else:
            inc_lines.append(int(token))
    # Produce output
    fpointer(".. code-block:: python\n")
    fpointer("\n")
    for num, line in enumerate(lines):
        if num + 1 in inc_lines:
            fpointer("    " + line.replace("\t", "    ") if line.strip() else "\n")
    fpointer("\n")

def
incfile
(
fname
,
fpointer
,
lrange
=
"1,6-"
,
sdir
=
)
:
# Read file
file_dir
=
(
sdir
if
sdir
else
os
.
environ
.
get
(
"TRACER_DIR"
,
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
)
)
)
)
fname
=
os
.
path
.
join
(
file_dir
,
fname
)
with
open
(
fname
)
as
fobj
:
lines
=
fobj
.
readlines
(
)
# Parse line specification
tokens
=
[
item
.
strip
(
)
for
item
in
lrange
.
split
(
","
)
]
inc_lines
=
[
]
for
token
in
tokens
:
if
"-"
in
token
:
subtokens
=
token
.
split
(
"-"
)
lmin
,
lmax
=
(
int
(
subtokens
[
0
]
)
,
int
(
subtokens
[
1
]
)
if
subtokens
[
1
]
else
len
(
lines
)
,
)
for
num
in
range
(
lmin
,
lmax
+
1
)
:
inc_lines
.
append
(
num
)
else
:
inc_lines
.
append
(
int
(
token
)
)
# Produce output
fpointer
(
".. code-block:: python\n"
)
fpointer
(
"\n"
)
for
num
,
line
in
enumerate
(
lines
)
:
if
num
+
1
in
inc_lines
:
fpointer
(
"    "
+
line
.
replace
(
"\t"
,
"    "
)
if
line
.
strip
(
)
else
"\n"
)
fpointer
(
"\n"
)

r Include a Python source file in a docstring formatted in reStructuredText .


def locate_package_json():
    """
    Find and return the location of package.json.
    """
    directory = settings.SYSTEMJS_PACKAGE_JSON_DIR
    if not directory:
        raise ImproperlyConfigured(
            "Could not locate 'package.json'. Set SYSTEMJS_PACKAGE_JSON_DIR "
            "to the directory that holds 'package.json'."
        )
    path = os.path.join(directory, 'package.json')
    if not os.path.isfile(path):
        raise ImproperlyConfigured("'package.json' does not exist, tried looking in %s" % path)
    return path

Find and return the location of package . json .


def parse_package_json():
    """
    Extract the JSPM configuration from package.json.
    """
    with open(locate_package_json()) as pjson:
        data = json.loads(pjson.read())
    return data

def parse_package_json ( ) : with open ( locate_package_json ( ) ) as pjson : data = json . loads ( pjson . read ( ) ) return data

Extract the JSPM configuration from package . json .


def _handle_api_error_with_json(http_exc, jsondata, response):
    """Handle YOURLS API errors.

    requests' raise_for_status doesn't show the user the YOURLS json response,
    so we parse that here and raise nicer exceptions.
    """
    if 'code' in jsondata and 'message' in jsondata:
        code = jsondata['code']
        message = jsondata['message']

        if code == 'error:noloop':
            raise YOURLSNoLoopError(message, response=response)
        elif code == 'error:nourl':
            raise YOURLSNoURLError(message, response=response)

    elif 'message' in jsondata:
        message = jsondata['message']
        raise YOURLSHTTPError(message, response=response)

    http_error_message = http_exc.args[0]
    raise YOURLSHTTPError(http_error_message, response=response)

def _handle_api_error_with_json ( http_exc , jsondata , response ) : if 'code' in jsondata and 'message' in jsondata : code = jsondata [ 'code' ] message = jsondata [ 'message' ] if code == 'error:noloop' : raise YOURLSNoLoopError ( message , response = response ) elif code == 'error:nourl' : raise YOURLSNoURLError ( message , response = response ) elif 'message' in jsondata : message = jsondata [ 'message' ] raise YOURLSHTTPError ( message , response = response ) http_error_message = http_exc . args [ 0 ] raise YOURLSHTTPError ( http_error_message , response = response )


def _validate_yourls_response(response, data):
    """Validate response from YOURLS server."""
    try:
        response.raise_for_status()
    except HTTPError as http_exc:
        # Collect full HTTPError information so we can reraise later if required.
        http_error_info = sys.exc_info()

        # We will reraise outside of try..except block to prevent exception
        # chaining showing wrong traceback when we try and parse JSON response.
        reraise = False

        try:
            jsondata = response.json()
        except ValueError:
            reraise = True
        else:
            logger.debug('Received error {response} with JSON {json}',
                         response=response, json=jsondata)
            _handle_api_error_with_json(http_exc, jsondata, response)

        if reraise:
            six.reraise(*http_error_info)
    else:
        # We have a valid HTTP response, but we need to check what the API says
        # about the request.
        jsondata = response.json()

        logger.debug('Received {response} with JSON {json}', response=response,
                     json=jsondata)

        if {'status', 'code', 'message'} <= set(jsondata.keys()):
            status = jsondata['status']
            code = jsondata['code']
            message = jsondata['message']

            if status == 'fail':
                if code == 'error:keyword':
                    raise YOURLSKeywordExistsError(message, keyword=data['keyword'])
                elif code == 'error:url':
                    url = _json_to_shortened_url(jsondata['url'], jsondata['shorturl'])
                    raise YOURLSURLExistsError(message, url=url)
                else:
                    raise YOURLSAPIError(message)
            else:
                return jsondata
        else:
            # Without status, nothing special needs to be handled.
            return jsondata


def _homogenize_waves(wave_a, wave_b):
    """
    Generate combined independent variable vector.

    The combination is from two waveforms and the (possibly interpolated)
    dependent variable vectors of these two waveforms
    """
    indep_vector = _get_indep_vector(wave_a, wave_b)
    dep_vector_a = _interp_dep_vector(wave_a, indep_vector)
    dep_vector_b = _interp_dep_vector(wave_b, indep_vector)
    return (indep_vector, dep_vector_a, dep_vector_b)

Generate combined independent variable vector .


def _interp_dep_vector(wave, indep_vector):
    """Create new dependent variable vector."""
    dep_vector_is_int = wave.dep_vector.dtype.name.startswith("int")
    dep_vector_is_complex = wave.dep_vector.dtype.name.startswith("complex")
    if (wave.interp, wave.indep_scale) == ("CONTINUOUS", "LOG"):
        wave_interp_func = scipy.interpolate.interp1d(
            np.log10(wave.indep_vector), wave.dep_vector
        )
        ret = wave_interp_func(np.log10(indep_vector))
    elif (wave.interp, wave.indep_scale) == ("CONTINUOUS", "LINEAR"):
        dep_vector = (
            wave.dep_vector.astype(np.float64)
            if not dep_vector_is_complex
            else wave.dep_vector
        )
        wave_interp_func = scipy.interpolate.interp1d(wave.indep_vector, dep_vector)
        ret = wave_interp_func(indep_vector)
    else:  # wave.interp == 'STAIRCASE'
        wave_interp_func = scipy.interpolate.interp1d(
            wave.indep_vector, wave.dep_vector, kind="zero"
        )
        # Interpolator does not return the right value for the last
        # data point, it gives the previous "stair" value
        ret = wave_interp_func(indep_vector)
        eq_comp = np.all(
            np.isclose(wave.indep_vector[-1], indep_vector[-1], FP_RTOL, FP_ATOL)
        )
        if eq_comp:
            ret[-1] = wave.dep_vector[-1]
    round_ret = np.round(ret, 0)
    return (
        round_ret.astype("int")
        if (dep_vector_is_int and np.all(np.isclose(round_ret, ret, FP_RTOL, FP_ATOL)))
        else ret
    )


def _get_indep_vector(wave_a, wave_b):
    """Create new independent variable vector."""
    exobj = pexdoc.exh.addex(RuntimeError, "Independent variable ranges do not overlap")
    min_bound = max(np.min(wave_a.indep_vector), np.min(wave_b.indep_vector))
    max_bound = min(np.max(wave_a.indep_vector), np.max(wave_b.indep_vector))
    exobj(bool(min_bound > max_bound))
    raw_range = np.unique(np.concatenate((wave_a.indep_vector, wave_b.indep_vector)))
    return raw_range[np.logical_and(min_bound <= raw_range, raw_range <= max_bound)]

Create new independent variable vector .


def _verify_compatibility(wave_a, wave_b, check_dep_units=True):
    """Verify that two waveforms can be combined with various mathematical functions."""
    exobj = pexdoc.exh.addex(RuntimeError, "Waveforms are not compatible")
    ctuple = (
        bool(wave_a.indep_scale != wave_b.indep_scale),
        bool(wave_a.dep_scale != wave_b.dep_scale),
        bool(wave_a.indep_units != wave_b.indep_units),
        (bool(wave_a.dep_units != wave_b.dep_units) if check_dep_units else False),
        bool(wave_a.interp != wave_b.interp),
    )
    exobj(any(ctuple))

def
_verify_compatibility
(
wave_a
,
wave_b
,
check_dep_units
=
True
)
:
exobj
=
pexdoc
.
exh
.
addex
(
RuntimeError
,
"Waveforms are not compatible"
)
ctuple
=
(
bool
(
wave_a
.
indep_scale
!=
wave_b
.
indep_scale
)
,
bool
(
wave_a
.
dep_scale
!=
wave_b
.
dep_scale
)
,
bool
(
wave_a
.
indep_units
!=
wave_b
.
indep_units
)
,
(
bool
(
wave_a
.
dep_units
!=
wave_b
.
dep_units
)
if
check_dep_units
else
False
)
,
bool
(
wave_a
.
interp
!=
wave_b
.
interp
)
,
)
exobj
(
any
(
ctuple
)
)

Verify that two waveforms can be combined with various mathematical functions .


def load_systemjs_manifest(self):
        """
        Load the existing systemjs manifest and remove any entries that no longer
        exist on the storage.
        """
        # backup the original name
        _manifest_name = self.manifest_name

        # load the custom bundle manifest
        self.manifest_name = self.systemjs_manifest_name
        bundle_files = self.load_manifest()
        # reset the manifest name
        self.manifest_name = _manifest_name

        # check that the files actually exist, if not, remove them from the manifest
        for file, hashed_file in bundle_files.copy().items():
            if not self.exists(file) or not self.exists(hashed_file):
                del bundle_files[file]
        return bundle_files

Load the existing systemjs manifest and remove any entries that no longer exist on the storage .


def trace_pars(mname):
    """Define trace parameters."""
    pickle_fname = os.path.join(os.path.dirname(__file__), "{0}.pkl".format(mname))
    ddir = os.path.dirname(os.path.dirname(__file__))
    moddb_fname = os.path.join(ddir, "moddb.json")
    in_callables_fname = moddb_fname if os.path.exists(moddb_fname) else None
    out_callables_fname = os.path.join(ddir, "{0}.json".format(mname))
    noption = os.environ.get("NOPTION", None)
    exclude = ["_pytest", "execnet"]
    partuple = collections.namedtuple(
        "ParTuple",
        [
            "pickle_fname",
            "in_callables_fname",
            "out_callables_fname",
            "noption",
            "exclude",
        ],
    )
    return partuple(
        pickle_fname, in_callables_fname, out_callables_fname, noption, exclude
    )

def trace_pars ( mname ) : pickle_fname = os . path . join ( os . path . dirname ( __file__ ) , "{0}.pkl" . format ( mname ) ) ddir = os . path . dirname ( os . path . dirname ( __file__ ) ) moddb_fname = os . path . join ( ddir , "moddb.json" ) in_callables_fname = moddb_fname if os . path . exists ( moddb_fname ) else None out_callables_fname = os . path . join ( ddir , "{0}.json" . format ( mname ) ) noption = os . environ . get ( "NOPTION" , None ) exclude = [ "_pytest" , "execnet" ] partuple = collections . namedtuple ( "ParTuple" , [ "pickle_fname" , "in_callables_fname" , "out_callables_fname" , "noption" , "exclude" , ] , ) return partuple ( pickle_fname , in_callables_fname , out_callables_fname , noption , exclude )


def run_trace(
    mname,
    fname,
    module_prefix,
    callable_names,
    no_print,
    module_exclude=None,
    callable_exclude=None,
    debug=False,
):
    """Run module tracing."""
    # pylint: disable=R0913
    module_exclude = [] if module_exclude is None else module_exclude
    callable_exclude = [] if callable_exclude is None else callable_exclude
    par = trace_pars(mname)
    start_time = datetime.datetime.now()
    with pexdoc.exdoc.ExDocCxt(
        exclude=par.exclude + module_exclude,
        pickle_fname=par.pickle_fname,
        in_callables_fname=par.in_callables_fname,
        out_callables_fname=par.out_callables_fname,
        _no_print=no_print,
    ) as exdoc_obj:
        fname = os.path.realpath(
            os.path.join(
                os.path.dirname(__file__),
                "..",
                "..",
                "tests",
                "test_{0}.py".format(fname),
            )
        )
        test_cmd = (
            ["--color=yes"]
            + (["-s", "-vv"] if debug else ["-q", "-q", "-q"])
            + ["--disable-warnings"]
            + ["-x"]
            + ([par.noption] if par.noption else [])
            + ["-m " + mname]
            + [fname]
        )
        with warnings.catch_warnings():
            warnings.filterwarnings("ignore", category=PytestWarning)
            if pytest.main(test_cmd):
                raise RuntimeError("Tracing did not complete successfully")
    stop_time = datetime.datetime.now()
    if not no_print:
        print(
            "Auto-generation of exceptions documentation time: {0}".format(
                pmisc.elapsed_time_string(start_time, stop_time)
            )
        )
        for callable_name in callable_names:
            callable_name = module_prefix + callable_name
            print("\nCallable: {0}".format(callable_name))
            print(exdoc_obj.get_sphinx_doc(callable_name, exclude=callable_exclude))
            print("\n")
    return copy.copy(exdoc_obj)


def shorten(self, url, keyword=None, title=None):
        """Shorten URL with optional keyword and title.

        Parameters:
            url: URL to shorten.
            keyword: Optionally choose keyword for short URL, otherwise automatic.
            title: Optionally choose title, otherwise taken from web page.

        Returns:
            ShortenedURL: Shortened URL and associated data.

        Raises:
            ~yourls.exceptions.YOURLSKeywordExistsError: The passed keyword
                already exists.

                .. note::

                    This exception has a ``keyword`` attribute.

            ~yourls.exceptions.YOURLSURLExistsError: The URL has already been
                shortened.

                .. note::

                    This exception has a ``url`` attribute, which is an instance
                    of :py:class:`ShortenedURL` for the existing short URL.

            ~yourls.exceptions.YOURLSNoURLError: URL missing.

            ~yourls.exceptions.YOURLSNoLoopError: Cannot shorten a shortened URL.

            ~yourls.exceptions.YOURLSAPIError: Unhandled API error.

            ~yourls.exceptions.YOURLSHTTPError: HTTP error with response from
                YOURLS API.

            requests.exceptions.HTTPError: Generic HTTP error.
        """
        data = dict(action='shorturl', url=url, keyword=keyword, title=title)
        jsondata = self._api_request(params=data)

        url = _json_to_shortened_url(jsondata['url'], jsondata['shorturl'])

        return url

def shorten ( self , url , keyword = None , title = None ) : data = dict ( action = 'shorturl' , url = url , keyword = keyword , title = title ) jsondata = self . _api_request ( params = data ) url = _json_to_shortened_url ( jsondata [ 'url' ] , jsondata [ 'shorturl' ] ) return url

Shorten URL with optional keyword and title .


def expand(self, short):
        """Expand short URL or keyword to long URL.

        Parameters:
            short: Short URL (``http://example.com/abc``) or keyword (abc).

        :return: Expanded/long URL, e.g.
                 ``https://www.youtube.com/watch?v=dQw4w9WgXcQ``

        Raises:
            ~yourls.exceptions.YOURLSHTTPError: HTTP error with response from
                YOURLS API.
            requests.exceptions.HTTPError: Generic HTTP error.
        """
        data = dict(action='expand', shorturl=short)
        jsondata = self._api_request(params=data)

        return jsondata['longurl']

def expand ( self , short ) : data = dict ( action = 'expand' , shorturl = short ) jsondata = self . _api_request ( params = data ) return jsondata [ 'longurl' ]

Expand short URL or keyword to long URL .


def url_stats(self, short):
        """Get stats for short URL or keyword.

        Parameters:
            short: Short URL (http://example.com/abc) or keyword (abc).

        Returns:
            ShortenedURL: Shortened URL and associated data.

        Raises:
            ~yourls.exceptions.YOURLSHTTPError: HTTP error with response from
                YOURLS API.
            requests.exceptions.HTTPError: Generic HTTP error.
        """
        data = dict(action='url-stats', shorturl=short)
        jsondata = self._api_request(params=data)

        return _json_to_shortened_url(jsondata['link'])

def url_stats ( self , short ) : data = dict ( action = 'url-stats' , shorturl = short ) jsondata = self . _api_request ( params = data ) return _json_to_shortened_url ( jsondata [ 'link' ] )


def stats(self, filter, limit, start=None):
        """Get stats about links.

        Parameters:
            filter: 'top', 'bottom', 'rand', or 'last'.
            limit: Number of links to return from filter.
            start: Optional start number.

        Returns:
            Tuple containing list of ShortenedURLs and DBStats.

        Example:

            .. code-block:: python

                links, stats = yourls.stats(filter='top', limit=10)

        Raises:
            ValueError: Incorrect value for filter parameter.
            requests.exceptions.HTTPError: Generic HTTP Error
        """
        # Normalise random to rand, even though it's accepted by API.
        if filter == 'random':
            filter = 'rand'

        valid_filters = ('top', 'bottom', 'rand', 'last')
        if filter not in valid_filters:
            msg = 'filter must be one of {}'.format(', '.join(valid_filters))
            raise ValueError(msg)

        data = dict(action='stats', filter=filter, limit=limit, start=start)
        jsondata = self._api_request(params=data)

        stats = DBStats(total_clicks=int(jsondata['stats']['total_clicks']),
                        total_links=int(jsondata['stats']['total_links']))

        links = []

        if 'links' in jsondata:
            for i in range(1, limit + 1):
                key = 'link_{}'.format(i)
                links.append(_json_to_shortened_url(jsondata['links'][key]))

        return links, stats


def db_stats(self):
        """Get database statistics.

        Returns:
            DBStats: Total clicks and links statistics.

        Raises:
            requests.exceptions.HTTPError: Generic HTTP Error
        """
        data = dict(action='db-stats')
        jsondata = self._api_request(params=data)

        stats = DBStats(total_clicks=int(jsondata['db-stats']['total_clicks']),
                        total_links=int(jsondata['db-stats']['total_links']))

        return stats

def db_stats ( self ) : data = dict ( action = 'db-stats' ) jsondata = self . _api_request ( params = data ) stats = DBStats ( total_clicks = int ( jsondata [ 'db-stats' ] [ 'total_clicks' ] ) , total_links = int ( jsondata [ 'db-stats' ] [ 'total_links' ] ) ) return stats


def ste(command, nindent, mdir, fpointer):
    r"""
    Echo terminal output.

    Print STDOUT resulting from a given Bash shell command (relative to the
    package :code:`pypkg` directory) formatted in reStructuredText

    :param command: Bash shell command, relative to
                    :bash:`${PMISC_DIR}/pypkg`
    :type  command: string

    :param nindent: Indentation level
    :type  nindent: integer

    :param mdir: Module directory
    :type  mdir: string

    :param fpointer: Output function pointer. Normally is :code:`cog.out` but
                     :code:`print` or other functions can be used for
                     debugging
    :type  fpointer: function object

    For example::

        .. This is a reStructuredText file snippet
        .. [[[cog
        .. import os, sys
        .. from docs.support.term_echo import term_echo
        .. file_name = sys.modules['docs.support.term_echo'].__file__
        .. mdir = os.path.realpath(
        ..     os.path.dirname(
        ..         os.path.dirname(os.path.dirname(file_name))
        ..     )
        .. )
        .. [[[cog ste('build_docs.py -h', 0, mdir, cog.out) ]]]

        .. code-block:: bash

        $ ${PMISC_DIR}/pypkg/build_docs.py -h
        usage: build_docs.py [-h] [-d DIRECTORY] [-n NUM_CPUS]
        ...

        .. ]]]

    """
    term_echo(
        "${{PMISC_DIR}}{sep}pypkg{sep}{cmd}".format(sep=os.path.sep, cmd=command),
        nindent,
        {"PMISC_DIR": mdir},
        fpointer,
    )

def ste ( command , nindent , mdir , fpointer ) : term_echo ( "${{PMISC_DIR}}{sep}pypkg{sep}{cmd}" . format ( sep = os . path . sep , cmd = command ) , nindent , { "PMISC_DIR" : mdir } , fpointer , )


def term_echo(command, nindent=0, env=None, fpointer=None, cols=60):
    """
    Print STDOUT resulting from a Bash shell command formatted in reStructuredText.

    :param command: Bash shell command
    :type  command: string

    :param nindent: Indentation level
    :type  nindent: integer

    :param env: Environment variable replacement dictionary. The Bash
                command is pre-processed and any environment variable
                represented in the full notation (:bash:`${...}`) is replaced.
                The dictionary key is the environment variable name and the
                dictionary value is the replacement value. For example, if
                **command** is :code:`'${PYTHON_CMD} -m "x=5"'` and **env**
                is :code:`{'PYTHON_CMD':'python3'}` the actual command issued
                is :code:`'python3 -m "x=5"'`
    :type  env: dictionary

    :param fpointer: Output function pointer. Normally is :code:`cog.out` but
                     :code:`print` or other functions can be used for
                     debugging
    :type  fpointer: function object

    :param cols: Number of columns of output
    :type  cols: integer
    """
    # pylint: disable=R0204
    # Set argparse width so that output does not need horizontal scroll
    # bar in narrow windows or displays
    os.environ["COLUMNS"] = str(cols)
    command_int = command
    if env:
        for var, repl in env.items():
            command_int = command_int.replace("${" + var + "}", repl)
    tokens = command_int.split(" ")
    # Add Python interpreter executable for Python scripts on Windows since
    # the shebang does not work
    if (platform.system().lower() == "windows") and (tokens[0].endswith(".py")):
        tokens = [sys.executable] + tokens
    proc = subprocess.Popen(tokens, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    stdout = proc.communicate()[0]
    if sys.hexversion >= 0x03000000:
        stdout = stdout.decode("utf-8")
    stdout = stdout.split("\n")
    indent = nindent * " "
    fpointer("\n", dedent=False)
    fpointer("{0}.. code-block:: bash\n".format(indent), dedent=False)
    fpointer("\n", dedent=False)
    fpointer("{0}    $ {1}\n".format(indent, command), dedent=False)
    for line in stdout:
        if line.strip():
            fpointer(indent + "    " + line.replace("\t", "    ") + "\n", dedent=False)
        else:
            fpointer("\n", dedent=False)
    fpointer("\n", dedent=False)

Print STDOUT resulting from a Bash shell command formatted in reStructuredText .


def log(self, msg, level=2):
        """
        Small log helper
        """
        if self.verbosity >= level:
            self.stdout.write(msg)

def log ( self , msg , level = 2 ) : if self . verbosity >= level : self . stdout . write ( msg )


def cached(method) -> property:
    """alternative to reify and property decorators. caches the value when it's
    generated. It cashes it as instance._name_of_the_property.
    """
    name = "_" + method.__name__

    @property
    def wrapper(self):
        try:
            return getattr(self, name)
        except AttributeError:
            val = method(self)
            setattr(self, name, val)
            return val

    return wrapper

def cached ( method ) -> property : name = "_" + method . __name__ @ property def wrapper ( self ) : try : return getattr ( self , name ) except AttributeError : val = method ( self ) setattr ( self , name , val ) return val return wrapper

alternative to reify and property decorators . caches the value when it s generated . It cashes it as instance . _name_of_the_property .


def chunkiter(iterable, chunksize):
    """break an iterable into chunks and yield those chunks as lists
    until there's nothing left to yeild.
    """
    iterator = iter(iterable)
    for chunk in iter(lambda: list(itertools.islice(iterator, chunksize)), []):
        yield chunk

def chunkiter ( iterable , chunksize ) : iterator = iter ( iterable ) for chunk in iter ( lambda : list ( itertools . islice ( iterator , chunksize ) ) , [ ] ) : yield chunk

break an iterable into chunks and yield those chunks as lists until there s nothing left to yeild .