plcopen/POUVariablesCollector.py
author Andrey Skvortsov <andrej.skvortzov@gmail.com>
Fri, 10 Aug 2018 17:45:33 +0300
changeset 2278 a3ac46366b86
parent 1973 cc7a46953471
child 3750 f62625418bff
permissions -rw-r--r--
Dirty fix for error '_object_has_no_attribute_'getSlave' in EtherCAT extension

traceback:
File "/home/developer/WorkData/PLC/beremiz/beremiz/IDEFrame.py", line 1433, in OnPouSelectedChanged
window.RefreshView()
File "/home/developer/WorkData/PLC/beremiz/beremiz/etherlab/ConfigEditor.py", line 837, in RefreshView
self.RefreshProcessVariables()
File "/home/developer/WorkData/PLC/beremiz/beremiz/etherlab/ConfigEditor.py", line 886, in RefreshProcessVariables
slaves = self.Controler.GetSlaves(**self.CurrentNodesFilter)
File "/home/developer/WorkData/PLC/beremiz/beremiz/etherlab/EthercatMaster.py", line 341, in GetSlaves
for slave in self.Config.getConfig().getSlave():
<type 'exceptions.AttributeError'>:_'lxml.etree._Element'_object_has_no_attribute_'getSlave'

Steps to reproduce problem:

- Add new EtherCAT master
- Add new EthercatNode to the master
- double click on


this is looks like dirty hack to fix strange problem with initial[0]
changing its type after returning from _init_ method to lxml.etree._Element
As a result all methods generated by class factory are lost.

For example, in function initMethod initial[0].__class__ points to
xmlclass.xmlclass.Config. After map(self.append, initial)
self.Config.__class__ is 'xmlclass.xmlclass.Config' as well.
But after returning from initMethod (_init) in CreateElement
self.Config.__class__ has changed to lxml.etree._Element.


I've noticed similar behavior if copy/deepcopy is used for any child
of etree.ElementBase. See simple example below.
[-------------------------------------------------------------]
#!/usr/bin/python

from __future__ import print_function
from lxml import etree
import copy

class DefaultElementClass(etree.ElementBase):
def getLocalTag(self):
return etree.QName(self.tag).localname


def printInformation(x):
print(x, x.__class__, "getLocalTag" in dir(x))


a = DefaultElementClass()
printInformation(a)

#
printInformation(copy.copy(a))
printInformation(copy.deepcopy(a))
[-------------------------------------------------------------]
814
5743cbdff669 Integration of PLCOpenEditor into Beremiz
Laurent Bessard
parents:
diff changeset
     1
#!/usr/bin/env python
5743cbdff669 Integration of PLCOpenEditor into Beremiz
Laurent Bessard
parents:
diff changeset
     2
# -*- coding: utf-8 -*-
1943
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
     3
# This file is part of Beremiz.
1571
486f94a8032c fix license notices in source files and license files under GPLv2+
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1508
diff changeset
     4
# See COPYING file for copyrights details.
1850
614396cbffbf fix pylint warning '(unused-import), Unused import connectors'
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1847
diff changeset
     5
1881
091005ec69c4 fix pylint py3k conversion warning: "(no-absolute-import) import missing `from __future__ import absolute_import`"
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1879
diff changeset
     6
from __future__ import absolute_import
1944
6162e34fb246 Moved some code from PLCController.py to other modules. Added necessary imports.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1943
diff changeset
     7
from plcopen.XSLTModelQuery import XSLTModelQuery, _StringValue, _BoolValue, _translate_args
6162e34fb246 Moved some code from PLCController.py to other modules. Added necessary imports.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1943
diff changeset
     8
from plcopen.types_enums import CLASS_TYPES, POU_TYPES, VAR_CLASS_INFOS
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1735
diff changeset
     9
1953
5736d25bb393 PEP8 and PyLint conformance: whitespaces and stuff
Edouard Tisserant
parents: 1952
diff changeset
    10
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    11
def class_extraction(value):
1944
6162e34fb246 Moved some code from PLCController.py to other modules. Added necessary imports.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1943
diff changeset
    12
    class_type = CLASS_TYPES.get(value)
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    13
    if class_type is not None:
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    14
        return class_type
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    15
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    16
    pou_type = POU_TYPES.get(value)
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    17
    if pou_type is not None:
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    18
        return pou_type
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    19
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    20
    var_type = VAR_CLASS_INFOS.get(value)
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    21
    if var_type is not None:
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    22
        return var_type[1]
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    23
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    24
    return None
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    25
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1735
diff changeset
    26
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    27
class _VariablesTreeItemInfos(object):
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    28
    __slots__ = ["name", "var_class", "type", "edit", "debug", "variables"]
1751
c28db6f7616b clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1749
diff changeset
    29
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    30
    def __init__(self, *args):
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    31
        for attr, value in zip(self.__slots__, args):
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    32
            setattr(self, attr, value if value is not None else "")
1751
c28db6f7616b clean-up: fix PEP8 E301 expected 1 blank line, found 0
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1749
diff changeset
    33
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    34
    def copy(self):
1872
866fb3ab8778 fix pylint error "(undefined-variable) Undefined variable 'X'"
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1852
diff changeset
    35
        return _VariablesTreeItemInfos(*[getattr(self, attr) for attr in self.__slots__])
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    36
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1735
diff changeset
    37
1831
56b48961cc68 fix (old-style-class) Old-style class defined error for most parts of
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1785
diff changeset
    38
class VariablesTreeInfosFactory(object):
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    39
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    40
    def __init__(self):
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    41
        self.Root = None
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    42
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    43
    def GetRoot(self):
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    44
        return self.Root
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    45
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    46
    def SetRoot(self, context, *args):
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    47
        self.Root = _VariablesTreeItemInfos(
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    48
            *([''] + _translate_args(
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    49
                [class_extraction, _StringValue] + [_BoolValue] * 2,
1348
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    50
                args) + [[]]))
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    51
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    52
    def AddVariable(self, context, *args):
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    53
        if self.Root is not None:
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    54
            self.Root.variables.append(_VariablesTreeItemInfos(
aee0a7eb833a Fixed pou variables instance information loading stylesheet
Laurent Bessard
parents: 1347
diff changeset
    55
                *(_translate_args(
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    56
                    [_StringValue, class_extraction, _StringValue] +
1378
cbc0f64a25eb Fixed bug with non-ascii characters in program comments
Laurent Bessard
parents: 1373
diff changeset
    57
                    [_BoolValue] * 2, args) + [[]])))
1316
df9d02bd3eb7 Replaced old pou instance variable list generating process by xslt stylesheet
Laurent Bessard
parents: 1315
diff changeset
    58
1736
7e61baa047f0 clean-up: fix PEP8 E302 expected 2 blank lines, found 1
Andrey Skvortsov <andrej.skvortzov@gmail.com>
parents: 1735
diff changeset
    59
1943
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    60
class POUVariablesCollector(XSLTModelQuery):
1321
83f41ea00b97 Replaced old pou instance type tagname computing by xslt stylesheet
Laurent Bessard
parents: 1319
diff changeset
    61
    def __init__(self, controller):
1943
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    62
        XSLTModelQuery.__init__(self,
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    63
                                controller,
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    64
                                "pou_variables.xslt",
1953
5736d25bb393 PEP8 and PyLint conformance: whitespaces and stuff
Edouard Tisserant
parents: 1952
diff changeset
    65
                                [(name, self.FactoryCaller(name))
5736d25bb393 PEP8 and PyLint conformance: whitespaces and stuff
Edouard Tisserant
parents: 1952
diff changeset
    66
                                 for name in ["SetRoot", "AddVariable"]])
1411
805d13d216c0 Fixed POU paste exception
Edouard Tisserant
parents: 1406
diff changeset
    67
1945
90bf6bd94b94 Fixed earlier XSLT optimizations. Some/most results were missing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1944
diff changeset
    68
    def FactoryCaller(self, funcname):
90bf6bd94b94 Fixed earlier XSLT optimizations. Some/most results were missing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1944
diff changeset
    69
        def CallFactory(*args):
90bf6bd94b94 Fixed earlier XSLT optimizations. Some/most results were missing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1944
diff changeset
    70
            return getattr(self.factory, funcname)(*args)
90bf6bd94b94 Fixed earlier XSLT optimizations. Some/most results were missing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1944
diff changeset
    71
        return CallFactory
90bf6bd94b94 Fixed earlier XSLT optimizations. Some/most results were missing.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1944
diff changeset
    72
1943
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    73
    def Collect(self, root, debug):
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    74
        self.factory = VariablesTreeInfosFactory()
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    75
        self._process_xslt(root, debug)
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    76
        res = self.factory.GetRoot()
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    77
        self.factory = None
9dc0e38552b2 GetPouVariables optimized with XSLTModelQuery
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 1942
diff changeset
    78
        return res