Skip to content

Commit 451e2e7

Browse files
awesomebytesclaude
andcommitted
Merge hook UX rework + re-measured demo + subscription-cache wiring
Owner-directed fixes: module/CLI renamed autoaccel->hook (python -m rclcppyy.hook); ONE env var (RCLCPPYY_ENABLE_HOOK=1 on, unset/0 off; DISABLE flag deleted); README table headers rclpy/rclcppyy; dev-history paragraph deleted; "Honest boundary" retitled factually; redundant section cut. rmem_max verdict: the sysctl was necessary and sufficient — 3 MB BEST_EFFORT now works at CycloneDDS defaults. Showcase re-measured big+fast: delivered rates match wherever the publisher can feed; CPU differs 2.6-3.1x (rclpy crosses a full core at 200-250 Hz @3 MB vs ~1/3 core). node.py now uses rclcpp_kit's per-type subscription cache (per-UUID cppdef gone): warm CLI start 7.0->4.2 s (supervisor-reproduced 4.22 s; stock 1.72 s; residual = uncached bringup discovery/adapters, identified as the next lever). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 parents ede8480 + e04f936 commit 451e2e7

7 files changed

Lines changed: 251 additions & 243 deletions

File tree

README.md

Lines changed: 77 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -238,116 +238,101 @@ the stock `ros2 topic hz` (and other rclpy-based verbs) runs on the C++ backend
238238
**zero code changes**:
239239

240240
```bash
241-
python -m rclcppyy.autoaccel install # once per environment (uninstall/status too)
241+
python -m rclcppyy.hook install # once per environment (uninstall/status too)
242242

243-
RCLCPPYY_ENABLE_HOOK=1 ros2 topic hz /some_topic # accelerated: rclcpp executor under the hood
243+
RCLCPPYY_ENABLE_HOOK=1 ros2 topic hz /some_topic # runs on the rclcpp backend
244244
ros2 topic hz /some_topic # env var unset -> ordinary rclpy, untouched
245245
```
246246

247-
Two environment variables gate it, side by side:
248-
249-
| Variable | Effect |
250-
|---|---|
251-
| `RCLCPPYY_ENABLE_HOOK=1` | turn the hook on for this process (unset = off) |
252-
| `RCLCPPYY_DISABLE_HOOK=1` | force it off even if `RCLCPPYY_ENABLE_HOOK=1` — the opt-out wins |
253-
254-
Mechanically, `install` writes a site-packages `.pth` (modelled on cppyy_kit's
255-
auto-PCH bootstrap: guarded, never-raising, silent and near-zero-cost when the env
256-
var is unset, `RCLCPPYY_DISABLE_HOOK=1` opt-out, fully uninstallable). At interpreter
257-
start the `.pth` registers a post-import hook on `rclpy`; the first `import rclpy`
258-
then triggers `enable_cpp_acceleration()` — after rclpy is importable but before the
259-
tool builds its node.
260-
261-
Making `ros2 topic hz` work took one addition to the accelerator: it drives its own
262-
loop with `rclpy.spin_once` (both in ros2cli's `DirectNode` discovery loop and the
263-
hz loop), which the stock rclpy executor cannot use to service rclcpp-backed
264-
entities — so `enable_cpp_acceleration()` now also patches `rclpy.spin_once` to
265-
drive an rclcpp executor. Without that the CLI hangs at node bring-up.
266-
267-
**What acceleration buys `ros2 topic hz`, measured** (stock `ros2 topic hz` vs the
268-
same binary under `RCLCPPYY_ENABLE_HOOK=1`, against a C++ publisher of a 256×256 `Image`
269-
≈ 0.19 MB, RELIABLE, `--window 100`; `pixi run -e heavydemo demo-topic-hz-cli`;
270-
absolute numbers vary by machine/run):
271-
272-
| target Hz | publisher Hz | reported Hz (both) | stock CPU % | RCLCPPYY_ENABLE_HOOK CPU % | CPU ratio |
247+
`RCLCPPYY_ENABLE_HOOK` is the single control: `RCLCPPYY_ENABLE_HOOK=1` turns the
248+
hook on for a process; unset, `0`, or any other value leaves it off. `install`
249+
writes a `.pth` into the environment's site-packages that runs at every interpreter
250+
start; when the hook is off it is a near-zero-cost no-op, and `python -m
251+
rclcppyy.hook uninstall` removes it.
252+
253+
At interpreter start the `.pth` registers a post-import hook on `rclpy`; the first
254+
`import rclpy` triggers `enable_cpp_acceleration()`, after rclpy is importable but
255+
before the tool builds its node. `ros2 topic hz` drives its loop with
256+
`rclpy.spin_once` (in ros2cli's `DirectNode` discovery loop and in the hz loop), so
257+
`enable_cpp_acceleration()` also patches `rclpy.spin_once` to run an rclcpp executor;
258+
otherwise the CLI would stall at node bring-up.
259+
260+
**Measured** (stock `ros2 topic hz` vs the same binary under
261+
`RCLCPPYY_ENABLE_HOOK=1`, against a C++ publisher of a `sensor_msgs/Image`,
262+
BEST_EFFORT, `--window 100`, with `net.core.rmem_max` raised (see below);
263+
`pixi run -e heavydemo demo-topic-hz-cli`; numbers vary by machine and run):
264+
265+
| payload | target Hz | rclpy Hz | rclcppyy Hz | rclpy CPU % | rclcppyy CPU % |
273266
|---|---|---|---|---|---|
274-
| 50 | 50.0 | 50.0 | 1.6 | 1.4 | 1.1× |
275-
| 100 | 100.0 | 100.0 | 3.8 | 2.1 | 1.8× |
276-
| 200 | 200.0 | 200.0 | 6.3 | 2.7 | 2.3× |
277-
| 500 | 500.0 | 500.0 | 11.7 | 6.3 | 1.9× |
278-
| 700 | 700.0 | ~690 | 22.0 | 16.6 | 1.3× |
279-
280-
Both report the true rate; the win is **CPU**: acceleration runs the same hz on
281-
roughly **half to a third** less CPU at moderate rates. The win is narrower than for
282-
a message-crunching node, and for an honest reason: `ros2 topic hz` (without
283-
`--filter`) subscribes with `raw=True`, so **stock rclpy already skips
284-
deserialisation** — the saving here is the C++ executor and message handling
285-
replacing the Python executor, not avoiding a per-message copy. At very high rates
286-
the gap narrows further because the accelerated path deserialises into a C++ proxy
287-
while the stock raw path deserialises nothing.
288-
289-
**Startup: the acceleration is a one-time cost.** Time-to-first-hz-line
267+
| 3.0 MB | 100 | 99.0 | 97.0 | 48.7 | 18.8 |
268+
| 3.0 MB | 200 | 195.1 | 197.0 | 92.2 | 34.5 |
269+
| 3.0 MB | 300 | 291.4 | 296.7 | 102.7 | 42.6 |
270+
| 0.05 MB | 1000 | 998.2 | 999.7 | 19.3 | 7.3 |
271+
| 0.05 MB | 3000 | 2967.6 | 2985.0 | 46.6 | 17.2 |
272+
273+
Both backends deliver essentially the publisher's rate wherever the publisher can
274+
sustain it; the difference is CPU — the accelerated backend uses about a third to a
275+
half as much. `ros2 topic hz` (without `--filter`) subscribes with `raw=True`, so
276+
stock rclpy does not deserialise the payload; the saving is the C++ executor and
277+
message handling replacing the Python executor, not avoiding a per-message copy.
278+
Delivered rates stay close because the raw stock reader is cheap enough to keep up
279+
where the publisher can feed it — but note where the CPU lands: on the 3 MB stream
280+
stock rclpy crosses one full core near 200–250 Hz (92–107 %), while the accelerated
281+
backend stays around a third of a core, so on a busier machine or at a higher rate
282+
the stock reader saturates first.
283+
284+
**Startup: a one-time cost.** Time to first hz line
290285
(`pixi run -e heavydemo demo-topic-hz-startup`):
291286

292287
| `ros2 topic hz` first hz line | time |
293288
|---|---|
294289
| stock (no acceleration) | ~1.7 s |
295-
| `RCLCPPYY_ENABLE_HOOK=1`, cold PCH cache | ~8.0 s |
296-
| `RCLCPPYY_ENABLE_HOOK=1`, warm PCH cache | ~7.0 s |
297-
298-
The suite's zero-config Cling PCH shaves ~1.1 s (the `rclcpp` header parse) off the
299-
first line, cold→warm; the remaining ~5 s over stock is one-time rclcpp bring-up
300-
plus first-use JIT of the message type and subscription glue, which the header PCH
301-
does not cover. So acceleration adds a multi-second startup and **pays off for
302-
long-running `hz` sessions**, not short invocations. (Needs the newer auto-PCH; see
303-
the dev-bridge note below.)
304-
305-
**On "why not 100 Hz?"** With the real tool the publisher hits its target exactly —
306-
`50.0 … 700.0` published Hz in the table, confirmed by the publisher's own
307-
`PUB achieved_hz=` line and by the stock hz reading. An earlier custom subscriber
308-
that reported ~93 at a 100 Hz target was measuring its own per-second window with a
309-
shallow RELIABLE queue that dropped a few messages, not a publisher shortfall.
310-
311-
**Honest boundary — heavy (3 MB) topics + BEST_EFFORT.** `ros2 topic hz` fixes its
312-
reader to `qos_profile_sensor_data` (BEST_EFFORT). A 3 MB image fragments into
313-
~2000 UDP datagrams, and this machine's `net.core.rmem_max` is 208 KB, so the
314-
socket buffer overflows and whole messages are lost — the stock hz reader often gets
315-
**nothing** on a 3 MB topic, and acceleration does not rescue it (same BEST_EFFORT
316-
reader). This is a transport/kernel limit, not an rclpy-vs-rclcpp one. To measure a
317-
genuinely heavy topic, raise the buffer first (owner action, needs root):
290+
| `RCLCPPYY_ENABLE_HOOK=1`, cold cache | ~8.3 s |
291+
| `RCLCPPYY_ENABLE_HOOK=1`, warm cache | ~4.1 s |
292+
293+
Two caches cut the warm start: the suite's Cling PCH removes the `rclcpp` header
294+
parse, and a per-message-type subscription cache removes the ~2.8 s one-time JIT of
295+
`create_subscription<MsgT>` (both built on the first run and loaded on later ones,
296+
cold → warm above). The warm figure is still above stock because the rest of the
297+
rclcpp bring-up — cppyy symbol discovery and the rclpy-compatibility adapters — is
298+
not yet cached. Acceleration therefore remains a one-time startup cost that pays off
299+
over a long-running `hz` session rather than a single short call. (Needs the newer
300+
suite; see the dev-bridge note below.)
301+
302+
### Large messages under BEST_EFFORT QoS
303+
304+
`ros2 topic hz` subscribes with `qos_profile_sensor_data` (BEST_EFFORT). A 3 MB
305+
image fragments into roughly two thousand UDP datagrams, and if the OS socket
306+
receive buffer is smaller than one message a single dropped fragment loses the whole
307+
message. On a stock Linux install `net.core.rmem_max` defaults to about 200 KB, so a
308+
BEST_EFFORT reader receives little or nothing on a 3 MB topic — for stock rclpy and
309+
for the accelerated backend alike, since both use the same reader QoS. Raising the
310+
kernel limit resolves it (this needs root, and applies to any DDS user, not only
311+
rclcppyy):
318312

319313
```bash
320-
sudo sysctl -w net.core.rmem_max=2147483647 # then re-run demo-topic-hz-cli --width 1024 --height 1024
314+
sudo sysctl -w net.core.rmem_max=2147483647
321315
```
322316

323-
The tests cover the feature hermetically (`test/test_autoaccel.py`: install /
324-
uninstall, `RCLCPPYY_ENABLE_HOOK=1` accelerates a fresh `import rclpy`, unset and
325-
`RCLCPPYY_DISABLE_HOOK=1` leave stock rclpy untouched).
326-
327-
### Controlled comparison: a deserialising subscriber (dev bridge)
317+
With that in place, CycloneDDS's default socket buffer is large enough that a 3 MB
318+
BEST_EFFORT topic is received normally; no `CYCLONEDDS_URI` tuning is required. The
319+
3 MB figures above were measured with this setting.
328320

329-
Where `ros2 topic hz` uses raw subscriptions, a *normal* node that reads message
330-
fields pays full per-message Python deserialisation on stock rclpy — and that is
331-
where acceleration wins biggest. `scripts/heavy_hz_demo/run_heavy_hz.py` is a
332-
controlled harness for that case (a C++ publisher + an hz-style subscriber that
333-
reads the header, same script both ways via one `enable_cpp_acceleration()` line).
334-
On a 3 MB image, RELIABLE, plain rclpy tops out ~210 Hz saturating ~1.6 cores while
335-
the accelerated subscriber climbs past 330 Hz at half the CPU and a third of the
336-
latency.
337-
338-
```bash
339-
pixi run -e heavydemo demo-heavy-hz # rclpy vs rclcppyy deserialising-subscriber table
340-
pixi run -e heavydemo demo-heavy-startup # cold vs warm rclcppyy bring-up
341-
```
321+
The startup hook is covered by `test/test_hook.py` (install / uninstall / status;
322+
`RCLCPPYY_ENABLE_HOOK=1` accelerates a fresh `import rclpy`; unset and `=0` leave
323+
stock rclpy untouched). For the acceleration on a node that *reads* message fields —
324+
where stock rclpy pays a per-message Python deserialisation that `ros2 topic hz`
325+
(raw subscription) does not — `scripts/heavy_hz_demo/run_heavy_hz.py` is a controlled
326+
publisher/subscriber harness (`pixi run -e heavydemo demo-heavy-hz`).
342327

343-
> **Dev bridge.** The cold-vs-warm startup story and the fastest bring-up need the
328+
> **Dev bridge.** The startup measurement and the fastest bring-up use the
344329
> zero-config auto-PCH, which postdates the published suite 0.1.0. Until the next
345330
> suite release the `heavydemo` pixi env bridges the newer `rclcpp_kit`/`cppyy_kit`
346-
> from a sibling `cppyy_kit` **source checkout** (default `../cppyy_kit`, override
347-
> `CPPYY_KIT_SRC`) and isolates its PCH cache under `.heavy_demo_cache/`. It is a
348-
> **dev/demo-only** env: shares the default solve (no extra conda deps) and leaves
349-
> the default env's published-channel dependency untouched
350-
> (`workspace_activation.sh`, gated on the `heavydemo` env).
331+
> from a sibling `cppyy_kit` source checkout (default `../cppyy_kit`, override
332+
> `CPPYY_KIT_SRC`) and isolates its PCH cache under `.heavy_demo_cache/`. It shares
333+
> the default solve (no extra conda deps) and leaves the default env's
334+
> published-channel dependency untouched (`workspace_activation.sh`, gated on the
335+
> `heavydemo` env).
351336
352337
### Extra demos (optional env)
353338

pixi.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,10 @@ demo-heavy-hz-rclpy = "python scripts/heavy_hz_demo/run_heavy_hz.py --variant rc
109109
demo-heavy-hz-rclcppyy = "python scripts/heavy_hz_demo/run_heavy_hz.py --variant rclcppyy"
110110
# Cold (fresh PCH cache) vs warm rclcppyy bringup: parse cost + time-to-first-msg.
111111
demo-heavy-startup = "python scripts/heavy_hz_demo/run_heavy_hz.py --startup-story"
112-
# Accelerate the REAL `ros2 topic hz` binary via RCLCPPYY_ENABLE_HOOK: plain vs auto CPU/hz
113-
# across a rate sweep (installs the opt-in .pth first; idempotent).
114-
demo-topic-hz-cli = "python scripts/heavy_hz_demo/run_topic_hz_cli.py --sweep"
112+
# Accelerate the REAL `ros2 topic hz` binary via RCLCPPYY_ENABLE_HOOK: rclpy vs
113+
# rclcppyy CPU/hz on a 3 MB image (installs the opt-in .pth first; idempotent).
114+
# Vary payload/rate with flags, e.g. --width 128 --height 128 --rates 1000,3000.
115+
demo-topic-hz-cli = "python scripts/heavy_hz_demo/run_topic_hz_cli.py --sweep --rates 100,200,300 --width 1024 --height 1024 --reliability best_effort"
115116
# Time-to-first-hz-line of the real `ros2 topic hz`: stock vs RCLCPPYY_ENABLE_HOOK, cold vs warm.
116117
demo-topic-hz-startup = "python scripts/heavy_hz_demo/run_topic_hz_cli.py --startup-story"
117118

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
"""Standalone bootstrap for rclcppyy's opt-in auto-acceleration (RCLCPPYY_ENABLE_HOOK).
1+
"""Standalone bootstrap for rclcppyy's startup hook (RCLCPPYY_ENABLE_HOOK).
22
33
A copy of this file is installed into the active environment's site-packages (as
4-
``_rclcppyy_autoaccel.py``) next to a ``.pth`` whose single line calls
5-
``activate()`` at **every interpreter start, before any user import**. That is what
6-
lets a process which never mentions rclcppyy -- the stock ``ros2`` CLI, for example
7-
-- pick up the C++ backend: with ``RCLCPPYY_ENABLE_HOOK=1`` set, ``activate()`` arranges
8-
for ``rclcppyy.enable_cpp_acceleration()`` to run the moment ``rclpy`` is imported,
9-
so ``rclpy.create_node`` / ``spin`` / ``spin_once`` are already patched before the
10-
tool builds its node.
11-
12-
The SAME module is imported by ``rclcppyy.autoaccel`` as the single source of the
4+
``_rclcppyy_hook.py``) next to a ``.pth`` whose single line calls ``activate()`` at
5+
**every interpreter start, before any user import**. That is what lets a process
6+
which never mentions rclcppyy -- the stock ``ros2`` CLI, for example -- pick up the
7+
C++ backend: with ``RCLCPPYY_ENABLE_HOOK=1`` set, ``activate()`` arranges for
8+
``rclcppyy.enable_cpp_acceleration()`` to run the moment ``rclpy`` is imported, so
9+
``rclpy.create_node`` / ``spin`` / ``spin_once`` are already patched before the tool
10+
builds its node.
11+
12+
The SAME module is imported by ``rclcppyy.hook`` as the single source of the
1313
install-path and activation logic. Two hard constraints follow (mirroring
1414
cppyy_kit's auto-PCH bootstrap):
1515
@@ -19,25 +19,23 @@
1919
* **never raises** -- a bootstrap that threw would print a traceback on every
2020
``python`` invocation. ``activate()`` swallows everything.
2121
22-
When ``RCLCPPYY_ENABLE_HOOK`` is unset (the default) ``activate()`` returns immediately,
23-
before importing anything, so the cost for unrelated processes is negligible.
24-
``RCLCPPYY_DISABLE_HOOK=1`` is an explicit opt-out that wins even if ``RCLCPPYY_ENABLE_HOOK=1``.
22+
The single control is ``RCLCPPYY_ENABLE_HOOK``: exactly ``"1"`` turns the hook on;
23+
unset, ``"0"``, or any other value leaves it off, so ``activate()`` returns
24+
immediately (before importing anything) and the cost for unrelated processes is
25+
negligible.
2526
"""
2627
import os
2728
import sys
2829

2930
ENABLE_ENV = "RCLCPPYY_ENABLE_HOOK"
30-
DISABLE_ENV = "RCLCPPYY_DISABLE_HOOK"
3131

3232
# Per-process guard. A module global (not an env var) so it never leaks into child
3333
# processes -- each interpreter decides for itself whether to accelerate.
3434
_activated = False
3535

3636

3737
def _enabled():
38-
"""Whether auto-acceleration is requested for this process."""
39-
if os.environ.get(DISABLE_ENV) == "1":
40-
return False
38+
"""Whether the hook is requested for this process (only ``"1"`` enables)."""
4139
return os.environ.get(ENABLE_ENV) == "1"
4240

4341

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,37 @@
44
accelerate a process you cannot edit -- notably the stock ``ros2`` CLI verbs
55
(``ros2 topic hz`` and friends) -- rclcppyy can install a startup ``.pth`` into the
66
environment's site-packages. The ``.pth`` runs at every interpreter start and calls
7-
``_autoaccel_boot.activate()``, which does nothing unless ``RCLCPPYY_ENABLE_HOOK=1`` is
7+
``_hook_boot.activate()``, which does nothing unless ``RCLCPPYY_ENABLE_HOOK=1`` is
88
set; when it is, it arranges for ``enable_cpp_acceleration()`` to run the moment
99
``rclpy`` is imported. So the workflow is:
1010
11-
python -m rclcppyy.autoaccel install # once per environment
11+
python -m rclcppyy.hook install # once per environment
1212
RCLCPPYY_ENABLE_HOOK=1 ros2 topic hz /some_topic # accelerated, zero code changes
1313
ros2 topic hz /some_topic # unchanged: env var unset -> stock
1414
15-
python -m rclcppyy.autoaccel status
16-
python -m rclcppyy.autoaccel uninstall
15+
python -m rclcppyy.hook status
16+
python -m rclcppyy.hook uninstall
1717
18-
This mirrors cppyy_kit's auto-PCH bootstrap: the ``.pth`` is opt-IN (gated on the
19-
env var), silent and near-zero-cost when unset, honours the ``RCLCPPYY_DISABLE_HOOK=1``
20-
opt-out, and is fully uninstallable.
18+
The single control is ``RCLCPPYY_ENABLE_HOOK``: exactly ``"1"`` turns the hook on
19+
for a process; unset, ``"0"``, or any other value leaves it off. The ``.pth`` itself
20+
is silent and near-zero-cost when the hook is off, and is fully uninstallable.
2121
"""
2222
import argparse
2323
import os
2424
import sys
2525
import sysconfig
2626

27-
from rclcppyy import _autoaccel_boot as _boot
27+
from rclcppyy import _hook_boot as _boot
2828

29-
# The installed boot copy is a top-level module (``_rclcppyy_autoaccel``) so it needs
30-
# no package on sys.path at interpreter start. The .pth's one line imports it and
31-
# calls activate(), fully guarded so a broken/absent copy can never crash or spam a
29+
# The installed boot copy is a top-level module (``_rclcppyy_hook``) so it needs no
30+
# package on sys.path at interpreter start. The .pth's one line imports it and calls
31+
# activate(), fully guarded so a broken/absent copy can never crash or spam a
3232
# traceback into an interpreter start.
33-
_PTH_NAME = "rclcppyy_autoaccel.pth"
34-
_BOOT_INSTALLED_NAME = "_rclcppyy_autoaccel.py"
33+
_PTH_NAME = "rclcppyy_hook.pth"
34+
_BOOT_INSTALLED_NAME = "_rclcppyy_hook.py"
3535
_PTH_LINE = (
3636
'import sys; exec('
37-
'"try:\\n import _rclcppyy_autoaccel as _m; _m.activate()\\n'
37+
'"try:\\n import _rclcppyy_hook as _m; _m.activate()\\n'
3838
'except Exception: pass")\n'
3939
)
4040

@@ -111,27 +111,26 @@ def status(site_dir=None):
111111
"site_dir": site,
112112
"installed": is_installed(site),
113113
"RCLCPPYY_ENABLE_HOOK": os.environ.get(_boot.ENABLE_ENV),
114-
"RCLCPPYY_DISABLE_HOOK": os.environ.get(_boot.DISABLE_ENV),
115114
}
116115

117116

118117
def main(argv=None):
119118
parser = argparse.ArgumentParser(
120-
prog="python -m rclcppyy.autoaccel",
119+
prog="python -m rclcppyy.hook",
121120
description="Install the opt-in RCLCPPYY_ENABLE_HOOK startup hook so stock ros2 CLI "
122121
"tools accelerate when RCLCPPYY_ENABLE_HOOK=1 is set.")
123122
sub = parser.add_subparsers(dest="cmd", required=True)
124123
sub.add_parser("install", help="install the .pth + boot module into site-packages")
125124
sub.add_parser("uninstall", help="remove the .pth + boot module")
126-
sub.add_parser("status", help="show whether the hook is installed and the env vars")
125+
sub.add_parser("status", help="show whether the hook is installed and the env var")
127126
args = parser.parse_args(argv)
128127

129128
if args.cmd == "install":
130129
paths = install()
131-
print("Installed rclcppyy auto-acceleration hook:")
130+
print("Installed rclcppyy startup hook:")
132131
print(" %s" % paths["pth"])
133132
print(" %s" % paths["boot"])
134-
print("Enable per process with RCLCPPYY_ENABLE_HOOK=1 (opt out with RCLCPPYY_DISABLE_HOOK=1).")
133+
print("Enable per process with RCLCPPYY_ENABLE_HOOK=1.")
135134
elif args.cmd == "uninstall":
136135
removed = uninstall()
137136
if removed:
@@ -142,10 +141,9 @@ def main(argv=None):
142141
print("Nothing to remove (hook not installed).")
143142
elif args.cmd == "status":
144143
st = status()
145-
print("site-packages : %s" % st["site_dir"])
146-
print("installed : %s" % st["installed"])
144+
print("site-packages : %s" % st["site_dir"])
145+
print("installed : %s" % st["installed"])
147146
print("RCLCPPYY_ENABLE_HOOK : %s" % (st["RCLCPPYY_ENABLE_HOOK"] or "<unset>"))
148-
print("RCLCPPYY_DISABLE_HOOK: %s" % (st["RCLCPPYY_DISABLE_HOOK"] or "<unset>"))
149147
return 0
150148

151149

0 commit comments

Comments
 (0)