Skip to content

Commit c630f1c

Browse files
libpyside: Add globals structure
Put global data into a struct which in the future will exist per interpreter as interpreters can only share immortal objects. Task-number: PYSIDE-3155 Change-Id: I45ccaac57b41219bd4bd6a9151f820b00a787b0e Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
1 parent 83cbfe0 commit c630f1c

File tree

7 files changed

+77
-23
lines changed

7 files changed

+77
-23
lines changed

sources/pyside6/libpyside/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(libpyside_HEADERS # installed below
2727
pysidemetatype.h
2828
pyside_numpy.h
2929
pyside_p.h
30+
pysideglobals_p.h
3031
pysideproperty.h
3132
pysideproperty_p.h
3233
pysideqapp.h
@@ -54,6 +55,7 @@ set(libpyside_SRC
5455
signalmanager.cpp
5556
pysideclassdecorator.cpp
5657
pysideclassinfo.cpp
58+
pysideglobals.cpp
5759
pysideqenum.cpp
5860
pysideqslotobject_p.cpp
5961
pysidemetafunction.cpp

sources/pyside6/libpyside/feature_select.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "basewrapper.h"
66
#include "pysidestaticstrings.h"
77
#include "class_property.h"
8+
#include "pysideglobals_p.h"
89

910
#include <autodecref.h>
1011
#include <sbkfeature_base.h>
@@ -119,15 +120,17 @@ createDerivedDictType()
119120
return reinterpret_cast<PyTypeObject *>(ChameleonDict);
120121
}
121122

122-
static PyTypeObject *new_dict_type = nullptr;
123-
124-
static void ensureNewDictType()
123+
static PyTypeObject *ensureNewDictType()
125124
{
126-
if (new_dict_type == nullptr) {
127-
new_dict_type = createDerivedDictType();
128-
if (new_dict_type == nullptr)
125+
auto *globals = PySide::globals();
126+
if (globals->newFeatureDictType == nullptr) {
127+
globals->newFeatureDictType = createDerivedDictType();
128+
if (globals->newFeatureDictType == nullptr) {
129+
PyErr_Print();
129130
Py_FatalError("libshiboken: Problem creating ChameleonDict");
131+
}
130132
}
133+
return globals->newFeatureDictType;
131134
}
132135

133136
static inline PyObject *nextInCircle(PyObject *dict)
@@ -165,9 +168,8 @@ static bool replaceClassDict(PyTypeObject *type)
165168
* Replace the type dict by the derived ChameleonDict.
166169
* This is mandatory for all type dicts when they are touched.
167170
*/
168-
ensureNewDictType();
171+
auto *ob_ndt = reinterpret_cast<PyObject *>(ensureNewDictType());
169172
AutoDecRef dict(PepType_GetDict(type));
170-
auto *ob_ndt = reinterpret_cast<PyObject *>(new_dict_type);
171173
auto *new_dict = PyObject_CallObject(ob_ndt, nullptr);
172174
if (new_dict == nullptr || PyDict_Update(new_dict, dict) < 0)
173175
return false;
@@ -190,7 +192,7 @@ static bool addNewDict(PyTypeObject *type, int select_id)
190192
*/
191193
AutoDecRef dict(PepType_GetDict(type));
192194
AutoDecRef orig_dict(PyObject_GetAttr(dict, PySideName::orig_dict()));
193-
auto *ob_ndt = reinterpret_cast<PyObject *>(new_dict_type);
195+
auto *ob_ndt = reinterpret_cast<PyObject *>(ensureNewDictType());
194196
auto *new_dict = PyObject_CallObject(ob_ndt, nullptr);
195197
if (new_dict == nullptr)
196198
return false;
@@ -293,13 +295,16 @@ static inline void SelectFeatureSetSubtype(PyTypeObject *type, int select_id)
293295
}
294296
}
295297

296-
static PyObject *cached_globals{};
297-
static int last_select_id{};
298-
299298
static inline int getFeatureSelectId()
300299
{
301300
static auto *undef = PyLong_FromLong(-1);
302-
static auto *feature_dict = GetFeatureDict();
301+
302+
auto *libGlobals = PySide::globals();
303+
PyObject *&feature_dict = PySide::globals()->featureDict;
304+
if (feature_dict == nullptr)
305+
feature_dict = GetFeatureDict();
306+
PyObject *&cached_globals = libGlobals->cachedFeatureGlobals;
307+
int &last_select_id = libGlobals->lastSelectedFeatureId;
303308

304309
Shiboken::AutoDecRef globals(PepEval_GetFrameGlobals());
305310
if (globals.isNull() || globals.object() == cached_globals)
@@ -342,7 +347,7 @@ static inline void SelectFeatureSet(PyTypeObject *type)
342347

343348
int select_id = getFeatureSelectId();
344349
static int last_select_id{};
345-
static PyTypeObject *last_type{};
350+
PyTypeObject *&last_type = PySide::globals()->lastFeatureType;
346351

347352
// PYSIDE-2029: Implement a very simple but effective cache that cannot fail.
348353
if (type == last_type && select_id == last_select_id)
@@ -415,9 +420,11 @@ void init()
415420
patch_property_impl();
416421
is_initialized = true;
417422
}
418-
last_select_id = 0;
423+
419424
// Reset the cache. This is called at any "from __feature__ import".
420-
cached_globals = nullptr;
425+
auto *globals = PySide::globals();
426+
globals->lastSelectedFeatureId = 0;
427+
globals->cachedFeatureGlobals = nullptr;
421428
}
422429

423430
void Enable(bool enable)

sources/pyside6/libpyside/pyside.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "pyside_p.h"
1212
#include "signalmanager.h"
1313
#include "pysideclassinfo_p.h"
14+
#include "pysideglobals_p.h"
1415
#include "pysideproperty_p.h"
1516
#include "class_property.h"
1617
#include "pysideproperty.h"
@@ -1020,18 +1021,16 @@ bool registerInternalQtConf()
10201021
return isRegistered;
10211022
}
10221023

1023-
static PyTypeObject *qObjType = nullptr;
1024-
10251024
PyTypeObject *qObjectType()
10261025
{
1027-
PyTypeObject *result = qObjType;
1026+
PyTypeObject *result = globals()->qobjectType;
10281027
Q_ASSERT(result);
10291028
return result;
10301029
}
10311030

10321031
void setQObjectType(PyTypeObject *t)
10331032
{
1034-
qObjType = t;
1033+
globals()->qobjectType = t;
10351034
}
10361035

10371036
bool isQObjectDerived(PyTypeObject *pyType, bool raiseError)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (C) 2025 The Qt Company Ltd.
2+
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3+
4+
#include "pysideglobals_p.h"
5+
6+
namespace PySide
7+
{
8+
9+
Globals *globals()
10+
{
11+
static Globals result;
12+
return &result;
13+
}
14+
15+
} // namespace PySide
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (C) 2025 The Qt Company Ltd.
2+
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3+
4+
#ifndef PYSIDE_GLOBALS_P_H
5+
#define PYSIDE_GLOBALS_P_H
6+
7+
#include <sbkpython.h>
8+
9+
namespace PySide
10+
{
11+
12+
struct Globals // Per interpreter globals of libpyside
13+
{
14+
PyTypeObject *newFeatureDictType = nullptr;
15+
PyObject *featureDict = nullptr;
16+
PyObject *cachedFeatureGlobals = nullptr;
17+
PyTypeObject *lastFeatureType = nullptr;
18+
int lastSelectedFeatureId = 0;
19+
PyTypeObject *qobjectType = nullptr;
20+
PyObject *emptyTuple = nullptr;
21+
PyObject *pickleReduceFunc;
22+
PyObject *pickleEvalFunc;
23+
};
24+
25+
Globals *globals();
26+
27+
} //namespace PySide
28+
29+
#endif //PYSIDE_GLOBALS_P_H

sources/pyside6/libpyside/pysideslot.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "pysidesignal_p.h"
55
#include "pysideslot_p.h"
66
#include "pysidestaticstrings.h"
7+
#include "pysideglobals_p.h"
78

89
#include <autodecref.h>
910
#include <basewrapper.h>
@@ -74,12 +75,12 @@ static PyTypeObject *PySideSlot_TypeF()
7475

7576
int slotTpInit(PyObject *self, PyObject *args, PyObject *kw)
7677
{
77-
static PyObject *emptyTuple = nullptr;
7878
static const char *kwlist[] = {"name", "result", "tag", nullptr};
7979
char *argName = nullptr;
8080
PyObject *argResult = nullptr;
8181
char *tag = nullptr;
8282

83+
PyObject *& emptyTuple = PySide::globals()->emptyTuple;
8384
if (emptyTuple == nullptr)
8485
emptyTuple = PyTuple_New(0);
8586

sources/pyside6/libpyside/signalmanager.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "pysideproperty.h"
88
#include "pysideproperty_p.h"
99
#include "pyside_p.h"
10+
#include "pysideglobals_p.h"
1011
#include "dynamicqmetaobject.h"
1112
#include "pysidemetafunction_p.h"
1213

@@ -196,7 +197,7 @@ QDataStream &operator<<(QDataStream &out, const PyObjectWrapper &myObj)
196197
return out;
197198
}
198199

199-
static PyObject *reduce_func = nullptr;
200+
PyObject *&reduce_func = PySide::globals()->pickleReduceFunc;
200201

201202
Shiboken::GilState gil;
202203
if (!reduce_func) {
@@ -228,7 +229,7 @@ QDataStream &operator>>(QDataStream &in, PyObjectWrapper &myObj)
228229
return in;
229230
}
230231

231-
static PyObject *eval_func = nullptr;
232+
PyObject *&eval_func = PySide::globals()->pickleEvalFunc;
232233

233234
Shiboken::GilState gil;
234235
if (!eval_func) {

0 commit comments

Comments
 (0)