#include "logging.hpp" #include "python_ngcore.hpp" namespace py = pybind11; using std::string; namespace ngcore { bool ngcore_have_numpy = false; bool parallel_pickling = true; void SetFlag(Flags &flags, string s, py::object value) { if (py::isinstance(value)) { Flags nested_flags; for(auto item : value.cast()) SetFlag(nested_flags, item.first.cast(), item.second.cast()); flags.SetFlag(s, nested_flags); return; } if (py::isinstance(value)) flags.SetFlag(s, value.cast()); if (py::isinstance(value)) flags.SetFlag(s, value.cast()); if (py::isinstance(value)) flags.SetFlag(s, double(value.cast())); if (py::isinstance(value)) flags.SetFlag(s, value.cast()); if (py::isinstance(value)) { auto vdl = py::cast(value); if (py::len(vdl) > 0) { if(py::isinstance(vdl[0]) || py::isinstance(vdl[0])) flags.SetFlag(s, makeCArray(vdl)); if(py::isinstance(vdl[0])) flags.SetFlag(s, makeCArray(vdl)); } else { Array dummystr; Array dummydbl; flags.SetFlag(s,dummystr); flags.SetFlag(s,dummydbl); } } if (py::isinstance(value)) { auto vdt = py::cast(value); if (py::isinstance(value)) flags.SetFlag(s, makeCArray(vdt)); if (py::isinstance(value)) flags.SetFlag(s, makeCArray(vdt)); if (py::isinstance(value)) flags.SetFlag(s, makeCArray(vdt)); } } Flags CreateFlagsFromKwArgs(const py::kwargs& kwargs, py::object pyclass, py::list info) { static std::shared_ptr logger = GetLogger("Flags"); py::dict flags_dict; if (kwargs.contains("flags")) { 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(kwargs["flags"]); for (auto item : addflags) flags_dict[item.first.cast().c_str()] = item.second; } py::dict special; if(!pyclass.is_none()) { auto flags_doc = pyclass.attr("__flags_doc__")(); for (auto item : kwargs) if (!flags_doc.contains(item.first.cast().c_str()) && !(item.first.cast() == "flags")) logger->warn("WARNING: kwarg '{}' is an undocumented flags option for class {}, maybe there is a typo?", item.first.cast(), 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(); if (name != "flags") { if(!special.contains(name.c_str())) flags_dict[name.c_str()] = item.second; } } Flags flags; for(auto item : flags_dict) SetFlag(flags, item.first.cast(), item.second.cast()); for (auto item : kwargs) { auto name = item.first.cast(); if (name != "flags") { if(special.contains(name.c_str())) special[name.c_str()](item.second, &flags, info); } } 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; } for(auto i : Range(flags.GetNAnyFlags())) { auto& a = flags.GetAnyFlag(i, key); d[key.c_str()] = CastAnyToPy(a); } return d; } } // namespace ngcore