示例#1
0
    def test_cell_new(self):
        cell_obj = types.CellType(1)
        self.assertEqual(cell_obj.cell_contents, 1)

        cell_obj = types.CellType()
        msg = "shouldn't be able to read an empty cell"
        with self.assertRaises(ValueError, msg=msg):
            cell_obj.cell_contents
示例#2
0
    def _function_getnewargs(self, func):
        code = func.__code__

        # base_globals represents the future global namespace of func at
        # unpickling time. Looking it up and storing it in
        # CloudpiPickler.globals_ref allow functions sharing the same globals
        # at pickling time to also share them once unpickled, at one condition:
        # since globals_ref is an attribute of a CloudPickler instance, and
        # that a new CloudPickler is created each time pickle.dump or
        # pickle.dumps is called, functions also need to be saved within the
        # same invocation of cloudpickle.dump/cloudpickle.dumps (for example:
        # cloudpickle.dumps([f1, f2])). There is no such limitation when using
        # CloudPickler.dump, as long as the multiple invocations are bound to
        # the same CloudPickler.
        base_globals = self.globals_ref.setdefault(id(func.__globals__), {})

        if base_globals == {}:
            # Add module attributes used to resolve relative imports
            # instructions inside func.
            for k in ["__package__", "__name__", "__path__", "__file__"]:
                if k in func.__globals__:
                    base_globals[k] = func.__globals__[k]

        # Do not bind the free variables before the function is created to
        # avoid infinite recursion.
        if func.__closure__ is None:
            closure = None
        else:
            closure = tuple(
                types.CellType() for _ in range(len(code.co_freevars)))

        return code, base_globals, None, None, closure
示例#3
0
def _populate_empty_object(cls, obj, dct):
    if cls is list:
        return obj.extend(_load_object(obj) for obj in dct["__value__"])
    if cls is tuple:
        return tuple(_load_object(obj) for obj in dct["__value__"])
    if cls is memoryview:
        return memoryview(_load_object(dct["__value__"]))
    if cls is set:
        return obj.update(_load_object(obj) for obj in dct["__value__"])
    if cls is frozenset:
        return frozenset(_load_object(obj) for obj in dct["__value__"])
    if cls is dict:
        return _load_dict(obj, dct)
    if cls is types.MappingProxyType:
        return _load_mapping(dct)
    if cls is types.MethodType:
        return types.MethodType(
            _load_object(dct["__func__"]),
            _load_object(dct["__self__"]),
        )
    if cls is types.FunctionType:
        return _load_func(dct)
    if cls is types.CellType:
        return types.CellType(_load_object(dct["__value__"]))
    if cls is types.ModuleType:
        return import_module(dct["__name__"])

    return None
示例#4
0
    def __deepcopy__(self, clone_from_id):
        cls = self.__class__
        result = cls.__new__(cls)
        clone_from_id[id(self)] = result
        for k, v in self.__dict__.items():
            if k in ["renderer", "time_progression"]:
                continue
            if k == "camera_class":
                setattr(result, k, v)
            setattr(result, k, copy.deepcopy(v, clone_from_id))
        result.mobject_updater_lists = []

        # Update updaters
        for mobject in self.mobjects:
            cloned_updaters = []
            for updater in mobject.updaters:
                # Make the cloned updater use the cloned Mobjects as free variables
                # rather than the original ones. Analyzing function bytecode with the
                # dis module will help in understanding this.
                # https://docs.python.org/3/library/dis.html
                # TODO: Do the same for function calls recursively.
                free_variable_map = inspect.getclosurevars(updater).nonlocals
                cloned_co_freevars = []
                cloned_closure = []
                for i, free_variable_name in enumerate(
                        updater.__code__.co_freevars):
                    free_variable_value = free_variable_map[free_variable_name]

                    # If the referenced variable has not been cloned, raise.
                    if id(free_variable_value) not in clone_from_id:
                        raise Exception(
                            f"{free_variable_name} is referenced from an updater "
                            "but is not an attribute of the Scene, which isn't "
                            "allowed.")

                    # Add the cloned object's name to the free variable list.
                    cloned_co_freevars.append(free_variable_name)

                    # Add a cell containing the cloned object's reference to the
                    # closure list.
                    cloned_closure.append(
                        types.CellType(clone_from_id[id(free_variable_value)]))

                cloned_updater = types.FunctionType(
                    updater.__code__.replace(
                        co_freevars=tuple(cloned_co_freevars)),
                    updater.__globals__,
                    updater.__name__,
                    updater.__defaults__,
                    tuple(cloned_closure),
                )
                cloned_updaters.append(cloned_updater)
            mobject_clone = clone_from_id[id(mobject)]
            mobject_clone.updaters = cloned_updaters
            if len(cloned_updaters) > 0:
                result.mobject_updater_lists.append(
                    (mobject_clone, cloned_updaters))
        return result
示例#5
0
def get_global_references_from_nested_code(code, global_scope, global_refs):
    for constant in code.co_consts:
        if inspect.iscode(constant):
            closure = tuple(
                types.CellType(None) for _ in range(len(constant.co_freevars)))
            dummy_function = types.FunctionType(constant,
                                                global_scope,
                                                'dummy_function',
                                                closure=closure)
            global_refs.update(inspect.getclosurevars(dummy_function).globals)
            get_global_references_from_nested_code(constant, global_scope,
                                                   global_refs)
示例#6
0
    def __deepcopy__(self, memo):
        cls = self.__class__
        result = cls.__new__(cls)
        memo[id(self)] = result
        for k, v in self.__dict__.items():
            if type(v) in [FrameServer, Event, Camera]:
                continue
            setattr(result, k, copy.deepcopy(v, memo))

        # Update updaters
        for mobject in self.mobjects:
            cloned_updaters = []
            for updater in mobject.updaters:
                # Make the cloned updater use the cloned Mobjects as free variables
                # rather than the original ones.
                # TODO: The the same for function calls recursively.
                free_variable_map = inspect.getclosurevars(updater).nonlocals
                cloned_co_freevars = []
                cloned_closure = []
                for i, free_variable_name in enumerate(
                        updater.__code__.co_freevars):
                    free_variable_value = free_variable_map[free_variable_name]
                    if isinstance(free_variable_value, Mobject):
                        random_name = get_random_name(free_variable_map)

                        # Put the cloned Mobject in the function's scope.
                        free_variable_map[random_name] = memo[id(
                            free_variable_value)]

                        # Add the cloned Mobject's name to the free variable list.
                        cloned_co_freevars.append(random_name)

                        # Add a cell containing the cloned Mobject's reference to the
                        # closure list.
                        cloned_closure.append(
                            types.CellType(memo[id(free_variable_value)]))
                    else:
                        cloned_co_freevars.append(free_variable_name)
                        cloned_closure.append(updater.__closure__[i])

                cloned_updater = types.FunctionType(
                    updater.__code__.replace(
                        co_freevars=tuple(cloned_co_freevars)),
                    updater.__globals__,
                    updater.__name__,
                    updater.__defaults__,
                    tuple(cloned_closure),
                )
                cloned_updaters.append(cloned_updater)
            memo[id(mobject)].updaters = cloned_updaters
        return result
示例#7
0
def cell_unpickle():
    return types.CellType(None)
示例#8
0
def dict_to_cell(obj):
    return types.CellType(obj)
示例#9
0
    lambda dct: memoryview(load_obj(dct["__value__"])),
    set:
    lambda dct: set(dct["__value__"]),
    frozenset:
    lambda dct: frozenset(dct["__value__"]),
    dict:
    load_dict,
    types.MappingProxyType:
    lambda dct: types.MappingProxyType(load_dict(dct)),
    types.FunctionType:
    load_func,
    types.CodeType:
    lambda dct: types.CodeType(*(load_obj(dct[key])
                                 for key in code_attributes)),
    types.CellType:
    lambda dct: types.CellType(load_obj(dct["__value__"])),
    types.ModuleType:
    lambda dct: import_module(dct["__name__"]),
}


def load_obj(obj2load):
    if type(obj2load) is list:
        return tuple(load_obj(element) for element in obj2load)

    if not type(obj2load) is dict:
        return obj2load

    tmp_obj, is_loaded = load_id_data(obj2load["__id__"])
    if is_loaded:
        return tmp_obj
示例#10
0
    def build(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
        bound_arguments = signature.bind(*args, **kwargs)
        bound_arguments.apply_defaults()

        global_dict: typing.Dict[str, typing.Any] = {
            # supported queries:
            #     with ... select ...
            #     select ...
            #     insert into ... select ...
            #     create table ... engine = ... as select ...
            #     create view ... as select ...
            #     create materialized view ... as select ...
            'with_':
            ast.Initial('with'),
            'select':
            ast.Initial('select'),
            'select_distinct':
            ast.Initial('select_distinct'),
            'insert':
            ast.Initial('insert'),
            'insert_into':
            ast.Initial('insert_into'),
            'create':
            ast.Initial('create'),
            'create_table':
            ast.Initial('create_table'),
            'create_table_if_not_exists':
            ast.Initial('create_table_if_not_exists'),
            'create_view':
            ast.Initial('create_view'),
            'create_or_replace_view':
            ast.Initial('create_or_replace_view'),
            'create_view_if_not_exists':
            ast.Initial('create_view_if_not_exists'),
            'create_materialized_view':
            ast.Initial('create_materialized_view'),
            'create_materialized_view_if_not_exists':
            ast.Initial('create_materialized_view_if_not_exists'),
        }

        local_dict: typing.Dict[str, typing.Any] = {
            **bound_arguments.arguments,
        }

        # TODO: use types.CellType in type annotation
        cells: typing.Tuple[typing.Any, ...] = (
            *(function.__closure__ or ()),
            *(
                types.CellType()  # type: ignore[attr-defined]
                for _ in function.__code__.co_cellvars or ()),
        )

        stack: typing.List[typing.Any] = []

        # notice: see dis.opmap
        for instruction in instructions:
            done = _run(global_dict, local_dict, cells, stack,
                        instruction.opname, instruction.arg,
                        instruction.argval)

            if done:
                assert len(stack) == 1

                return stack.pop()

        return None
示例#11
0
文件: scheme.py 项目: techieji/Lisp
import re, copy, types, forbiddenfruit

env = types.CellType({})
def copyswitch(prenv): env.cell_contents = prenv
def dummy(*args, **kwargs): return args[kwargs["i"]]
def rmap(fn, i, t=tuple): yield from [t(rmap(fn, x)) if type(x) == t else fn(x) for x in i]
def define(i): env.cell_contents[i[0]] = i[1]
def safe(fn, *args, **kwargs):
    try: return fn(*args)
    except: return kwargs["default"]

def binit(self, bname): self.name, self.exists = bname, True
def bcall(self, *args): return (self,) + tuple(args)
bvar = type("bvar", (), {"__init__": binit, "__repr__": lambda self: f"<bound variable '{self.name}'>", "__call__": bcall})
fns = (lambda d: dict(map(lambda tup: (tup[0], lambda i: (ans if any(map(lambda x: hasattr(x, "exists"), (ans := (tup[0],) + i))) else tup[1](i))), d.items())))({'+': sum, '-': lambda i: i[0] - sum(i[1:]), "if": lambda i: i[1] if i[0] else i[2], "define": define, "string": lambda i: " ".join(i), "display": lambda i: print(i[0], end=""), "run": lambda c: [k for x in c if (k := (lambda i: tuple(map(lambda x: dummy((prenv := env.cell_contents), copyswitch(copy.copy(prenv)), runln(x), copyswitch(prenv), i=2), i[1:])).sc(runln(i[0])) if type(i) == tuple else (env.cell_contents[i] if i in env.cell_contents else safe(lambda: eval(i, {}, {}), default=i)))(x)) != None], "lambda": lambda i: lambda reals: fns["run"](tuple(rmap(lambda a: dict(zip(i[0], reals)).get(a, a), i[1:])))})
parse = lambda t: t.regex(r'".*"', lambda x: f"(string {x.group(0)[1:-1]})").regex(r"\s", lambda x: " ").regex(r"[^\(\) ]+", lambda x: f"'{x.group(0)}',").regex(r"\)+", lambda x: x.group(0) + ",")[:-1].run()
runln = lambda i: tuple(map(lambda x: dummy((prenv := env.cell_contents), copyswitch(copy.copy(prenv)), runln(x), copyswitch(prenv), i=2), i[1:])).sc(runln(i[0])) if type(i) == tuple else (env.cell_contents[i] if i in env.cell_contents else (fns[i] if i in fns else safe(lambda: eval(i, {}, {}), default=i)))
run = lambda c: [k for x in c if (k := runln(x)) != None]
def expose(): globals().update(env.cell_contents)
forbiddenfruit.curse(str, "regex", lambda x, y, z: re.sub(y, z, x))
forbiddenfruit.curse(str, "run", lambda self: eval("(" + self + ",)"))
forbiddenfruit.curse(tuple, "sc", lambda self, i: safe(lambda: (ans if (ans := env.cell_contents.get(i)) else (ans if (ans := fns.get(i)) else bvar(i))(self)), default=(i,) + self))


# code = '(display ((lambda (x) (+ x 1)) 1))\n(newline)\n(display "That was it!")'
code = '(define inc (lambda (x) (+ x 1)))'
print(run(parse(code)))
expose()
print(run(inc((5,))))