Skip to content

[BUG]: 3.0.0rc1 regression: pybind11/cast.h:70:32: error: invalid ‘static_cast’ #5694

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 of 3 tasks
HinTak opened this issue May 25, 2025 · 8 comments
Open
2 of 3 tasks
Assignees
Labels
triage New bug, unverified

Comments

@HinTak
Copy link

HinTak commented May 25, 2025

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

2.3.0rc1

Problem description

I am trying out the numpy 2.3.0rc1 arm windows support,
and accidentally enabled building skia-python against pybind11 3.0.0rc1 too - https://github.com/kyamagu/skia-python/actions/runs/15240052449 -

It is failing with pybind11's cast.h:

src/skia/Canvas.cpp:239:19:   required from here
        /opt/python/cp310-cp310/lib/python3.10/site-packages/pybind11/include/pybind11/cast.h:70:32: error: invalid ‘static_cast’ from type ‘const SkCanvas::Lattice::RectType* const’ to type ‘pybind11::detail::type_caster_enum_type<SkCanvas::Lattice::RectType>::Underlying’ {aka ‘unsigned char’}
           70 |             return native_enum(static_cast<Underlying>(src)).release();
              |                                ^~~~~~~~~~

I had a quick look at the upgrade guide and nothing jumps out to me yet.

Reproducible example code


Is this a regression? Put the last known working version here if it is.

2.13.6

@HinTak HinTak added the triage New bug, unverified label May 25, 2025
@henryiii henryiii changed the title [BUG]: 2.3.0rc1 regression: pybind11/cast.h:70:32: error: invalid ‘static_cast’ [BUG]: 3.0.0rc1 regression: pybind11/cast.h:70:32: error: invalid ‘static_cast’ May 27, 2025
@rwgk
Copy link
Collaborator

rwgk commented May 27, 2025

What version (or hash if on master) of pybind11 are you using?
2.3.0rc1

Do you mean 3.0.0rc1?

I am trying out the numpy 2.3.0rc1 arm windows support,
and accidentally enabled building skia-python against pybind11 3.0.0rc1 too - https://github.com/kyamagu/skia-python/actions/runs/15240052449 -

I'm getting a 404 clicking on the link. Could you please double-check the link?

I had a quick look at the upgrade guide and nothing jumps out to me yet.

Did you see/try this already?

  • pybind11/docs/upgrade.rst

    Lines 103 to 118 in 1c10d5e

    * In rare cases, a C++ enum may be bound to Python via a
    :ref:`custom type caster <custom_type_caster>`. In such cases, a
    template specialization like this may be required:
    .. code-block:: cpp
    #if defined(PYBIND11_HAS_NATIVE_ENUM)
    namespace pybind11::detail {
    template <typename FancyEnum>
    struct type_caster_enum_type_enabled<
    FancyEnum,
    enable_if_t<is_fancy_enum<FancyEnum>::value>> : std::false_type {};
    }
    #endif
    This specialization is needed only if the custom type caster is templated.

error: invalid ‘static_cast’ from type ‘const SkCanvas::Lattice::RectType* const’

Hm ... a pointer?

A reproducer would be extremely useful.

@HinTak
Copy link
Author

HinTak commented May 27, 2025

Apologies for so many things - yes, it is pybind11 3.0.0rc1 I accidentally enabled when I enabled numpy 2.3.0rc1 . Numpy 2.3.0rc1, or rather, arm64 windows turned out to be quite a change and I had about a dozen changes to get ci to pass, so I deleted the failed ci logs... anyway, the line of code the log referred is

https://github.com/HinTak/skia-python/blob/1547890ce648f3b8a40abe4120acdfea6277b853/src/skia/Canvas.cpp#L239

Where the enum is defined a few lines up:

https://github.com/HinTak/skia-python/blob/1547890ce648f3b8a40abe4120acdfea6277b853/src/skia/Canvas.cpp#L211

Afaic, it is just doing def_readwrite on a py::enum struct member for which the underlying type is "unsigned char" (a very small enum which takes only a handful of values, 256 is enough). The pointer is just the def_readwrite part to write to it. Hope this make sense?

@HinTak
Copy link
Author

HinTak commented May 27, 2025

Anyway, binding against pybind11 2.13.x is passing now, so this is definitely a regression.

@rwgk
Copy link
Collaborator

rwgk commented May 27, 2025

Sorry I don't have a lot of time to spend on this, could you please

  1. Try the type_caster_enum_type_enabled specialization as documented in the upgrade guide? — I strongly believe that should work.
  2. Reduce your production code into a unit test (and post as a draft PR here)? — This is to help me understand the situation.

Note that the native_enum feature passed testing in a gigantic code base, including many third-party packages (Google, when I was still working there). Therefore your case is likely to be an unusual corner case.

@HinTak
Copy link
Author

HinTak commented May 27, 2025

Okay, thanks for the time. I see it looks similar to #5555 (comment) - I am busy with the original stuff for which this issue comes as a side line, for a few more days. I'll come back to this perhaps in a weeks' time with trying the type caster in 1, and will try to do 2 too.

@henryiii
Copy link
Collaborator

Might this be because it used to convert to the underlying integer type, but now it's expecting a py::native_enum caster to be registered?

@rwgk
Copy link
Collaborator

rwgk commented May 27, 2025

Might this be because it used to convert to the underlying integer type, but now it's expecting a py::native_enum caster to be registered?

... no, I think. The error in the issue description is a compiler error. py::native_enum types are registered at runtime.

I looked around:

include/core/SkCanvas.h:

    struct Lattice {
...
        enum RectType : uint8_t {
            kDefault     = 0, //!< draws SkBitmap into lattice rectangle
            kTransparent,     //!< skips lattice rectangle by making it transparent
            kFixedColor,      //!< draws one of fColors into lattice rectangle
        };
...
    };

That looks totally fine.

But looking at the error message again, I beginning to think what's missing is dealing with pointers to enums correctly. And I'm beginning to be surprised that this didn't surface before. (The cast.h code did pass global testing.)

I think we need to add

    template <typename SrcType>                                                 
    static handle cast(const SrcType *src, return_value_policy, handle parent) {

or similar.

@HinTak
Copy link
Author

HinTak commented May 28, 2025

Looking at the skia-python code again, I am not sure it makes sense for it to be def_readwrite - that field is indeed a pointer to enum (with the underlying uint8_t), but it is meant to be an array of enums where the counts are kept nearby in fXCount / fYCount . So the getter and the setter should manipulate all 3 of those values together. That said, I kind of expect pybind11 to be just dereferencing the first value of the array, like it normally does, instead of failing to compile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage New bug, unverified
Projects
None yet
Development

No branches or pull requests

3 participants