Skip to content

[BUG]: Supplying nb::arg()s changes implicit conversion behavior for self #1061

@inducer

Description

@inducer

Problem description

The self argument to a function appears to undergo implicit conversion if a method is wrapped without supplying any nb::args, but as soon as they are supplied, implicit conversion no longer takes place.

To reproduce: Within nanobind_example, use this as nanobind_example_ext.cpp:

#include <nanobind/nanobind.h>

namespace nb = nanobind;

using namespace nb::literals;

struct a {};
struct b {
    b(a const &inst_a)
    {}
};

void f(b const &inst_b, int i)
{ }

NB_MODULE(nanobind_example_ext, m) {
    nb::class_<a> wrap_a(m, "A");
    nb::class_<b> wrap_b(m, "B");

    wrap_a.def(nb::init<>());
    wrap_b.def(nb::init_implicit<a const &>());
    wrap_a.def("f_no_args", f);
    wrap_a.def("f_with_args", f, nb::arg("i"));
}

Use this as __init__.py:

from .nanobind_example_ext import A, B

And run the following script:

import nanobind_example as nbex

a = nbex.A()
a.f_no_args(0)
a.f_with_args(0)

Observe the following output:

$ python nbex.py
Traceback (most recent call last):
  File "/home/andreas/tmp/nbex.py", line 5, in <module>
    a.f_with_args(0)
    ~~~~~~~~~~~~~^^^
TypeError: f_with_args(): incompatible function arguments. The following argument types are supported:
    1. f_with_args(self, i: int) -> None

Invoked with types: nanobind_example.nanobind_example_ext.A, int

Observe that the call to f_no_args has succeeded, but the call to f_with_args is failing.

I've chased this down to a point where I think supplying args must be clearing the cast_flags::convert on the self argument. But I wasn't able to pinpoint how/where that happens.

Observed with nanobind 2.7.0, Python 3.13.3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions