@@ -7,13 +7,17 @@ The core of the implementation is handled by the `pexpect` library. We have a sm
77``` python
88# | id: repl-contextmanager
99# | id: repl-contextmanager
10+ # | id: repl-contextmanager
11+ # | id: repl-contextmanager
12+ # | id: repl-contextmanager
1013def spawn (config : ReplConfig):
14+ env = dict (os.environ) | config.environment
1115 child: pexpect.spawn[str ] = pexpect.spawn(
1216 config.command,
1317 timeout = config.timeout,
1418 echo = False ,
1519 encoding = " utf-8" ,
16- env = config.environment,
20+ env = dict (os.environ) | config.environment,
1721 )
1822 return child
1923
@@ -47,7 +51,7 @@ def repl(config: ReplConfig) -> Generator[Callable[[str], str | None]]:
4751
4852 still_waiting: bool = True
4953 for line in lines:
50- logging.debug(" sending: %s " , line)
54+ logging.debug(" sending: ' %s ' " , line)
5155 _ = child.sendline(line)
5256 logging.debug(" waiting for prompt or continuation" )
5357 _ = child.expect(
@@ -66,7 +70,7 @@ def repl(config: ReplConfig) -> Generator[Callable[[str], str | None]]:
6670
6771 if still_waiting:
6872 logging.debug(f " waiting for last prompt " )
69- # _ = child.sendline("")
73+ _ = child.sendline(" " )
7074 _ = child.expect(prompt)
7175 logging.debug(f " got: %s " , child.before)
7276 if child.before:
@@ -76,7 +80,7 @@ def repl(config: ReplConfig) -> Generator[Callable[[str], str | None]]:
7680 return None
7781
7882 if config.strip_ansi:
79- ansi_escape = re.compile(r " ( \u001b \[ | \x1B\[ ) [0-? ]* [ - \/ ]* [@-~ ]" )
83+ ansi_escape = re.compile(r " ( \u001b | \x1B ) ( \[ [0-? ]* [ - \/ ]* [@-~ ]| [ \>\= ] ) " )
8084 return ansi_escape.sub(" " , answer[- 1 ].strip())
8185
8286 return answer[- 1 ].strip()
@@ -94,7 +98,7 @@ def repl(config: ReplConfig) -> Generator[Callable[[str], str | None]]:
9498 return None
9599
96100 if config.strip_ansi:
97- ansi_escape = re.compile(r " ( \u001b \[ | \x1B\[ ) [0-? ]* [ - \/ ]* [@-~ ]" )
101+ ansi_escape = re.compile(r " ( \u001b | \x1B ) ( \[ [0-? ]* [ - \/ ]* [@-~ ]| [ \>\= ] ) " )
98102 return ansi_escape.sub(" " , answer)
99103
100104 return answer
@@ -109,6 +113,9 @@ We use this to run a session. The session is modified in place.
109113``` python
110114# | id: run-session
111115# | id: run-session
116+ # | id: run-session
117+ # | id: run-session
118+ # | id: run-session
112119def run_session (session : ReplSession):
113120 with repl(session.config) as run:
114121 for cmd in session.commands:
@@ -129,6 +136,9 @@ I/O is handled by `msgspec`.
129136``` python
130137# | id: io
131138# | id: io
139+ # | id: io
140+ # | id: io
141+ # | id: io
132142def read_session (port : IO [str ] = sys.stdin) -> ReplSession:
133143 data: str = port.read()
134144 return msgspec.yaml.decode(data, type = ReplSession)
@@ -146,6 +156,9 @@ def write_session(session: ReplSession, port: IO[str] = sys.stdout):
146156``` python
147157# | id: imports
148158# | id: imports
159+ # | id: imports
160+ # | id: imports
161+ # | id: imports
149162# from datetime import datetime, tzinfo
150163from typing import IO , cast
151164from collections.abc import Generator, Callable
@@ -156,6 +169,7 @@ import uuid
156169import sys
157170import re
158171import logging
172+ import os
159173
160174import pexpect
161175import msgspec
@@ -171,6 +185,9 @@ __version__ = importlib.metadata.version("repl-session")
171185``` python
172186# | file: src/repl_session/__init__.py
173187# | file: src/repl_session/__init__.py
188+ # | file: src/repl_session/__init__.py
189+ # | file: src/repl_session/__init__.py
190+ # | file: src/repl_session/__init__.py
174191"""
175192`repl-session` is a command-line tool to evaluate a given session
176193in any REPL, and store the results.
0 commit comments