Troubleshooting

Compilation errors

error: invalid use of incomplete type

pybind11 requires you to use complete types when binding an object. Typically this means that somewhere in the header there was a forward declaration:

class Foo;

Foo is defined in some header, but not the header you’re scanning. To fix it, tell the generator to include the header:

extra_includes:
- path/to/Foo.h

error: ‘SomeEnum’ has not been declared

Often this is referring to a parameter type or a default argument. You can use the ‘param_override’ setting for that function to fix it. For example, if you had the following C++ code:

void fnWithEnum(SomeEnum e);

And SomeEnum was actually somens::SomeEnum but robotpy-build wasn’t able to automatically determine that. You could fix it like so:

functions:
  fnWithEnum:
    param_override:
      # e is the name of the param
      e:
        # x_type tells the generator to force the type to the specified string
        x_type: "somens::SomeEnum"

error: static assertion failed: Cannot use an alias class with a non-polymorphic type

pybind11 has a static assert that occurs when an trampoline class is specified for a class that is a subclass of some other class, but none of its bases have any virtual functions. This is to prevent

robotpy-build generates trampoline classes to allow python code to override virtual functions in C++ classes. robotpy-build isn’t always able to detect when a trampoline isn’t appropriate.

When this error occurs, you can force robotpy-build to turn off trampoline classes for a specific type:

classes:
  X:
    force_no_trampoline: true

error: ‘rpygen/__SomeClassName.hpp’ file not found

This occurs when robotpy-build has created a trampoline class for a child class, and it is trying to include the header for the parent trampoline class. There are several reasons why this might happen.

Sometimes this error occurs because the parent lives in a different package that you didn’t declare a dependency on in pyproject.toml. Add the dependency and the parent trampoline class should be found.

If the base class is polymorphic in a way that robotpy-build wasn’t able to detect, you can force it to be polymorphic:

classes:
  X:
    is_polymorphic: true

Unfortunately, sometimes the base isn’t a polymorphic type and you can’t change it. In this case you can turn off the trampoline class for the child class:

classes:
  X:
    force_no_trampoline: true

build_pyi errors

Sometimes when running the build_pyi step, you’ll see errors that look like this.

ERROR - def fn(arg: frc::LinearPlantInversionFeedforward<1, 1>) -> None: ...
ERROR -               ^-- Invalid syntax

What this means is the argument ‘arg’ is not currently wrapped by pybind11 – or if it is, it hasn’t been imported by the current python package.

  • If it hasn’t been wrapped, wrap it

  • If it hasn’t been imported, you can just add the other package to the wrapper’s depends list.

Runtime errors

ImportError: dynamic module does not define module export function (PyInit__XXX)

Sometimes this exhibits itself as unresolved external symbol PyInit__XXX.

This error indicates that you compiled a Python C++ module without actually defining a module. Most likely, you forgot to to add a file which contains these contents:

#include <rpygen_wrapper.hpp>

RPYBUILD_PYBIND11_MODULE(m) {
    initWrapper(m);
}

You can of course put other content in here if needed.