Bug 92848 - shape.String gives an exception in TableShape with PyUno
Summary: shape.String gives an exception in TableShape with PyUno
Status: RESOLVED FIXED
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: Impress (show other bugs)
Version:
(earliest affected)
5.1.0.0.alpha0+ Master
Hardware: All All
: medium normal
Assignee: Stephan Bergmann
URL:
Whiteboard: target:6.2.0
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-21 01:46 UTC by Ofir
Modified: 2018-11-01 15:40 UTC (History)
2 users (show)

See Also:
Crash report or crash signature:


Attachments
Presentation with a table shape (11.70 KB, application/vnd.oasis.opendocument.presentation)
2015-07-21 01:46 UTC, Ofir
Details
Python script reproducing the error (512 bytes, text/plain)
2015-07-30 16:55 UTC, Ofir
Details
Python script that use the old python-uno syntax (681 bytes, text/plain)
2015-07-31 12:08 UTC, Ofir
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ofir 2015-07-21 01:46:47 UTC
Created attachment 117348 [details]
Presentation with a table shape

com.sun.star.drawing.TableShape has a String attribute but trying to access it or check that it exists with hasattr(shape, "String")gives an error:
uno.RuntimeException: illegal object given!

I'm not sure if the table should have the String attribute but checking that the attribute exists shouldn't give an error in any case.

To reproduce, start LibreOffice with:
libreoffice "--accept=pipe,name=test;urp;StarOffice.Servicemanager"

and execute the following python-uno code:

import uno
from pythonscript import ScriptContext

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext('com.sun.star.bridge.UnoUrlResolver',localContext)
client = resolver.resolve("uno:pipe,name=test;urp;StarOffice.ComponentContext")
xscriptcontext = ScriptContext(client, None, None)
doc = xscriptcontext .getDocument()

slide = doc.DrawPages[0]
for shape in slide:
  print(hasattr(shape, "String"))
Comment 1 Buovjaga 2015-07-30 16:36:48 UTC
(In reply to Ofir from comment #0)
> and execute the following python-uno code:

How do I do this?
Comment 2 Ofir 2015-07-30 16:55:44 UTC
Created attachment 117538 [details]
Python script reproducing the error
Comment 3 Ofir 2015-07-30 16:57:05 UTC
Make sure you have the python-uno binding.
On Ubuntu you can get them with
sudo apt-get install libreoffice-script-provider-python

Run LibreOffice with:
libreoffice "--accept=pipe,name=test;urp;StarOffice.Servicemanager"

Download the attached python script and run it with:
python3 test.py
Comment 4 Buovjaga 2015-07-30 17:48:24 UTC
(In reply to Ofir from comment #3)
> Make sure you have the python-uno binding.
> On Ubuntu you can get them with
> sudo apt-get install libreoffice-script-provider-python
> 
> Run LibreOffice with:
> libreoffice "--accept=pipe,name=test;urp;StarOffice.Servicemanager"
> 
> Download the attached python script and run it with:
> python3 test.py

I get:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    slide = doc.DrawPages[0]
AttributeError: DrawPages
Comment 5 Ofir 2015-07-30 18:22:40 UTC
The python script expects LibreOffice 5.1.

To test with LO < 5.0 and below use this:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import uno
from pythonscript import ScriptContext

localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext('com.sun.star.bridge.UnoUrlResolver',localContext)
client = resolver.resolve("uno:pipe,name=test;urp;StarOffice.ComponentContext")
xscriptcontext = ScriptContext(client, None, None)
doc = xscriptcontext .getDocument()

## new API in LibreOffice 5.1
#slide = doc.DrawPages[0]
#for shape in slide:
#  print(hasattr(shape, "String"))

slide = doc.DrawPages.getByIndex(0)
for i in range(slide.Count):
  shape = slide.getByIndex(i)
  print(hasattr(shape, "String"))
Comment 6 Buovjaga 2015-07-30 18:37:50 UTC
Oh, sorry I forgot to mention I tested with 5.1:

Ubuntu 15.04 64-bit 
Version: 5.1.0.0.alpha1+
Build ID: 902255645328efde34ddf62227c8278e8dd61ff0
TinderBox: Linux-rpm_deb-x86_64@70-TDF-dbg, Branch:master, Time: 2015-07-30_03:52:32
Locale: en-US (en_US.UTF-8)
Comment 7 Ofir 2015-07-30 18:48:53 UTC
Did you open the attached ODP in LibreOffice after starting it in server mode?
Comment 8 Buovjaga 2015-07-30 19:04:13 UTC
(In reply to Ofir from comment #7)
> Did you open the attached ODP in LibreOffice after starting it in server
> mode?

No. You didn't mention that step.

Now that I did, I get this after launching python3 test.py:

Traceback (most recent call last):
  File "test.py", line 13, in <module>
    slide = doc.DrawPages[0]
TypeError: 'pyuno' object is not subscriptable
Comment 9 Ofir 2015-07-30 19:35:09 UTC
You need to make sure you are using the LibreOffice 5.1 version of py-uno by setting the environment variables.

On Ubuntu I'm using this:
export PYTHONPATH=/usr/lib/python3.4/site-packages:/opt/libreofficedev5.1/program
export URE_BOOTSTRAP="vnd.sun.star.pathname:/opt/libreofficedev5.1/program/fundamentalrc"

Another option is to test the modified python script from Comment 5 that will work with previous version of LibreOffice.
Comment 10 Buovjaga 2015-07-31 10:06:09 UTC
Ok, I set the vars, adjusting to my 5.1 folder, but I still get the same error as in comment 8.
Comment 11 Ofir 2015-07-31 12:08:21 UTC
Created attachment 117561 [details]
Python script that use the old python-uno syntax
Comment 12 Ofir 2015-07-31 12:09:42 UTC
You don't use the new python-uno API or you didn't open the ODP.

Please try the python scripted I attached that can work with LibreOffice 5 and below.
Comment 13 Buovjaga 2015-07-31 12:20:58 UTC
Ok, now I got it with 5.1:
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    print(hasattr(shape, "String"))
uno.RuntimeException: illegal object given!

I had failed to do the exports in both terminal windows: the one where I launch LibO AND the second one where I launch the py.

Ubuntu 15.04 64-bit 
Version: 5.1.0.0.alpha1+
Build ID: 902255645328efde34ddf62227c8278e8dd61ff0
TinderBox: Linux-rpm_deb-x86_64@70-TDF-dbg, Branch:master, Time: 2015-07-30_03:52:32
Locale: en-US (en_US.UTF-8)
Comment 14 QA Administrators 2016-09-20 10:21:20 UTC Comment hidden (obsolete)
Comment 15 Ofir 2016-09-20 11:12:01 UTC
Still reproducible with:

Version: 5.2.1.2
Build ID: 1:5.2.1~rc2-0ubuntu1~xenial0
CPU Threads: 1; OS Version: Linux 4.4; UI Render: default; 
Locale: en-US (en_US.UTF-8); Calc: group
Comment 16 Xisco Faulí 2017-09-29 08:49:27 UTC Comment hidden (obsolete)
Comment 17 Ofir 2018-10-30 08:02:31 UTC
Still reproducible with LibreOffice 6.1.2.1
Comment 18 Mike Kaganski 2018-10-31 09:59:33 UTC
Since [1] (Python 3.2+), Python only tests for AttributeError in its hasattr(). Thus, returning other types of errors (as is done in our PyUno implementation [2]) would give wrong results. Still, it's not enough to just always return AttributeError from PyUNO_getattr: this will defeat the idea behind the Python change (see [3]). In this case, an interface is found that has the property (com.sun.star.text.XTextAppend), and its getter is attempted on the passed object, which is queried for that interface to do that. The query fails in IdlReflectionServiceImpl::mapToUno (more precisely, in extract() called there), and generic RuntimeException is thrown. It's unclear (to me) how to handle that here.

[1] https://hg.python.org/cpython/rev/2de9d4457082/
[2] https://git.libreoffice.org/core/+/08c3c504644ee978c2ec75ba083765b6ffddf08c/pyuno/source/module/pyuno.cxx#1378
[3] https://stackoverflow.com/questions/35566680/pythons-hasattr-sometimes-returns-incorrect-results
Comment 19 Mike Kaganski 2018-10-31 10:57:07 UTC
Stephan, would you please take a look at this?
Comment 20 Stephan Bergmann 2018-11-01 13:44:17 UTC
The problem is that SvxTableShape (aka OBJ_TABLE) doesn't implement css::text::XTextAppend (it just derives from SvxShape, see svx/source/unodraw/shapeimpl.hxx), so while ImplIntrospectionAccess::hasProperty (stoc/source/inspect/introspection.cxx) returns true for "String" (because css::text::XTextAppend -> css::text::XText -> css::text::XSimpleText -> css::text::XTextRange has get/setString methods), its ImplIntrospectionAccess::getPropertyValue counterpart ultimately fails because querying the SvxTableShape instance for XTextAppend fails.

Fix at <https://gerrit.libreoffice.org/#/c/62739/> "tdf#92848: SvxTableShape doesn't implement css::text::XTextAppend".
Comment 21 Stephan Bergmann 2018-11-01 13:46:50 UTC
(In reply to Ofir from comment #0)
> com.sun.star.drawing.TableShape has a String attribute but trying to access
> it or check that it exists with hasattr(shape, "String")gives an error:
> uno.RuntimeException: illegal object given!

Not sure what "com.sun.star.drawing.TableShape" is meant to be, but the relevant table shape object in the reproducer Python code doesn't actually support a String attribute, so hasattr(shape, "String") will now return False.
Comment 22 Commit Notification 2018-11-01 15:36:55 UTC
Stephan Bergmann committed a patch related to this issue.
It has been pushed to "master":

https://git.libreoffice.org/core/+/4bd701a306c8068911203f976145adc717f015d2%5E%21

tdf#92848: SvxTableShape doesn't implement css::text::XTextAppend

It will be available in 6.2.0.

The patch should be included in the daily builds available at
https://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More
information about daily builds can be found at:
https://wiki.documentfoundation.org/Testing_Daily_Builds

Affected users are encouraged to test the fix and report feedback.