17
17
The OpenTelemetry loader module is mainly used internally to load the
18
18
implementation for global objects like :func:`opentelemetry.trace.tracer`.
19
19
20
- When loading an implementation, the following algorithm is used:
20
+ .. _loader-factory:
21
+
22
+ An instance of a global object of type ``T`` is always created with a factory
23
+ function with the following signature::
24
+
25
+ def my_factory_for_t(api_type: typing.Type[T]) -> typing.Optional[T]:
26
+ # ...
27
+
28
+ That function is called with e.g., the type of the global object it should
29
+ create as an argument (e.g. the type object
30
+ :class:`opentelemetry.trace.Tracer`) and should return an instance of that type
31
+ (such that ``instanceof(my_factory_for_t(T), T)`` is true). Alternatively, it
32
+ may return ``None`` to indicate that the no-op default should be used.
33
+
34
+ When loading an implementation, the following algorithm is used to find a
35
+ factory function or other means to create the global object:
21
36
22
37
1. If the environment variable
23
38
:samp:`OPENTELEMETRY_PYTHON_IMPLEMENTATION_{getter-name}` (e.g.,
24
39
``OPENTELEMETRY_PYTHON_IMPLEMENTATION_TRACER``) is set to an nonempty
25
- value, an attempt is made to import a module with that name and call a
26
- function ``get_opentelemetry_implementation`` in it. The function
27
- receives the API type that is expected as an argument and should return
28
- an instance of it or ``None`` (e.g., the argument is
29
- :class:`opentelemetry.trace.Tracer` and the function should return an
30
- instance of a :class:`~opentelemetry.trace.Tracer` (probably of a
31
- derived type).
32
- 2. Otherwise, ``OPENTELEMETRY_PYTHON_IMPLEMENTATION_DEFAULT`` is tried
33
- instead.
40
+ value, an attempt is made to import a module with that name and use a
41
+ factory function named ``get_opentelemetry_implementation`` in it.
42
+ 2. Otherwise, the same is tried with the environment
43
+ variable ``OPENTELEMETRY_PYTHON_IMPLEMENTATION_DEFAULT``.
34
44
3. Otherwise, if a :samp:`set_preferred_{<type>}_implementation` was
35
- called, the callback set there is used.
45
+ called (e.g.
46
+ :func:`opentelemetry.trace.set_preferred_tracer_implementation`), the
47
+ callback set there is used (that is, the environment variables override
48
+ the callback set in code).
36
49
4. Otherwise, if :func:`set_preferred_default_implementation` was called,
37
50
the callback set there is used.
38
51
5. Otherwise, an attempt is made to import and use the OpenTelemetry SDK.
42
55
If any of the above steps fails (e.g., a module is loaded but does not define
43
56
the required function or a module name is set but the module fails to load),
44
57
the search immediatelly skips to the last step.
58
+
59
+ Note that the first two steps (those that query environment variables) are
60
+ skipped if :data:`sys.flags` has ``ignore_environment`` set (which usually
61
+ means that the Python interpreter was invoked with the ``-E`` or ``-I`` flag).
45
62
"""
46
63
47
64
from typing import Type , TypeVar , Optional , Callable
54
71
# "Untrusted" because this is usually user-provided and we don't trust the user
55
72
# to really return a _T: by using object, mypy forces us to check/cast
56
73
# explicitly.
57
- _UntrustedImplFactory = Callable [[Type [_T ]], object ]
74
+ _UntrustedImplFactory = Callable [[Type [_T ]], Optional [ object ] ]
58
75
59
76
60
77
# This would be the normal ImplementationFactory which would be used to
61
78
# annotate setters, were it not for https://github.com/python/mypy/issues/7092
62
79
# Once that bug is resolved, setters should use this instead of duplicating the
63
80
# code.
64
- #ImplementationFactory = Callable[[Type[_T]], _T ]
81
+ #ImplementationFactory = Callable[[Type[_T]], Optional[_T] ]
65
82
66
83
_DEFAULT_IMPLEMENTATION_MODNAME = (
67
84
'opentelemetry.sdk.internal.implementation_impl' )
@@ -136,7 +153,9 @@ def _try_load_configured_impl(
136
153
137
154
# Public to other opentelemetry-api modules
138
155
def _load_impl (
139
- api_type : Type [_T ], factory : Optional [Callable [[Type [_T ]], _T ]]) -> _T :
156
+ api_type : Type [_T ],
157
+ factory : Optional [Callable [[Type [_T ]], Optional [_T ]]]
158
+ ) -> _T :
140
159
"""Tries to load a configured implementation, if unsuccessful, returns a
141
160
fast no-op implemenation that is always available.
142
161
"""
@@ -147,8 +166,8 @@ def _load_impl(
147
166
return result
148
167
149
168
def set_preferred_default_implementation (
150
- implementation_module : _UntrustedImplFactory ) -> None :
151
- """Sets a callback that may be queried for any implementation object. See
152
- the module docs for more details."""
169
+ implementation_factory : _UntrustedImplFactory ) -> None :
170
+ """Sets a factory function that may be called for any implementation
171
+ object. See the :ref:` module docs <loader-factory>` for more details."""
153
172
global _DEFAULT_FACTORY #pylint:disable=global-statement
154
- _DEFAULT_FACTORY = implementation_module
173
+ _DEFAULT_FACTORY = implementation_factory
0 commit comments