Quantcast
Channel: AFPy's Planet
Viewing all articles
Browse latest Browse all 3786

Un gestionnaire de contexte libéré, (délivré, …)

$
0
0

@entwanne, @debnet et moi jouons avec les gestionnaires de contextes ces temps-ci, ça m’a permis de faire ça par exemple : mdk/forking - La forge de l'AFPy

Le jeu du jour et d’aller plus loin dans la libération des gestionnaires de contextes, et je commence à toucher quelque chose, probablement encore un peu fragile, à peine testé, mais ça commence à marcher :

import ast
import inspect
import sys
import textwrap


class Stop(Exception):
    """Internal exception to block the execution of the context body."""


class With:
    def tracer_cb(self, frame, event, arg):
        if frame is self.frame and event == "opcode":
            raise Stop

    def __enter__(self):
        current_frame = inspect.currentframe()
        self.frame = current_frame.f_back
        self.frame.f_trace = self.tracer_cb
        self.frame.f_trace_opcodes = True
        sys.settrace(self.tracer_cb)

    def execute(self, body):
        """Do whatever with the body of the with statement."""
        raise NotImplementedError

    def _locate_with_body(self, tree, lineno):
        """Locate the with statement, in tree, at lineno."""
        for node in ast.walk(tree):
            try:
                node_lineno = node.lineno
            except AttributeError:
                continue
            if node_lineno == lineno:
                return node.body

    def __exit__(self, exc_type, exc, tb):
        frame = tb.tb_frame
        src = textwrap.dedent(inspect.getsource(tb.tb_frame))
        tree = ast.parse(src)
        module = ast.Module(body=self._locate_with_body(tree, tb.tb_frame.f_lineno))
        compiled = compile(module, filename="", mode="exec")
        Function = type(Repeat.__enter__)
        self.execute(Function(compiled, frame.f_globals, name=""))
        return True


class Repeat(With):
    def __init__(self, times):
        self.times = times

    def execute(self, body):
        for _ in range(self.times):
            body()



with Repeat(4):
    print(42)

2 messages - 2 participant(e)s

Lire le sujet en entier


Viewing all articles
Browse latest Browse all 3786

Trending Articles