Пример #1
0
    def __init__(
        self,
        data: Dict[str, Any],
        entry_point_cls: Optional[Dict[str, Callable[..., EntryPoint]]] = None,
        plan_ext: str = ".plan",
    ):
        """Initialize a new plan.

        :param data: a dictionary defining additional globals to push
            into plan associated module
        :param entry_point_cls: dict associating a list of decorator name
            with an entry point class
        :param plan_ext: plan extension, by default ".plan". This is used to
            detect whether a specific frame is in a plan or in our code. See
            PlanContext._add_action
        """
        self.mod = types.ModuleType("_anod_plan_")

        # Some additional user symbols
        for k, v in data.items():
            self.mod.__dict__[k] = v

        self.entry_points: Dict[str, EntryPoint] = {}

        if entry_point_cls is None:
            entry_point_cls = {}

        self.plan_ext = plan_ext

        self.mod.__dict__["machine"] = partial(entry_point, self.entry_points,
                                               Machine, "machine")

        for name, cls in entry_point_cls.items():
            self.mod.__dict__[name] = partial(entry_point, self.entry_points,
                                              cls, name)

        self.plan_date = datetime.now(timezone.utc)
        self.mod.__dict__["cond"] = self.cond
        self.toggleable_bool_group = ToggleableBooleanGroup()
Пример #2
0
def test_toggleable_bools():
    g = ToggleableBooleanGroup()
    for i, v in enumerate((True, True, False, True, False, False)):
        g.add(name="seed{}".format(i), value=v)

    result = []
    result.append([bool(c) for c in g])
    for series in g.shuffle():
        result.append([bool(c) for c in series])
        assert series == list(g)
        assert len(g) == 6

    assert result == [
        [True, True, False, True, False, False],
        [True, True, True, True, True, True],
        [True, True, True, True, True, False],
        [True, True, True, True, False, True],
        [True, True, True, True, False, False],
        [True, True, True, False, True, True],
        [True, True, True, False, True, False],
        [True, True, True, False, False, True],
        [True, True, True, False, False, False],
        [True, True, False, True, True, True],
        [True, True, False, True, True, False],
        [True, True, False, True, False, True],
        [True, True, False, False, True, True],
        [True, True, False, False, True, False],
        [True, True, False, False, False, True],
        [True, True, False, False, False, False],
        [True, False, True, True, True, True],
        [True, False, True, True, True, False],
        [True, False, True, True, False, True],
        [True, False, True, True, False, False],
        [True, False, True, False, True, True],
        [True, False, True, False, True, False],
        [True, False, True, False, False, True],
        [True, False, True, False, False, False],
        [True, False, False, True, True, True],
        [True, False, False, True, True, False],
        [True, False, False, True, False, True],
        [True, False, False, True, False, False],
        [True, False, False, False, True, True],
        [True, False, False, False, True, False],
        [True, False, False, False, False, True],
        [True, False, False, False, False, False],
        [False, True, True, True, True, True],
        [False, True, True, True, True, False],
        [False, True, True, True, False, True],
        [False, True, True, True, False, False],
        [False, True, True, False, True, True],
        [False, True, True, False, True, False],
        [False, True, True, False, False, True],
        [False, True, True, False, False, False],
        [False, True, False, True, True, True],
        [False, True, False, True, True, False],
        [False, True, False, True, False, True],
        [False, True, False, True, False, False],
        [False, True, False, False, True, True],
        [False, True, False, False, True, False],
        [False, True, False, False, False, True],
        [False, True, False, False, False, False],
        [False, False, True, True, True, True],
        [False, False, True, True, True, False],
        [False, False, True, True, False, True],
        [False, False, True, True, False, False],
        [False, False, True, False, True, True],
        [False, False, True, False, True, False],
        [False, False, True, False, False, True],
        [False, False, True, False, False, False],
        [False, False, False, True, True, True],
        [False, False, False, True, True, False],
        [False, False, False, True, False, True],
        [False, False, False, True, False, False],
        [False, False, False, False, True, True],
        [False, False, False, False, True, False],
        [False, False, False, False, False, True],
        [False, False, False, False, False, False],
    ]
Пример #3
0
class Plan:
    """Electrolyt Plan.

    :ivar entry_points: list of entry points found in the plans
    :vartype entry_points: dict
    """
    def __init__(
        self,
        data: Dict[str, Any],
        entry_point_cls: Optional[Dict[str, Callable[..., EntryPoint]]] = None,
        plan_ext: str = ".plan",
    ):
        """Initialize a new plan.

        :param data: a dictionary defining additional globals to push
            into plan associated module
        :param entry_point_cls: dict associating a list of decorator name
            with an entry point class
        :param plan_ext: plan extension, by default ".plan". This is used to
            detect whether a specific frame is in a plan or in our code. See
            PlanContext._add_action
        """
        self.mod = types.ModuleType("_anod_plan_")

        # Some additional user symbols
        for k, v in data.items():
            self.mod.__dict__[k] = v

        self.entry_points: Dict[str, EntryPoint] = {}

        if entry_point_cls is None:
            entry_point_cls = {}

        self.plan_ext = plan_ext

        self.mod.__dict__["machine"] = partial(entry_point, self.entry_points,
                                               Machine, "machine")

        for name, cls in entry_point_cls.items():
            self.mod.__dict__[name] = partial(entry_point, self.entry_points,
                                              cls, name)

        self.plan_date = datetime.now(timezone.utc)
        self.mod.__dict__["cond"] = self.cond
        self.toggleable_bool_group = ToggleableBooleanGroup()

    def cond(self, name: str, date: Callable[[datetime],
                                             bool]) -> ToggleableBoolean:
        """Generate a new conditional boolean.

        :param name: variable name
        :param date: function that takes the plan date and return a boolean.
            This can be used to set a value depending on the day of the week,
            e.g. by setting the constant to True on weekend:
            lambda d: d.isoweekday() in [6, 7]
        """
        return self.toggleable_bool_group.add(name, date(self.plan_date))

    def load(self, filename: str) -> None:
        """Load python code from file.

        :param filename: path to the python code
        """
        with open(filename, "rb") as fd:
            source_code = fd.read()
        self.load_chunk(source_code, filename)

    def check(self, code_ast: ast.AST) -> None:
        """Check plan coding style."""
        del self, code_ast

    def load_chunk(self,
                   source_code: bytes,
                   filename: str = "<unknown>") -> None:
        """Load a chunk of Python code.

        :param source_code: python source code
        :param filename: filename associated with the Python code
        """
        code_ast = ast.parse(source_code, filename)
        self.check(code_ast)
        code = compile(code_ast, filename, "exec")
        exec(code, self.mod.__dict__)