Пример #1
0
def tmatch() -> TypeMatcher:
    "A fixture for type matches."

    matcher = TypeMatcher({
        int: (lambda x: x + 4),
        str: (lambda s: f"Hello, {s}!"),
        (int, str): (lambda amount, chr_: amount * chr_),
        (int, Any): (lambda amount, x: [x for n in range(amount)]),
        (int, int, int): lambda a,b,c: [matcher(a), matcher(b), matcher(c)],
        ASupertype: lambda x: f"super: {x.__class__.__name__}",
        ASubtype: lambda x: f"spec: subtype"
    })  # yapf: disable

    @matcher.case
    def its_a_float(x: float):
        return x - 1.1

    @matcher.case
    def superspecial_float_substraction(x: float, y: float, present: str):
        return present.format(x + y)

    @matcher.case
    def only_kwargs(**kwargs: Any):
        return kwargs['x'] + 3

    @matcher.case
    def sum_variadic_only(a: int, b: int, *c: int):
        return sum(c)

    @matcher.case
    def mix(a: str, b: str, *pos: Any, **kw: Any):
        return sum(pos) + sum(kw.values())

    return matcher
Пример #2
0
def test_vmatch_missed_decl() -> None:
    "Should handle unmatched calls if ´Miss` is defined when initialized"
    match = TypeMatcher({Miss: lambda *args, **kwargs: 'default'})
    assert match('lksflkjl', x=1) == 'default'
Пример #3
0
from kingston.match import (matches, match, move, Matcher, TypeMatcher,
                            ValueMatcher, Miss, Mismatch, Conflict)

from kingston.testing import between, diff_ints, same

pytestmark = pytest.mark.wbox


@fixture.params(
    "value, pattern, expected",
    (1, 1, True),
    ('x', 1, False),
    (1.1, 1, False),
    (object(), 1, False),
    (TypeMatcher(), 1, False),
    ((1,2,3), (1,2,3), True),
)  # yapf: disable
def test_match(value, pattern, expected) -> None:
    "Should match_hit"
    assert match(value, pattern) == expected


@fixture.params(
    "value, pattern, expected",
    (int, int, True),
    (int, float, False),
    # (1.0, 5.0, True),
    ((int, ), tuple, True),
    ((float, ), list, False),
    # (int, tuple, False),
Пример #4
0
def empty_matcher():
    return TypeMatcher()
Пример #5
0
Example of a stupid but hopefully thought-provoking expression
builder/evaluator.
"""

from kingston.match import Matcher, TypeMatcher, ValueMatcher
from typing import Any

stupid: Matcher[Any, int] = TypeMatcher({
    int:
    lambda x: x,
    str:
    lambda x: 99999,
    (Any, str, Any):
    ValueMatcher({
        (Any, '+', Any): lambda a, op, b: a + b,
        (Any, '-', Any): lambda a, op, b: a - b,
        (Any, '*', Any): lambda a, op, b: a * b,
        (Any, '/', Any): lambda a, op, b: a / b,
    }),
    (int, int, ...):
    lambda begin, end, *seq: seq[begin:end],
    (int, ...):
    lambda n, *seq: seq[0:n]
    # (Callable, ...): ... # Dr McCarthy, I presume? ;-) -- not supported (yet?)
})

if __name__ == '__main__':
    print(f"Single int -> just an identity op: {stupid(1)} (should be 1)")
    print(
        f"A string -> just an arbitrary recognizable value: {stupid('hello')} (should be 9999)"
    )
    print(f"Addition: stupid(1, '+', 1) == {stupid(1, '+', 1)} (should be 2)")
Пример #6
0
# yapf

import ast
from kingston.match import Matcher, TypeMatcher  # type: ignore[attr-defined]
from kingston.decl import box
from typing import Any, Collection, List, Dict
from types import CodeType, FunctionType, ModuleType
import traceback
from functools import singledispatch

from ormsnack import make, mappings

compiler: Matcher[ast.AST, CodeType] = TypeMatcher()

fix = ast.fix_missing_locations


def autoname(node: ast.AST, idx: int) -> str:
    return f"{node.__class__.__name__}_{idx}"


@compiler.case
def compile_module(module: ast.Module) -> CodeType:
    back, *_ = traceback.extract_stack()
    if any(mappings.countnames(node) == 0 for node in module.body):
        for idx, node in enumerate(module.body):
            if mappings.countnames(node) == 0:
                name = autoname(node, idx)
                assigned = make.make(name, node)
                module.body[idx] = fix(assigned)
Пример #7
0
N = _node_factory


def module(nodes: Collection,
           type_ignores: List = [],
           lineno: int = 0,
           col_offset: int = 0) -> ast.Module:
    "Does module"
    mod = N(ast.Module, body=list(nodes), type_ignores=type_ignores)
    mod.lineno = lineno
    mod.col_offset = col_offset
    return mod


assign: Matcher[Any, ast.Assign] = TypeMatcher()


def arith(Op: ast.AST) -> Callable:
    "Returns a function that generates a basic arithmetic operation"

    def assemble(left: Any, _: Any, right: Any) -> ast.BinOp:
        return ast.BinOp(left=ast.Name(id=left), op=Op(), right=make(right))

    return assemble


def rescue(mystery: Any) -> ast.AST:
    if isinstance(mystery, ast.AST):
        return mystery
    else:
Пример #8
0
def examine(top: ast.AST) -> int:
    """Recur down ``top`` to find if there are nodes that wouldn't be
    findable after exec."""
    if isinstance(top, ast.AST):
        nodec = count_nodes(top)
        print(f'XXX How to count children in {top}???')
        import pdb
        pdb.set_trace()
        return 0
    else:
        raise TypeError(f"Not possible to count names in {top}")


never = lambda: 0
always = lambda: 1

countnames: Matcher[ast.AST, int] = TypeMatcher({
    ast.Lambda: never,
    ast.Assign: always,
    ast.FunctionDef: always,
    ast.BinOp: never,
    ast.Constant: never,
    ast.Module: never,
    Miss: examine
})  # yapf: disable


@countnames.case
def interactive_names(inter: ast.Interactive) -> int:
    return sum([countnames(sub) for sub in inter.body])
Пример #9
0
~~~~~~~~~~~~~~~~~~~~~~~~

Hm.
"""
import ast

from kingston.match import Matcher, TypeMatcher, ValueMatcher

nodeRep: Matcher[ast.AST, str] = TypeMatcher({
    ast.Interactive:
    lambda: '',
    ast.FunctionDef:
    lambda node: f"def {node.name}(",
    ast.arguments:
    (lambda node: ','.join(arg.arg for arg in node.args) + '):\n'),
    ast.BinOp:
    lambda node: '',
    ast.Constant:
    lambda node: str(node.value),
    ast.Return:
    lambda node: '    return ',
    ast.Add:
    lambda: ' + ',
})

topnode = compile("""
def helo():
    return 1 + 1
""", 'examples.ormsnackis', 'single', ast.PyCF_ONLY_AST)


def test(tree):