pythonimmediate.multiengine module
- class pythonimmediate.multiengine.MultiChildProcessEngine(engine_name: Literal['pdftex', 'xetex', 'luatex'], count: int = 2, *args: Any, **kwargs: Any)[source]
Bases:
EngineAn engine that can be used to run multiple identical child processes. This is useful for terminating one in order to observe its output.
Warning
There must be no randomization in the child process.
Example:
>>> from pythonimmediate.util import pdftotext >>> from pythonimmediate import execute, default_engine >>> with MultiChildProcessEngine("pdftex", 2) as engine, default_engine.set_engine(engine): ... execute(r"\documentclass{article} \pagenumbering{gobble} \begin{document} \begin{center} Hello") ... with engine.extract_one() as child1: ... execute(r"\end{center} \end{document}", expecting_exit=True) # only execute on child1 ... output1=child1.read_output_file() ... execute(r"world") ... with engine.extract_one() as child2: ... execute(r"\end{center} \end{document}", expecting_exit=True) ... output2=child2.read_output_file() >>> pdftotext(output1, ["-nopgbrk"]).strip() b'Hello' >>> pdftotext(output2, ["-nopgbrk"]).strip() b'Hello world'
Basically you need to:
Start an engine. See explanation of parameters below.
Note that it is mandatory to call
__enter__().Execute commands on the engine.
In other to observe the output, use
extract_one().
Warning
This is not thread-safe.
- Parameters
count – the number of child processes to start by at initialization. You can start more or less later with
start_child_process()andextract_one().args – arguments to pass to the child process constructor. Refer to
ChildProcessEngine.
- extract_one(do_replace: bool = True) Generator[ChildProcessEngine, None, None][source]
Extract one child process from the engine. See
MultiChildProcessEnginefor an example.- Parameters
do_replace – whether to replace the extracted child process with a new one.
- transient_context() Generator[None, None, None][source]
A context that can be used to mark the code being executed as transient.
This is useful to reduce overhead of restarting the engine when the code does not mutate the state of the engine.
The actual explanation is a bit complicated, and depends on the implementation detail. When a child process is restarted, everything is replayed from the beginning.
In addition, in an transient context, only the first child process is used.
>>> from pythonimmediate import T, execute, default_engine >>> with MultiChildProcessEngine("pdftex", 2) as engine, default_engine.set_engine(engine): ... T.l_tmpa_tl.str("Hello world") # mutates the state, cannot be put in transient context ... with engine.transient_context(): ... with engine.transient_context(): ... T.l_tmpa_tl.str() # does not mutate the state, can be put in transient context 'Hello world' 'Hello world'
As seen above, this context manager can be nested as well.