Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / pyuno / source / module / uno.py
blobbd894a0eea4ef872a39b2fa0ca7988945337843a
1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 # This file incorporates work covered by the following license notice:
11 # Licensed to the Apache Software Foundation (ASF) under one or more
12 # contributor license agreements. See the NOTICE file distributed
13 # with this work for additional information regarding copyright
14 # ownership. The ASF licenses this file to you under the Apache
15 # License, Version 2.0 (the "License"); you may not use this file
16 # except in compliance with the License. You may obtain a copy of
17 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 import pyuno
20 import sys
21 import traceback
22 import warnings
24 # since on Windows sal3.dll no longer calls WSAStartup
25 import socket
27 # Some Python 2/3 compatibility code copied from the six library
28 PY2 = sys.version_info[0] == 2
30 if PY2:
31 six_string_types = basestring,
32 else:
33 six_string_types = str,
35 # All functions and variables starting with a underscore (_) must be
36 # considered private and can be changed at any time. Don't use them.
37 _component_context = pyuno.getComponentContext()
40 def getComponentContext():
41 """Returns the UNO component context used to initialize the Python runtime."""
43 return _component_context
46 def getCurrentContext():
47 """Returns the current context.
49 See http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context
50 for an explanation on the current context concept.
51 """
53 return pyuno.getCurrentContext()
56 def setCurrentContext(newContext):
57 """Sets newContext as new UNO context.
59 The newContext must implement the XCurrentContext interface. The
60 implementation should handle the desired properties and delegate
61 unknown properties to the old context. Ensure that the old one
62 is reset when you leave your stack, see
63 http://udk.openoffice.org/common/man/concept/uno_contexts.html#current_context
64 """
66 return pyuno.setCurrentContext(newContext)
69 def getConstantByName(constant):
70 """Looks up the value of an IDL constant by giving its explicit name."""
72 return pyuno.getConstantByName(constant)
75 def getTypeByName(typeName):
76 """Returns a `uno.Type` instance of the type given by typeName.
78 If the type does not exist, a `com.sun.star.uno.RuntimeException` is raised.
79 """
81 return pyuno.getTypeByName(typeName)
84 def createUnoStruct(typeName, *args, **kwargs):
85 """Creates a UNO struct or exception given by typeName.
87 Can be called with:
89 1) No additional argument.
90 In this case, you get a default constructed UNO structure.
91 (e.g. `createUnoStruct("com.sun.star.uno.Exception")`)
92 2) Exactly one additional argument that is an instance of typeName.
93 In this case, a copy constructed instance of typeName is returned
94 (e.g. `createUnoStruct("com.sun.star.uno.Exception" , e)`)
95 3) As many additional arguments as the number of elements within typeName
96 (e.g. `createUnoStruct("com.sun.star.uno.Exception", "foo error" , self)`).
97 4) Keyword arguments to give values for each element of the struct by name.
98 5) A mix of 3) and 4), such that each struct element is given a value exactly once,
99 either by a positional argument or by a keyword argument.
101 The additional and/or keyword arguments must match the type of each struct element,
102 otherwise an exception is thrown.
105 return getClass(typeName)(*args, **kwargs)
108 def getClass(typeName):
109 """Returns the class of a concrete UNO exception, struct, or interface."""
111 return pyuno.getClass(typeName)
114 def isInterface(obj):
115 """Returns True, when obj is a class of a UNO interface."""
117 return pyuno.isInterface(obj)
120 def generateUuid():
121 """Returns a 16 byte sequence containing a newly generated uuid or guid.
123 For more information, see rtl/uuid.h.
126 return pyuno.generateUuid()
129 def systemPathToFileUrl(systemPath):
130 """Returns a file URL for the given system path."""
132 return pyuno.systemPathToFileUrl(systemPath)
135 def fileUrlToSystemPath(url):
136 """Returns a system path.
138 This path is determined by the system that the Python interpreter is running on.
141 return pyuno.fileUrlToSystemPath(url)
144 def absolutize(path, relativeUrl):
145 """Returns an absolute file url from the given urls."""
147 return pyuno.absolutize(path, relativeUrl)
150 class Enum:
151 """Represents a UNO enum.
153 Use an instance of this class to explicitly pass an enum to UNO.
155 :param typeName: The name of the enum as a string.
156 :param value: The actual value of this enum as a string.
159 def __init__(self, typeName, value):
160 self.typeName = typeName
161 self.value = value
162 pyuno.checkEnum(self)
164 def __repr__(self):
165 return "<Enum instance %s (%r)>" % (self.typeName, self.value)
167 def __eq__(self, that):
168 if not isinstance(that, Enum):
169 return False
171 return (self.typeName == that.typeName) and (self.value == that.value)
173 def __ne__(self,other):
174 return not self.__eq__(other)
177 class Type:
178 """Represents a UNO type.
180 Use an instance of this class to explicitly pass a type to UNO.
182 :param typeName: Name of the UNO type
183 :param typeClass: Python Enum of TypeClass, see com/sun/star/uno/TypeClass.idl
186 def __init__(self, typeName, typeClass):
187 self.typeName = typeName
188 self.typeClass = typeClass
189 pyuno.checkType(self)
191 def __repr__(self):
192 return "<Type instance %s (%r)>" % (self.typeName, self.typeClass)
194 def __eq__(self, that):
195 if not isinstance(that, Type):
196 return False
198 return self.typeClass == that.typeClass and self.typeName == that.typeName
200 def __ne__(self,other):
201 return not self.__eq__(other)
203 def __hash__(self):
204 return self.typeName.__hash__()
207 class Bool(object):
208 """Represents a UNO boolean.
210 Use an instance of this class to explicitly pass a boolean to UNO.
212 Note: This class is deprecated. Use Python's True and False directly instead.
215 def __new__(cls, value):
216 message = "The Bool class is deprecated. Use Python's True and False directly instead."
217 warnings.warn(message, DeprecationWarning)
219 if isinstance(value, six_string_types) and value == "true":
220 return True
222 if isinstance(value, six_string_types) and value == "false":
223 return False
225 if value:
226 return True
228 return False
231 class Char:
232 """Represents a UNO char.
234 Use an instance of this class to explicitly pass a char to UNO.
236 For Python 2, this class only works with unicode objects. Creating
237 a Char instance with a normal str object or comparing a Char instance
238 to a normal str object will raise an AssertionError.
240 :param value: A Unicode string with length 1
243 def __init__(self, value):
244 if PY2:
245 assert isinstance(value, unicode), "Expected unicode object, got %s instead." % type(value)
246 else:
247 assert isinstance(value, str), "Expected str object, got %s instead." % type(value)
249 assert len(value) == 1, "Char value must have length of 1."
251 self.value = value
253 def __repr__(self):
254 return "<Char instance %s>" % (self.value,)
256 def __eq__(self, that):
257 if isinstance(that, six_string_types):
258 if len(that) > 1:
259 return False
261 return self.value == that[0]
263 if isinstance(that, Char):
264 return self.value == that.value
266 return False
268 def __ne__(self,other):
269 return not self.__eq__(other)
272 class ByteSequence:
273 """Represents a UNO ByteSequence value.
275 Use an instance of this class to explicitly pass a byte sequence to UNO.
277 :param value: A string or bytesequence
280 def __init__(self, value):
281 if isinstance(value, bytes):
282 self.value = value
284 elif isinstance(value, ByteSequence):
285 self.value = value.value
287 else:
288 raise TypeError("Expected bytes object or ByteSequence, got %s instead." % type(value))
290 def __repr__(self):
291 return "<ByteSequence instance '%s'>" % (self.value,)
293 def __eq__(self, that):
294 if isinstance(that, bytes):
295 return self.value == that
297 if isinstance(that, ByteSequence):
298 return self.value == that.value
300 return False
302 def __len__(self):
303 return len(self.value)
305 def __getitem__(self, index):
306 return self.value[index]
308 def __iter__(self):
309 return self.value.__iter__()
311 def __add__(self, b):
312 if isinstance(b, bytes):
313 return ByteSequence(self.value + b)
315 elif isinstance(b, ByteSequence):
316 return ByteSequence(self.value + b.value)
318 else:
319 raise TypeError("Can't add ByteString and %s." % type(b))
321 def __hash__(self):
322 return self.value.hash()
325 class Any:
326 """Represents a UNO Any value.
328 Use only in connection with uno.invoke() to pass an explicit typed Any.
331 def __init__(self, type, value):
332 if isinstance(type, Type):
333 self.type = type
334 else:
335 self.type = getTypeByName(type)
337 self.value = value
340 def invoke(object, methodname, argTuple):
341 """Use this function to pass exactly typed Anys to the callee (using uno.Any)."""
343 return pyuno.invoke(object, methodname, argTuple)
346 # -----------------------------------------------------------------------------
347 # Don't use any functions beyond this point; private section, likely to change.
348 # -----------------------------------------------------------------------------
349 _builtin_import = __import__
352 def _uno_import(name, *optargs, **kwargs):
353 """Overrides built-in import to allow directly importing LibreOffice classes."""
355 try:
356 return _builtin_import(name, *optargs, **kwargs)
357 except ImportError as e:
358 # process optargs
359 globals, locals, fromlist = list(optargs)[:3] + [kwargs.get('globals', {}), kwargs.get('locals', {}),
360 kwargs.get('fromlist', [])][len(optargs):]
362 # from import form only, but skip if a uno lookup has already failed
363 if not fromlist or hasattr(e, '_uno_import_failed'):
364 raise
366 # hang onto exception for possible use on subsequent uno lookup failure
367 py_import_exc = e
369 mod = None
370 d = sys.modules
372 for module in name.split("."):
373 if module in d:
374 mod = d[module]
375 else:
376 # How to create a module ??
377 mod = pyuno.__class__(module)
379 d = mod.__dict__
381 RuntimeException = pyuno.getClass("com.sun.star.uno.RuntimeException")
383 for class_name in fromlist:
384 if class_name not in d:
385 failed = False
387 try:
388 # check for structs, exceptions or interfaces
389 d[class_name] = pyuno.getClass(name + "." + class_name)
390 except RuntimeException:
391 # check for enums
392 try:
393 d[class_name] = Enum(name, class_name)
394 except RuntimeException:
395 # check for constants
396 try:
397 d[class_name] = getConstantByName(name + "." + class_name)
398 except RuntimeException:
399 # check for constant group
400 try:
401 d[class_name] = _impl_getConstantGroupByName(name, class_name)
402 except ValueError:
403 failed = True
405 if failed:
406 # We have an import failure, but cannot distinguish between
407 # uno and non-uno errors as uno lookups are attempted for all
408 # "from xxx import yyy" imports following a python failure.
410 # In Python 3, the original python exception traceback is reused
411 # to help pinpoint the actual failing location. Its original
412 # message, unlike Python 2, is unlikely to be helpful for uno
413 # failures, as it most commonly is just a top level module like
414 # 'com'. So our exception appends the uno lookup failure.
415 # This is more ambiguous, but it plus the traceback should be
416 # sufficient to identify a root cause for python or uno issues.
418 # Our exception is raised outside of the nested exception
419 # handlers above, to avoid Python 3 nested exception
420 # information for the RuntimeExceptions during lookups.
422 # Finally, a private attribute is used to prevent further
423 # processing if this failure was in a nested import. That
424 # keeps the exception relevant to the primary failure point,
425 # preventing us from re-processing our own import errors.
427 uno_import_exc = ImportError("%s (or '%s.%s' is unknown)" %
428 (py_import_exc, name, class_name))
430 if sys.version_info[0] >= 3:
431 uno_import_exc = uno_import_exc.with_traceback(py_import_exc.__traceback__)
433 uno_import_exc._uno_import_failed = True
434 raise uno_import_exc
436 return mod
439 try:
440 import __builtin__
441 except ImportError:
442 import builtins as __builtin__
444 # hook into the __import__ chain
445 __builtin__.__dict__['__import__'] = _uno_import
448 class _ConstantGroup(object):
449 """Represents a group of UNOIDL constants."""
451 __slots__ = ['_constants']
453 def __init__(self, constants):
454 self._constants = constants
456 def __dir__(self):
457 return self._constants.keys()
459 def __getattr__(self, name):
460 if name in self._constants:
461 return self._constants[name]
463 raise AttributeError("The constant '%s' could not be found." % name)
466 def _impl_getConstantGroupByName(module, group):
467 """Gets UNOIDL constant group by name."""
469 constants = Enum('com.sun.star.uno.TypeClass', 'CONSTANTS')
470 one = Enum('com.sun.star.reflection.TypeDescriptionSearchDepth', 'ONE')
471 type_desc_mgr = _component_context.getValueByName('/singletons/com.sun.star.reflection.theTypeDescriptionManager')
472 type_descs = type_desc_mgr.createTypeDescriptionEnumeration(module, (constants,), one)
473 qualified_name = module + '.' + group
475 for type_desc in type_descs:
476 if type_desc.Name == qualified_name:
477 return _ConstantGroup(dict(
478 (c.Name.split('.')[-1], c.ConstantValue)
479 for c in type_desc.Constants))
481 raise ValueError("The constant group '%s' could not be found." % qualified_name)
484 def _uno_struct__init__(self, *args, **kwargs):
485 """Initializes a UNO struct.
487 Referenced from the pyuno shared library.
489 This function can be called with either an already constructed UNO struct, which it
490 will then just reference without copying, or with arguments to create a new UNO struct.
493 # Check to see if this function was passed an existing UNO struct
494 if len(kwargs) == 0 and len(args) == 1 and getattr(args[0], "__class__", None) == self.__class__:
495 self.__dict__['value'] = args[0]
496 else:
497 struct, used = pyuno._createUnoStructHelper(self.__class__.__pyunostruct__, args, **kwargs)
499 for kwarg in kwargs.keys():
500 if not used.get(kwarg):
501 RuntimeException = pyuno.getClass("com.sun.star.uno.RuntimeException")
502 raise RuntimeException("_uno_struct__init__: unused keyword argument '%s'." % kwarg, None)
504 self.__dict__["value"] = struct
507 def _uno_struct__getattr__(self, name):
508 """Gets attribute from UNO struct.
510 Referenced from the pyuno shared library.
513 return getattr(self.__dict__["value"], name)
516 def _uno_struct__setattr__(self, name, value):
517 """Sets attribute on UNO struct.
519 Referenced from the pyuno shared library.
522 return setattr(self.__dict__["value"], name, value)
525 def _uno_struct__repr__(self):
526 """Converts a UNO struct to a printable string.
528 Referenced from the pyuno shared library.
531 return repr(self.__dict__["value"])
534 def _uno_struct__str__(self):
535 """Converts a UNO struct to a string."""
537 return str(self.__dict__["value"])
539 def _uno_struct__ne__(self, other):
540 return not self.__eq__(other)
542 def _uno_struct__eq__(self, that):
543 """Compares two UNO structs.
545 Referenced from the pyuno shared library.
548 if hasattr(that, "value"):
549 return self.__dict__["value"] == that.__dict__["value"]
551 return False
554 def _uno_extract_printable_stacktrace(trace):
555 """Extracts a printable stacktrace.
557 Referenced from pyuno shared lib and pythonscript.py.
560 return ''.join(traceback.format_tb(trace))
562 # vim: set shiftwidth=4 softtabstop=4 expandtab: