Coverage for /home/runner/work/viur-core/viur-core/viur/src/viur/core/prototypes/instanced_module.py: 0%
13 statements
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-16 22:16 +0000
« prev ^ index » next coverage.py v7.6.3, created at 2024-10-16 22:16 +0000
1import copy
3from viur.core import Module
6class InstancedModule:
7 """InstancedModule is a base class for modules, which can be passed as instance to the viur-core.
9 Normally, the viur-core expects classes from modules and instantiates them during setup.
10 However, there are cases where you want to pass already instantiated
11 classes, i.e. module instances, to the core. For example, to integrate
12 plugins. This is where this base class comes into play. If it is included
13 as an ADDITIONAL base class to the module class, the viur-core accepts an
14 instance of this class. The class itself is then no longer
15 instantiated in the core.
17 In order to preserve the well-known ViUR module concept, this class
18 overwrites the __init__ method so that it behaves like a classic object
19 constructor. The __call__ method then takes on the role of the
20 conventional __init__ module.
21 However, as each render requires its own module instance, as the render
22 itself is then referenced to this instance via the "render" attribute,
23 several instances are required. Therefore, a copy of the module instance
24 is created using the internal method `_viur_clone`. This can be changed
25 if necessary. A shadow-copy is created here by default.
27 Here an example:
29 .. code-block:: python
31 from viur.core.prototypes import List
32 from viur.core.prototypes.instanced_module import InstancedModule
35 class MyModule(InstancedModule, List):
36 def __init__(self, configuration):
37 self.configuration = configuration
40 my_module = MyModule(
41 configuration=...
42 )
44 As you can see, the configuration parameter is set from outside and not
45 in the class. This may seem a bit strange here, but now imagine that the
46 class definition `MyModule` is not within the same file but in an imported
47 pip package. Then this instantiation is much easier than using a subclass.
48 """
50 def __init__(self, *args, **kwargs):
51 """Overwrite the Module.__init__ and do nothing
53 Can be overwritten as needed, e.g. to assign instance attributes.
54 """
55 object.__init__(self)
57 def __call__(self, moduleName: str, modulePath: str, *args, **kwargs) -> "InstancedModule":
58 """Do the instance initialisation
60 Take the role of Module.__init__ (and call it).
61 """
62 if modulePath == f"/{moduleName}":
63 # For the default renderer we use the original instance
64 instance = self
65 else:
66 # For other renderer we use a copy
67 instance = self._viur_clone()
68 Module.__init__(instance, moduleName, modulePath, *args, **kwargs)
69 return instance
71 def _viur_clone(self):
72 """Creates a copy for non-standard renderers.
74 Since viur keeps one instance per render. Can be overwritten if desired.
75 """
76 return copy.copy(self)