예제 #1
0
def test_walk_one__with_recursive2():
    got = _walk(get_walker(Member, recursive=True))
    want = {
        "Team": {"name": str(str), "members": str(t.List[Member])},
        "Member": {"name": str(str), "team": str(Team)},
    }
    assert want == got
예제 #2
0
def test_walk_list():
    got = _walk(get_walker([Team, Member]))
    want = {
        "Team": {"name": str(str), "members": str(t.List[Member])},
        "Member": {"name": str(str), "team": str(Team)},
    }
    assert want == got
예제 #3
0
def emit2(targets, *, resources):
    m = Module(indent="  ")
    w = get_walker([])

    m.stmt('include classpath("application.conf")')
    m.stmt("queues {")
    with m.scope():
        for i, cls in enumerate(targets):
            name = resources[id(cls)]  # xxx:

            m.stmt("{} {{", name)
            with m.scope():
                for name, info, metadata in w.for_type(cls).walk():
                    value = metadata["default"]
                    if value is None:
                        continue
                    if isinstance(value, int):
                        m.stmt("{} = {} seconds", name, value)
                    else:
                        m.stmt("{} = {}", name, to_val(value))
            m.stmt("}")
            if i < len(targets) - 1:
                m.sep()
    m.stmt("}")
    return m
예제 #4
0
def main(mod: ModuleType) -> None:
    def _guess_kind(
        cls: t.Any,
        *,
        _builtins=set(id(v) for v in sys.modules["builtins"].__dict__.values()),
    ) -> t.Optional[Kind]:
        # is module?
        if hasattr(cls, "__loader__"):
            return None

        # is typed user_defined_type class or callable?
        if not hasattr(cls, "__name__"):
            return None

        if id(cls) in _builtins:
            return None
        if not callable(cls):
            return None

        if inspect.isclass(cls):
            return "object"
        return None

    w = runtime.get_walker(
        mod, recursive=True, aggressive=True, _guess_kind=_guess_kind
    )
    m = Module()
    o = sys.stderr if bool(os.environ.get("DEBUG", "")) else sys.stdout
    ctx = Context(w, is_minimum=bool(os.environ.get("MINIMUM", "")))
    print(emit(ctx, m=m), file=o)
예제 #5
0
def walk(classes: t.List[t.Type[t.Any]],
         *,
         _nonetype: t.Type[t.Any] = type(None)) -> t.Iterator[Item]:
    w = runtime.get_walker(classes)
    for cls in w.walk(kinds=["object", None]):
        if (getattr(cls, "__origin__", None) == t.Union
                and _nonetype not in cls.__args__):
            yield Item(type_=cls, fields=[], args=cls.__args__)
            for subtyp in cls.__args__:
                if subtyp.__module__ != "builtins":
                    w.append(subtyp)
            continue

        fields: t.List[Row] = []
        for name, info, _metadata in w.for_type(cls).walk(
                ignore_private=False):
            if name.startswith("_") and name.endswith("_"):
                continue

            filled_metadata: Metadata = metadata()
            filled_metadata.update(_metadata)
            if filled_metadata.get("default") == MISSING:
                filled_metadata.pop("default")
            if info.is_optional:
                filled_metadata["required"] = False

            if info.normalized.__module__ != "builtins":
                w.append(info.normalized)
            if hasattr(info.normalized, "__origin__"):  # list, dict, etc..
                for subtyp in t.get_args(info.normalized):
                    if subtyp.__module__ != "builtins":
                        w.append(subtyp)

            fields.append((name, info, filled_metadata))
        yield Item(type_=cls, fields=fields, args=[])
예제 #6
0
def get_walker(guess_kind: t.Any = None) -> Walker:
    from metashape.runtime import get_walker

    guess_kind = guess_kind or _guess_kind

    return get_walker(aggressive=True,
                      recursive=True,
                      _depth=2,
                      _guess_kind=guess_kind)
예제 #7
0
def test_walk_one__union():
    from metashape.name import NewNamedType

    got = _walk(get_walker(NewNamedType("MemberOrTeam", t.Union[Member, Team])))
    want = {
        "Member": {"name": str(str), "team": str(Team)},
        "Team": {"name": str(str), "members": str(t.List[Member])},
    }
    assert want == got
예제 #8
0
def run(name: str):
    m = import_module(name)
    w = get_walker(m, aggressive=True, recursive=False)

    def _to_str_typeinfo(info: typeinfo.TypeInfo) -> str:
        """
        >>> _to_str_typeinfo(str)
        'str'

        >>> _to_str_typeinfo(Literal["x", "y", "z"])
        ' `x, y, z` '

        >>> Color = Literal["Red", "Green", "Blue"]
        >>> _to_str_typeinfo(Color)
        '[Color](#Color)'
        """
        if info.underlying != info.type_:  # enum
            name = w.resolver.resolve_typename(info.type_)
            if name != "_GenericAlias":
                return f"[{name}](#{name})"
            args = [str(x) for x in typing.get_args(info.type_)]
            return f" `{', '.join(args)}` "

        name = info.underlying.__name__
        if not info.user_defined_type:
            return name
        return f"[{name}](#{name})"

    for cls in w.walk(kinds=["object", "enum"]):
        print("")
        print(f"## {cls.__name__}")

        kind = guess_mark(cls)  # todo: use resolve
        if kind == "enum":
            print("")
            print("```")
            args = typing.get_args(cls)
            print(f"   {args[0]}")
            for x in args[1:]:
                print(f" | {x}")
            print("```")
            print("")
        else:
            doc = w.resolver.metadata.resolve_doc(cls, verbose=True)
            if doc is not None:
                print("")
                print(doc)

            print("")
            print("| name | type | description |")
            print("| :--- | :--- | :--- |")
            for name, info, metadata in w.walk_fields(cls):
                print(
                    f"| {name} | {typeinfo.to_string(info, to_str=_to_str_typeinfo)} | {metadata.get('description') or ''}|"
                )
예제 #9
0
def walk(classes: t.List[t.Type[t.Any]]) -> t.Iterator[Item]:
    w = runtime.get_walker(classes)
    for cls in w.walk(kinds=["object", None]):
        fields: t.List[Row] = []
        for name, typeinfo, metadata in w.for_type(cls).walk():
            if metadata is None:
                metadata = {}
            if typeinfo.normalized.__module__ != "builtins":
                w.append(typeinfo.normalized)
            fields.append((name, typeinfo, metadata))
        yield Item(cls=cls, fields=fields)
예제 #10
0
def run(
    filename: str,
    *,
    aggressive: bool = False,
    is_member: t.Optional[t.Callable[[t.Type[T]], bool]] = None,
    emit: t.Optional[EmitFunc] = None,
) -> None:
    m = import_module(filename, cwd=True)
    walker = get_walker(m, aggressive=aggressive)
    emit = emit or import_symbol("metashape.outputs.raw:emit")  # xxx:
    logger.debug("collect members: %d", len(walker))
    emit(walker, output=sys.stdout)
예제 #11
0
def run(dst: str):
    w = get_walker(aggressive=True, here=__name__)

    with output(dst,
                use_console=True,
                verbose=True,
                opener=partial(Module, indent="\t")) as fs:
        for cls in w.walk():
            with fs.open(f"{snakecase(cls.__name__)}.go", "w") as m:
                ctx = Context(package="gen", w=w, m=m)
                emit_package_clause(ctx)
                m.sep()
                emit_simple_type_definition(ctx, cls)
예제 #12
0
def emit(items: t.Iterator[Item], *, name: str) -> Module:
    from metashape.runtime import get_walker

    m = Module(indent="  ")
    m.stmt('syntax = "proto3";')
    m.sep()
    m.stmt(f"package {name};")
    m.sep()
    m._import_area

    items = list(items)
    w = get_walker([])

    classes: t.Dict[t.Type[t.Any], Item] = {}
    aliases: t.Dict[t.Any, Symbol] = {}
    for item in items:
        if item.kind in ("object", "enum", "service"):
            classes[item.type_] = item
            w.append(item.type_)

        if hasattr(item.type_, "PROTO_PACKAGE"):
            prefix = m.import_(item.type_.PROTO_PACKAGE)
            aliases[item.type_] = getattr(prefix, item.name)
        else:
            aliases[item.type_] = m.symbol(item.name)

    resolver = TypeResolver(m, aliases=aliases)

    for cls in w.walk(kinds=["object", None]):
        if hasattr(cls, "PROTO_PACKAGE"):
            continue

        item = classes[cls]
        if item.kind == "object":
            emit_class(m, item, w=w, resolver=resolver)
        elif item.kind == "enum":
            emit_enum(m, item, w=w, resolver=resolver)
        elif item.kind == "service":
            emit_service(m, item, w=w, resolver=resolver)
        m.sep()

    for item in items:
        if item.kind == "list":
            emit_list(m, item, w=w, resolver=resolver)
    return m
예제 #13
0
def emit(targets, *, resources):
    m = Module(indent="  ")
    w = get_walker([])

    for i, cls in enumerate(targets):
        name = resources[id(cls)]  # xxx:

        m.stmt("resource {} {} {{", to_val(get_name(cls)), to_val(name))
        with m.scope():
            for name, info, metadata in w.for_type(cls).walk():
                value = metadata["default"]
                if value is None:
                    continue
                m.stmt("{} = {}", name, to_val(value))
        m.stmt("}")
        if i < len(targets) - 1:
            m.sep()
    return m
예제 #14
0
def run(dst: str):
    import sys

    m = sys.modules[__name__]
    w = get_walker(m, aggressive=True)

    with output(dst,
                use_console=True,
                verbose=True,
                opener=partial(Module, indent="\t")) as fs:
        for cls in w.walk():
            if issubclass(cls, Context):
                continue

            with fs.open(f"{snakecase(cls.__name__)}.go", "w") as m:
                ctx = Context(package="gen", w=w, m=m)
                emit_package_clause(ctx)
                m.sep()
                emit_simple_type_definition(ctx, cls)
예제 #15
0
from metashape.declarative import mark
from metashape.runtime import get_walker
from metashape.outputs.openapi import codegen


@mark
class Person:
    name: str
    age: int
    extra: "Extra"


@mark
class Extra:
    memo: str


# main
codegen(get_walker([Person]))
예제 #16
0
from __future__ import annotations
import typing as t
from metashape.declarative import shape
from metashape import runtime


@shape
class Person:
    name: str
    age: int
    father: t.Optional[Person]
    mother: t.Optional[Person]


w = runtime.get_walker(Person)
assert [Person] == list(w.walk())
예제 #17
0
import dataclasses
from metashape.declarative import ignore, field


@ignore
@dataclasses.dataclass
class Service:
    name: str
    outdated: bool = False


class XXXServices:
    foo: Service = field(default=Service(name="foo"))
    bar: Service = field(default=Service(name="bar"))
    boo: Service = field(default=Service(name="boo"))


if __name__ == "__main__":
    from metashape.runtime import get_walker

    for cls in get_walker(aggressive=True).walk():
        print(cls)
예제 #18
0
from metashape.runtime import graph, get_walker

g = graph(get_walker(aggressive=True))

g.User.deps  # => {"tweets": Tweet, "favorites": Tweet}
g.User.rdeps  # => {Twitter: {"author": "tweets", "favorited": "favorites"}}
예제 #19
0

# self references
class Person:
    name: str
    spouse: t.Optional[Person]  # reverse: spouse,  synmetric one-to-one
    friends: t.Set[Person]  # reverse: friends, synmetric many-to-many
    manager: t.Optional[Person]  # reverse: employees, one side of non-synmetric
    employees: t.Set[Person]  # reverse: manager, another side of non-synmetric


# multiple relationships between two entities
class User:
    name: str
    tweets: t.Set[Tweet]  # reverse: author
    favorites: t.Set[Tweet]  # reverse: favorited


class Tweet:
    text: str
    author: User  # reverse tweets
    favorited: t.Set[User]  # reverse favorites


import sys
from metashape.runtime import get_walker
from metashape.outputs.openapi import emit

w = get_walker([User, Person], aggressive=True, recursive=True)
emit(w, output=sys.stdout)
예제 #20
0
def test_walk_one__container():
    got = _walk(get_walker(t.List[Member]))
    want = {
        "Member": {"name": str(str), "team": str(Team)},
    }
    assert want == got
예제 #21
0
import typing as t
from metashape.runtime import get_walker
from prestring.python import Module
from prestring.utils import LazyFormat, LazyArgumentsAndKeywords
from typestr import typestr


class Hello:
    name: str
    age: int
    nickname: t.Optional[str] = None


m = Module()
w = get_walker([Hello])
for cls in w.walk():
    name = w.resolver.resolve_typename(cls)
    args = []
    for fieldname, info, metadata in w.for_type(cls).walk():
        # todo: default
        if "default" in metadata:
            args.append(
                LazyFormat(
                    "{}: {} = {}", fieldname, typestr(info.raw), metadata["default"]
                )
            )
        else:
            args.append(LazyFormat("{}: {}", fieldname, typestr(info.raw)))

    with m.def_(name, LazyArgumentsAndKeywords(args)):
        m.stmt("...")
예제 #22
0
import typing as t
from common import User


class WUser(User):
    nickname: t.Optional[str] = None


def get_module(typ: t.Type[t.Any]) -> str:
    return getattr(typ, "__module__")


assert get_module(User) == "common"
assert get_module(WUser) == "__main__"

# accessing
from metashape.runtime import get_walker  # noqa 401

w = get_walker([WUser])
for cls in w.walk():
    for name, info, metadata in w.for_type(cls).walk():
        print(name, metadata)
예제 #23
0
def get_walker(classes: t.List[t.Type[t.Any]]) -> Walker:
    from metashape.runtime import get_walker
    from metashape.analyze.config import Config

    return get_walker(classes,
                      config=Config(option=Config.Option(strict=False)))
예제 #24
0
from metashape import runtime


class Person:
    name: str
    age: int


w = runtime.get_walker([Person])
for cls in w.walk():
    print(cls)
    for name, typeinfo, metadata in w.walk_fields(cls):
        print("\t", name, typeinfo.raw, metadata)
예제 #25
0
def test_walk_one():
    got = _walk(get_walker(Team))
    want = {"Team": {"name": str(str), "members": str(t.List[Member])}}
    assert want == got
예제 #26
0
from __future__ import annotations
import typing as t
import sys
from metashape.runtime import get_walker
from metashape.outputs.openapi import emit


class Team:
    name: str
    members: t.List[Person]


class Person:
    team: Team
    name: str
    age: int
    nickname: t.Optional[str]
    parents: t.List[Person]


emit(get_walker(aggressive=True), output=sys.stdout)
예제 #27
0
import typing as t
import sys
import string
from metashape.runtime import get_walker
from metashape.outputs.openapi import scan, emit


class Person:
    name: str
    age: int


ctx = scan(get_walker(aggressive=True))


class _Formatter(string.Formatter):
    def __init__(self):
        self.d = {}

    def get_value(self, key: str, args: list, kwargs: dict) -> object:
        self.d[key] = key
        return self.d[key]


def extract_parameters(f, fmt_string) -> t.List[str]:
    f.format(fmt_string)
    r = list(f.d.keys())
    f.d.clear()
    return r

예제 #28
0
    primary_number: str
    state_abbreviation: str
    street_name: str
    street_predirection: str
    street_suffix: str
    zipcode: str


class Metadatum:
    carrier_route: str
    congressional_district: str
    county_fips: str
    county_name: str
    dst: bool
    elot_sequence: str
    elot_sort: str
    latitude: float
    longitude: float
    precision: str
    rdi: str
    record_type: str
    time_zone: str
    utc_offset: int
    zip_type: str


w = get_walker(Data, aggressive=True, recursive=True)
targets = list(w.walk())
for cls in targets:
    print(cls)
예제 #29
0
class Person:
    name: str = "foo"
    age: int = 20


from metashape.runtime import get_walker
from prestring.naming import untitleize

d = {}
w = get_walker(aggressive=True)
for cls in w.walk():
    props = {}
    for name, _, _ in w.for_type(cls).walk():
        #  camelCase?
        props[name] = getattr(cls, name)

    typename = w.resolver.resolve_typename(cls)
    d[untitleize(typename)] = props

from dictknife import loading

loading.dumpfile(d, format="yaml")
예제 #30
0
from __future__ import annotations
import typing as t
import conf
from metashape.runtime import get_walker
from metashape.analyze.walker import Walker
from metashape.analyze.collector import Collector
from dictknife import loading


@Collector
def collect(cls: t.Type[t.Any], *, w: t.Optional[Walker]):
    props = {}
    for name, typeinfo, metadata in w.for_type(cls).walk():
        fieldname = w.resolver.metadata.resolve_name(metadata, default=name)
        props[fieldname] = collect(getattr(cls, name), w=w)
    return props


w = get_walker(conf.Toplevel)
for cls in w.walk():
    loading.dumpfile(collect(cls, w=w))