Skip to content

[cpyrt] Detect enum arguments by type in overload priority - #75

Open
aaronj0 wants to merge 22 commits into
compiler-research:mainfrom
aaronj0:enum-args-by-type-priority
Open

[cpyrt] Detect enum arguments by type in overload priority#75
aaronj0 wants to merge 22 commits into
compiler-research:mainfrom
aaronj0:enum-args-by-type-priority

Conversation

@aaronj0

@aaronj0 aaronj0 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

GetPriority() deprioritizes enum arguments so that a competing integer overload wins, since C++ has no implicit int->enum conversion, but it detected them with IsEnumScope(GetScope(name)). GetScope does not resolve an enum name to a scope, so the penalty never applied. Query the argument type with IsEnumType as well, per the existing FIXME.

aaronj0 and others added 22 commits August 25, 2026 15:17
…er-research#41)

* [cpyrt] Improve error reporting for method calls without C++ object

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* [test] Add test for method calls on an instance without a C++ object

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Grigori Rybkine <Grigori.Rybkine@cern.ch>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…esearch#40)

* [cpyrt] Penalize void* arguments in overload priority as intended

* [test] Add regression test for void* overload priority

---------

Co-authored-by: Emery Conrad <emery.conrad@chicagotrading.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…rch#42)

Fixes the long-standing header duplication (previously `Cppyy.h` and `cpp_cppyy.h`) between cpyrt and interop, so that there is only a single source of definitions for the `cppjit::interop` API and types.
Changed definition of a function to the test it is actually used, and added a missing import
…er-research#50)

Drops wheel sizes by about half. Previously the entire install tree of CppInterOp was staged that included duplicate shared libs due to versioning. This is fixed by adding a stripped shared-lib option in CppInterOp, leveraged in this patch.
…ch#52)

[cpyrt] Clear the error indicator only where a call failed

A debug build of CPython asserts when a C API call is made with the
error indicator already set, so the __cpp_cross__ annotation, the
meta_setattro fallthrough to tp_setattro, and the VectorData alias need
it cleared. Clear it only on the failing path: AddToClass reports
failure, and the two CPPScope sites can test the value they just
produced, so an error raised elsewhere still propagates.

meta_getattro returns a new reference; release it instead of leaking it.
* [test] Find eigen and boost under the Homebrew and MacPorts prefixes

* [ci] Build and test manylinux and macOS arm64 wheels
…esearch#54)

SetArg() created an element converter per call and appended it to
fConverters, but Clear() frees only fBuffer, so the vector grew without
bound across repeated std::initializer_list conversions. Create each
element converter once, on first use of its index, and reuse it.
…iler-research#51)

* Serialize and atomize test dictionary builds

* Force loadfile scheduling for distributed test runs

* Normalize the xfail marker keyword order

* Correct the xfail markers and add missing reasons

* Add the --run-crashing-xfails collection option

* Enable strict xfail

* Drop xfail markers that no longer fail on macOS and cling

* Make the span tests include their own header
…ompiler-research#66)

A deleted function is not callable, yet it still entered the overload
set and contributed a spurious conversion error to every failed-call
report. That defeats SetDetailedException's rule that failures which are
all C++ exceptions of one type are re-raised as that type.

Un-xfails test34_no_ctors_in_base in test_crossinheritance.py, which
expects TypeError for a class whose only constructors are deleted.
…mpiler-research#64)

Expose method const-qualification in func_overloads_types

* [cpyrt] Add per-overload 'is_const' to GetSignatureTypes
* [test] Add regression test for overload constness reporting

Co-authored-by: Yasser Rathore <yasser.rathore@chicagotrading.com>
Co-authored-by: rathorey-ctc <rathorey-ctc@users.noreply.github.com>
…h#69)

[test] Correct the xfail marks tripping the nightly matrix
…arch#72)

* [ci] Skip README-only PRs and drop the dead master push trigger

* [ci] Run the nightly matrix on PRs labeled test-nightly
…arch#71)

VoidPtrRefConverter was registered only for "const void*&", so a mutable
void*& fell under the general ban on non-const pointer references.
Passing an object through an opaque void*& handle is supported by
design; the exact-match factory lookup runs before the T*& rejection,
which stays in effect for typed pointer references.
…rch#70)

ExecuteFast() ends with a Windows-only block that drops the result when
a Python exception is pending. It is shared by every CPPMethod subclass,
including CPPConstructor, whose executor returns the address of the new
C++ object cast to PyObject*; decref'ing that corrupts the heap. Ask the
method whether its executor hands back a real PyObject* first. The
object leaks instead, on the error path of a call that is already
failing.
…earch#65)

LowLevelView.reshape() verified sizes by comparing the sum of the
dimensions instead of the number of elements, their product: reshaping a
five element array to (2, 3) was accepted because 5 == 2 + 3, while
(1, 5) was rejected. The check is skipped for arrays of unknown size,
the ones that typically get reshaped, which is why this went unnoticed.

A correct size check is not enough, though: the strides and the
converter projecting sub-views are chosen for the rank and layout of the
view's C++ type and are not re-derived when reshaping. Any rank change
produced a view reading garbage, and even the identity reshape of a
fixed int[3][5] corrupted its strides.

Reshape therefore now does what it is actually used for: providing the
extent of dimensions the type leaves open, such as the size of an array
behind a pointer. The rank must match, and only an unknown or empty
dimension may be set, with -1 still standing for "unknown"; anything
else raises ValueError, including dimensions whose byte size would
overflow. The byte length is counted in strides of the outermost
dimension as the creators count it, which for views with an itemsize
override (const char*[], notably) differs from the itemsize, and the
strides themselves are left as the creator laid them down.

Also share the "fake max" marking an unknown outermost dimension between
the creators and reshape (it was rederived from the itemsize, mistaking
the unknown size of row-pointer and itemsize-overridden views for a
known one), give the shape property a proper setter (reshape was
installed directly despite its mismatching signature, so assignment
misreported its result and deletion crashed), refuse to reshape a view
without dimensions instead of reading through its null strides, and
check allocations in the shape getter.
…ompiler-research#67)

Every Python object has a __name__, so an object naming no C++ type
reached AddTypeName's fallback, where GetType() returned null; that null
was then pushed as a template argument and dereferenced by IsEnumType.
Skip such an argument, and report the string-based path's failure as
TypeError like the type-based one already does.
GetPriority() deprioritizes enum arguments so that a competing integer
overload wins, since C++ has no implicit int->enum conversion, but it
detected them with IsEnumScope(GetScope(name)). GetScope does not
resolve an enum name to a scope, so the penalty never applied. Query the
argument type with IsEnumType as well, per the existing FIXME.
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.

4 participants