https://bugs.documentfoundation.org/show_bug.cgi?id=171139

            Bug ID: 171139
           Summary: Use service constructors in internal Python code
           Product: LibreOffice
           Version: unspecified
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Keywords: difficultyBeginner, easyHack, skillPython
          Severity: enhancement
          Priority: medium
         Component: sdk
          Assignee: [email protected]
          Reporter: [email protected]

In pyuno, previously the only way to create an instance of a service was using
the create methods of the service manager. Those methods require passing the
name of the service as a string and the arguments to the constructor as a
tuple. Since 346e0f8891f632e6410dc369564bc56d271e09f3 it is possible to import
the name of the service using an “import” statement in Python and then call a
constructor using a class method. This is a bit more robust than passing the
arguments in a tuple because the types and the number of arguments are checked
to match the ones declared in the constructor.

For an example, see 7930a07d76d7708b69372fd54133675af0e0ec9e

This changes code like this:

xToolkit = xContext.ServiceManager.createInstance('com.sun.star.awt.Toolkit')
xToolkit.waitUntilAllIdlesDispatched()

To look like this:

from com.sun.star.awt import Toolkit
Toolkit.create(self._xContext).waitUntilAllIdlesDispatched()

You can find potential code to change with a git-grep command like this:

git grep -E '\bcreateInstance(With(ArgumentsAnd)?Context|WithArguments|)\b' \
         -- \*.py

You should look at the SDK documentation for the service to see what
constructors are available. For example, if you want to construct a
SequenceInputStream, you can see that there is a constructor called
createStreamFromSequence here:

https://api.libreoffice.org/docs/idl/ref/servicecom_1_1sun_1_1star_1_1io_1_1SequenceInputStream.html

Sometimes the documentation will say that a service is a “single-instance
service” and that it has been deprecated in favour of a singleton. In that case
you might want to replace the constructor with a call to the singleton getter
instead. For example instead of constructing com.sun.star.frame.Desktop, you
can use the “theDesktop” singleton like this:

from com.sun.star.frame import theDesktop
desktop = theDesktop.get(context)

Some services are still using an obsolete format known as “accumulation-based
services”. These don’t have any constructors so they aren’t yet possible to
access with the approach described in this bug report.

Note that it is probably best to avoid making this change in Python example
code until this functionality makes it into a released version of LibreOffice.

This is an easyhack that can be worked on in parallel. Please don’t do a
large-scale change over the whole codebase; only change one or two files at a
time. Do not assign this issue to you, because of the parallel nature of the
task.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to