Salome HOME
Copyright update 2021
[modules/yacs.git] / src / pyqt / gui / adapt.py
1 # Copyright (C) 2006-2021  CEA/DEN, EDF R&D
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 class AdaptationError(TypeError):
21         pass
22 class LiskovViolation(AdaptationError):
23         pass
24
25 _adapter_factory_registry = {}
26
27 def registerAdapterFactory(objtype, protocol, factory):
28         _adapter_factory_registry[objtype, protocol] = factory
29
30 def unregisterAdapterFactory(objtype, protocol):
31         del _adapter_factory_registry[objtype, protocol]
32
33 def _adapt_by_registry(obj, protocol, alternate):
34         factory = _adapter_factory_registry.get((type(obj), protocol))
35         if factory is None:
36             adapter = alternate
37         else:
38             adapter = factory(obj, protocol, alternate)
39         if adapter is AdaptationError:
40             raise AdaptationError(obj)
41         else:
42             return adapter
43
44
45 def adapt(obj, protocol, alternate=AdaptationError):
46
47         t = type(obj)
48
49         # (a) first check to see if object has the exact protocol
50         if t is protocol:
51            return obj
52
53         try:
54             # (b) next check if t.__conform__ exists & likes protocol
55             conform = getattr(t, '__conform__', None)
56             if conform is not None:
57                 result = conform(obj, protocol)
58                 if result is not None:
59                     return result
60
61             # (c) then check if protocol.__adapt__ exists & likes obj
62             adapt = getattr(type(protocol), '__adapt__', None)
63             if adapt is not None:
64                 result = adapt(protocol, obj)
65                 if result is not None:
66                     return result
67         except LiskovViolation:
68             pass
69         else:
70             # (d) check if object is instance of protocol
71             try:
72                if isinstance(obj, protocol):
73                    return obj
74             except:
75                pass
76
77         # (e) last chance: try the registry
78         return _adapt_by_registry(obj, protocol, alternate)