mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 05:50:32 +05:00
parse additional kwargs internally as flags to avoid bad_any_cast
There seem to be somehow multiple py::kwargs classes created in different libraries, because of this the any_cast is failing. To circumvent this we attach them to the MeshingParameters object as flags.
This commit is contained in:
parent
114a517030
commit
9e63ba0943
@ -40,7 +40,7 @@ namespace ngcore
|
||||
|
||||
if (py::isinstance<py::list>(value))
|
||||
{
|
||||
py::list vdl(value);
|
||||
auto vdl = py::cast<py::list>(value);
|
||||
if (py::len(vdl) > 0)
|
||||
{
|
||||
if(py::isinstance<double>(vdl[0]))
|
||||
@ -59,7 +59,7 @@ namespace ngcore
|
||||
|
||||
if (py::isinstance<py::tuple>(value))
|
||||
{
|
||||
py::tuple vdt(value);
|
||||
auto vdt = py::cast<py::tuple>(value);
|
||||
if (py::isinstance<py::float_>(value))
|
||||
flags.SetFlag(s, makeCArray<double>(vdt));
|
||||
if (py::isinstance<py::int_>(value))
|
||||
@ -69,29 +69,32 @@ namespace ngcore
|
||||
}
|
||||
}
|
||||
|
||||
Flags CreateFlagsFromKwArgs(py::object pyclass, const py::kwargs& kwargs, py::list info)
|
||||
Flags CreateFlagsFromKwArgs(const py::kwargs& kwargs, py::object pyclass, py::list info)
|
||||
{
|
||||
static std::shared_ptr<Logger> logger = GetLogger("Flags");
|
||||
auto flags_doc = pyclass.attr("__flags_doc__")();
|
||||
py::dict flags_dict;
|
||||
|
||||
if (kwargs.contains("flags"))
|
||||
{
|
||||
logger->warn("WARNING: using flags as kwarg is deprecated in {}, use the flag arguments as kwargs instead!",
|
||||
std::string(py::str(pyclass)));
|
||||
logger->warn("WARNING: using flags as kwarg is deprecated{}, use the flag arguments as kwargs instead!",
|
||||
pyclass.is_none() ? "" : std::string(" in ") + std::string(py::str(pyclass)));
|
||||
auto addflags = py::cast<py::dict>(kwargs["flags"]);
|
||||
for (auto item : addflags)
|
||||
flags_dict[item.first.cast<string>().c_str()] = item.second;
|
||||
}
|
||||
for (auto item : kwargs)
|
||||
if (!flags_doc.contains(item.first.cast<string>().c_str()) &&
|
||||
!(item.first.cast<string>() == "flags"))
|
||||
logger->warn("WARNING: kwarg '{}' is an undocumented flags option for class {}, maybe there is a typo?",
|
||||
item.first.cast<string>(), std::string(py::str(pyclass)));
|
||||
|
||||
py::dict special;
|
||||
if(py::hasattr(pyclass,"__special_treated_flags__"))
|
||||
special = pyclass.attr("__special_treated_flags__")();
|
||||
if(!pyclass.is_none())
|
||||
{
|
||||
auto flags_doc = pyclass.attr("__flags_doc__")();
|
||||
for (auto item : kwargs)
|
||||
if (!flags_doc.contains(item.first.cast<string>().c_str()) &&
|
||||
!(item.first.cast<string>() == "flags"))
|
||||
logger->warn("WARNING: kwarg '{}' is an undocumented flags option for class {}, maybe there is a typo?",
|
||||
item.first.cast<string>(), std::string(py::str(pyclass)));
|
||||
|
||||
if(py::hasattr(pyclass,"__special_treated_flags__"))
|
||||
special = pyclass.attr("__special_treated_flags__")();
|
||||
}
|
||||
for (auto item : kwargs)
|
||||
{
|
||||
auto name = item.first.cast<string>();
|
||||
@ -116,4 +119,47 @@ namespace ngcore
|
||||
return flags;
|
||||
}
|
||||
|
||||
py::dict CreateDictFromFlags(const Flags& flags)
|
||||
{
|
||||
py::dict d;
|
||||
std::string key;
|
||||
for(auto i : Range(flags.GetNFlagsFlags()))
|
||||
{
|
||||
auto& f = flags.GetFlagsFlag(i, key);
|
||||
d[key.c_str()] = CreateDictFromFlags(f);
|
||||
}
|
||||
for(auto i : Range(flags.GetNStringListFlags()))
|
||||
{
|
||||
auto strlistflag = flags.GetStringListFlag(i, key);
|
||||
py::list lst;
|
||||
for(auto& val : *strlistflag)
|
||||
lst.append(val);
|
||||
d[key.c_str()] = lst;
|
||||
}
|
||||
for(auto i : Range(flags.GetNNumListFlags()))
|
||||
{
|
||||
auto numlistflag = flags.GetNumListFlag(i, key);
|
||||
py::list lst;
|
||||
for(auto& val : *numlistflag)
|
||||
lst.append(val);
|
||||
d[key.c_str()] = lst;
|
||||
}
|
||||
for(auto i : Range(flags.GetNStringFlags()))
|
||||
{
|
||||
auto val = flags.GetStringFlag(i, key);
|
||||
d[key.c_str()] = val;
|
||||
}
|
||||
for(auto i : Range(flags.GetNNumFlags()))
|
||||
{
|
||||
auto val = flags.GetNumFlag(i, key);
|
||||
d[key.c_str()] = val;
|
||||
}
|
||||
for(auto i : Range(flags.GetNDefineFlags()))
|
||||
{
|
||||
auto val = flags.GetDefineFlag(i, key);
|
||||
d[key.c_str()] = val;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
} // namespace ngcore
|
||||
|
@ -16,10 +16,9 @@ namespace ngcore
|
||||
Array<T> makeCArray(const py::object& obj)
|
||||
{
|
||||
Array<T> arr;
|
||||
arr.SetAllocSize(py::len(obj));
|
||||
if(py::isinstance<py::list>(obj))
|
||||
for(auto& val : py::cast<py::list>(obj))
|
||||
arr.Append(py::cast<T>(val));
|
||||
for(auto& val : py::cast<py::list>(obj))
|
||||
arr.Append(py::cast<T>(val));
|
||||
else if(py::isinstance<py::tuple>(obj))
|
||||
for(auto& val : py::cast<py::tuple>(obj))
|
||||
arr.Append(py::cast<T>(val));
|
||||
@ -30,7 +29,10 @@ namespace ngcore
|
||||
|
||||
void NGCORE_API SetFlag(Flags &flags, std::string s, py::object value);
|
||||
// Parse python kwargs to flags
|
||||
Flags NGCORE_API CreateFlagsFromKwArgs(py::object pyclass, const py::kwargs& kwargs, py::list info = py::list());
|
||||
Flags NGCORE_API CreateFlagsFromKwArgs(const py::kwargs& kwargs, py::object pyclass = py::none(),
|
||||
py::list info = py::list());
|
||||
// Create python dict from kwargs
|
||||
py::dict NGCORE_API CreateDictFromFlags(const Flags& flags);
|
||||
|
||||
// *************** Archiving functionality **************
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
#ifndef NETGEN_MESHING_PYTHON_MESH_HPP
|
||||
#define NETGEN_MESHING_PYTHON_MESH_HPP
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
#include <core/python_ngcore.hpp>
|
||||
#include "meshing.hpp"
|
||||
|
||||
namespace netgen
|
||||
@ -168,7 +172,10 @@ inline void CreateMPfromKwargs(MeshingParameters& mp, py::kwargs kwargs, bool th
|
||||
{
|
||||
if(throw_if_not_all_parsed)
|
||||
throw Exception(string("Not all kwargs given to GenerateMesh could be parsed:") + string(py::str(kwargs)));
|
||||
mp.geometrySpecificParameters = kwargs;
|
||||
mp.geometrySpecificParameters = CreateFlagsFromKwArgs(kwargs);
|
||||
}
|
||||
}
|
||||
} // namespace netgen
|
||||
|
||||
#endif // NETGEN_MESHING_PYTHON_MESH_HPP
|
||||
|
||||
|
@ -32,7 +32,7 @@ edgecornerangle: float =
|
||||
|
||||
)delimiter";
|
||||
|
||||
void CreateSTLParametersFromKwargs(STLParameters& stlparam, py::kwargs kwargs)
|
||||
void CreateSTLParametersFromKwargs(STLParameters& stlparam, py::dict kwargs)
|
||||
{
|
||||
if(kwargs.contains("yangle"))
|
||||
stlparam.yangle = py::cast<double>(kwargs.attr("pop")("yangle"));
|
||||
@ -198,14 +198,14 @@ DLL_HEADER void ExportSTL(py::module & m)
|
||||
STLParameters stlparam;
|
||||
if(pars)
|
||||
{
|
||||
if(pars->geometrySpecificParameters.has_value() &&
|
||||
(pars->geometrySpecificParameters.type() == typeid(py::kwargs)))
|
||||
try
|
||||
{
|
||||
auto mp_kwargs = any_cast<py::kwargs>(pars->geometrySpecificParameters);
|
||||
py::print("geometry specific kwargs:", mp_kwargs);
|
||||
auto mp_flags = any_cast<Flags>(pars->geometrySpecificParameters);
|
||||
auto mp_kwargs = CreateDictFromFlags(mp_flags);
|
||||
CreateSTLParametersFromKwargs(stlparam, mp_kwargs);
|
||||
pars->geometrySpecificParameters.reset();
|
||||
}
|
||||
catch(std::bad_any_cast) {}
|
||||
mp = *pars;
|
||||
}
|
||||
CreateSTLParametersFromKwargs(stlparam, kwargs);
|
||||
|
Loading…
Reference in New Issue
Block a user