wizards/source/scriptforge/python/scriptforge.py |   64 ++++++++++-------------
 1 file changed, 29 insertions(+), 35 deletions(-)

New commits:
commit 87bfd87ecf1a613a979a829b915dd1ddac3eb9f2
Author:     Jean-Pierre Ledure <j...@ledure.be>
AuthorDate: Tue Sep 3 18:00:38 2024 +0200
Commit:     Jean-Pierre Ledure <j...@ledure.be>
CommitDate: Wed Sep 4 10:14:42 2024 +0200

    ScriptForge (scriptforge.py) fine tune getattr/setattr()
    
    Several minor changes
    - comments
    - 'cls' used where relevant i.o. class name
    - dynamic getting/setting properties reviewed
    - SF_Platform properties:
      set level = 1 i.o. 0 when returned
      by PythonHelper module
    
    Change-Id: I4e9877bc16efd340dc14693833c032c998329b6e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172836
    Reviewed-by: Jean-Pierre Ledure <j...@ledure.be>
    Tested-by: Jenkins

diff --git a/wizards/source/scriptforge/python/scriptforge.py 
b/wizards/source/scriptforge/python/scriptforge.py
index 5a06d302271e..dafd22e8612d 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -49,7 +49,7 @@
             from scriptforge import CreateScriptService
 
         When Python and LibreOffice are started in separate processes,
-        LibreOffice being started from console ... (example for Linux with 
port = 2023)
+        LibreOffice being started from console ... (example for Linux with 
port = 2024)
             ./soffice --accept='socket,host=localhost,port=2024;urp;'
         then use next statements:
             from scriptforge import CreateScriptService, ScriptForge
@@ -259,7 +259,7 @@ class ScriptForge(object, metaclass = _Singleton):
             return _paramarray, _fullscript, _xscript
 
         # The frequently called PythonDispatcher in the ScriptForge Basic 
library is cached to privilege performance
-        if cls.servicesdispatcher is not None and script == 
ScriptForge.basicdispatcher:
+        if cls.servicesdispatcher is not None and script == 
cls.basicdispatcher:
             xscript = cls.servicesdispatcher
             fullscript = script
             paramarray = True
@@ -271,7 +271,7 @@ class ScriptForge(object, metaclass = _Singleton):
             return None
 
         # At 1st execution of the common Basic dispatcher, buffer xscript
-        if fullscript == ScriptForge.basicdispatcher and 
cls.servicesdispatcher is None:
+        if fullscript == cls.basicdispatcher and cls.servicesdispatcher is 
None:
             cls.servicesdispatcher = xscript
 
         # Execute the script with the given arguments
@@ -316,7 +316,7 @@ class ScriptForge(object, metaclass = _Singleton):
                     - a new SFServices() object or one of its subclasses 
otherwise
             """
         # Constants
-        script = ScriptForge.basicdispatcher
+        script = cls.basicdispatcher
         cstNoArgs = '+++NOARGS+++'
         cstValue, cstVarType, cstDims, cstClass, cstType, cstService, cstName 
= 0, 1, 2, 2, 3, 4, 5
 
@@ -360,10 +360,10 @@ class ScriptForge(object, metaclass = _Singleton):
         #   An array, tuple or tuple of tuples - manage dates inside
         #   A scalar, Nothing, a date
         returnvalue = returntuple[cstValue]
-        if returntuple[cstVarType] == ScriptForge.V_OBJECT and 
len(returntuple) > cstClass:  # Skip Nothing
-            if returntuple[cstClass] == ScriptForge.objUNO:
+        if returntuple[cstVarType] == cls.V_OBJECT and len(returntuple) > 
cstClass:  # Skip Nothing
+            if returntuple[cstClass] == cls.objUNO:
                 pass
-            elif returntuple[cstClass] == ScriptForge.objDICT:
+            elif returntuple[cstClass] == cls.objDICT:
                 dico = CreateScriptService('ScriptForge.Dictionary')
                 if not isinstance(returnvalue, uno.ByteSequence):   # if array 
not empty
                     dico.ImportFromPropertyValues(returnvalue, overwrite = 
True)
@@ -377,7 +377,7 @@ class ScriptForge(object, metaclass = _Singleton):
                 subcls = cls.serviceslist[servname]
                 if subcls is not None:
                     return subcls(returnvalue, returntuple[cstType], 
returntuple[cstClass], returntuple[cstName])
-        elif returntuple[cstVarType] >= ScriptForge.V_ARRAY:
+        elif returntuple[cstVarType] >= cls.V_ARRAY:
             # Intercept empty array
             if isinstance(returnvalue, uno.ByteSequence):
                 return ()
@@ -391,15 +391,15 @@ class ScriptForge(object, metaclass = _Singleton):
                     returnvalue = tuple(arr)
                 else:                                   # 1D tuple
                     returnvalue = 
tuple(map(SFScriptForge.SF_Basic.CDateFromUnoDateTime, returnvalue))
-        elif returntuple[cstVarType] == ScriptForge.V_DATE:
+        elif returntuple[cstVarType] == cls.V_DATE:
             dat = SFScriptForge.SF_Basic.CDateFromUnoDateTime(returnvalue)
             return dat
         else:  # All other scalar values
             pass
         return returnvalue
 
-    @staticmethod
-    def SetAttributeSynonyms():
+    @classmethod
+    def SetAttributeSynonyms(cls):
         """
             A synonym of an attribute is either the lowercase or the camelCase 
form of its original ProperCase name.
             In every subclass of SFServices:
@@ -526,7 +526,7 @@ class SFServices(object):
     # Basic class type
     moduleClass, moduleStandard = 2, 1
     #
-    # Empty dictionary for lower/camelcased homonyms or properties
+    # Empty dictionary for lower/camelcased homonyms of properties
     propertysynonyms = {}
     # To operate dynamic property getting/setting it is necessary to
     # enumerate all types of properties and adapt __getattr__() and 
__setattr__() according to their type
@@ -559,42 +559,36 @@ class SFServices(object):
             if name in ('serviceproperties', 'internal_attributes', 
'propertysynonyms'):
                 pass
             elif name in self.serviceproperties:
-                if self.serviceproperties[name] in (0, 2):  # value may be 
fetched from the instance's local __dict__
-                    if name in self.__dict__:
-                        return self.__dict__[name]
-                    else:
-                        # Get Property from Basic and store it
-                        prop = self.GetProperty(name)
-                        self.__dict__[name] = prop
-                        return prop
-                else:  # Get Property from Basic and do not store it
-                    return self.GetProperty(name)
+                prop = self.GetProperty(name)   # Get Property from Basic
+                if self.serviceproperties[name] in (0, 2):  # Store the 
property value for later re-use
+                    object.__setattr__(self, name, prop)
+                return prop
         # Execute the usual attributes getter
         return super(SFServices, self).__getattribute__(name)
 
     def __setattr__(self, name, value):
         """
             Executed for EVERY property assignment, including in __init__() !!
-            Setting a property requires for serviceproperties() to be executed 
in Basic
-            Management of __dict__ is automatically done in the final usual 
object.__setattr__ method
+            Setting a property required for all serviceproperties() to be 
executed in Basic
+            The new value is stored for re-use in the local instance when 
relevant
             """
         if self.serviceimplementation == 'basic':
-            if name in ('serviceproperties', 'internal_attributes', 
'propertysynonyms'):
-                pass
-            elif name[0:2] == '__' or name in self.internal_attributes:
+            if name in self.internal_attributes:
                 pass
             elif name in self.serviceproperties or name in 
self.propertysynonyms:
                 if name in self.propertysynonyms:  # Reset real name if 
argument provided in lower or camel case
                     name = self.propertysynonyms[name]
-                if self.serviceproperties[name] in (2, 3):  # Editable
+                proplevel = self.serviceproperties[name]
+                if proplevel in (2, 3):  # Editable
                     self.SetProperty(name, value)
-                    return
+                    if proplevel == 3:  # Do not store in the local instance
+                        return
                 else:
                     raise AttributeError(
                         "object of type '" + self.objecttype + "' has no 
editable property '" + name + "'")
             else:
                 raise AttributeError("object of type '" + self.objecttype + "' 
has no property '" + name + "'")
-        object.__setattr__(self, name, value)
+        object.__setattr__(self, name, value)   # Store the new value in the 
local instance
         return
 
     def __repr__(self):
@@ -1308,11 +1302,11 @@ class SFScriptForge:
         serviceimplementation = 'basic'
         servicename = 'ScriptForge.Platform'
         servicesynonyms = ('platform', 'scriptforge.platform')
-        serviceproperties = dict(Architecture = 0, ComputerName = 0, CPUCount 
= 0, CurrentUser = 0,
+        serviceproperties = dict(Architecture = 1, ComputerName = 1, CPUCount 
= 1, CurrentUser = 1,
                                  Extensions = 0, FilterNames = 0, Fonts = 0, 
FormatLocale = 0,
-                                 Locale = 0, Machine = 0, OfficeLocale = 0, 
OfficeVersion = 0,
-                                 OSName = 0, OSPlatform = 0, OSRelease = 0, 
OSVersion = 0,
-                                 Printers = 0, Processor = 0, PythonVersion = 
0, SystemLocale = 0,
+                                 Locale = 0, Machine = 1, OfficeLocale = 0, 
OfficeVersion = 0,
+                                 OSName = 1, OSPlatform = 1, OSRelease = 1, 
OSVersion = 1,
+                                 Printers = 0, Processor = 1, PythonVersion = 
1, SystemLocale = 0,
                                  UserData = 0)
         # Python helper functions
         py = ScriptForge.pythonhelpermodule + '$' + '_SF_Platform'
@@ -2004,7 +1998,7 @@ class SFDialogs:
         def ReviewServiceArgs(cls, container = '', library = 'Standard', 
dialogname = ''):
             """
                 Transform positional and keyword arguments into positional only
-                Add the 
XComfile:///home/jean-pierre/.config/libreoffice/4/user/Scripts/python/QA/scriptforge.pyponentContext
 as last argument
+                Add the XComponentContext as last argument
                 """
             return container, library, dialogname, ScriptForge.componentcontext
 

Reply via email to