Skip to content

Commit

Permalink
Python: Fix Init Order
Browse files Browse the repository at this point in the history
The init order cannot reference types as arguments, return types
or base classes that are not yet known to Python. This fixes this.

After install, seen with
```
pybind11-stubgen --exit-code -o src/binding/python/ openpmd_api
```
as preparation for Python stub file creation.
  • Loading branch information
ax3l committed Oct 24, 2023
1 parent acaa542 commit bd3adad
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 43 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,6 @@ if(openPMD_HAVE_PYTHON)
src/binding/python/BaseRecord.cpp
src/binding/python/BaseRecordComponent.cpp
src/binding/python/ChunkInfo.cpp
src/binding/python/Container.cpp
src/binding/python/Dataset.cpp
src/binding/python/Datatype.cpp
src/binding/python/Error.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
*
* BSD-style license, see pybind11 LICENSE file.
*/
#pragma once

#include "openPMD/backend/Container.hpp"

#include "openPMD/binding/python/Common.hpp"
Expand All @@ -33,7 +35,7 @@
#include <string>
#include <utility>

namespace detail
namespace openPMD
{
/* based on std_bind.h in pybind11
*
Expand All @@ -46,7 +48,7 @@ template <
typename holder_type = std::unique_ptr<Map>,
typename... Args>
py::class_<Map, holder_type, Attributable>
bind_container(py::handle scope, std::string const &name, Args &&...args)
declare_container(py::handle scope, std::string const &name, Args &&...args)
{
using KeyType = typename Map::key_type;
using MappedType = typename Map::mapped_type;
Expand Down Expand Up @@ -101,6 +103,20 @@ bind_container(py::handle scope, std::string const &name, Args &&...args)
return stream.str();
});

return cl;
}

template <
typename Map,
typename holder_type = std::unique_ptr<Map>,
typename... Args>
py::class_<Map, holder_type, Attributable>
finalize_container(py::class_<Map, holder_type, Attributable> cl)
{
using KeyType = typename Map::key_type;
using MappedType = typename Map::mapped_type;
using Class_ = py::class_<Map, holder_type, Attributable>;

cl.def(
"items",
[](Map &m) { return py::make_iterator(m.begin(), m.end()); },
Expand Down Expand Up @@ -137,23 +153,4 @@ bind_container(py::handle scope, std::string const &name, Args &&...args)

return cl;
}
} // namespace detail

void init_Container(py::module &m)
{
::detail::bind_container<PyIterationContainer>(m, "Iteration_Container");
::detail::bind_container<PyMeshContainer>(m, "Mesh_Container");
::detail::bind_container<PyPartContainer>(m, "Particle_Container");
::detail::bind_container<PyPatchContainer>(m, "Particle_Patches_Container");
::detail::bind_container<PyRecordContainer>(m, "Record_Container");
::detail::bind_container<PyPatchRecordContainer>(
m, "Patch_Record_Container");
::detail::bind_container<PyRecordComponentContainer>(
m, "Record_Component_Container");
::detail::bind_container<PyMeshRecordComponentContainer>(
m, "Mesh_Record_Component_Container");
::detail::bind_container<PyPatchRecordComponentContainer>(
m, "Patch_Record_Component_Container");
::detail::bind_container<PyBaseRecordComponentContainer>(
m, "Base_Record_Component_Container");
}
} // namespace openPMD
2 changes: 2 additions & 0 deletions src/binding/python/BaseRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ Returns true if this record only contains a single component.
m, "Base_Record_Record_Component")
.def_property_readonly(
"scalar", &BaseRecord<RecordComponent>::scalar, doc_scalar);

py::class_<
BaseRecord<MeshRecordComponent>,
Container<MeshRecordComponent> >(m, "Base_Record_Mesh_Record_Component")
.def_property_readonly(
"scalar", &BaseRecord<MeshRecordComponent>::scalar, doc_scalar);

py::class_<
BaseRecord<PatchRecordComponent>,
Container<PatchRecordComponent> >(
Expand Down
6 changes: 6 additions & 0 deletions src/binding/python/BaseRecordComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@
#include "openPMD/Datatype.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/Numpy.hpp"

#include <sstream>

void init_BaseRecordComponent(py::module &m)
{
auto py_brc_cont = declare_container<PyBaseRecordComponentContainer>(
m, "Base_Record_Component_Container");

py::class_<BaseRecordComponent, Attributable>(m, "Base_Record_Component")
.def(
"__repr__",
Expand All @@ -46,4 +50,6 @@ void init_BaseRecordComponent(py::module &m)
.def_property_readonly("dtype", [](BaseRecordComponent &brc) {
return dtype_to_numpy(brc.getDatatype());
});

finalize_container<PyBaseRecordComponentContainer>(py_brc_cont);
}
2 changes: 1 addition & 1 deletion src/binding/python/Helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void init_Helper(py::module &m)
py::print(s.str());
},
py::arg("series"),
py::arg_v("longer", false, "Print more verbose output."),
py::arg("longer") = false,
"List information about an openPMD data series")
// CLI entry point
.def(
Expand Down
6 changes: 6 additions & 0 deletions src/binding/python/Iteration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@
#include "openPMD/Iteration.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"

#include <ios>
#include <sstream>
#include <string>

void init_Iteration(py::module &m)
{
auto py_it_cont =
declare_container<PyIterationContainer>(m, "Iteration_Container");

py::class_<Iteration, Attributable>(m, "Iteration")
.def(py::init<Iteration const &>())

Expand Down Expand Up @@ -93,4 +97,6 @@ void init_Iteration(py::module &m)
py::return_value_policy::copy,
// garbage collection: return value must be freed before Iteration
py::keep_alive<1, 0>());

finalize_container<PyIterationContainer>(py_it_cont);
}
18 changes: 12 additions & 6 deletions src/binding/python/Mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "openPMD/backend/MeshRecordComponent.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/Pickle.hpp"
#include "openPMD/binding/python/UnitDimension.hpp"

Expand All @@ -31,7 +32,17 @@

void init_Mesh(py::module &m)
{
auto py_m_cont = declare_container<PyMeshContainer>(m, "Mesh_Container");

py::class_<Mesh, BaseRecord<MeshRecordComponent> > cl(m, "Mesh");

py::enum_<Mesh::Geometry>(m, "Geometry") // TODO: m -> cl
.value("cartesian", Mesh::Geometry::cartesian)
.value("thetaMode", Mesh::Geometry::thetaMode)
.value("cylindrical", Mesh::Geometry::cylindrical)
.value("spherical", Mesh::Geometry::spherical)
.value("other", Mesh::Geometry::other);

cl.def(py::init<Mesh const &>())

.def(
Expand Down Expand Up @@ -107,10 +118,5 @@ void init_Mesh(py::module &m)
return series.iterations[n_it].meshes[group.at(3)];
});

py::enum_<Mesh::Geometry>(m, "Geometry")
.value("cartesian", Mesh::Geometry::cartesian)
.value("thetaMode", Mesh::Geometry::thetaMode)
.value("cylindrical", Mesh::Geometry::cylindrical)
.value("spherical", Mesh::Geometry::spherical)
.value("other", Mesh::Geometry::other);
finalize_container<PyMeshContainer>(py_m_cont);
}
6 changes: 6 additions & 0 deletions src/binding/python/MeshRecordComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@
#include "openPMD/Series.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/Pickle.hpp"

#include <string>
#include <vector>

void init_MeshRecordComponent(py::module &m)
{
auto py_mrc_cnt = declare_container<PyMeshRecordComponentContainer>(
m, "Mesh_Record_Component_Container");

py::class_<MeshRecordComponent, RecordComponent> cl(
m, "Mesh_Record_Component");
cl.def(
Expand Down Expand Up @@ -79,4 +83,6 @@ void init_MeshRecordComponent(py::module &m)
uint64_t const n_it = std::stoull(group.at(1));
return series.iterations[n_it].meshes[group.at(3)][group.at(4)];
});

finalize_container<PyMeshRecordComponentContainer>(py_mrc_cnt);
}
6 changes: 6 additions & 0 deletions src/binding/python/ParticlePatches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@
#include "openPMD/backend/PatchRecord.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"

#include <string>

void init_ParticlePatches(py::module &m)
{
auto py_pp_cnt =
declare_container<PyPatchContainer>(m, "Particle_Patches_Container");

py::class_<ParticlePatches, Container<PatchRecord> >(m, "Particle_Patches")
.def(
"__repr__",
Expand All @@ -40,4 +44,6 @@ void init_ParticlePatches(py::module &m)
})

.def_property_readonly("num_patches", &ParticlePatches::numPatches);

finalize_container<PyPatchContainer>(py_pp_cnt);
}
6 changes: 6 additions & 0 deletions src/binding/python/ParticleSpecies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "openPMD/backend/Container.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/Pickle.hpp"

#include <sstream>
Expand All @@ -32,6 +33,9 @@

void init_ParticleSpecies(py::module &m)
{
auto py_ps_cnt =
declare_container<PyPartContainer>(m, "Particle_Container");

py::class_<ParticleSpecies, Container<Record> > cl(m, "ParticleSpecies");
cl.def(
"__repr__",
Expand All @@ -49,4 +53,6 @@ void init_ParticleSpecies(py::module &m)
uint64_t const n_it = std::stoull(group.at(1));
return series.iterations[n_it].particles[group.at(3)];
});

finalize_container<PyPartContainer>(py_ps_cnt);
}
6 changes: 6 additions & 0 deletions src/binding/python/PatchRecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@
#include "openPMD/backend/PatchRecordComponent.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/UnitDimension.hpp"

void init_PatchRecord(py::module &m)
{
auto py_pr_cnt =
declare_container<PyPatchRecordContainer>(m, "Patch_Record_Container");

py::class_<PatchRecord, BaseRecord<PatchRecordComponent> >(
m, "Patch_Record")
.def_property(
Expand All @@ -38,4 +42,6 @@ void init_PatchRecord(py::module &m)

// TODO remove in future versions (deprecated)
.def("set_unit_dimension", &PatchRecord::setUnitDimension);

finalize_container<PyPatchRecordContainer>(py_pr_cnt);
}
6 changes: 6 additions & 0 deletions src/binding/python/PatchRecordComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "openPMD/backend/BaseRecordComponent.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/Numpy.hpp"

namespace
Expand All @@ -42,6 +43,9 @@ struct Prc_Load

void init_PatchRecordComponent(py::module &m)
{
auto py_prc_cnt = declare_container<PyPatchRecordComponentContainer>(
m, "Patch_Record_Component_Container");

py::class_<PatchRecordComponent, BaseRecordComponent>(
m, "Patch_Record_Component")
.def_property(
Expand Down Expand Up @@ -195,4 +199,6 @@ void init_PatchRecordComponent(py::module &m)

// TODO remove in future versions (deprecated)
.def("set_unit_SI", &PatchRecordComponent::setUnitSI);

finalize_container<PyPatchRecordComponentContainer>(py_prc_cnt);
}
5 changes: 5 additions & 0 deletions src/binding/python/Record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "openPMD/backend/BaseRecord.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/Pickle.hpp"
#include "openPMD/binding/python/UnitDimension.hpp"

Expand All @@ -31,6 +32,8 @@

void init_Record(py::module &m)
{
auto py_r_cnt = declare_container<PyRecordContainer>(m, "Record_Container");

py::class_<Record, BaseRecord<RecordComponent> > cl(m, "Record");
cl.def(py::init<Record const &>())

Expand Down Expand Up @@ -71,4 +74,6 @@ void init_Record(py::module &m)
uint64_t const n_it = std::stoull(group.at(1));
return series.iterations[n_it].particles[group.at(3)][group.at(4)];
});

finalize_container<PyRecordContainer>(py_r_cnt);
}
6 changes: 6 additions & 0 deletions src/binding/python/RecordComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "openPMD/backend/BaseRecordComponent.hpp"

#include "openPMD/binding/python/Common.hpp"
#include "openPMD/binding/python/Container.H"
#include "openPMD/binding/python/Numpy.hpp"
#include "openPMD/binding/python/Pickle.hpp"

Expand Down Expand Up @@ -757,6 +758,9 @@ void init_RecordComponent(py::module &m)
return view.currentView();
});

auto py_rc_cnt = declare_container<PyRecordComponentContainer>(
m, "Record_Component_Container");

py::class_<RecordComponent, BaseRecordComponent> cl(m, "Record_Component");
cl.def(
"__repr__",
Expand Down Expand Up @@ -1122,6 +1126,8 @@ void init_RecordComponent(py::module &m)
.particles[group.at(3)][group.at(4)][group.at(5)];
});

finalize_container<PyRecordComponentContainer>(py_rc_cnt);

py::enum_<RecordComponent::Allocation>(m, "Allocation")
.value("USER", RecordComponent::Allocation::USER)
.value("API", RecordComponent::Allocation::API)
Expand Down
5 changes: 3 additions & 2 deletions src/binding/python/Series.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ struct SeriesIteratorPythonAdaptor : SeriesIterator

void init_Series(py::module &m)
{
py::class_<IndexedIteration, Iteration>(m, "IndexedIteration")
.def_readonly("iteration_index", &IndexedIteration::iterationIndex);

py::class_<WriteIterations>(m, "WriteIterations", R"END(
Writing side of the streaming API.
Expand Down Expand Up @@ -100,8 +103,6 @@ not possible once it has been closed.
&WriteIterations::currentIteration,
"Return the iteration that is currently being written to, if it "
"exists.");
py::class_<IndexedIteration, Iteration>(m, "IndexedIteration")
.def_readonly("iteration_index", &IndexedIteration::iterationIndex);

py::class_<SeriesIteratorPythonAdaptor>(m, "SeriesIterator")
.def(
Expand Down
Loading

0 comments on commit bd3adad

Please sign in to comment.