From e9dedb13ab767bffcf942080d8963e23c4657519 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 4 Jun 2025 16:45:42 +0100 Subject: [PATCH 1/2] Allow calling mark() when not tracing --- src/etwtrace/__init__.py | 30 +++++++++++++++++++++--------- tests/test_etw.py | 12 ++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/etwtrace/__init__.py b/src/etwtrace/__init__.py index 886b2d4..9e4171b 100644 --- a/src/etwtrace/__init__.py +++ b/src/etwtrace/__init__.py @@ -171,22 +171,34 @@ def enable_if(enable_var, type_var): def mark(name): """Emits a mark event with the provided text.""" - if not _tracer: - raise RuntimeError("unable to mark when global tracer is not enabled") - _tracer.mark(name) + if _tracer: + _tracer.mark(name) + else: + import warnings + warnings.warn("Unable to mark when global tracer is not enabled", RuntimeWarning) + + +class _NullRange: + def __enter__(self): return self + def __exit__(self, *exc_info): pass def mark_range(name): """Context manager to emit start/stop mark events with the provided text.""" - if not _tracer: - raise RuntimeError("unable to mark when global tracer is not enabled") - return _tracer.mark_range(name) + if _tracer: + return _tracer.mark_range(name) + else: + import warnings + warnings.warn("Unable to mark when global tracer is not enabled", RuntimeWarning) + return _NullRange() def _mark_stack(mark): - if not _tracer: - raise RuntimeError("unable to mark when global tracer is not enabled") - return _tracer._mark_stack(mark) + if _tracer: + return _tracer._mark_stack(mark) + else: + import warnings + warnings.warn("Unable to mark when global tracer is not enabled", RuntimeWarning) _TEMP_PROFILE = None diff --git a/tests/test_etw.py b/tests/test_etw.py index a72e83e..4d52292 100644 --- a/tests/test_etw.py +++ b/tests/test_etw.py @@ -234,6 +234,18 @@ def test_but_do_we_instrument(): ) +def test_but_do_we_warn_on_mark(): + with pytest.warns(RuntimeWarning): + etwtrace.mark("Test mark without tracing") + + with pytest.warns(RuntimeWarning): + with etwtrace.mark_range("Test mark without tracing"): + pass + + with pytest.warns(RuntimeWarning): + etwtrace._mark_stack("Test mark without tracing") + + def test_basic(trace_events): funcs = set() with trace_events("basic.py", providers=['Python']) as etl: From 400a1f33d6aa025e65704509b99300c7bb002179 Mon Sep 17 00:00:00 2001 From: Steve Dower Date: Wed, 4 Jun 2025 16:47:13 +0100 Subject: [PATCH 2/2] Add is_active function --- src/etwtrace/__init__.py | 5 +++++ tests/test_etw.py | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/etwtrace/__init__.py b/src/etwtrace/__init__.py index 9e4171b..7f0ad5b 100644 --- a/src/etwtrace/__init__.py +++ b/src/etwtrace/__init__.py @@ -169,6 +169,11 @@ def enable_if(enable_var, type_var): tracer.enable() +def is_active(): + """Returns True if tracing is active.""" + return bool(_tracer) + + def mark(name): """Emits a mark event with the provided text.""" if _tracer: diff --git a/tests/test_etw.py b/tests/test_etw.py index 4d52292..3ed3a33 100644 --- a/tests/test_etw.py +++ b/tests/test_etw.py @@ -234,6 +234,10 @@ def test_but_do_we_instrument(): ) +def test_but_are_we_inactive(): + assert etwtrace.is_active() is False + + def test_but_do_we_warn_on_mark(): with pytest.warns(RuntimeWarning): etwtrace.mark("Test mark without tracing")