Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions atom/src/atomdict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,14 @@ int AtomDict_traverse( AtomDict* self, visitproc visit, void* arg )

void AtomDict_dealloc( AtomDict* self )
{
PyTypeObject* tp = Py_TYPE( self );
PyObject_GC_UnTrack( self );
cppy::clear( &self->m_key_validator );
cppy::clear( &self->m_value_validator );
delete atomdict_cast( self )->pointer;
atomdict_cast( self )->pointer = 0;
PyDict_Type.tp_dealloc( pyobject_cast( self ) );
Py_DECREF( tp );
}


Expand Down Expand Up @@ -345,8 +347,7 @@ PyType_Spec AtomDict::TypeObject_Spec = {
0, /* tp_itemsize */
Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_HAVE_VERSION_TAG, /* tp_flags */
| Py_TPFLAGS_HAVE_GC, /* tp_flags */
AtomDict_Type_slots /* slots */
};

Expand Down Expand Up @@ -428,8 +429,7 @@ PyType_Spec DefaultAtomDict::TypeObject_Spec = {
0, /* tp_itemsize */
Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC
| Py_TPFLAGS_HAVE_VERSION_TAG, /* tp_flags */
| Py_TPFLAGS_HAVE_GC, /* tp_flags */
DefaultAtomDict_Type_slots /* slots */
};

Expand Down Expand Up @@ -458,8 +458,9 @@ bool DefaultAtomDict::Ready()
// This will work only if we create this type after the standard AtomDict
// The reference will be handled by the module to which we will add the type
cppy::ptr bases( PyTuple_New( 1 ) );
if ( !bases )
if ( !bases ) {
return false; // LCOV_EXCL_LINE (failed tuple creation)
}
PyTuple_SET_ITEM( bases.get(), 0, cppy::incref( pyobject_cast( AtomDict::TypeObject ) ) );
TypeObject = pytype_cast(
PyType_FromSpecWithBases( &TypeObject_Spec, bases.get() )
Expand Down
4 changes: 4 additions & 0 deletions atom/src/atomlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,13 @@ int AtomList_traverse( AtomList* self, visitproc visit, void* arg )
void
AtomList_dealloc( AtomList* self )
{
PyTypeObject* tp = Py_TYPE( self );
PyObject_GC_UnTrack( self );
cppy::clear( &self->validator );
delete self->pointer;
self->pointer = 0;
PyList_Type.tp_dealloc( pyobject_cast( self ) );
Py_DECREF( tp );
}


Expand Down Expand Up @@ -1034,12 +1036,14 @@ int AtomCList_traverse( AtomCList* self, visitproc visit, void* arg )
void
AtomCList_dealloc( AtomCList* self )
{
PyTypeObject* tp = Py_TYPE( self );
PyObject_GC_UnTrack( self );
cppy::clear( &self->member );
cppy::clear( &atomlist_cast( self )->validator );
delete atomlist_cast( self )->pointer;
atomlist_cast( self )->pointer = 0;
PyList_Type.tp_dealloc( pyobject_cast( self ) );
Py_DECREF( tp );
}


Expand Down
5 changes: 4 additions & 1 deletion atom/src/atomset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ PyObject* validate_set( AtomSet* set, PyObject* value )
return 0;
}
}
if ( PyErr_Occurred() )
if ( PyErr_Occurred() ) {
return 0;
}
return val_set.release();
}

Expand Down Expand Up @@ -122,11 +123,13 @@ int AtomSet_traverse( AtomSet* self, visitproc visit, void* arg )

void AtomSet_dealloc( AtomSet* self )
{
PyTypeObject* tp = Py_TYPE( self );
PyObject_GC_UnTrack( self );
cppy::clear( &self->m_value_validator );
delete atomset_cast( self )->pointer;
atomset_cast( self )->pointer = 0;
PySet_Type.tp_dealloc( pyobject_cast( self ) );
Py_DECREF( tp );
}


Expand Down
8 changes: 7 additions & 1 deletion atom/src/catom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ CAtom_traverse( CAtom* self, visitproc visit, void* arg )
void
CAtom_dealloc( CAtom* self )
{
PyTypeObject* tp = Py_TYPE( self );
if( self->has_guards() )
{
CAtom::clear_guards( self );
Expand All @@ -146,7 +147,8 @@ CAtom_dealloc( CAtom* self )
}
delete self->observers;
self->observers = 0;
Py_TYPE(self)->tp_free( pyobject_cast( self ) );
tp->tp_free( pyobject_cast( self ) );
Py_DECREF( tp );
}


Expand Down Expand Up @@ -401,6 +403,7 @@ CAtom_getstate( CAtom* self )
if (!value ) {
// Following CPython impl it is not an error if the attribute is
// not present.
PyErr_Clear();
continue;
}
else if ( PyDict_SetItem(stateptr.get(), name, value.get()) ) {
Expand Down Expand Up @@ -474,6 +477,9 @@ CAtom_setstate( CAtom* self, PyObject* state )
if ( PyObject_SetAttr( pyobject_cast(self), key.get(), value.get() ) )
return 0;
}
if ( PyErr_Occurred() ) {
return 0;
}

if ( frozen )
self->set_frozen(true);
Expand Down
66 changes: 29 additions & 37 deletions atom/src/catommodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,88 +76,80 @@ bool add_objects( PyObject* mod )

// atomlist
cppy::ptr atom_list( pyobject_cast( AtomList::TypeObject ) );
if( PyModule_AddObject( mod, "atomlist", atom_list.get() ) < 0 ) // LCOV_EXCL_BR_LINE
if( PyModule_AddObjectRef( mod, "atomlist", atom_list.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
atom_list.release();

// atomclist
cppy::ptr atom_clist( pyobject_cast( AtomCList::TypeObject ) );
if( PyModule_AddObject( mod, "atomclist", atom_clist.get() ) < 0 ) // LCOV_EXCL_BR_LINE
if( PyModule_AddObjectRef( mod, "atomclist", atom_clist.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
atom_clist.release();

// atomdict
cppy::ptr atom_dict( pyobject_cast( AtomDict::TypeObject ) );
if( PyModule_AddObject( mod, "atomdict", atom_dict.get() ) < 0 ) // LCOV_EXCL_BR_LINE
if( PyModule_AddObjectRef( mod, "atomdict", atom_dict.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
atom_dict.release();

// defaultatomdict
cppy::ptr defaultatom_dict( pyobject_cast( DefaultAtomDict::TypeObject ) );
if( PyModule_AddObject( mod, "defaultatomdict", defaultatom_dict.get() ) < 0 ) // LCOV_EXCL_BR_LINE
if( PyModule_AddObjectRef( mod, "defaultatomdict", defaultatom_dict.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
defaultatom_dict.release();

// atomset
cppy::ptr atom_set( pyobject_cast( AtomSet::TypeObject ) );
if( PyModule_AddObject( mod, "atomset", atom_set.get() ) < 0 ) // LCOV_EXCL_BR_LINE
if( PyModule_AddObjectRef( mod, "atomset", atom_set.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
atom_set.release();

// atomref
cppy::ptr atom_ref( pyobject_cast( AtomRef::TypeObject ) );
if( PyModule_AddObject( mod, "atomref", atom_ref.get() ) < 0 ) // LCOV_EXCL_BR_LINE
if( PyModule_AddObjectRef( mod, "atomref", atom_ref.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
atom_ref.release();

// Member
cppy::ptr member( pyobject_cast( Member::TypeObject ) );
if( PyModule_AddObject( mod, "Member", member.get() ) < 0 ) // LCOV_EXCL_BR_LINE
if( PyModule_AddObjectRef( mod, "Member", member.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
member.release();

// CAtom
cppy::ptr catom( pyobject_cast( CAtom::TypeObject ) );
if( PyModule_AddObject( mod, "CAtom", catom.get() ) < 0 )
if( PyModule_AddObjectRef( mod, "CAtom", catom.get() ) < 0 ) // LCOV_EXCL_BR_LINE
{
return false; // LCOV_EXCL_LINE (failed type addition to module)
}
catom.release();

cppy::incref( PyGetAttr );
cppy::incref( PySetAttr );
cppy::incref( PyDelAttr );
cppy::incref( PyPostGetAttr );
cppy::incref( PyPostSetAttr );
cppy::incref( PyDefaultValue );
cppy::incref( PyValidate );
cppy::incref( PyPostValidate );
cppy::incref( PyGetState );
cppy::incref( PyChangeType );
PyModule_AddObject( mod, "GetAttr", PyGetAttr );
PyModule_AddObject( mod, "SetAttr", PySetAttr );
PyModule_AddObject( mod, "DelAttr", PyDelAttr );
PyModule_AddObject( mod, "PostGetAttr", PyPostGetAttr );
PyModule_AddObject( mod, "PostSetAttr", PyPostSetAttr );
PyModule_AddObject( mod, "DefaultValue", PyDefaultValue );
PyModule_AddObject( mod, "Validate", PyValidate );
PyModule_AddObject( mod, "PostValidate", PyPostValidate );
PyModule_AddObject( mod, "GetState", PyGetState );
PyModule_AddObject( mod, "ChangeType", PyChangeType );

if (PyModule_AddObjectRef( mod, "GetAttr", PyGetAttr ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "SetAttr", PySetAttr ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "DelAttr", PyDelAttr ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "PostGetAttr", PyPostGetAttr ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "PostSetAttr", PyPostSetAttr ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "DefaultValue", PyDefaultValue ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "Validate", PyValidate ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "PostValidate", PyPostValidate ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "GetState", PyGetState ) < 0)
return false;
if (PyModule_AddObjectRef( mod, "ChangeType", PyChangeType ) < 0)
return false;

return true;
}
Expand Down
3 changes: 2 additions & 1 deletion atom/src/enumtypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ add_long( cppy::ptr& dict_ptr, const char* name, T value )
{
return false; // LCOV_EXCL_LINE (failed long creation, impossible)
}
// PyDict_SetItemString does not steal a reference so cppy::ptr
// must decref the pyint reference after insertion.
if( PyDict_SetItemString( dict_ptr.get(), name, pyint.get() ) != 0 )
{
return false; // LCOV_EXCL_LINE (failed dict insertion, impossible)
}
pyint.release(); // Release the reference since the operation succeeded
return true;
}

Expand Down
2 changes: 2 additions & 0 deletions atom/src/getattrbehavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ cached_property_handler( Member* member, CAtom* atom )
if( value )
return value.release();
value = property_handler( member, atom );
if( !value )
return 0;
atom->set_slot( member->index, value.get() ); // exception-safe
return value.release();
}
Expand Down
6 changes: 3 additions & 3 deletions atom/src/member.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,13 @@ Member_traverse( Member* self, visitproc visit, void* arg )
void
Member_dealloc( Member* self )
{
PyTypeObject* tp = Py_TYPE( self );
PyObject_GC_UnTrack( self );
Member_clear( self );
delete self->static_observers;
self->static_observers = 0;
Py_TYPE(self)->tp_free( pyobject_cast( self ) );
tp->tp_free( pyobject_cast( self ) );
Py_DECREF( tp );
}


Expand Down Expand Up @@ -917,12 +919,10 @@ Member_methods[] = {
"Notify the static observers for the given member and atom." },
{ "tag", ( PyCFunction )Member_tag, METH_VARARGS | METH_KEYWORDS,
"Tag the member with metatdata. " },
#if PY_VERSION_HEX >= 0x03090000
// Generic aliases have been added in 3.9 and allow to index types
// This removes the need to quote explicit member type annotations
{ "__class_getitem__", (PyCFunction)Py_GenericAlias, METH_O|METH_CLASS,
"See PEP 585"},
#endif
{ 0 } // sentinel
};

Expand Down
6 changes: 3 additions & 3 deletions atom/src/methodwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ PyTypeObject* AtomMethodWrapper::TypeObject = NULL;
PyType_Spec AtomMethodWrapper::TypeObject_Spec = {
PACKAGE_TYPENAME( "AtomMethodWrapper" ), /* tp_name */
sizeof( AtomMethodWrapper ), /* tp_basicsize */
0, /* tp_itemsize */
Py_TPFLAGS_DEFAULT, /* tp_flags */
AtomMethodWrapper_Type_slots /* slots */
0, /* tp_itemsize */
Py_TPFLAGS_DEFAULT, /* tp_flags */
AtomMethodWrapper_Type_slots /* slots */
};


Expand Down
15 changes: 14 additions & 1 deletion atom/src/modifyguard.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,19 @@ class ModifyGuard
// modification have been done as otherwise it can (Python 3) cause
// boolean tests (PyObject_IsTrue) to fail for wrong reasons.
bool exception_set = false;
#if PY_VERSION_HEX >= 0x030D0000
PyObject *exc;
if( PyErr_Occurred() ){
exc = PyErr_GetRaisedException();
exception_set = true;
}
#else
PyObject *type, *value, *traceback;
if( PyErr_Occurred() ){
PyErr_Fetch(&type, &value, &traceback);
exception_set = true;
}
#endif

if( m_owner.get_modify_guard() == this )
{
Expand All @@ -56,8 +64,13 @@ class ModifyGuard
}

// Restore previous exception if one was set.
if( exception_set )
if( exception_set ) {
#if PY_VERSION_HEX >= 0x030D0000
PyErr_SetRaisedException(exc);
#else
PyErr_Restore(type, value, traceback);
#endif
}
}

void add_task( ModifyTask* task ) { m_tasks.push_back( task ); }
Expand Down
3 changes: 2 additions & 1 deletion atom/src/sortedmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ struct SortedMap
self->setitem( PySequence_Fast_GET_ITEM( pair.get(), 0 ),
PySequence_Fast_GET_ITEM( pair.get(), 1 ) );
}
if ( PyErr_Occurred() )
if ( PyErr_Occurred() ) {
return 0; // error during iteration
}
}
}

Expand Down
6 changes: 5 additions & 1 deletion atom/src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,12 @@ inline bool safe_richcompare( PyObject* first, PyObject* second, int opid )

// Clear the error if one happened because we attempted an invalid
// comparison.
if( PyErr_Occurred() )
if( PyErr_Occurred() ) {
// Do not swallow KeyboardInterrupt or SystemExit
if( !PyErr_ExceptionMatches( PyExc_Exception ) )
return false; // or propagate somehow
PyErr_Clear();
}

// Fallback to the Python 2 default 3 way compare.
int c = fallback_3way_compare( first, second );
Expand Down
2 changes: 2 additions & 0 deletions atom/src/validatebehavior.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -893,6 +893,7 @@ range_handler( Member* member, CAtom* atom, PyObject* oldvalue, PyObject* newval
Py_TYPE( pyobject_cast( atom ) )->tp_name
);
default:
// Exception occurred during comparison
return 0;
}
}
Expand All @@ -910,6 +911,7 @@ range_handler( Member* member, CAtom* atom, PyObject* oldvalue, PyObject* newval
Py_TYPE( pyobject_cast( atom ) )->tp_name
);
default:
// Exception occurred during comparison
return 0;
}
}
Expand Down
Loading
Loading