@@ -593,8 +593,8 @@ QorePythonThreadInfo QorePythonProgram::setContext() const {
593593 if (!python) {
594594 python = PyThreadState_New (interpreter);
595595
596- // printd(5, "QorePythonProgram::setContext() this: %p created new thread context: %p (py_thr_map: %p " \
597- // "size: %d)\n", this, python, &py_thr_map, (int)py_thr_map.size());
596+ printd (5 , " QorePythonProgram::setContext() this: %p created new thread context: %p (py_thr_map: %p "
597+ " size: %d)\n " , this , python, &py_thr_map, (int )py_thr_map.size ());
598598 assert (python);
599599 assert (python->gilstate_counter == 1 );
600600 // the thread state will be deleted when the thread terminates or the interpreter is deleted
@@ -1179,7 +1179,8 @@ void QorePythonProgram::exportClass(ExceptionSink* xsink, QoreString& arg) {
11791179 ns = ns->findCreateNamespacePathAll (ns_str.c_str ());
11801180 }
11811181
1182- addClassToNamespaceIntern (xsink, ns, (PyTypeObject*)*obj, strpath.back ().c_str (), i);
1182+ strset_t nsset;
1183+ addClassToNamespaceIntern (xsink, ns, (PyTypeObject*)*obj, strpath.back ().c_str (), i, nsset);
11831184}
11841185
11851186void QorePythonProgram::addModulePath (ExceptionSink* xsink, QoreString& arg) {
@@ -2068,7 +2069,8 @@ QoreClass* QorePythonProgram::getCreateQorePythonClass(ExceptionSink* xsink, PyT
20682069 return nullptr ;
20692070 }
20702071
2071- return getCreateQorePythonClassIntern (xsink, type, nullptr , flags);
2072+ strset_t nsset;
2073+ return getCreateQorePythonClassIntern (xsink, type, nsset, nullptr , flags);
20722074}
20732075
20742076QoreNamespace* QorePythonProgram::getNamespaceForObject (PyObject* obj) {
@@ -2115,7 +2117,7 @@ QoreNamespace* QorePythonProgram::getNamespaceForObject(PyObject* obj) {
21152117}
21162118
21172119QoreClass* QorePythonProgram::getCreateQorePythonClassIntern (ExceptionSink* xsink, PyTypeObject* type,
2118- const char * cname, int flags) {
2120+ strset_t & nsset, const char * cname, int flags) {
21192121 // printd(5, "QorePythonProgram::getCreateQorePythonClassIntern() class: '%s'\n", type->tp_name);
21202122 // see if the Python type already represents a Qore class
21212123 if (PyQoreObjectType_Check (type)) {
@@ -2131,11 +2133,11 @@ QoreClass* QorePythonProgram::getCreateQorePythonClassIntern(ExceptionSink* xsin
21312133 }
21322134
21332135 // get relative path to class and class name
2134- std::string rpath_str;
2136+ QoreString rpath_str;
21352137 if (!cname) {
21362138 const char * p = strrchr (type->tp_name , ' .' );
21372139 if (p) {
2138- rpath_str = std::string (type->tp_name , p - type->tp_name );
2140+ rpath_str. set (type->tp_name , p - type->tp_name );
21392141 cname = p + 1 ;
21402142 } else {
21412143 cname = type->tp_name ;
@@ -2144,42 +2146,60 @@ QoreClass* QorePythonProgram::getCreateQorePythonClassIntern(ExceptionSink* xsin
21442146
21452147 // create new QorePythonClass
21462148 QoreNamespace* ns = getNamespaceForObject (reinterpret_cast <PyObject*>(type));
2147- return addClassToNamespaceIntern (xsink, ns, type, cname, i, flags);
2149+ if (!rpath_str.empty () && rpath_str.startsWith (ns->getName ())) {
2150+ size_t len = strlen (ns->getName ());
2151+ if (rpath_str[len] == ' .' && rpath_str.size () > len) {
2152+ rpath_str.replace (0 , len + 1 , nullptr );
2153+ rpath_str.replaceAll (" ." , " ::" );
2154+ ns = ns->findCreateNamespacePathAll (rpath_str.c_str ());
2155+ }
2156+ }
2157+ return addClassToNamespaceIntern (xsink, ns, type, cname, i, nsset, flags);
21482158}
21492159
21502160QorePythonClass* QorePythonProgram::addClassToNamespaceIntern (ExceptionSink* xsink, QoreNamespace* ns,
2151- PyTypeObject* type, const char * cname, clmap_t ::iterator i, int flags) {
2161+ PyTypeObject* type, const char * cname, clmap_t ::iterator i, strset_t & nsset, int flags) {
21522162 // get a unique name for the class
21532163 QoreString cname_str = cname;
2164+ // namespace path
2165+ std::string ns_path = ns->getPath (true );
2166+ // full path of class with ns
2167+ std::string full_path;
2168+ strset_t ::iterator nsi;
21542169 {
21552170 int base = 0 ;
2156- while (ns->findLocalClass (cname_str.c_str ())) {
2171+ while (true ) {
2172+ full_path = ns_path + " ::" + cname_str.c_str ();
2173+ nsi = nsset.find (full_path);
2174+ if (nsi == nsset.end () && !ns->findLocalClass (cname_str.c_str ())) {
2175+ break ;
2176+ }
21572177 cname_str.clear ();
21582178 cname_str.sprintf (" %s_base_%d" , cname, base++);
21592179 }
21602180 }
21612181 cname = cname_str.c_str ();
21622182
21632183 // create new class
2164- std::string path = ns-> getPath ( true );
2165- path += " :: " ;
2166- path += cname;
2167- std::unique_ptr<QorePythonClass> cls ( new QorePythonClass ( this , cname, path. c_str ()) );
2184+ std::unique_ptr<QorePythonClass> cls ( new QorePythonClass ( this , cname, full_path. c_str ()) );
2185+
2186+ // add to nsset
2187+ nsset. insert (nsi, full_path );
21682188
21692189 // insert into map
21702190 clmap.insert (i, clmap_t::value_type (type, cls.get ()));
21712191
21722192 // printd(5, "QorePythonProgram::addClassToNamespaceIntern() ns: '%s' cls: '%s' (%s id: %d)\n", ns->getName(),
21732193 // cls->getName(), type->tp_name, cls->getID());
21742194
2175- return setupQorePythonClass (xsink, ns, type, cls, flags);
2195+ return setupQorePythonClass (xsink, ns, type, cls, nsset, flags);
21762196}
21772197
21782198static constexpr int static_meth_flags = QCF_USES_EXTRA_ARGS;
21792199static constexpr int normal_meth_flags = static_meth_flags | QCF_ABSTRACT_OVERRIDE_ALL;
21802200
21812201QorePythonClass* QorePythonProgram::setupQorePythonClass (ExceptionSink* xsink, QoreNamespace* ns, PyTypeObject* type,
2182- std::unique_ptr<QorePythonClass>& cls, int flags) {
2202+ std::unique_ptr<QorePythonClass>& cls, strset_t & nsset, int flags) {
21832203 // printd(5, "QorePythonProgram::setupQorePythonClass() ns: '%s' cls: '%s' (%s) flags: %d\n", ns->getName(),
21842204 // cls->getName(), type->tp_name, flags);
21852205 cls->addConstructor ((void *)type, (q_external_constructor_t )execPythonConstructor, Public,
@@ -2193,7 +2213,7 @@ QorePythonClass* QorePythonProgram::setupQorePythonClass(ExceptionSink* xsink, Q
21932213
21942214 // add single base class
21952215 if (type->tp_base ) {
2196- QoreClass* bclass = getCreateQorePythonClassIntern (xsink, type->tp_base );
2216+ QoreClass* bclass = getCreateQorePythonClassIntern (xsink, type->tp_base , nsset );
21972217 if (!bclass) {
21982218 assert (*xsink);
21992219 return nullptr ;
@@ -2737,7 +2757,8 @@ int QorePythonProgram::importSymbol(ExceptionSink* xsink, PyObject* value, const
27372757 if (PyType_Check (value)) {
27382758 // printd(5, "QorePythonProgram::importSymbol() class sym: '%s' -> '%s' (%p)\n", symbol,
27392759 // reinterpret_cast<PyTypeObject*>(value)->tp_name, value);
2740- getCreateQorePythonClassIntern (xsink, reinterpret_cast <PyTypeObject*>(value));
2760+ strset_t nsset;
2761+ getCreateQorePythonClassIntern (xsink, reinterpret_cast <PyTypeObject*>(value), nsset);
27412762 if (*xsink) {
27422763 return -1 ;
27432764 }
0 commit comments