1818#include < limits.h>
1919#include < structmember.h>
2020
21-
2221namespace CPyCppyy {
2322
2423enum ETypeDetails {
@@ -35,7 +34,7 @@ enum ETypeDetails {
3534static PyObject* dm_get (CPPDataMember* dm, CPPInstance* pyobj, PyObject* /* kls */ )
3635{
3736// cache lookup for low level views
38- if (dm->fFlags & kIsCachable ) {
37+ if (pyobj && dm->fFlags & kIsCachable ) {
3938 CPyCppyy::CI_DatamemberCache_t& cache = pyobj->GetDatamemberCache ();
4039 for (auto it = cache.begin (); it != cache.end (); ++it) {
4140 if (it->first == dm->fOffset ) {
@@ -49,6 +48,11 @@ static PyObject* dm_get(CPPDataMember* dm, CPPInstance* pyobj, PyObject* /* kls
4948 }
5049 }
5150
51+ // non-initialized or public data accesses through class (e.g. by help())
52+ void * address = dm->GetAddress (pyobj);
53+ if (!address || (intptr_t )address == -1 /* Cling error */ )
54+ return nullptr ;
55+
5256 if (dm->fFlags & (kIsEnumPrep | kIsEnumType )) {
5357 if (dm->fFlags & kIsEnumPrep ) {
5458 // still need to do lookup; only ever try this once, then fallback on converter
@@ -220,7 +224,7 @@ static void dm_dealloc(CPPDataMember* dm)
220224static PyMemberDef dm_members[] = {
221225 {(char *)" __doc__" , T_OBJECT, offsetof (CPPDataMember, fDoc ), 0 ,
222226 (char *)" writable documentation" },
223- {NULL } /* Sentinel */
227+ {NULL , 0 , 0 , 0 , nullptr } /* Sentinel */
224228};
225229
226230// = CPyCppyy datamember proxy access to internals ============================
@@ -308,10 +312,17 @@ PyTypeObject CPPDataMember_Type = {
308312#if PY_VERSION_HEX >= 0x03040000
309313 , 0 // tp_finalize
310314#endif
315+ #if PY_VERSION_HEX >= 0x03080000
316+ , 0 // tp_vectorcall
317+ #endif
318+ #if PY_VERSION_HEX >= 0x030c0000
319+ , 0 // tp_watched
320+ #endif
311321};
312322
313323} // namespace CPyCppyy
314324
325+
315326// - public members -----------------------------------------------------------
316327void CPyCppyy::CPPDataMember::Set (Cppyy::TCppScope_t scope, Cppyy::TCppScope_t data)
317328{
0 commit comments