fdo#50470: Restore pyuno object method introspection in Python 3

Switch to __dir__ entry point for introspection as Python 3 dropped support
for __members__/__methods__.  This is backwards compatible to Python 2.6.

Module initialization adjusted to complete type setup (needed for tp_dict)
via PyType_Ready.

Change-Id: Ie1f7b9dd4279242de89d009eb7acdc8c786dab8f
Reviewed-on: https://gerrit.libreoffice.org/5375
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Tested-by: Michael Stahl <mstahl@redhat.com>
This commit is contained in:
David Bolen
2013-08-09 23:35:27 -04:00
committed by Michael Stahl
parent 87b5ac652d
commit 1be8e912ba
3 changed files with 45 additions and 24 deletions

View File

@@ -427,6 +427,32 @@ PyObject *PyUNO_str( PyObject * self )
return PyStr_FromString( buf.getStr()); return PyStr_FromString( buf.getStr());
} }
PyObject* PyUNO_dir (PyObject* self)
{
PyUNO* me = (PyUNO*) self;
PyObject* member_list = NULL;
Sequence<OUString> oo_member_list;
try
{
oo_member_list = me->members->xInvocation->getMemberNames ();
member_list = PyList_New (oo_member_list.getLength ());
for (int i = 0; i < oo_member_list.getLength (); i++)
{
// setitem steals a reference
PyList_SetItem (member_list, i, ustring2PyString(oo_member_list[i]).getAcquired() );
}
}
catch( const RuntimeException &e )
{
raisePyExceptionWithAny( makeAny(e) );
}
return member_list;
}
PyObject* PyUNO_getattr (PyObject* self, char* name) PyObject* PyUNO_getattr (PyObject* self, char* name)
{ {
PyUNO* me; PyUNO* me;
@@ -437,31 +463,10 @@ PyObject* PyUNO_getattr (PyObject* self, char* name)
Runtime runtime; Runtime runtime;
me = (PyUNO*) self; me = (PyUNO*) self;
//Handle Python dir () stuff first...
if (strcmp (name, "__members__") == 0)
{
PyObject* member_list;
Sequence<OUString> oo_member_list;
oo_member_list = me->members->xInvocation->getMemberNames ();
member_list = PyList_New (oo_member_list.getLength ());
for (int i = 0; i < oo_member_list.getLength (); i++)
{
// setitem steals a reference
PyList_SetItem (member_list, i, ustring2PyString(oo_member_list[i]).getAcquired() );
}
return member_list;
}
if (strcmp (name, "__dict__") == 0) if (strcmp (name, "__dict__") == 0)
{ {
Py_INCREF (Py_None); Py_INCREF (Py_TYPE(me)->tp_dict);
return Py_None; return Py_TYPE(me)->tp_dict;
}
if (strcmp (name, "__methods__") == 0)
{
Py_INCREF (Py_None);
return Py_None;
} }
if (strcmp (name, "__class__") == 0) if (strcmp (name, "__class__") == 0)
{ {
@@ -638,6 +643,13 @@ static PyObject* PyUNO_cmp( PyObject *self, PyObject *that, int op )
return result; return result;
} }
static PyMethodDef PyUNOMethods[] =
{
{"__dir__", (PyCFunction)PyUNO_dir, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL}
};
/* Python 2 has a tp_flags value for rich comparisons. Python 3 does not (on by default) */ /* Python 2 has a tp_flags value for rich comparisons. Python 3 does not (on by default) */
#ifdef Py_TPFLAGS_HAVE_RICHCOMPARE #ifdef Py_TPFLAGS_HAVE_RICHCOMPARE
#define TP_FLAGS (Py_TPFLAGS_HAVE_RICHCOMPARE) #define TP_FLAGS (Py_TPFLAGS_HAVE_RICHCOMPARE)
@@ -674,7 +686,7 @@ static PyTypeObject PyUNOType =
0, 0,
(getiterfunc)0, (getiterfunc)0,
(iternextfunc)0, (iternextfunc)0,
NULL, PyUNOMethods,
NULL, NULL,
NULL, NULL,
NULL, NULL,
@@ -698,6 +710,11 @@ static PyTypeObject PyUNOType =
#endif #endif
}; };
int PyUNO_initType()
{
return PyType_Ready(&PyUNOType);
}
PyRef getPyUnoClass() PyRef getPyUnoClass()
{ {
return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) ); return PyRef( reinterpret_cast< PyObject * > ( &PyUNOType ) );

View File

@@ -188,6 +188,8 @@ typedef ::boost::unordered_map
typedef ::boost::unordered_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet; typedef ::boost::unordered_set< PyRef , PyRef::Hash , std::equal_to<PyRef> > ClassSet;
int PyUNO_initType();
PyObject* PyUNO_new( PyObject* PyUNO_new(
const com::sun::star::uno::Any & targetInterface, const com::sun::star::uno::Any & targetInterface,
const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf); const com::sun::star::uno::Reference<com::sun::star::lang::XSingleServiceFactory> & ssf);

View File

@@ -867,6 +867,7 @@ extern "C"
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
PyObject* PyInit_pyuno() PyObject* PyInit_pyuno()
{ {
PyUNO_initType();
// noop when called already, otherwise needed to allow multiple threads // noop when called already, otherwise needed to allow multiple threads
PyEval_InitThreads(); PyEval_InitThreads();
static struct PyModuleDef moduledef = static struct PyModuleDef moduledef =
@@ -886,6 +887,7 @@ PyObject* PyInit_pyuno()
#else #else
void initpyuno() void initpyuno()
{ {
PyUNO_initType();
PyEval_InitThreads(); PyEval_InitThreads();
Py_InitModule ("pyuno", PyUNOModule_methods); Py_InitModule ("pyuno", PyUNOModule_methods);
} }