Skip to content

Conversation

@youknowone
Copy link
Member

@youknowone youknowone commented Feb 1, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Call-site line numbers for calls now reflect the call start for more accurate tracebacks.
    • Crash dumps traverse live frames and emit per-thread tracebacks for clearer diagnostics.
    • Signal-handler reentrancy now defers nested handling to avoid unsafe recursion.
    • Improved cross-platform fatal-signal/exception handling and cleaner traceback formatting.
  • New Features

    • Full per-thread current-frame tracking and signal-safe frame chains for more reliable diagnostics.
    • Thread identifier now directly available from the threading API.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 1, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Propagates call-expression source ranges into CALL bytecode emission; introduces lock-free, signal-safe per-thread frame pointers and per-thread frame stacks; replaces snapshot-based faulthandler traces with live-frame traversal; adds signal reentrancy guard and updates signal/exception registration and related VM APIs.

Changes

Cohort / File(s) Summary
Bytecode source-range propagation
crates/codegen/src/compile.rs
Capture call_range in compile_call, thread it into codegen_call_helper, update signature, and set the source range before emitting CallKw, Call, and CallFunctionEx.
Faulthandler: live-frame dumping & signal handling
crates/stdlib/src/faulthandler.rs
Remove snapshot-based frame storage; add live-frame traversal APIs (dump_live_frames, dump_frame_from_*), per-thread slot iteration, switch to sigaction on Unix and vectored exception handling on Windows, and change several pyfunction signatures to accept &VirtualMachine.
Frame structure (lock-free chain)
crates/vm/src/frame.rs
Add pub(crate) previous: AtomicPtr<Frame> and previous_frame() accessor; initialize previous in Frame::new.
Signal reentrancy guard
crates/vm/src/signal.rs
Add thread-local IN_SIGNAL_HANDLER: Cell<bool> and SignalHandlerGuard RAII to defer nested handling and ensure proper enter/exit semantics.
Per-thread frame stack & atomic pointer
crates/vm/src/vm/thread.rs
Change CurrentFrameSlot to Arc<Mutex<Vec<FrameRef>>>; add pub(crate) static CURRENT_FRAME: AtomicPtr<Frame> and new APIs (push_thread_frame, pop_thread_frame, set_current_frame, get_current_frame); improve fork handling and frame preservation.
VM frame linking on enter/exit
crates/vm/src/vm/mod.rs
with_frame now pushes/pops the per-thread stack, sets frame.previous to the prior frame, updates/restores CURRENT_FRAME, and unlinks on exit to support signal-safe traversal.
Thread stdlib exports & frame iterator
crates/vm/src/stdlib/thread.rs
Publicly re-export _thread::get_ident; change get_all_current_frames to return the top (most recent) frame per thread by using slot.lock().last().
Call-site & API adjustments
multiple files (pyfunctions, tests)
Update call sites to pass call_range to codegen_call_helper; adapt faulthandler/signal pyfunctions to accept &VirtualMachine; update tests/manifests accordingly.
Misc / manifests
Cargo.toml, tests...
Manifest and test updates to reflect changed signatures and feature flags, minor docs/comments.

Sequence Diagram(s)

sequenceDiagram
    participant Thread
    participant VM as VirtualMachine.with_frame()
    participant FrameStack as Per-thread Frame Stack
    participant CurrentFrame as CURRENT_FRAME (AtomicPtr)
    participant Signal as OS Signal/Exception
    participant Faulthandler as Faulthandler

    Thread->>VM: enter frame
    VM->>FrameStack: push_thread_frame(new_frame)
    VM->>CurrentFrame: set_current_frame(new_frame)
    Note over VM: new_frame.previous = old_frame (atomic pointer)

    Thread->>Thread: execute bytecode (calls emitted with call_range)

    Signal-->>Faulthandler: signal/exception delivered
    Faulthandler->>CurrentFrame: get_current_frame() (atomic, no lock)
    loop walk frames via previous pointers
        Faulthandler->>Faulthandler: read frame.previous
        Faulthandler->>Faulthandler: render frame entry
    end
    Faulthandler->>Signal: restore/return handler

    Thread->>VM: exit frame
    VM->>CurrentFrame: set_current_frame(restored_frame)
    VM->>FrameStack: pop_thread_frame()
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • ShaharNaveh
  • fanninpm

Poem

🐇 I hop through frames with pointers tight,

Call ranges mark where calls take flight,
Live traces whisper in signal night,
Stacks and atoms keep traceback bright,
I nibble bugs and toast the byte!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Update faulthandler to 3.14.2' is vague and does not clearly convey the primary technical changes in this comprehensive pull request. Consider a more descriptive title that highlights the main changes, such as 'Implement live frame walking and multi-thread traceback support in faulthandler' or 'Add signal-safe frame linking and per-thread traceback emission.'
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 2, 2026

Code has been automatically formatted

The code in this PR has been formatted using:

  • cargo fmt --all
    Please pull the latest changes before pushing again:
git pull origin faulthandler

@youknowone youknowone marked this pull request as ready for review February 2, 2026 09:21
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
crates/vm/src/vm/thread.rs (1)

1-106: ⚠️ Potential issue | 🟠 Major

Use AtomicPtr for CURRENT_FRAME to ensure signal-safe access.

Cell<*const Frame> is not safe when accessed from a signal handler. The replace() and get() operations are not atomic and can be torn if a signal interrupts set_current_frame(). Replace with AtomicPtr<Frame> using Ordering::Relaxed for atomic, signal-safe pointer updates.

🔧 Proposed fix
-use core::{
-    cell::{Cell, RefCell},
-    ptr::NonNull,
-};
+use core::{
+    cell::{Cell, RefCell},
+    ptr::NonNull,
+    sync::atomic::{AtomicPtr, Ordering},
+};
@@
-    pub(crate) static CURRENT_FRAME: Cell<*const Frame> = const { Cell::new(core::ptr::null()) };
+    pub(crate) static CURRENT_FRAME: AtomicPtr<Frame> =
+        const { AtomicPtr::new(core::ptr::null_mut()) };
@@
 pub fn set_current_frame(frame: *const Frame) -> *const Frame {
-    CURRENT_FRAME.with(|c| c.replace(frame))
+    CURRENT_FRAME.with(|c| c.swap(frame as *mut Frame, Ordering::Relaxed) as *const Frame)
 }
@@
 pub fn get_current_frame() -> *const Frame {
-    CURRENT_FRAME.with(|c| c.get())
+    CURRENT_FRAME.with(|c| c.load(Ordering::Relaxed) as *const Frame)
 }
crates/stdlib/src/faulthandler.rs (2)

1052-1085: ⚠️ Potential issue | 🟡 Minor

The all_threads setting in user signal handler only affects the header, not the actual dump.

When all_threads=true, the header says "Current thread..." but only the current thread's frames are dumped via dump_live_frames(). If the intent is to dump all threads when all_threads=true, this needs to iterate over thread frame slots like dump_all_threads() does.

If dumping only the current thread is intentional for signal safety reasons (which is valid - accessing other threads' frames from a signal handler is unsafe), consider:

  1. Changing the header to always say "Stack (most recent call first):" regardless of all_threads, or
  2. Documenting that all_threads is ignored in signal handlers

1323-1331: ⚠️ Potential issue | 🔴 Critical

Remove undefined function call snapshot_current_frames(vm) at line 1327—this will cause a compilation error.

The function snapshot_current_frames does not exist anywhere in the codebase. It is called only once (line 1327) and is never defined, imported, or conditionally compiled elsewhere. This is dead code from an earlier refactoring that removed snapshot-based frame access.

Fix
 #[cfg(windows)]
 #[pyfunction]
 fn _raise_exception(args: RaiseExceptionArgs, vm: &VirtualMachine) {
     use windows_sys::Win32::System::Diagnostics::Debug::RaiseException;

     suppress_crash_report();
-    snapshot_current_frames(vm);
+    let _ = vm;
     unsafe {
         RaiseException(args.code, args.flags, 0, core::ptr::null());
     }
 }
🤖 Fix all issues with AI agents
In `@crates/codegen/src/compile.rs`:
- Around line 4626-4628: In compile_class_def, capture the class statement
source range at the start (e.g., let class_stmt_range =
self.current_source_range.clone() or equivalent) before compiling
decorators/body, and then use that saved class_stmt_range when emitting the
__build_class__ call (replace uses of self.current_source_range in the
codegen_call_helper(2, arguments, self.current_source_range)? invocation with
the saved class_stmt_range) so the call site points to the class statement
instead of a range overwritten by decorator/body compilation.

In `@crates/vm/src/vm/mod.rs`:
- Around line 941-951: The current sequence publishes the new frame via
set_current_frame(frame_ptr) before setting frame.previous, causing a race where
a signal handler can see the new frame with a null previous pointer; fix by
reading the current thread frame first (use
crate::vm::thread::get_current_frame() or equivalent) and store that pointer
into frame.previous with frame.previous.store(..., Ordering::Relaxed) before
calling crate::vm::thread::set_current_frame(frame_ptr); keep the existing push
to self.frames and the #[cfg(feature = "threading")]
crate::vm::thread::push_thread_frame(frame.clone()) but ensure the previous-link
is populated prior to publishing the new frame pointer.
🧹 Nitpick comments (1)
crates/stdlib/src/faulthandler.rs (1)

122-147: Consider consolidating puts and puts_bytes to reduce duplication.

Both functions have nearly identical implementations differing only in the input type. Since &str can be converted to &[u8] via as_bytes(), you could have puts delegate to puts_bytes.

♻️ Proposed refactor
 #[cfg(any(unix, windows))]
 fn puts(fd: i32, s: &str) {
-    let _ = unsafe {
-        #[cfg(windows)]
-        {
-            libc::write(fd, s.as_ptr() as *const libc::c_void, s.len() as u32)
-        }
-        #[cfg(not(windows))]
-        {
-            libc::write(fd, s.as_ptr() as *const libc::c_void, s.len())
-        }
-    };
+    puts_bytes(fd, s.as_bytes());
 }

Comment on lines 4626 to 4642
if let Some(arguments) = arguments {
self.codegen_call_helper(2, arguments)?;
self.codegen_call_helper(2, arguments, self.current_source_range)?;
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Preserve class statement range for build_class call.

current_source_range is likely overwritten while compiling decorators and the class body, so the call location can incorrectly point inside the class body instead of the class statement. Capture the class statement range at the start of compile_class_def and reuse it here.

🛠️ Suggested fix
 fn compile_class_def(
     &mut self,
     name: &str,
     body: &[ast::Stmt],
     decorator_list: &[ast::Decorator],
     type_params: Option<&ast::TypeParams>,
     arguments: Option<&ast::Arguments>,
 ) -> CompileResult<()> {
+    // Preserve the class statement range for __build_class__ call location.
+    let class_call_range = self.current_source_range;
     self.prepare_decorators(decorator_list)?;

     let is_generic = type_params.is_some();
     let firstlineno = self.get_source_line_number().get().to_u32();
@@
-            if let Some(arguments) = arguments {
-                self.codegen_call_helper(2, arguments, self.current_source_range)?;
+            if let Some(arguments) = arguments {
+                self.codegen_call_helper(2, arguments, class_call_range)?;
             } else {
                 emit!(self, Instruction::Call { nargs: 2 });
             }
🤖 Prompt for AI Agents
In `@crates/codegen/src/compile.rs` around lines 4626 - 4628, In
compile_class_def, capture the class statement source range at the start (e.g.,
let class_stmt_range = self.current_source_range.clone() or equivalent) before
compiling decorators/body, and then use that saved class_stmt_range when
emitting the __build_class__ call (replace uses of self.current_source_range in
the codegen_call_helper(2, arguments, self.current_source_range)? invocation
with the saved class_stmt_range) so the call site points to the class statement
instead of a range overwritten by decorator/body compilation.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/vm/src/vm/thread.rs`:
- Around line 29-33: The CURRENT_FRAME static must be an atomic pointer so
signal handlers can read it safely; replace the Cell<*const Frame> static with
an AtomicPtr<Frame> initialized to null (use
AtomicPtr::new(core::ptr::null_mut() or equivalent) ) and update all uses
(including set_current_frame and any direct reads) to use atomic store/load with
Ordering::Relaxed; ensure conversions between *const Frame and *mut Frame are
handled where needed and update any helper functions that previously assumed
Cell to call AtomicPtr::store/load instead.
🧹 Nitpick comments (3)
crates/stdlib/src/faulthandler.rs (3)

334-357: Inconsistent thread header output compared to write_thread_id.

dump_traceback_thread_frames manually writes the thread header inline (lines 342-348) instead of reusing write_thread_id. While functionally similar, this duplicates the format logic. Consider extracting a common helper or reusing write_thread_id for consistency.

♻️ Suggested refactor to reuse write_thread_id

The write_thread_id function could be modified to accept a thread_id parameter instead of always using current_thread_id(), then both call sites could use the same function.

 #[cfg(any(unix, windows))]
-fn write_thread_id(fd: i32, is_current: bool) {
+fn write_thread_id(fd: i32, thread_id: u64, is_current: bool) {
     if is_current {
         puts(fd, "Current thread ");
     } else {
         puts(fd, "Thread ");
     }
-    let thread_id = current_thread_id();
     // dump_hexadecimal already writes "0x" prefix
     dump_hexadecimal(fd, thread_id, core::mem::size_of::<usize>() * 2);
     puts(fd, " (most recent call first):\n");
 }

866-879: Watchdog thread marks all threads as non-current.

When the watchdog dumps tracebacks, all threads are passed is_current: false (line 872), so none are labeled "Current thread". This may be intentional since the watchdog runs in its own thread, but it differs from CPython's behavior where the thread that triggered the timeout is marked as current.

For the non-threading path (lines 876-879), write_thread_id is called with is_current: false which also seems inconsistent—in a single-threaded build, the main thread should arguably be marked as current.

♻️ Suggested fix for non-threading case
                 #[cfg(not(feature = "threading"))]
                 {
-                    write_thread_id(fd, false);
+                    write_thread_id(fd, true);
                     dump_live_frames(fd);
                 }

1051-1085: all_threads flag doesn't dump all threads in signal context.

The faulthandler_user_signal handler checks user.all_threads but only affects the header text (lines 1058-1063). The actual frame dumping via dump_live_frames (line 1066) only dumps the current thread regardless of this flag.

This is likely a deliberate limitation for signal safety (can't safely access other threads' data from a signal handler), but the behavior is inconsistent with what all_threads=True would suggest. Consider adding a comment documenting this limitation, or adjusting the header when all_threads is true to avoid implying all threads will be dumped.

📝 Suggested documentation improvement
     #[cfg(unix)]
     extern "C" fn faulthandler_user_signal(signum: libc::c_int) {
         let user = match user_signals::get_user_signal(signum as usize) {
             Some(u) if u.enabled => u,
             _ => return,
         };
 
-        // Write traceback header based on all_threads setting
+        // Note: In signal context, we can only safely dump the current thread.
+        // The all_threads flag only affects the header format for compatibility.
         if user.all_threads {
             write_thread_id(user.fd, true);
         } else {
             puts(user.fd, "Stack (most recent call first):\n");
         }
 
-        // Dump live frame chain (walks Frame.previous pointers)
+        // Dump current thread's live frame chain only (signal-safe limitation)
         dump_live_frames(user.fd);

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@crates/stdlib/src/faulthandler.rs`:
- Around line 252-281: The truncation of function names in dump_frame_from_raw
and dump_frame_from_ref currently slices &funcname[..MAX_FUNCTION_NAME_LEN]
which can cut a UTF-8 codepoint and panic; create a small helper (e.g.
safe_truncate_funcname) that takes &str and MAX_FUNCTION_NAME_LEN, checks
is_char_boundary at that byte index and if not valid decrements the index until
it is a valid boundary, then returns the &str slice to use with puts; update
both dump_frame_from_raw and dump_frame_from_ref to call this helper before
calling puts and preserve the "..." behavior when truncation occurred.
- Around line 283-302: faulthandler_dump_traceback currently ignores the
all_threads flag (it only changes the header) and only dumps the current thread
via dump_live_frames/get_current_frame; either implement a signal-safe
multi-thread capture or explicitly document/emit that limitation—do the quick
fix by making faulthandler_dump_traceback detect when all_threads==true and emit
a clear signal-safe message (using puts/write_thread_id) that other threads
cannot be dumped from a fatal signal handler, and keep calling dump_live_frames
for the current thread; reference faulthandler_dump_traceback, dump_live_frames,
get_current_frame, and the non-signal functions dump_traceback/dump_all_threads
so the change is easy to locate.

In `@crates/vm/src/vm/thread.rs`:
- Around line 30-36: The CURRENT_FRAME atomic is currently stored inside
thread_local! and accessed via get_current_frame(), which uses TLS lookups that
are not async-signal-safe; move CURRENT_FRAME out of the thread_local! wrapper
to a plain static per-thread storage accessible without invoking
thread_local!.with() (e.g., a dedicated static AtomicPtr<Frame> per OS thread or
a non-TLS global map updated manually on thread enter/exit) and update
get_current_frame(), thread enter/exit logic, and any callers that read/write
CURRENT_FRAME so they use the new signal-safe static access pattern instead of
thread_local! lookups.

Comment on lines +30 to +36
/// Current top frame for signal-safe traceback walking.
/// Mirrors `PyThreadState.current_frame`. Read by faulthandler's signal
/// handler to dump tracebacks without accessing RefCell or locks.
/// Uses AtomicPtr for async-signal-safety (signal handlers may read this
/// while the owning thread is writing).
pub(crate) static CURRENT_FRAME: AtomicPtr<Frame> =
const { AtomicPtr::new(core::ptr::null_mut()) };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the actual code in the target file
cd crates/vm/src/vm && head -50 thread.rs | cat -n

Repository: RustPython/RustPython

Length of output: 2286


🏁 Script executed:

# Get more context around lines 30-36
sed -n '1,50p' crates/vm/src/vm/thread.rs | cat -n

Repository: RustPython/RustPython

Length of output: 2286


🏁 Script executed:

# Search for CURRENT_FRAME definition and usage patterns
rg 'CURRENT_FRAME' crates/vm/src/vm/thread.rs -B 3 -A 3

Repository: RustPython/RustPython

Length of output: 2546


🏁 Script executed:

# Search for get_current_frame function
rg 'get_current_frame' crates/vm/src/ -A 10

Repository: RustPython/RustPython

Length of output: 819


🏁 Script executed:

# Check if there are any thread_local macros in the file
rg 'thread_local!' crates/vm/src/vm/thread.rs

Repository: RustPython/RustPython

Length of output: 149


🌐 Web query:

Rust thread_local async-signal-safety POSIX signal handlers

💡 Result:

  • Don’t use thread_local!() (TLS) from a POSIX signal handler in Rust. TLS access is not async-signal-safe; even “just reading” a TLS slot can involve runtime/TLS machinery that POSIX does not guarantee is safe in an async handler. (users.rust-lang.org)
  • In POSIX, a signal handler must restrict itself to async-signal-safe operations/functions (the standard provides a specific allowlist; e.g., write, _exit, sigaction, etc.). Anything not on that list is unsafe to call from the handler (may deadlock, corrupt global state, etc.). (man7.org)
  • errno note: reading/writing errno is considered async-signal-safe if you save it on entry and restore it before returning. (manpages.debian.org)

Practical Rust pattern: do the absolute minimum in the handler (typically set an AtomicBool/AtomicUsize and/or write() 1 byte to a pipe/socket), then handle the real logic on a normal thread/task. This is the common “self-pipe” style design used by Rust signal crates. (man7.org)

Citations:


🏁 Script executed:

# Search for faulthandler or signal handler usage with get_current_frame
rg 'faulthandler|signal' crates/vm/src/ -A 5 -B 2 | head -100

Repository: RustPython/RustPython

Length of output: 5811


🏁 Script executed:

# Check if get_current_frame is called from any signal-related code
rg 'get_current_frame' crates/vm/src/ -B 5 -A 5

Repository: RustPython/RustPython

Length of output: 795


🏁 Script executed:

# Look for signal handler registration or unsafe signal code
rg 'signal|SignalHandler|SIGABRT|SIGSEGV' crates/vm/src/ -l

Repository: RustPython/RustPython

Length of output: 507


CURRENT_FRAME cannot be safely accessed from signal handlers due to thread-local! machinery.

While AtomicPtr itself is async-signal-safe, thread_local! access via .with() is not. POSIX signal handlers must restrict themselves to the async-signal-safe function list, which does not include TLS lookups. Accessing CURRENT_FRAME from get_current_frame() in a signal handler can deadlock or corrupt state.

To achieve true signal safety, store CURRENT_FRAME as a plain static (not within thread_local!), accepting that it requires manual per-thread management for sys._current_frames() or implement a signal-safe variant of frame access (e.g., using a separate, non-TLS global data structure for faulthandler).

🤖 Prompt for AI Agents
In `@crates/vm/src/vm/thread.rs` around lines 30 - 36, The CURRENT_FRAME atomic is
currently stored inside thread_local! and accessed via get_current_frame(),
which uses TLS lookups that are not async-signal-safe; move CURRENT_FRAME out of
the thread_local! wrapper to a plain static per-thread storage accessible
without invoking thread_local!.with() (e.g., a dedicated static AtomicPtr<Frame>
per OS thread or a non-TLS global map updated manually on thread enter/exit) and
update get_current_frame(), thread enter/exit logic, and any callers that
read/write CURRENT_FRAME so they use the new signal-safe static access pattern
instead of thread_local! lookups.

CPython Developers and others added 2 commits February 3, 2026 13:41
- Rewrite faulthandler with live frame walking via
  Frame.previous AtomicPtr chain and thread-local
  CURRENT_FRAME (AtomicPtr) instead of frame snapshots
- Add signal-safe traceback dumping (dump_live_frames,
  dump_frame_from_raw) walking the Frame.previous chain
- Add safe_truncate/dump_ascii for UTF-8 safe string
  truncation in signal handlers
- Refactor write_thread_id to accept thread_id parameter
- Add SA_RESTART for user signal registration, SA_NODEFER
  only when chaining
- Save/restore errno in faulthandler_user_signal
- Add signal re-entrancy guard in trigger_signals to
  prevent recursive handler invocation
- Add thread frame tracking (push/pop/cleanup/reinit)
  with force_unlock fallback for post-fork recovery
- Remove expectedFailure markers for now-passing tests
@youknowone youknowone enabled auto-merge February 3, 2026 04:43
@youknowone youknowone disabled auto-merge February 3, 2026 04:43
@youknowone youknowone merged commit ec34bef into RustPython:main Feb 3, 2026
13 of 14 checks passed
@youknowone youknowone deleted the faulthandler branch February 3, 2026 04:43
@github-actions
Copy link
Contributor

github-actions bot commented Feb 3, 2026

📦 Library Dependencies

The following Lib/ modules were modified. Here are their dependencies:

[x] test: cpython/Lib/test/test_faulthandler.py (TODO: 5)

dependencies:

dependent tests: (1 tests)

  • faulthandler: test_faulthandler

[x] lib: cpython/Lib/inspect.py
[ ] test: cpython/Lib/test/test_inspect (TODO: 54)

dependencies:

  • inspect

dependent tests: (44 tests)

  • inspect: test_abc test_argparse test_asyncgen test_builtin test_code test_collections test_coroutines test_decimal test_enum test_functools test_generators test_grammar test_inspect test_ntpath test_operator test_patma test_posixpath test_signal test_traceback test_types test_typing test_unittest test_yield_from test_zipimport
    • asyncio: test_asyncio test_contextlib_async test_logging test_os test_sys_settrace test_unittest
    • bdb: test_bdb
    • dataclasses: test__colorize test_genericalias test_pprint test_regrtest test_zoneinfo
      • pprint: test_htmlparser test_ssl test_sys_setprofile
    • importlib.metadata: test_importlib
    • pydoc:
      • xmlrpc.server: test_docxmlrpc test_xmlrpc
    • rlcompleter: test_rlcompleter
    • trace: test_trace

[ ] test: cpython/Lib/test/test_list.py (TODO: 5)
[ ] test: cpython/Lib/test/test_listcomps.py (TODO: 1)
[ ] test: cpython/Lib/test/test_userlist.py

dependencies:

dependent tests: (no tests depend on list)

[x] test: cpython/Lib/test/test_setcomps.py

dependencies:

dependent tests: (no tests depend on setcomps)

[ ] lib: cpython/Lib/traceback.py
[ ] test: cpython/Lib/test/test_traceback.py (TODO: 69)

dependencies:

  • traceback (native: collections.abc, itertools, sys)
    • codeop
    • io (native: _io, _thread, errno, sys)
    • tokenize (native: _tokenize, builtins, itertools, sys)
    • _colorize, contextlib, keyword, linecache, textwrap, warnings

dependent tests: (31 tests)

  • traceback: test_asyncio test_builtin test_code_module test_contextlib test_contextlib_async test_coroutines test_listcomps test_pyexpat test_setcomps test_socket test_ssl test_subprocess test_threadedtempfile test_threading test_traceback test_unittest test_with test_zipimport
    • code:
      • sqlite3.main: test_sqlite3
    • concurrent.futures.process: test_concurrent_futures
    • logging.config: test_logging
    • py_compile: test_argparse test_cmd_line_script test_compileall test_importlib test_multiprocessing_main_handling test_py_compile test_runpy
    • pydoc: test_enum
      • xmlrpc.server: test_docxmlrpc test_xmlrpc

Legend:

  • [+] path exists in CPython
  • [x] up-to-date, [ ] outdated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant