Files
libreoffice/pyuno/qa/pytests/testcollections_XEnumeration.py

123 lines
3.0 KiB
Python
Raw Normal View History

Make PyUNO provide more Pythonic behaviour - Simplifies working with UNO objects by giving the behaviour of Python lists, dicts and iterators to objects which implement UNO container interfaces - Applies a custom behaviour to allow objects which implement com::sun::star::table::XCellRange to yield cells and cell ranges by subscript - When UNO container objects are addressed in the new style, eliminates the requirement to manually construct Any objects for contained elements which are typed sequences - Allows lists and iterators to be passed wherever a UNO method accepts a sequence - Relaxes the requirements for initialising UNO structs to allow some members to be skipped when all initialisers are passed by name 1. Collection interfaces ======================== Objects which implement core UNO collection interfaces are made to behave in a way that is more natural for Python code. com::sun::star::container::XIndexAccess com::sun::star::container::XIndexReplace com::sun::star::container::XIndexContainer - Objects provide Python list access semantics num = len(obj) # Number of elements val = obj[0] # Access by index val1,val2 = obj[2:4] # Access by slice val1,val2 = obj[0:3:2] # Access by extended slice if val in obj: ... # Test value presence for val in obj: ... # Implicit iterator (values) itr = iter(obj) # Named iterator (values) obj[0] = val # Replace by index obj[2:4] = val1,val2 # Replace by slice obj[0:3:2] = val1,val2 # Replace by extended slice obj[2:3] = val1,val2 # Insert/replace by slice obj[2:2] = (val,) # Insert by slice obj[2:4] = (val,) # Replace/delete by slice obj[2:3] = () # Delete by slice (implicit) del obj[0] # Delete by index del obj[2:4] # Delete by slice com::sun::star::container::XNameAccess com::sun::star::container::XNameReplace com::sun::star::container::XNameContainer - Objects provide Python dict access semantics num = len(obj) # Number of keys val = obj[key] # Access by key if key in obj: ... # Test key presence for key in obj: ... # Implicit iterator (keys) itr = iter(obj) # Named iterator (keys) obj[key] = val # Replace by key obj[key] = val # Insert by key del obj[key] # Delete by key com::sun::star::container::XEnumerationAccess - Objects provide Python iterable semantics for val in obj: ... # Implicit iterator itr = iter(obj) # Named iterator com::sun::star::container::XEnumeration - Objects provide Python iterator semantics for val in itr: ... # Iteration of named iterator if val in itr: ... # Test value presence Objects which implement both XIndex* and XName* are supported, and respond to both integer and string keys. However, iterating over such an object will return the keys (like a Python dict) rather than the values (like a Python list). 2. Cell ranges ============== A custom behaviour is applied to objects which implement com::sun::star::table::XCellRange to allow their cells and cell ranges to be addressed by subscript, in the style of a Python list or dict (read-only). This is applicable to Calc spreadsheet sheets, Writer text tables and cell ranges created upon these. cell = cellrange[0,0] # Access cell by indices rng = cellrange[0,1:2] # Access cell range by index,slice rng = cellrange[1:2,0] # Access cell range by slice,index rng = cellrange[0:1,2:3] # Access cell range by slices rng = cellrange['A1:B2'] # Access cell range by descriptor rng = cellrange['Name'] # Access cell range by name Note that the indices used are in Python/C order, and differ from the arguments to methods provided by XCellRange. - The statement cellrange[r,c], which returns the cell from row r and column c, is equivalent to calling XCellRange::getCellByPosition(c,r) - The statement cellrange[t:b,l:r], which returns a cell range covering rows t to b(non-inclusive) and columns l to r(non- inclusive), is equivalent to calling XCellRange::getCellRangeByPosition(l,t,r-1,b-1). In contrast to the handling of objects implementing XIndex*, extended slice syntax is not supported. Negative indices (from-end addresses) are supported only for objects which also implement com::sun::star::table::XColumnRowRange (currently Calc spreadsheet sheets and cell ranges created upon these). For such objects, the following syntax is also available: rng = cellrange[0] # Access cell range by row index rng = cellrange[0,:] # Access cell range by row index rng = cellrange[:,0] # Access cell range by column index 3. Elimination of explicit Any ============================== PyUNO has not previously been able to cope with certain method arguments which are typed as Any but require a sequence of specific type to be passed. This is a particular issue for container interfaces such as XIndexContainer and XNameContainer. The existing solution to dealing with such methods is to use a special method to pass an explicitly typed Any, giving code such as: index = doc.createInstance("com.sun.star.text.ContentIndex"); ... uno.invoke( index.LevelParagraphStyles , "replaceByIndex", (0, uno.Any("[]string", ('Caption',))) ) The new Pythonic container access is able to correctly infer the expected type of the sequences required by these arguments. In the new style, the above call to .replaceByIndex() can instead be written: index.LevelParagraphStyles[0] = ('Caption',) 4. List and iterator arguments ============================== Wherever a UNO API expects a sequence, a Python list or iterator can now be passed. This enables the use of list comprehensions and generator expressions for method calls and property assignments. Example: tbl = doc.createInstance('com.sun.star.text.TextTable') tbl.initialize(10,10) # ... insert table ... # Assign numbers 0..99 to the cells using a generator expression tbl.Data = ((y for y in range(10*x,10*x + 10)) for x in range(10)) 5. Tolerant struct initialisation ================================= Previously, a UNO struct could be created fully uninitialised, or by passing a combination of positional and/or named arguments to its constructor. However, if any arguments were passed, all members were required to be initialised or an exception was thrown. This requirement is relaxed such that when all arguments passed to a struct constructor are by name, some may be omitted. The existing requirement that all members must be explicitly initialised when some constructor arguments are unnamed (positional) is not affected. Example: from com.sun.star.beans import PropertyValue prop = PropertyValue(Name='foo', Value='bar') Change-Id: Id29bff10a18099b1a00af1abee1a6c1bc58b3978 Reviewed-on: https://gerrit.libreoffice.org/16272 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Matthew Francis <mjay.francis@gmail.com>
2015-06-01 18:34:04 +08:00
#!/usr/bin/env python
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
import unittest
import uno
from testcollections_base import CollectionsTestBase
from com.sun.star.beans import PropertyValue
# Tests behaviour of objects implementing XEnumeration using the new-style
# collection accessors
# The objects chosen have no special meaning, they just happen to implement the
# tested interfaces
class TestXEnumeration(CollectionsTestBase):
# Tests syntax:
# for val in itr: ... # Iteration of named iterator
# For:
# 1 element
def test_XEnumeration_ForIn(self):
# Given
doc = self.createBlankTextDocument()
# When
paragraphs = []
itr = iter(doc.Text.createEnumeration())
for para in itr:
paragraphs.append(para)
# Then
self.assertEqual(1, len(paragraphs))
DeInitVCL in PythonTest After b9757f5cfdb62b24e79eeb4c0ef0c8b98056cecf "loplugin:useuniqueptr in vcl/svdata" ASan/UBSan builds started to fail (like <https://ci.libreoffice.org//job/lo_ubsan/1025/>) at the end of PythonTest_dbaccess_python (and probably other PythonTests), when during exit the static utl::ConfigManager instance already happens to be destroyed by the time the static ImplSVData's mpSettingsConfigItem is destroyed (which would normally be cleared during DeInitVCL, if PythonTests would call that, and which in the past had thus simply been leaked in PythonTests when that mpSettingsConfigItem was a plain pointer instead of std::unique_ptr). So ensure that PythonTests that initialize VCL also call DeInitVCL, via a new private_deinitTestEnvironment, complementing the existing private_initTestEnvironment. However, while private_initTestEnvironment is called once (typically via UnoInProcess.setUp, which internally makes sure to only call it once) as soon as the first executed test needs it, private_deinitTestEnvironment must be called once after the lasts test needing it has executed. The only way that I found to do that is to override unittest.TextTestResult's stopTestRun method, which is called once after all tests have been executed. Hence a new test runner setup in unotest/source/python/org/libreoffice/unittest.py that is now called from solenv/gbuild/PythonTest.mk. That revealed a few places in PythonTests that didn't yet close/delete documents that they had opened, which has now been added. One remaining problem then is that classes like SwXTextDocument and friends call Application::GetSolarMutex from their dtors, via sw::UnoImplPtrDeleter (a "Smart pointer class ensuring that the pointed object is deleted with a locked SolarMutex", sw/inc/unobaseclass.hxx). That means that any PyUNO proxies to such C++ objects that remain alive after private_deinitTestEnvironment will cause issues at exit, when Python does a final garbage collection of those objects. The ultimate fix will be to remove that unhelpful UnoImplPtrDeleter and its locking of SolarMutex from the dtors of UNO objects; until then, the Python code is now sprinkled with some HACKs to make sure all those PyUNO proxies are released in a timely fashion (see the comment in unotest/source/python/org/libreoffice/unittest.py for details). (Also, it would probably help if UnoInProcess didn't keep a local self.xDoc around referencing (just) the last result of calling one of its open* methods, confusingly making it the responsibility of UnoInProcess to close that one document while making it the responsibility of the test code making the other UnoInProcess.open* calls to close any other documents.) Change-Id: Ief27c81e2b763e9be20cbf3234b68924315f13be Reviewed-on: https://gerrit.libreoffice.org/60100 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2018-09-06 17:13:54 +02:00
doc.close(True)
Make PyUNO provide more Pythonic behaviour - Simplifies working with UNO objects by giving the behaviour of Python lists, dicts and iterators to objects which implement UNO container interfaces - Applies a custom behaviour to allow objects which implement com::sun::star::table::XCellRange to yield cells and cell ranges by subscript - When UNO container objects are addressed in the new style, eliminates the requirement to manually construct Any objects for contained elements which are typed sequences - Allows lists and iterators to be passed wherever a UNO method accepts a sequence - Relaxes the requirements for initialising UNO structs to allow some members to be skipped when all initialisers are passed by name 1. Collection interfaces ======================== Objects which implement core UNO collection interfaces are made to behave in a way that is more natural for Python code. com::sun::star::container::XIndexAccess com::sun::star::container::XIndexReplace com::sun::star::container::XIndexContainer - Objects provide Python list access semantics num = len(obj) # Number of elements val = obj[0] # Access by index val1,val2 = obj[2:4] # Access by slice val1,val2 = obj[0:3:2] # Access by extended slice if val in obj: ... # Test value presence for val in obj: ... # Implicit iterator (values) itr = iter(obj) # Named iterator (values) obj[0] = val # Replace by index obj[2:4] = val1,val2 # Replace by slice obj[0:3:2] = val1,val2 # Replace by extended slice obj[2:3] = val1,val2 # Insert/replace by slice obj[2:2] = (val,) # Insert by slice obj[2:4] = (val,) # Replace/delete by slice obj[2:3] = () # Delete by slice (implicit) del obj[0] # Delete by index del obj[2:4] # Delete by slice com::sun::star::container::XNameAccess com::sun::star::container::XNameReplace com::sun::star::container::XNameContainer - Objects provide Python dict access semantics num = len(obj) # Number of keys val = obj[key] # Access by key if key in obj: ... # Test key presence for key in obj: ... # Implicit iterator (keys) itr = iter(obj) # Named iterator (keys) obj[key] = val # Replace by key obj[key] = val # Insert by key del obj[key] # Delete by key com::sun::star::container::XEnumerationAccess - Objects provide Python iterable semantics for val in obj: ... # Implicit iterator itr = iter(obj) # Named iterator com::sun::star::container::XEnumeration - Objects provide Python iterator semantics for val in itr: ... # Iteration of named iterator if val in itr: ... # Test value presence Objects which implement both XIndex* and XName* are supported, and respond to both integer and string keys. However, iterating over such an object will return the keys (like a Python dict) rather than the values (like a Python list). 2. Cell ranges ============== A custom behaviour is applied to objects which implement com::sun::star::table::XCellRange to allow their cells and cell ranges to be addressed by subscript, in the style of a Python list or dict (read-only). This is applicable to Calc spreadsheet sheets, Writer text tables and cell ranges created upon these. cell = cellrange[0,0] # Access cell by indices rng = cellrange[0,1:2] # Access cell range by index,slice rng = cellrange[1:2,0] # Access cell range by slice,index rng = cellrange[0:1,2:3] # Access cell range by slices rng = cellrange['A1:B2'] # Access cell range by descriptor rng = cellrange['Name'] # Access cell range by name Note that the indices used are in Python/C order, and differ from the arguments to methods provided by XCellRange. - The statement cellrange[r,c], which returns the cell from row r and column c, is equivalent to calling XCellRange::getCellByPosition(c,r) - The statement cellrange[t:b,l:r], which returns a cell range covering rows t to b(non-inclusive) and columns l to r(non- inclusive), is equivalent to calling XCellRange::getCellRangeByPosition(l,t,r-1,b-1). In contrast to the handling of objects implementing XIndex*, extended slice syntax is not supported. Negative indices (from-end addresses) are supported only for objects which also implement com::sun::star::table::XColumnRowRange (currently Calc spreadsheet sheets and cell ranges created upon these). For such objects, the following syntax is also available: rng = cellrange[0] # Access cell range by row index rng = cellrange[0,:] # Access cell range by row index rng = cellrange[:,0] # Access cell range by column index 3. Elimination of explicit Any ============================== PyUNO has not previously been able to cope with certain method arguments which are typed as Any but require a sequence of specific type to be passed. This is a particular issue for container interfaces such as XIndexContainer and XNameContainer. The existing solution to dealing with such methods is to use a special method to pass an explicitly typed Any, giving code such as: index = doc.createInstance("com.sun.star.text.ContentIndex"); ... uno.invoke( index.LevelParagraphStyles , "replaceByIndex", (0, uno.Any("[]string", ('Caption',))) ) The new Pythonic container access is able to correctly infer the expected type of the sequences required by these arguments. In the new style, the above call to .replaceByIndex() can instead be written: index.LevelParagraphStyles[0] = ('Caption',) 4. List and iterator arguments ============================== Wherever a UNO API expects a sequence, a Python list or iterator can now be passed. This enables the use of list comprehensions and generator expressions for method calls and property assignments. Example: tbl = doc.createInstance('com.sun.star.text.TextTable') tbl.initialize(10,10) # ... insert table ... # Assign numbers 0..99 to the cells using a generator expression tbl.Data = ((y for y in range(10*x,10*x + 10)) for x in range(10)) 5. Tolerant struct initialisation ================================= Previously, a UNO struct could be created fully uninitialised, or by passing a combination of positional and/or named arguments to its constructor. However, if any arguments were passed, all members were required to be initialised or an exception was thrown. This requirement is relaxed such that when all arguments passed to a struct constructor are by name, some may be omitted. The existing requirement that all members must be explicitly initialised when some constructor arguments are unnamed (positional) is not affected. Example: from com.sun.star.beans import PropertyValue prop = PropertyValue(Name='foo', Value='bar') Change-Id: Id29bff10a18099b1a00af1abee1a6c1bc58b3978 Reviewed-on: https://gerrit.libreoffice.org/16272 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Matthew Francis <mjay.francis@gmail.com>
2015-06-01 18:34:04 +08:00
# Tests syntax:
# if val in itr: ... # Test value presence
# For:
# Present value
def test_XEnumeration_IfIn_Present(self):
# Given
doc = self.createBlankTextDocument()
# When
paragraph = doc.Text.createEnumeration().nextElement()
itr = iter(doc.Text.createEnumeration())
result = paragraph in itr
# Then
self.assertTrue(result)
DeInitVCL in PythonTest After b9757f5cfdb62b24e79eeb4c0ef0c8b98056cecf "loplugin:useuniqueptr in vcl/svdata" ASan/UBSan builds started to fail (like <https://ci.libreoffice.org//job/lo_ubsan/1025/>) at the end of PythonTest_dbaccess_python (and probably other PythonTests), when during exit the static utl::ConfigManager instance already happens to be destroyed by the time the static ImplSVData's mpSettingsConfigItem is destroyed (which would normally be cleared during DeInitVCL, if PythonTests would call that, and which in the past had thus simply been leaked in PythonTests when that mpSettingsConfigItem was a plain pointer instead of std::unique_ptr). So ensure that PythonTests that initialize VCL also call DeInitVCL, via a new private_deinitTestEnvironment, complementing the existing private_initTestEnvironment. However, while private_initTestEnvironment is called once (typically via UnoInProcess.setUp, which internally makes sure to only call it once) as soon as the first executed test needs it, private_deinitTestEnvironment must be called once after the lasts test needing it has executed. The only way that I found to do that is to override unittest.TextTestResult's stopTestRun method, which is called once after all tests have been executed. Hence a new test runner setup in unotest/source/python/org/libreoffice/unittest.py that is now called from solenv/gbuild/PythonTest.mk. That revealed a few places in PythonTests that didn't yet close/delete documents that they had opened, which has now been added. One remaining problem then is that classes like SwXTextDocument and friends call Application::GetSolarMutex from their dtors, via sw::UnoImplPtrDeleter (a "Smart pointer class ensuring that the pointed object is deleted with a locked SolarMutex", sw/inc/unobaseclass.hxx). That means that any PyUNO proxies to such C++ objects that remain alive after private_deinitTestEnvironment will cause issues at exit, when Python does a final garbage collection of those objects. The ultimate fix will be to remove that unhelpful UnoImplPtrDeleter and its locking of SolarMutex from the dtors of UNO objects; until then, the Python code is now sprinkled with some HACKs to make sure all those PyUNO proxies are released in a timely fashion (see the comment in unotest/source/python/org/libreoffice/unittest.py for details). (Also, it would probably help if UnoInProcess didn't keep a local self.xDoc around referencing (just) the last result of calling one of its open* methods, confusingly making it the responsibility of UnoInProcess to close that one document while making it the responsibility of the test code making the other UnoInProcess.open* calls to close any other documents.) Change-Id: Ief27c81e2b763e9be20cbf3234b68924315f13be Reviewed-on: https://gerrit.libreoffice.org/60100 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2018-09-06 17:13:54 +02:00
doc.close(True)
Make PyUNO provide more Pythonic behaviour - Simplifies working with UNO objects by giving the behaviour of Python lists, dicts and iterators to objects which implement UNO container interfaces - Applies a custom behaviour to allow objects which implement com::sun::star::table::XCellRange to yield cells and cell ranges by subscript - When UNO container objects are addressed in the new style, eliminates the requirement to manually construct Any objects for contained elements which are typed sequences - Allows lists and iterators to be passed wherever a UNO method accepts a sequence - Relaxes the requirements for initialising UNO structs to allow some members to be skipped when all initialisers are passed by name 1. Collection interfaces ======================== Objects which implement core UNO collection interfaces are made to behave in a way that is more natural for Python code. com::sun::star::container::XIndexAccess com::sun::star::container::XIndexReplace com::sun::star::container::XIndexContainer - Objects provide Python list access semantics num = len(obj) # Number of elements val = obj[0] # Access by index val1,val2 = obj[2:4] # Access by slice val1,val2 = obj[0:3:2] # Access by extended slice if val in obj: ... # Test value presence for val in obj: ... # Implicit iterator (values) itr = iter(obj) # Named iterator (values) obj[0] = val # Replace by index obj[2:4] = val1,val2 # Replace by slice obj[0:3:2] = val1,val2 # Replace by extended slice obj[2:3] = val1,val2 # Insert/replace by slice obj[2:2] = (val,) # Insert by slice obj[2:4] = (val,) # Replace/delete by slice obj[2:3] = () # Delete by slice (implicit) del obj[0] # Delete by index del obj[2:4] # Delete by slice com::sun::star::container::XNameAccess com::sun::star::container::XNameReplace com::sun::star::container::XNameContainer - Objects provide Python dict access semantics num = len(obj) # Number of keys val = obj[key] # Access by key if key in obj: ... # Test key presence for key in obj: ... # Implicit iterator (keys) itr = iter(obj) # Named iterator (keys) obj[key] = val # Replace by key obj[key] = val # Insert by key del obj[key] # Delete by key com::sun::star::container::XEnumerationAccess - Objects provide Python iterable semantics for val in obj: ... # Implicit iterator itr = iter(obj) # Named iterator com::sun::star::container::XEnumeration - Objects provide Python iterator semantics for val in itr: ... # Iteration of named iterator if val in itr: ... # Test value presence Objects which implement both XIndex* and XName* are supported, and respond to both integer and string keys. However, iterating over such an object will return the keys (like a Python dict) rather than the values (like a Python list). 2. Cell ranges ============== A custom behaviour is applied to objects which implement com::sun::star::table::XCellRange to allow their cells and cell ranges to be addressed by subscript, in the style of a Python list or dict (read-only). This is applicable to Calc spreadsheet sheets, Writer text tables and cell ranges created upon these. cell = cellrange[0,0] # Access cell by indices rng = cellrange[0,1:2] # Access cell range by index,slice rng = cellrange[1:2,0] # Access cell range by slice,index rng = cellrange[0:1,2:3] # Access cell range by slices rng = cellrange['A1:B2'] # Access cell range by descriptor rng = cellrange['Name'] # Access cell range by name Note that the indices used are in Python/C order, and differ from the arguments to methods provided by XCellRange. - The statement cellrange[r,c], which returns the cell from row r and column c, is equivalent to calling XCellRange::getCellByPosition(c,r) - The statement cellrange[t:b,l:r], which returns a cell range covering rows t to b(non-inclusive) and columns l to r(non- inclusive), is equivalent to calling XCellRange::getCellRangeByPosition(l,t,r-1,b-1). In contrast to the handling of objects implementing XIndex*, extended slice syntax is not supported. Negative indices (from-end addresses) are supported only for objects which also implement com::sun::star::table::XColumnRowRange (currently Calc spreadsheet sheets and cell ranges created upon these). For such objects, the following syntax is also available: rng = cellrange[0] # Access cell range by row index rng = cellrange[0,:] # Access cell range by row index rng = cellrange[:,0] # Access cell range by column index 3. Elimination of explicit Any ============================== PyUNO has not previously been able to cope with certain method arguments which are typed as Any but require a sequence of specific type to be passed. This is a particular issue for container interfaces such as XIndexContainer and XNameContainer. The existing solution to dealing with such methods is to use a special method to pass an explicitly typed Any, giving code such as: index = doc.createInstance("com.sun.star.text.ContentIndex"); ... uno.invoke( index.LevelParagraphStyles , "replaceByIndex", (0, uno.Any("[]string", ('Caption',))) ) The new Pythonic container access is able to correctly infer the expected type of the sequences required by these arguments. In the new style, the above call to .replaceByIndex() can instead be written: index.LevelParagraphStyles[0] = ('Caption',) 4. List and iterator arguments ============================== Wherever a UNO API expects a sequence, a Python list or iterator can now be passed. This enables the use of list comprehensions and generator expressions for method calls and property assignments. Example: tbl = doc.createInstance('com.sun.star.text.TextTable') tbl.initialize(10,10) # ... insert table ... # Assign numbers 0..99 to the cells using a generator expression tbl.Data = ((y for y in range(10*x,10*x + 10)) for x in range(10)) 5. Tolerant struct initialisation ================================= Previously, a UNO struct could be created fully uninitialised, or by passing a combination of positional and/or named arguments to its constructor. However, if any arguments were passed, all members were required to be initialised or an exception was thrown. This requirement is relaxed such that when all arguments passed to a struct constructor are by name, some may be omitted. The existing requirement that all members must be explicitly initialised when some constructor arguments are unnamed (positional) is not affected. Example: from com.sun.star.beans import PropertyValue prop = PropertyValue(Name='foo', Value='bar') Change-Id: Id29bff10a18099b1a00af1abee1a6c1bc58b3978 Reviewed-on: https://gerrit.libreoffice.org/16272 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Matthew Francis <mjay.francis@gmail.com>
2015-06-01 18:34:04 +08:00
# Tests syntax:
# if val in itr: ... # Test value presence
# For:
# Absent value
def test_XEnumeration_IfIn_Absent(self):
# Given
doc1 = self.createBlankTextDocument()
doc2 = self.createBlankTextDocument()
# When
paragraph = doc2.Text.createEnumeration().nextElement()
itr = iter(doc1.Text.createEnumeration())
result = paragraph in itr
# Then
self.assertFalse(result)
DeInitVCL in PythonTest After b9757f5cfdb62b24e79eeb4c0ef0c8b98056cecf "loplugin:useuniqueptr in vcl/svdata" ASan/UBSan builds started to fail (like <https://ci.libreoffice.org//job/lo_ubsan/1025/>) at the end of PythonTest_dbaccess_python (and probably other PythonTests), when during exit the static utl::ConfigManager instance already happens to be destroyed by the time the static ImplSVData's mpSettingsConfigItem is destroyed (which would normally be cleared during DeInitVCL, if PythonTests would call that, and which in the past had thus simply been leaked in PythonTests when that mpSettingsConfigItem was a plain pointer instead of std::unique_ptr). So ensure that PythonTests that initialize VCL also call DeInitVCL, via a new private_deinitTestEnvironment, complementing the existing private_initTestEnvironment. However, while private_initTestEnvironment is called once (typically via UnoInProcess.setUp, which internally makes sure to only call it once) as soon as the first executed test needs it, private_deinitTestEnvironment must be called once after the lasts test needing it has executed. The only way that I found to do that is to override unittest.TextTestResult's stopTestRun method, which is called once after all tests have been executed. Hence a new test runner setup in unotest/source/python/org/libreoffice/unittest.py that is now called from solenv/gbuild/PythonTest.mk. That revealed a few places in PythonTests that didn't yet close/delete documents that they had opened, which has now been added. One remaining problem then is that classes like SwXTextDocument and friends call Application::GetSolarMutex from their dtors, via sw::UnoImplPtrDeleter (a "Smart pointer class ensuring that the pointed object is deleted with a locked SolarMutex", sw/inc/unobaseclass.hxx). That means that any PyUNO proxies to such C++ objects that remain alive after private_deinitTestEnvironment will cause issues at exit, when Python does a final garbage collection of those objects. The ultimate fix will be to remove that unhelpful UnoImplPtrDeleter and its locking of SolarMutex from the dtors of UNO objects; until then, the Python code is now sprinkled with some HACKs to make sure all those PyUNO proxies are released in a timely fashion (see the comment in unotest/source/python/org/libreoffice/unittest.py for details). (Also, it would probably help if UnoInProcess didn't keep a local self.xDoc around referencing (just) the last result of calling one of its open* methods, confusingly making it the responsibility of UnoInProcess to close that one document while making it the responsibility of the test code making the other UnoInProcess.open* calls to close any other documents.) Change-Id: Ief27c81e2b763e9be20cbf3234b68924315f13be Reviewed-on: https://gerrit.libreoffice.org/60100 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2018-09-06 17:13:54 +02:00
doc1.close(True)
doc2.close(True)
Make PyUNO provide more Pythonic behaviour - Simplifies working with UNO objects by giving the behaviour of Python lists, dicts and iterators to objects which implement UNO container interfaces - Applies a custom behaviour to allow objects which implement com::sun::star::table::XCellRange to yield cells and cell ranges by subscript - When UNO container objects are addressed in the new style, eliminates the requirement to manually construct Any objects for contained elements which are typed sequences - Allows lists and iterators to be passed wherever a UNO method accepts a sequence - Relaxes the requirements for initialising UNO structs to allow some members to be skipped when all initialisers are passed by name 1. Collection interfaces ======================== Objects which implement core UNO collection interfaces are made to behave in a way that is more natural for Python code. com::sun::star::container::XIndexAccess com::sun::star::container::XIndexReplace com::sun::star::container::XIndexContainer - Objects provide Python list access semantics num = len(obj) # Number of elements val = obj[0] # Access by index val1,val2 = obj[2:4] # Access by slice val1,val2 = obj[0:3:2] # Access by extended slice if val in obj: ... # Test value presence for val in obj: ... # Implicit iterator (values) itr = iter(obj) # Named iterator (values) obj[0] = val # Replace by index obj[2:4] = val1,val2 # Replace by slice obj[0:3:2] = val1,val2 # Replace by extended slice obj[2:3] = val1,val2 # Insert/replace by slice obj[2:2] = (val,) # Insert by slice obj[2:4] = (val,) # Replace/delete by slice obj[2:3] = () # Delete by slice (implicit) del obj[0] # Delete by index del obj[2:4] # Delete by slice com::sun::star::container::XNameAccess com::sun::star::container::XNameReplace com::sun::star::container::XNameContainer - Objects provide Python dict access semantics num = len(obj) # Number of keys val = obj[key] # Access by key if key in obj: ... # Test key presence for key in obj: ... # Implicit iterator (keys) itr = iter(obj) # Named iterator (keys) obj[key] = val # Replace by key obj[key] = val # Insert by key del obj[key] # Delete by key com::sun::star::container::XEnumerationAccess - Objects provide Python iterable semantics for val in obj: ... # Implicit iterator itr = iter(obj) # Named iterator com::sun::star::container::XEnumeration - Objects provide Python iterator semantics for val in itr: ... # Iteration of named iterator if val in itr: ... # Test value presence Objects which implement both XIndex* and XName* are supported, and respond to both integer and string keys. However, iterating over such an object will return the keys (like a Python dict) rather than the values (like a Python list). 2. Cell ranges ============== A custom behaviour is applied to objects which implement com::sun::star::table::XCellRange to allow their cells and cell ranges to be addressed by subscript, in the style of a Python list or dict (read-only). This is applicable to Calc spreadsheet sheets, Writer text tables and cell ranges created upon these. cell = cellrange[0,0] # Access cell by indices rng = cellrange[0,1:2] # Access cell range by index,slice rng = cellrange[1:2,0] # Access cell range by slice,index rng = cellrange[0:1,2:3] # Access cell range by slices rng = cellrange['A1:B2'] # Access cell range by descriptor rng = cellrange['Name'] # Access cell range by name Note that the indices used are in Python/C order, and differ from the arguments to methods provided by XCellRange. - The statement cellrange[r,c], which returns the cell from row r and column c, is equivalent to calling XCellRange::getCellByPosition(c,r) - The statement cellrange[t:b,l:r], which returns a cell range covering rows t to b(non-inclusive) and columns l to r(non- inclusive), is equivalent to calling XCellRange::getCellRangeByPosition(l,t,r-1,b-1). In contrast to the handling of objects implementing XIndex*, extended slice syntax is not supported. Negative indices (from-end addresses) are supported only for objects which also implement com::sun::star::table::XColumnRowRange (currently Calc spreadsheet sheets and cell ranges created upon these). For such objects, the following syntax is also available: rng = cellrange[0] # Access cell range by row index rng = cellrange[0,:] # Access cell range by row index rng = cellrange[:,0] # Access cell range by column index 3. Elimination of explicit Any ============================== PyUNO has not previously been able to cope with certain method arguments which are typed as Any but require a sequence of specific type to be passed. This is a particular issue for container interfaces such as XIndexContainer and XNameContainer. The existing solution to dealing with such methods is to use a special method to pass an explicitly typed Any, giving code such as: index = doc.createInstance("com.sun.star.text.ContentIndex"); ... uno.invoke( index.LevelParagraphStyles , "replaceByIndex", (0, uno.Any("[]string", ('Caption',))) ) The new Pythonic container access is able to correctly infer the expected type of the sequences required by these arguments. In the new style, the above call to .replaceByIndex() can instead be written: index.LevelParagraphStyles[0] = ('Caption',) 4. List and iterator arguments ============================== Wherever a UNO API expects a sequence, a Python list or iterator can now be passed. This enables the use of list comprehensions and generator expressions for method calls and property assignments. Example: tbl = doc.createInstance('com.sun.star.text.TextTable') tbl.initialize(10,10) # ... insert table ... # Assign numbers 0..99 to the cells using a generator expression tbl.Data = ((y for y in range(10*x,10*x + 10)) for x in range(10)) 5. Tolerant struct initialisation ================================= Previously, a UNO struct could be created fully uninitialised, or by passing a combination of positional and/or named arguments to its constructor. However, if any arguments were passed, all members were required to be initialised or an exception was thrown. This requirement is relaxed such that when all arguments passed to a struct constructor are by name, some may be omitted. The existing requirement that all members must be explicitly initialised when some constructor arguments are unnamed (positional) is not affected. Example: from com.sun.star.beans import PropertyValue prop = PropertyValue(Name='foo', Value='bar') Change-Id: Id29bff10a18099b1a00af1abee1a6c1bc58b3978 Reviewed-on: https://gerrit.libreoffice.org/16272 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Matthew Francis <mjay.francis@gmail.com>
2015-06-01 18:34:04 +08:00
# Tests syntax:
# if val in itr: ... # Test value presence
# For:
# None
def test_XEnumeration_IfIn_None(self):
# Given
doc = self.createBlankTextDocument()
# When
itr = iter(doc.Text.createEnumeration())
result = None in itr
# Then
self.assertFalse(result)
DeInitVCL in PythonTest After b9757f5cfdb62b24e79eeb4c0ef0c8b98056cecf "loplugin:useuniqueptr in vcl/svdata" ASan/UBSan builds started to fail (like <https://ci.libreoffice.org//job/lo_ubsan/1025/>) at the end of PythonTest_dbaccess_python (and probably other PythonTests), when during exit the static utl::ConfigManager instance already happens to be destroyed by the time the static ImplSVData's mpSettingsConfigItem is destroyed (which would normally be cleared during DeInitVCL, if PythonTests would call that, and which in the past had thus simply been leaked in PythonTests when that mpSettingsConfigItem was a plain pointer instead of std::unique_ptr). So ensure that PythonTests that initialize VCL also call DeInitVCL, via a new private_deinitTestEnvironment, complementing the existing private_initTestEnvironment. However, while private_initTestEnvironment is called once (typically via UnoInProcess.setUp, which internally makes sure to only call it once) as soon as the first executed test needs it, private_deinitTestEnvironment must be called once after the lasts test needing it has executed. The only way that I found to do that is to override unittest.TextTestResult's stopTestRun method, which is called once after all tests have been executed. Hence a new test runner setup in unotest/source/python/org/libreoffice/unittest.py that is now called from solenv/gbuild/PythonTest.mk. That revealed a few places in PythonTests that didn't yet close/delete documents that they had opened, which has now been added. One remaining problem then is that classes like SwXTextDocument and friends call Application::GetSolarMutex from their dtors, via sw::UnoImplPtrDeleter (a "Smart pointer class ensuring that the pointed object is deleted with a locked SolarMutex", sw/inc/unobaseclass.hxx). That means that any PyUNO proxies to such C++ objects that remain alive after private_deinitTestEnvironment will cause issues at exit, when Python does a final garbage collection of those objects. The ultimate fix will be to remove that unhelpful UnoImplPtrDeleter and its locking of SolarMutex from the dtors of UNO objects; until then, the Python code is now sprinkled with some HACKs to make sure all those PyUNO proxies are released in a timely fashion (see the comment in unotest/source/python/org/libreoffice/unittest.py for details). (Also, it would probably help if UnoInProcess didn't keep a local self.xDoc around referencing (just) the last result of calling one of its open* methods, confusingly making it the responsibility of UnoInProcess to close that one document while making it the responsibility of the test code making the other UnoInProcess.open* calls to close any other documents.) Change-Id: Ief27c81e2b763e9be20cbf3234b68924315f13be Reviewed-on: https://gerrit.libreoffice.org/60100 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2018-09-06 17:13:54 +02:00
doc.close(True)
Make PyUNO provide more Pythonic behaviour - Simplifies working with UNO objects by giving the behaviour of Python lists, dicts and iterators to objects which implement UNO container interfaces - Applies a custom behaviour to allow objects which implement com::sun::star::table::XCellRange to yield cells and cell ranges by subscript - When UNO container objects are addressed in the new style, eliminates the requirement to manually construct Any objects for contained elements which are typed sequences - Allows lists and iterators to be passed wherever a UNO method accepts a sequence - Relaxes the requirements for initialising UNO structs to allow some members to be skipped when all initialisers are passed by name 1. Collection interfaces ======================== Objects which implement core UNO collection interfaces are made to behave in a way that is more natural for Python code. com::sun::star::container::XIndexAccess com::sun::star::container::XIndexReplace com::sun::star::container::XIndexContainer - Objects provide Python list access semantics num = len(obj) # Number of elements val = obj[0] # Access by index val1,val2 = obj[2:4] # Access by slice val1,val2 = obj[0:3:2] # Access by extended slice if val in obj: ... # Test value presence for val in obj: ... # Implicit iterator (values) itr = iter(obj) # Named iterator (values) obj[0] = val # Replace by index obj[2:4] = val1,val2 # Replace by slice obj[0:3:2] = val1,val2 # Replace by extended slice obj[2:3] = val1,val2 # Insert/replace by slice obj[2:2] = (val,) # Insert by slice obj[2:4] = (val,) # Replace/delete by slice obj[2:3] = () # Delete by slice (implicit) del obj[0] # Delete by index del obj[2:4] # Delete by slice com::sun::star::container::XNameAccess com::sun::star::container::XNameReplace com::sun::star::container::XNameContainer - Objects provide Python dict access semantics num = len(obj) # Number of keys val = obj[key] # Access by key if key in obj: ... # Test key presence for key in obj: ... # Implicit iterator (keys) itr = iter(obj) # Named iterator (keys) obj[key] = val # Replace by key obj[key] = val # Insert by key del obj[key] # Delete by key com::sun::star::container::XEnumerationAccess - Objects provide Python iterable semantics for val in obj: ... # Implicit iterator itr = iter(obj) # Named iterator com::sun::star::container::XEnumeration - Objects provide Python iterator semantics for val in itr: ... # Iteration of named iterator if val in itr: ... # Test value presence Objects which implement both XIndex* and XName* are supported, and respond to both integer and string keys. However, iterating over such an object will return the keys (like a Python dict) rather than the values (like a Python list). 2. Cell ranges ============== A custom behaviour is applied to objects which implement com::sun::star::table::XCellRange to allow their cells and cell ranges to be addressed by subscript, in the style of a Python list or dict (read-only). This is applicable to Calc spreadsheet sheets, Writer text tables and cell ranges created upon these. cell = cellrange[0,0] # Access cell by indices rng = cellrange[0,1:2] # Access cell range by index,slice rng = cellrange[1:2,0] # Access cell range by slice,index rng = cellrange[0:1,2:3] # Access cell range by slices rng = cellrange['A1:B2'] # Access cell range by descriptor rng = cellrange['Name'] # Access cell range by name Note that the indices used are in Python/C order, and differ from the arguments to methods provided by XCellRange. - The statement cellrange[r,c], which returns the cell from row r and column c, is equivalent to calling XCellRange::getCellByPosition(c,r) - The statement cellrange[t:b,l:r], which returns a cell range covering rows t to b(non-inclusive) and columns l to r(non- inclusive), is equivalent to calling XCellRange::getCellRangeByPosition(l,t,r-1,b-1). In contrast to the handling of objects implementing XIndex*, extended slice syntax is not supported. Negative indices (from-end addresses) are supported only for objects which also implement com::sun::star::table::XColumnRowRange (currently Calc spreadsheet sheets and cell ranges created upon these). For such objects, the following syntax is also available: rng = cellrange[0] # Access cell range by row index rng = cellrange[0,:] # Access cell range by row index rng = cellrange[:,0] # Access cell range by column index 3. Elimination of explicit Any ============================== PyUNO has not previously been able to cope with certain method arguments which are typed as Any but require a sequence of specific type to be passed. This is a particular issue for container interfaces such as XIndexContainer and XNameContainer. The existing solution to dealing with such methods is to use a special method to pass an explicitly typed Any, giving code such as: index = doc.createInstance("com.sun.star.text.ContentIndex"); ... uno.invoke( index.LevelParagraphStyles , "replaceByIndex", (0, uno.Any("[]string", ('Caption',))) ) The new Pythonic container access is able to correctly infer the expected type of the sequences required by these arguments. In the new style, the above call to .replaceByIndex() can instead be written: index.LevelParagraphStyles[0] = ('Caption',) 4. List and iterator arguments ============================== Wherever a UNO API expects a sequence, a Python list or iterator can now be passed. This enables the use of list comprehensions and generator expressions for method calls and property assignments. Example: tbl = doc.createInstance('com.sun.star.text.TextTable') tbl.initialize(10,10) # ... insert table ... # Assign numbers 0..99 to the cells using a generator expression tbl.Data = ((y for y in range(10*x,10*x + 10)) for x in range(10)) 5. Tolerant struct initialisation ================================= Previously, a UNO struct could be created fully uninitialised, or by passing a combination of positional and/or named arguments to its constructor. However, if any arguments were passed, all members were required to be initialised or an exception was thrown. This requirement is relaxed such that when all arguments passed to a struct constructor are by name, some may be omitted. The existing requirement that all members must be explicitly initialised when some constructor arguments are unnamed (positional) is not affected. Example: from com.sun.star.beans import PropertyValue prop = PropertyValue(Name='foo', Value='bar') Change-Id: Id29bff10a18099b1a00af1abee1a6c1bc58b3978 Reviewed-on: https://gerrit.libreoffice.org/16272 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Matthew Francis <mjay.francis@gmail.com>
2015-06-01 18:34:04 +08:00
# Tests syntax:
# if val in itr: ... # Test value presence
# For:
# Invalid value (string)
# Note: Ideally this would raise TypeError in the same manner as for
# XEnumerationAccess, but an XEnumeration doesn't know the type of its
# values
def test_XEnumeration_IfIn_String(self):
# Given
doc = self.createBlankTextDocument()
# When
itr = iter(doc.Text.createEnumeration())
result = 'foo' in itr
# Then
self.assertFalse(result)
DeInitVCL in PythonTest After b9757f5cfdb62b24e79eeb4c0ef0c8b98056cecf "loplugin:useuniqueptr in vcl/svdata" ASan/UBSan builds started to fail (like <https://ci.libreoffice.org//job/lo_ubsan/1025/>) at the end of PythonTest_dbaccess_python (and probably other PythonTests), when during exit the static utl::ConfigManager instance already happens to be destroyed by the time the static ImplSVData's mpSettingsConfigItem is destroyed (which would normally be cleared during DeInitVCL, if PythonTests would call that, and which in the past had thus simply been leaked in PythonTests when that mpSettingsConfigItem was a plain pointer instead of std::unique_ptr). So ensure that PythonTests that initialize VCL also call DeInitVCL, via a new private_deinitTestEnvironment, complementing the existing private_initTestEnvironment. However, while private_initTestEnvironment is called once (typically via UnoInProcess.setUp, which internally makes sure to only call it once) as soon as the first executed test needs it, private_deinitTestEnvironment must be called once after the lasts test needing it has executed. The only way that I found to do that is to override unittest.TextTestResult's stopTestRun method, which is called once after all tests have been executed. Hence a new test runner setup in unotest/source/python/org/libreoffice/unittest.py that is now called from solenv/gbuild/PythonTest.mk. That revealed a few places in PythonTests that didn't yet close/delete documents that they had opened, which has now been added. One remaining problem then is that classes like SwXTextDocument and friends call Application::GetSolarMutex from their dtors, via sw::UnoImplPtrDeleter (a "Smart pointer class ensuring that the pointed object is deleted with a locked SolarMutex", sw/inc/unobaseclass.hxx). That means that any PyUNO proxies to such C++ objects that remain alive after private_deinitTestEnvironment will cause issues at exit, when Python does a final garbage collection of those objects. The ultimate fix will be to remove that unhelpful UnoImplPtrDeleter and its locking of SolarMutex from the dtors of UNO objects; until then, the Python code is now sprinkled with some HACKs to make sure all those PyUNO proxies are released in a timely fashion (see the comment in unotest/source/python/org/libreoffice/unittest.py for details). (Also, it would probably help if UnoInProcess didn't keep a local self.xDoc around referencing (just) the last result of calling one of its open* methods, confusingly making it the responsibility of UnoInProcess to close that one document while making it the responsibility of the test code making the other UnoInProcess.open* calls to close any other documents.) Change-Id: Ief27c81e2b763e9be20cbf3234b68924315f13be Reviewed-on: https://gerrit.libreoffice.org/60100 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2018-09-06 17:13:54 +02:00
doc.close(True)
Make PyUNO provide more Pythonic behaviour - Simplifies working with UNO objects by giving the behaviour of Python lists, dicts and iterators to objects which implement UNO container interfaces - Applies a custom behaviour to allow objects which implement com::sun::star::table::XCellRange to yield cells and cell ranges by subscript - When UNO container objects are addressed in the new style, eliminates the requirement to manually construct Any objects for contained elements which are typed sequences - Allows lists and iterators to be passed wherever a UNO method accepts a sequence - Relaxes the requirements for initialising UNO structs to allow some members to be skipped when all initialisers are passed by name 1. Collection interfaces ======================== Objects which implement core UNO collection interfaces are made to behave in a way that is more natural for Python code. com::sun::star::container::XIndexAccess com::sun::star::container::XIndexReplace com::sun::star::container::XIndexContainer - Objects provide Python list access semantics num = len(obj) # Number of elements val = obj[0] # Access by index val1,val2 = obj[2:4] # Access by slice val1,val2 = obj[0:3:2] # Access by extended slice if val in obj: ... # Test value presence for val in obj: ... # Implicit iterator (values) itr = iter(obj) # Named iterator (values) obj[0] = val # Replace by index obj[2:4] = val1,val2 # Replace by slice obj[0:3:2] = val1,val2 # Replace by extended slice obj[2:3] = val1,val2 # Insert/replace by slice obj[2:2] = (val,) # Insert by slice obj[2:4] = (val,) # Replace/delete by slice obj[2:3] = () # Delete by slice (implicit) del obj[0] # Delete by index del obj[2:4] # Delete by slice com::sun::star::container::XNameAccess com::sun::star::container::XNameReplace com::sun::star::container::XNameContainer - Objects provide Python dict access semantics num = len(obj) # Number of keys val = obj[key] # Access by key if key in obj: ... # Test key presence for key in obj: ... # Implicit iterator (keys) itr = iter(obj) # Named iterator (keys) obj[key] = val # Replace by key obj[key] = val # Insert by key del obj[key] # Delete by key com::sun::star::container::XEnumerationAccess - Objects provide Python iterable semantics for val in obj: ... # Implicit iterator itr = iter(obj) # Named iterator com::sun::star::container::XEnumeration - Objects provide Python iterator semantics for val in itr: ... # Iteration of named iterator if val in itr: ... # Test value presence Objects which implement both XIndex* and XName* are supported, and respond to both integer and string keys. However, iterating over such an object will return the keys (like a Python dict) rather than the values (like a Python list). 2. Cell ranges ============== A custom behaviour is applied to objects which implement com::sun::star::table::XCellRange to allow their cells and cell ranges to be addressed by subscript, in the style of a Python list or dict (read-only). This is applicable to Calc spreadsheet sheets, Writer text tables and cell ranges created upon these. cell = cellrange[0,0] # Access cell by indices rng = cellrange[0,1:2] # Access cell range by index,slice rng = cellrange[1:2,0] # Access cell range by slice,index rng = cellrange[0:1,2:3] # Access cell range by slices rng = cellrange['A1:B2'] # Access cell range by descriptor rng = cellrange['Name'] # Access cell range by name Note that the indices used are in Python/C order, and differ from the arguments to methods provided by XCellRange. - The statement cellrange[r,c], which returns the cell from row r and column c, is equivalent to calling XCellRange::getCellByPosition(c,r) - The statement cellrange[t:b,l:r], which returns a cell range covering rows t to b(non-inclusive) and columns l to r(non- inclusive), is equivalent to calling XCellRange::getCellRangeByPosition(l,t,r-1,b-1). In contrast to the handling of objects implementing XIndex*, extended slice syntax is not supported. Negative indices (from-end addresses) are supported only for objects which also implement com::sun::star::table::XColumnRowRange (currently Calc spreadsheet sheets and cell ranges created upon these). For such objects, the following syntax is also available: rng = cellrange[0] # Access cell range by row index rng = cellrange[0,:] # Access cell range by row index rng = cellrange[:,0] # Access cell range by column index 3. Elimination of explicit Any ============================== PyUNO has not previously been able to cope with certain method arguments which are typed as Any but require a sequence of specific type to be passed. This is a particular issue for container interfaces such as XIndexContainer and XNameContainer. The existing solution to dealing with such methods is to use a special method to pass an explicitly typed Any, giving code such as: index = doc.createInstance("com.sun.star.text.ContentIndex"); ... uno.invoke( index.LevelParagraphStyles , "replaceByIndex", (0, uno.Any("[]string", ('Caption',))) ) The new Pythonic container access is able to correctly infer the expected type of the sequences required by these arguments. In the new style, the above call to .replaceByIndex() can instead be written: index.LevelParagraphStyles[0] = ('Caption',) 4. List and iterator arguments ============================== Wherever a UNO API expects a sequence, a Python list or iterator can now be passed. This enables the use of list comprehensions and generator expressions for method calls and property assignments. Example: tbl = doc.createInstance('com.sun.star.text.TextTable') tbl.initialize(10,10) # ... insert table ... # Assign numbers 0..99 to the cells using a generator expression tbl.Data = ((y for y in range(10*x,10*x + 10)) for x in range(10)) 5. Tolerant struct initialisation ================================= Previously, a UNO struct could be created fully uninitialised, or by passing a combination of positional and/or named arguments to its constructor. However, if any arguments were passed, all members were required to be initialised or an exception was thrown. This requirement is relaxed such that when all arguments passed to a struct constructor are by name, some may be omitted. The existing requirement that all members must be explicitly initialised when some constructor arguments are unnamed (positional) is not affected. Example: from com.sun.star.beans import PropertyValue prop = PropertyValue(Name='foo', Value='bar') Change-Id: Id29bff10a18099b1a00af1abee1a6c1bc58b3978 Reviewed-on: https://gerrit.libreoffice.org/16272 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Matthew Francis <mjay.francis@gmail.com>
2015-06-01 18:34:04 +08:00
if __name__ == '__main__':
unittest.main()
# vim:set shiftwidth=4 softtabstop=4 expandtab: