Python TipsAndTricks
January 2024
You can help by adding links to this article from other relevant articles.
January 2024
Some tips to help you out
Class Defines
If you add no_init to a class define then that class cant be constructed via python. This is good for classes like players, weapons and entitys that have a special method of constuction.
Example:
bp::class_< NoNew >("CantMakeMe", bp::no_init);
A lot of classes in Source are non copyable (i.e. you use pointers to reference them not stack objects) and thus you will need to state that they are non copyable otherwise strange compile errors or run time errors occur. This doesnt mean you cant make multiplie objects in python that point to this, just that boost wont try and copy it in the python bindings.
bp::class_< NoCopy, boost::noncopyable >("BoostCantCopyMe", bp::no_init);
Function Defines
When a function (or member function) your rapping returns a pointer you will have to tell boost how to handle it. If your return a new object, boost needs to know to hang onto and if you return a pointer to an existing object you have to boost to just use it. If you do the latter your python classes shouldnt hold on to the object as boost only ensures its valid for the lifetime of the function call.
Example New Object:
MyClass* pyGetNewClass()
{
return new MyClass();
}
bp::def("NewClass", pyGetNewClass, bp::return_value_policy<bp::manage_new_object>()); //callee needs to delete it
Example Existing Object:
CBasePlayer* pyGetPlayerByIndex(int index)
{
return UTIL_PlayerByIndex(index);
}
bp::def("GetPlayerByIndex", pyGetPlayerByIndex, bp::return_value_policy<bp::reference_existing_object>()); //callee doesnt need to delete it
Function Calls
If your passing a pointer to a python function call and you marked the class as non copyable (see above) you will need to wrap it in the function ptr().
Example:
virtual void OnPlayerKilled(CBasePlayer *pVictim, CBasePlayer *pKiller, CBaseEntity *pWeapon)
{
this->get_override("OnPlayerKilled")(bp::ptr(pVictim), bp::ptr(pKiller), bp::ptr(pWeapon));
}