Skip to content

[P2] Opening a device with an existing capsule returns SystemError after native success #245

Description

@drebbe-intrepid

Bug

PyNeoDeviceEx_SetHandle checks !PyCapsule_SetPointer(...) as failure, but that API returns zero on success. Updating an existing capsule therefore reports false without setting an exception after the native open already succeeded.

Reviewed commit: 45167e09de6b886cd451a4245f842c8221349711 (current master on 2026-09-15).
Source: src/methods.cpp:980; src/methods.cpp:1320

Reproduction

This reproducer uses a hardware-free DLL. Save this as mock.c:

#define API __declspec(dllexport)
typedef unsigned long long size_t;
API int icsneoOpenDevice(void* d, void** h, void* nets, int config, int options, void* extra, unsigned long reserved) { *h = (void*)0x1234; return 1; }

Build with LLVM on Windows x64:

clang-cl /nologo /c /GS- /Zl mock.c /Fomock.obj
lld-link /dll /noentry /nodefaultlib /out:mock.dll mock.obj

Then run:

import ics
import ctypes
from pathlib import Path
ics.override_library_name(str(Path('mock.dll').resolve()))
d = ics.PyNeoDeviceEx()
d._auto_handle_close = False
print(ics.open_device(d) is d)
print(ics.open_device(d) is d)

Observed / expected

First call prints True. The second raises SystemError: <built-in function open_device> returned NULL without setting an exception. Expected either a deliberate rejection before opening an already-open device or correct handling of the successful capsule update.

Suggested fix and regression coverage

Treat PyCapsule_SetPointer return value != 0 as failure. Define/test already-open behavior and ensure a successfully opened native handle is not orphaned when Python bookkeeping fails.

Validation environment

Windows x64, CPython 3.14.5, extension rebuilt from the commit above. Hardware-dependent entry points below were exercised with a mock DLL, not a connected device. The existing 30 tests pass despite these findings.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions