Skip to content

Enforcement of const in instance methods #100

@philthompson10

Description

@philthompson10

SIP considers the constness of a C++ function so that...

Bar foo();
Bar foo() const;

...have different signatures. However it will then complain about the two functions having the same Python signature. Normally the bindings author would just wrap the non-const overload. (The alternative would be to wrap the other overload using the /PyName/ annotation.)

Currently the wrapper of a C++ instance assumes that the instance is non-const and therefore assumes that it is safe to call its non-const functions. This is enforced so that if a C++ function returns a reference to a const object then SIP will make a non-const copy on the heap and wrap that rather than the original object to ensure that non-const calls are safe. There are obvious problems with this (longstanding) approach:

  • if the state of the original C++ instance changes then those changes will not be accessible from the Python wrapper
  • no protection is provided for const pointers.

The solution is to make the Python wrapper aware of the constness of the C++ instance and to take it into account when determining which overload to call. This will also allow both non-const and const overloads (as above) to be wrapped and called appropriately.

In practice the current approach doesn't cause significant problems (there has never been a bug report related to it). However it does depend on the availability of a copy ctor for the type being returned. Modern C++ code tends to pay more attention to whether an instance can be copied, moved or neither and so the assumption about the availability of a copy ctor is becoming less safe.

The changes required are relatively simple to implement, however more problematic is how to manage the change. Method calls that previously worked fine (although strictly speaking were buggy) will now raise an exception. It is unacceptable to impose the change as part of a normal version update.

Options:

  • The ability to dynamically select the new behaviour (on a per-application basis) is added to currently supported ABIs:
    • the old behaviour is the default
    • the old behaviour is the default but results in a deprecation warning
    • the new behaviour is the default
    • the old behaviour is removed.
  • The new behaviour is implemented in ABI v14 only. (ABI v14 is the ABI that supports multiple interpreters and free threading.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions