What version (or hash if on master) of pybind11 are you using?
pybind11-2.11.1-py3-none-any.whl.metadata (copied from pip install output when executing pip install -e .)
This was done in MacOS Ventura 13.5.2.
Python 3.10.13 (main, Aug 24 2023, 22:36:46) [Clang 14.0.3 (clang-1403.0.22.14.1)] on darwin
Problem description
The problem happens when I wrap a class to Python where that class enclosed another class.
class P {
public:
EnclosedClass& get();
EnclosedClass enclosed;
};
When calling get(), sometimes the copy constructor of EnclosedClass is called and sometimes it isn't. It all depends on if there is a Python object holding the data member in Python (e.g., when a = P() is defined in Python, setting another variable b = a.enclosed or not affects the calls of copy constructor of EnclosedClass).
The above dependence on a Python object is unexpected. I would hope that the copy constructor is never called at all cases because the codes was returning a reference. Could someone please point me out which thing I have missed?
# Run by `pytest .`
import myproj._example
def test_enclosed_class():
a = myproj._example.TestBind()
# b = a.enclosed
enc = a.get(6)
enc2 = a.get(6)
assert a.enclosed.c == 17
assert enc2.c == 17
assert enc.c == 17
def test_enclosed_class_2():
a = myproj._example.TestBind()
b = a.enclosed
enc = a.get(6)
enc2 = a.get(6)
assert a.enclosed.c == 17
assert enc2.c == 17
assert enc.c == 17
# assert False. # uncomment this line to see the print out that copy constructor of Enclosed is not called.
pyproject.toml
# Run in your virtual environment with `pip install -e .`
[build-system]
requires = ["scikit-build-core>=0.5.0", "pybind11==2.11.1"]
build-backend = "scikit_build_core.build"
[tool.scikit-build]
wheel.expand-macos-universal-tags = true
[project]
name = "myproj"
version = "0.1.0"
description="MYPROJ"
readme = "README.md"
authors = [{ name = "My Name", email = "me@email.com" }]
requires-python = ">=3.10"
classifiers = [
"Development Status :: 3 - Alpha",
# "License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
# "Operating System :: OS Independent",
]
urls = { Homepage = "https://nodarsensor.com" }
dependencies = [ # related to "requires" in setup.py. See https://peps.python.org/pep-0621/#other-names-for-dependencies-optional-dependencies
]
# Originally called "extra-requires" but the python community decided to rename it.
# https://peps.python.org/pep-0621/#other-names-for-dependencies-optional-dependencies
[project.optional-dependencies]
dev = [
"black",
"isort",
"mypy",
"pre-commit",
"pytest",
"pybind11",
"ipython >= 8.15.0",
"jupyter >= 1.0.0",
"notebook >= 7.0.3",
]
all = [
"myproj[dev]",
]
Required prerequisites
What version (or hash if on master) of pybind11 are you using?
pybind11-2.11.1-py3-none-any.whl.metadata (copied from pip install output when executing
pip install -e .
)This was done in MacOS Ventura 13.5.2.
Problem description
The problem happens when I wrap a class to Python where that class enclosed another class.
When calling get(), sometimes the copy constructor of
EnclosedClass
is called and sometimes it isn't. It all depends on if there is a Python object holding the data member in Python (e.g., whena = P()
is defined in Python, setting another variableb = a.enclosed
or not affects the calls of copy constructor ofEnclosedClass
).The above dependence on a Python object is unexpected. I would hope that the copy constructor is never called at all cases because the codes was returning a reference. Could someone please point me out which thing I have missed?
Reproducible example code
I pushed to this repo.
cpp_src/example.cpp
tests/test_enc.py
pyproject.toml
CMakeLists.txt
Is this a regression? Put the last known working version here if it is.
Not a regression