Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@

### Fixed

- `import scope_profiler` works on Pyodide, whose `time` has no `thread_time_ns`; the process
clock stands in for it there.
- Summary: a recursive row's total sums only the outermost calls, so it no longer
exceeds the time of its caller, and the regions called from a recursive
function are no longer marked with the recursive symbol (#313).
Expand Down
7 changes: 6 additions & 1 deletion src/scope_profiler/concurrency.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@
import sys
import threading
import weakref
from time import perf_counter_ns, thread_time_ns
from time import perf_counter_ns

try:
from time import thread_time_ns
except ImportError: # Emscripten (Pyodide): no per-thread clock, and only one thread
from time import process_time_ns as thread_time_ns
from typing import Any

import numpy as np
Expand Down
14 changes: 14 additions & 0 deletions src/scope_profiler/tests/unit/test_concurrency.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""The lane bookkeeping behind ``track_threads`` and ``track_async``."""

import asyncio
import subprocess
import sys
import threading

import numpy as np
Expand Down Expand Up @@ -316,3 +318,15 @@ def previous(frame, event, arg):
sys.setprofile(None)
tracker.uninstall()
threading.setprofile(None)


def test_imports_without_a_per_thread_clock():
"""Pyodide's ``time`` has no ``thread_time_ns``; the process clock stands in."""
code = (
"import time\n"
"del time.thread_time_ns\n"
"import scope_profiler\n"
"from scope_profiler import concurrency\n"
"assert concurrency.thread_time_ns is time.process_time_ns\n"
)
subprocess.run([sys.executable, "-c", code], check=True)
Loading