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:
committed by
Michael Stahl
parent
87b5ac652d
commit
1be8e912ba
@@ -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 ) );
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user