mirror of
https://github.com/NGSolve/netgen.git
synced 2024-12-26 13:50:33 +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))
|
if (py::isinstance<py::list>(value))
|
||||||
{
|
{
|
||||||
py::list vdl(value);
|
auto vdl = py::cast<py::list>(value);
|
||||||
if (py::len(vdl) > 0)
|
if (py::len(vdl) > 0)
|
||||||
{
|
{
|
||||||
if(py::isinstance<double>(vdl[0]))
|
if(py::isinstance<double>(vdl[0]))
|
||||||
@ -59,7 +59,7 @@ namespace ngcore
|
|||||||
|
|
||||||
if (py::isinstance<py::tuple>(value))
|
if (py::isinstance<py::tuple>(value))
|
||||||
{
|
{
|
||||||
py::tuple vdt(value);
|
auto vdt = py::cast<py::tuple>(value);
|
||||||
if (py::isinstance<py::float_>(value))
|
if (py::isinstance<py::float_>(value))
|
||||||
flags.SetFlag(s, makeCArray<double>(vdt));
|
flags.SetFlag(s, makeCArray<double>(vdt));
|
||||||
if (py::isinstance<py::int_>(value))
|
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");
|
static std::shared_ptr<Logger> logger = GetLogger("Flags");
|
||||||
auto flags_doc = pyclass.attr("__flags_doc__")();
|
|
||||||
py::dict flags_dict;
|
py::dict flags_dict;
|
||||||
|
|
||||||
if (kwargs.contains("flags"))
|
if (kwargs.contains("flags"))
|
||||||
{
|
{
|
||||||
logger->warn("WARNING: using flags as kwarg is deprecated in {}, use the flag arguments as kwargs instead!",
|
logger->warn("WARNING: using flags as kwarg is deprecated{}, use the flag arguments as kwargs instead!",
|
||||||
std::string(py::str(pyclass)));
|
pyclass.is_none() ? "" : std::string(" in ") + std::string(py::str(pyclass)));
|
||||||
auto addflags = py::cast<py::dict>(kwargs["flags"]);
|
auto addflags = py::cast<py::dict>(kwargs["flags"]);
|
||||||
for (auto item : addflags)
|
for (auto item : addflags)
|
||||||
flags_dict[item.first.cast<string>().c_str()] = item.second;
|
flags_dict[item.first.cast<string>().c_str()] = item.second;
|
||||||
}
|
}
|
||||||
|
py::dict special;
|
||||||
|
if(!pyclass.is_none())
|
||||||
|
{
|
||||||
|
auto flags_doc = pyclass.attr("__flags_doc__")();
|
||||||
for (auto item : kwargs)
|
for (auto item : kwargs)
|
||||||
if (!flags_doc.contains(item.first.cast<string>().c_str()) &&
|
if (!flags_doc.contains(item.first.cast<string>().c_str()) &&
|
||||||
!(item.first.cast<string>() == "flags"))
|
!(item.first.cast<string>() == "flags"))
|
||||||
logger->warn("WARNING: kwarg '{}' is an undocumented flags option for class {}, maybe there is a typo?",
|
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)));
|
item.first.cast<string>(), std::string(py::str(pyclass)));
|
||||||
|
|
||||||
py::dict special;
|
|
||||||
if(py::hasattr(pyclass,"__special_treated_flags__"))
|
if(py::hasattr(pyclass,"__special_treated_flags__"))
|
||||||
special = pyclass.attr("__special_treated_flags__")();
|
special = pyclass.attr("__special_treated_flags__")();
|
||||||
|
}
|
||||||
for (auto item : kwargs)
|
for (auto item : kwargs)
|
||||||
{
|
{
|
||||||
auto name = item.first.cast<string>();
|
auto name = item.first.cast<string>();
|
||||||
@ -116,4 +119,47 @@ namespace ngcore
|
|||||||
return flags;
|
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
|
} // namespace ngcore
|
||||||
|
@ -16,7 +16,6 @@ namespace ngcore
|
|||||||
Array<T> makeCArray(const py::object& obj)
|
Array<T> makeCArray(const py::object& obj)
|
||||||
{
|
{
|
||||||
Array<T> arr;
|
Array<T> arr;
|
||||||
arr.SetAllocSize(py::len(obj));
|
|
||||||
if(py::isinstance<py::list>(obj))
|
if(py::isinstance<py::list>(obj))
|
||||||
for(auto& val : py::cast<py::list>(obj))
|
for(auto& val : py::cast<py::list>(obj))
|
||||||
arr.Append(py::cast<T>(val));
|
arr.Append(py::cast<T>(val));
|
||||||
@ -30,7 +29,10 @@ namespace ngcore
|
|||||||
|
|
||||||
void NGCORE_API SetFlag(Flags &flags, std::string s, py::object value);
|
void NGCORE_API SetFlag(Flags &flags, std::string s, py::object value);
|
||||||
// Parse python kwargs to flags
|
// 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 **************
|
// *************** Archiving functionality **************
|
||||||
|
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
|
#ifndef NETGEN_MESHING_PYTHON_MESH_HPP
|
||||||
|
#define NETGEN_MESHING_PYTHON_MESH_HPP
|
||||||
|
|
||||||
#include <pybind11/pybind11.h>
|
#include <pybind11/pybind11.h>
|
||||||
|
|
||||||
|
#include <core/python_ngcore.hpp>
|
||||||
#include "meshing.hpp"
|
#include "meshing.hpp"
|
||||||
|
|
||||||
namespace netgen
|
namespace netgen
|
||||||
@ -168,7 +172,10 @@ inline void CreateMPfromKwargs(MeshingParameters& mp, py::kwargs kwargs, bool th
|
|||||||
{
|
{
|
||||||
if(throw_if_not_all_parsed)
|
if(throw_if_not_all_parsed)
|
||||||
throw Exception(string("Not all kwargs given to GenerateMesh could be parsed:") + string(py::str(kwargs)));
|
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
|
} // namespace netgen
|
||||||
|
|
||||||
|
#endif // NETGEN_MESHING_PYTHON_MESH_HPP
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ edgecornerangle: float =
|
|||||||
|
|
||||||
)delimiter";
|
)delimiter";
|
||||||
|
|
||||||
void CreateSTLParametersFromKwargs(STLParameters& stlparam, py::kwargs kwargs)
|
void CreateSTLParametersFromKwargs(STLParameters& stlparam, py::dict kwargs)
|
||||||
{
|
{
|
||||||
if(kwargs.contains("yangle"))
|
if(kwargs.contains("yangle"))
|
||||||
stlparam.yangle = py::cast<double>(kwargs.attr("pop")("yangle"));
|
stlparam.yangle = py::cast<double>(kwargs.attr("pop")("yangle"));
|
||||||
@ -198,14 +198,14 @@ DLL_HEADER void ExportSTL(py::module & m)
|
|||||||
STLParameters stlparam;
|
STLParameters stlparam;
|
||||||
if(pars)
|
if(pars)
|
||||||
{
|
{
|
||||||
if(pars->geometrySpecificParameters.has_value() &&
|
try
|
||||||
(pars->geometrySpecificParameters.type() == typeid(py::kwargs)))
|
|
||||||
{
|
{
|
||||||
auto mp_kwargs = any_cast<py::kwargs>(pars->geometrySpecificParameters);
|
auto mp_flags = any_cast<Flags>(pars->geometrySpecificParameters);
|
||||||
py::print("geometry specific kwargs:", mp_kwargs);
|
auto mp_kwargs = CreateDictFromFlags(mp_flags);
|
||||||
CreateSTLParametersFromKwargs(stlparam, mp_kwargs);
|
CreateSTLParametersFromKwargs(stlparam, mp_kwargs);
|
||||||
pars->geometrySpecificParameters.reset();
|
pars->geometrySpecificParameters.reset();
|
||||||
}
|
}
|
||||||
|
catch(std::bad_any_cast) {}
|
||||||
mp = *pars;
|
mp = *pars;
|
||||||
}
|
}
|
||||||
CreateSTLParametersFromKwargs(stlparam, kwargs);
|
CreateSTLParametersFromKwargs(stlparam, kwargs);
|
||||||
|
Loading…
Reference in New Issue
Block a user