GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix import ctypes by youknowone · Pull Request #6304 · RustPython/RustPython

Conversation

@youknowone

@youknowone youknowone commented Nov 28, 2025 •
edited by coderabbitai Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Pointer type generation with automatic caching and working POINTER/pointer APIs
    • Library loading can target the current process when no name is provided
    • Simple ctypes types gain a from_param conversion method
  • Bug Fixes

    • Pointer instantiation now returns usable pointer objects
    • Function-pointer construction handles address/name forms and reports errors cleanly
    • Array construction preserves the provided type when creating instances

✏️ Tip: You can customize this high-level summary in your review settings.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@youknowone
youknowone requested a review from arihant2math November 28, 2025 14:45
@coderabbitai

coderabbitai Bot commented Nov 28, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

Walkthrough

Unix library loader now accepts None to obtain the current process handle; ctypes gains cached pointer-type creation and pointer-instantiation APIs exposed as POINTER/pointer; PyCSimpleType.from_param added; PyCFuncPtr constructor refactored to support empty, address, and (name,dll) forms.

Changes

Cohort / File(s) Summary
Unix library loading
crates/vm/src/stdlib/ctypes.rs
load_library_unix signature changed to accept Option<String>; None calls libc::dlopen(null, RTLD_NOW) to return current process handle; previous cache insertion preserved for Some(name).
Pointer type & instance APIs
crates/vm/src/stdlib/ctypes.rs
Added pub fn create_pointer_type(cls: PyObjectRef, vm: &VirtualMachine) -> PyResult and pub fn create_pointer_inst(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult; introduced _pointer_type_cache usage and dynamic pointer-type construction; updated POINTER and pointer bindings to these implementations.
PyCSimpleType.from_param
crates/vm/src/stdlib/ctypes/base.rs
Added #[pyclassmethod] fn from_param(cls: PyTypeRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult that returns value if already instance of cls, otherwise reads _as_parameter_ and delegates recursively or raises TypeError.
PyCFuncPtr constructor refactor
crates/vm/src/stdlib/ctypes/function.rs
Changed constructor Args from (PyTupleRef, FuncArgs) to FuncArgs; py_new now inspects args and branches: empty → uninitialized pointer, integer → treat as function address, tuple → treat as (name, dll) with library loading and symbol lookup; added error handling for invalid forms.
PyCArray construction typing
crates/vm/src/stdlib/ctypes/array.rs
py_new now accepts cls: PyTypeRef and constructs return via .into_ref_with_type(vm, cls).map(Into::into) instead of .into_pyobject(vm) to preserve type.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant PyCFuncPtr as PyCFuncPtr::py_new
    participant FormInspector as Form Branching
    participant AddrHandler as Address Path
    participant TupleHandler as Tuple (name,dll) Path
    participant LibLoader as Library Loader
    participant Result as PyCFuncPtr Construction

    Caller->>PyCFuncPtr: call py_new(args)
    PyCFuncPtr->>FormInspector: inspect args

    alt args empty
        FormInspector->>Result: create uninitialized PyCFuncPtr
    else first arg is integer
        FormInspector->>AddrHandler: extract address
        AddrHandler->>Result: build PyCFuncPtr with pointer, name, handler
    else first arg is tuple (name,dll)
        FormInspector->>TupleHandler: extract name and dll
        TupleHandler->>LibLoader: resolve library handle (load_library_unix / LoadLibrary)
        LibLoader->>LibLoader: lookup symbol by name
        LibLoader->>Result: return code pointer or None
        Result->>Result: construct PyCFuncPtr with resolved data
    else invalid form
        FormInspector->>Result: return TypeError
    end

    Result-->>Caller: PyResult<PyCFuncPtr>
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Attention areas:
    • crates/vm/src/stdlib/ctypes/function.rs: branching correctness, safety around raw addresses, symbol lookup and error propagation.
    • crates/vm/src/stdlib/ctypes.rs: _pointer_type_cache concurrency/validation, type derivation correctness, public API bindings.
    • crates/vm/src/stdlib/ctypes/base.rs: recursion and attribute lookup semantics in from_param.
    • crates/vm/src/stdlib/ctypes/array.rs: ensuring correct type-ref construction and ownership.

Possibly related PRs

  • Fix import ctypes #6304 — mirrors the same ctypes changes (load_library_unix signature, create_pointer_type/create_pointer_inst, POINTER/pointer bindings).
  • _ctypes pt. 5 #5653 — overlapping ctypes subsystem modifications including Unix library-loading behavior and pointer/funcptr implementations.

Suggested reviewers

  • arihant2math

Poem

🐰
I nibble bytes where pointers grow,
Cache a type and off I go.
Address, tuple, or empty start,
Functions bound and types take part.
Hooray — ctypes hops with rabbit heart!

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix import ctypes' is vague and does not clearly convey the primary changes. The PR introduces significant new functionality (pointer type generation, caching, Unix/Windows library loading improvements) that goes well beyond a simple 'import' fix. Consider using a more descriptive title that captures the main purpose, such as 'Implement ctypes pointer type generation and library loading' or 'Add POINTER and pointer functions to ctypes module'.
✅ 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%.

📜 Recent review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 469c93a and 7c66122.

⛔ Files ignored due to path filters (1)
  • Lib/ctypes/__init__.py is excluded by !Lib/**
📒 Files selected for processing (4)
  • crates/vm/src/stdlib/ctypes.rs (3 hunks)
  • crates/vm/src/stdlib/ctypes/array.rs (1 hunks)
  • crates/vm/src/stdlib/ctypes/base.rs (1 hunks)
  • crates/vm/src/stdlib/ctypes/function.rs (1 hunks)

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
  • X
  • Mastodon
  • Reddit
  • LinkedIn

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ShaharNaveh
ShaharNaveh reviewed Nov 28, 2025
View reviewed changes
Comment thread crates/vm/src/stdlib/ctypes/base.rs Outdated
return PyCSimpleType::from_param(cls, as_parameter, vm);
}

Err(vm.new_type_error("wrong type".to_string()))

@ShaharNaveh ShaharNaveh Nov 28, 2025

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Suggested change
Err(vm.new_type_error("wrong type".to_string()))
Err(vm.new_type_error("wrong type"))

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

youknowone reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
ShaharNaveh
ShaharNaveh reviewed Nov 28, 2025
View reviewed changes
Comment thread crates/vm/src/stdlib/ctypes.rs Outdated
// If None, call libc::dlopen(null, mode) to get the current process handle
let handle = unsafe { libc::dlopen(std::ptr::null(), libc::RTLD_NOW) };
if handle.is_null() {
return Err(vm.new_os_error("dlopen() error".to_string()));

@ShaharNaveh ShaharNaveh Nov 28, 2025

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Suggested change
return Err(vm.new_os_error("dlopen() error".to_string()));
return Err(vm.new_os_error("dlopen() error"));

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

youknowone reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@youknowone
youknowone force-pushed the import-ctypes branch 2 times, most recently from 3e78ddf to 469c93a Compare November 28, 2025 15:57
@youknowone
youknowone marked this pull request as ready for review November 28, 2025 16:07
coderabbitai[bot]
coderabbitai Bot reviewed Nov 28, 2025
View reviewed changes

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this 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 (1)
crates/vm/src/stdlib/ctypes.rs (1)

192-205: Inconsistent error handling with Unix version.

Line 203 uses .unwrap() which will panic if library loading fails, while the Unix version on lines 220-222 properly maps the error to a Python OSError. Consider consistent error handling.

     fn load_library_windows(
         name: String,
         _load_flags: OptionalArg<i32>,
         vm: &VirtualMachine,
     ) -> PyResult<usize> {
         // TODO: audit functions first
         // TODO: load_flags
         let cache = library::libcache();
         let mut cache_write = cache.write();
-        let (id, _) = cache_write.get_or_insert_lib(&name, vm).unwrap();
+        let (id, _) = cache_write
+            .get_or_insert_lib(&name, vm)
+            .map_err(|e| vm.new_os_error(e.to_string()))?;
         Ok(id)
     }
🧹 Nitpick comments (1)
crates/vm/src/stdlib/ctypes.rs (1)

245-283: Implementation is correct, but consider caching the module lookup.

The function works correctly for creating and caching pointer types. However, vm.import("_ctypes", 0)? is called on every invocation. For frequently-called code paths, this could be optimized by accessing the module through vm context directly if available.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fef9de2 and 469c93a.

⛔ Files ignored due to path filters (1)
  • Lib/ctypes/__init__.py is excluded by !Lib/**
📒 Files selected for processing (3)
  • crates/vm/src/stdlib/ctypes.rs (3 hunks)
  • crates/vm/src/stdlib/ctypes/base.rs (1 hunks)
  • crates/vm/src/stdlib/ctypes/function.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.rs: Follow the default rustfmt code style in Rust code (cargo fmt to format)
Always run clippy to lint Rust code (cargo clippy) before completing tasks and fix any warnings or lints introduced by your changes
Follow Rust best practices for error handling and memory management

Files:

  • crates/vm/src/stdlib/ctypes/function.rs
  • crates/vm/src/stdlib/ctypes/base.rs
  • crates/vm/src/stdlib/ctypes.rs
**/src/**/*.rs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use the macro system (pyclass, pymodule, pyfunction, etc.) when implementing Python functionality in Rust

Files:

  • crates/vm/src/stdlib/ctypes/function.rs
  • crates/vm/src/stdlib/ctypes/base.rs
  • crates/vm/src/stdlib/ctypes.rs
🧬 Code graph analysis (1)
crates/vm/src/stdlib/ctypes/function.rs (1)
crates/vm/src/stdlib/ctypes/base.rs (2)
  • py_new (214-242)
  • new (167-173)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Run snippets and cpython tests (windows-latest)
  • GitHub Check: Run rust tests (windows-latest)
  • GitHub Check: Run snippets and cpython tests (macos-latest)
  • GitHub Check: Run snippets and cpython tests (ubuntu-latest)
🔇 Additional comments (4)
crates/vm/src/stdlib/ctypes/base.rs (1)

175-188: LGTM! The from_param implementation follows CPython's pattern correctly.

The method properly handles:

  1. Direct instance check with early return
  2. Fallback to _as_parameter_ attribute lookup
  3. Recursive conversion via from_param
crates/vm/src/stdlib/ctypes.rs (2)

225-232: LGTM! Proper handling for None to get current process handle.

The implementation correctly uses libc::dlopen(null, RTLD_NOW) to obtain the current process handle when name is None, with appropriate null-check error handling. The error message now matches the past review suggestion.


286-295: LGTM!

Clean delegation pattern that correctly:

  1. Gets the object's type
  2. Creates the corresponding pointer type via create_pointer_type
  3. Instantiates the pointer with the object
crates/vm/src/stdlib/ctypes/function.rs (1)

195-201: The review comment is incorrect: trailing null termination is explicitly allowed and potentially beneficial in libloading.

According to libloading's documentation, Library::get() accepts symbol names with optional trailing NUL bytes (e.g., b"foo\0"), and the trailing NUL is explicitly noted as potentially avoiding an allocation. The current code pattern format!("{}\0", &name) followed by lib.get(terminated.as_bytes()) is valid and may be preferable to the suggested name.as_bytes() for efficiency reasons.

The concern that "the library expects a clean symbol name" is unfounded—trailing NUL bytes are explicitly documented as allowed and do not cause issues.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread crates/vm/src/stdlib/ctypes/function.rs Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread crates/vm/src/stdlib/ctypes/function.rs
Comment on lines +147 to +159
if let Ok(addr) = first_arg.try_int(vm) {
let ptr_val = addr.as_bigint().to_usize().unwrap_or(0);
return Ok(Self {
ptr: PyRwLock::new(Some(CodePtr(ptr_val as *mut _))),
needs_free: AtomicCell::new(false),
arg_types: PyRwLock::new(None),
_flags_: AtomicCell::new(0),
res_type: PyRwLock::new(None),
name: PyRwLock::new(Some(format!("CFuncPtr@{:#x}", ptr_val))),
handler: vm.ctx.new_int(ptr_val).into(),
}
.to_pyobject(vm));
}

@coderabbitai coderabbitai Bot Nov 28, 2025

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Silent fallback to address 0 may mask invalid input.

When to_usize() fails (e.g., negative or oversized integer), the code silently uses address 0, which will likely cause a crash or undefined behavior when the function is called later. Consider returning an error instead.

         if let Ok(addr) = first_arg.try_int(vm) {
-            let ptr_val = addr.as_bigint().to_usize().unwrap_or(0);
+            let ptr_val = addr
+                .as_bigint()
+                .to_usize()
+                .ok_or_else(|| vm.new_value_error("Invalid function address".to_string()))?;
             return Ok(Self {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if let Ok(addr) = first_arg.try_int(vm) {
let ptr_val = addr.as_bigint().to_usize().unwrap_or(0);
return Ok(Self {
ptr: PyRwLock::new(Some(CodePtr(ptr_val as *mut _))),
needs_free: AtomicCell::new(false),
arg_types: PyRwLock::new(None),
_flags_: AtomicCell::new(0),
res_type: PyRwLock::new(None),
name: PyRwLock::new(Some(format!("CFuncPtr@{:#x}", ptr_val))),
handler: vm.ctx.new_int(ptr_val).into(),
}
.to_pyobject(vm));
}
if let Ok(addr) = first_arg.try_int(vm) {
let ptr_val = addr
.as_bigint()
.to_usize()
.ok_or_else(|| vm.new_value_error("Invalid function address".to_string()))?;
return Ok(Self {
ptr: PyRwLock::new(Some(CodePtr(ptr_val as *mut _))),
needs_free: AtomicCell::new(false),
arg_types: PyRwLock::new(None),
_flags_: AtomicCell::new(0),
res_type: PyRwLock::new(None),
name: PyRwLock::new(Some(format!("CFuncPtr@{:#x}", ptr_val))),
handler: vm.ctx.new_int(ptr_val).into(),
}
.to_pyobject(vm));
}
🤖 Prompt for AI Agents
In crates/vm/src/stdlib/ctypes/function.rs around lines 147-159, the code
currently uses addr.as_bigint().to_usize().unwrap_or(0) which silently falls
back to address 0 on conversion failure; instead match on to_usize() and when it
returns None return an Err created from the VM (e.g., vm.new_value_error or
vm.new_type_error) with a clear message about invalid pointer value, so the
function creation aborts rather than constructing a CFuncPtr@0.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
youknowone added 2 commits November 29, 2025 01:29
@youknowone
Fix ctypes import blockers
4bfbdff
@youknowone
Update Lib/ctypes/__init__.py from cpython3.13.9
7c66122
@youknowone
youknowone force-pushed the import-ctypes branch from 469c93a to 7c66122 Compare November 28, 2025 16:32
@youknowone
youknowone merged commit 23ec5a5 into RustPython:main Nov 28, 2025
10 of 13 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@youknowone
youknowone deleted the import-ctypes branch November 28, 2025 16:32
@coderabbitai coderabbitai Bot mentioned this pull request Nov 29, 2025
ctypes buffer #6311
Merged
This was referenced Dec 11, 2025
a few unreachable->unimplemented, clippy #6405
Merged
TypeData #6403
Merged
@coderabbitai coderabbitai Bot mentioned this pull request Dec 21, 2025
Enable ctypes #6457
Merged
@coderabbitai coderabbitai Bot mentioned this pull request Feb 17, 2026
Update ctypes from v3.14.3 and make _ctypes compatible #7165
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ShaharNaveh ShaharNaveh ShaharNaveh left review comments
@coderabbitai coderabbitai[bot] coderabbitai[bot] left review comments
@arihant2math arihant2math Awaiting requested review from arihant2math

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@youknowone @ShaharNaveh
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.