hl7apy 1.4.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hl7apy/__init__.py +331 -0
- hl7apy/base_datatypes.py +461 -0
- hl7apy/consts.py +80 -0
- hl7apy/core.py +2140 -0
- hl7apy/exceptions.py +350 -0
- hl7apy/factories.py +335 -0
- hl7apy/mllp.py +209 -0
- hl7apy/parser.py +809 -0
- hl7apy/utils.py +163 -0
- hl7apy/v2_1/__init__.py +88 -0
- hl7apy/v2_1/base_datatypes.py +37 -0
- hl7apy/v2_1/datatypes.py +98 -0
- hl7apy/v2_1/fields.py +440 -0
- hl7apy/v2_1/groups.py +88 -0
- hl7apy/v2_1/messages.py +215 -0
- hl7apy/v2_1/segments.py +477 -0
- hl7apy/v2_2/__init__.py +89 -0
- hl7apy/v2_2/datatypes.py +438 -0
- hl7apy/v2_2/fields.py +791 -0
- hl7apy/v2_2/groups.py +199 -0
- hl7apy/v2_2/messages.py +554 -0
- hl7apy/v2_2/segments.py +896 -0
- hl7apy/v2_3/__init__.py +90 -0
- hl7apy/v2_3/datatypes.py +787 -0
- hl7apy/v2_3/fields.py +1472 -0
- hl7apy/v2_3/groups.py +1789 -0
- hl7apy/v2_3/messages.py +864 -0
- hl7apy/v2_3/segments.py +1693 -0
- hl7apy/v2_3_1/__init__.py +91 -0
- hl7apy/v2_3_1/datatypes.py +901 -0
- hl7apy/v2_3_1/fields.py +1489 -0
- hl7apy/v2_3_1/groups.py +1866 -0
- hl7apy/v2_3_1/messages.py +894 -0
- hl7apy/v2_3_1/segments.py +1710 -0
- hl7apy/v2_3_1/tables.py +564 -0
- hl7apy/v2_4/__init__.py +91 -0
- hl7apy/v2_4/datatypes.py +925 -0
- hl7apy/v2_4/fields.py +1815 -0
- hl7apy/v2_4/groups.py +2360 -0
- hl7apy/v2_4/messages.py +1339 -0
- hl7apy/v2_4/segments.py +2092 -0
- hl7apy/v2_4/tables.py +824 -0
- hl7apy/v2_5/__init__.py +92 -0
- hl7apy/v2_5/datatypes.py +962 -0
- hl7apy/v2_5/fields.py +2120 -0
- hl7apy/v2_5/groups.py +3275 -0
- hl7apy/v2_5/messages.py +1810 -0
- hl7apy/v2_5/segments.py +2400 -0
- hl7apy/v2_5/tables.py +5263 -0
- hl7apy/v2_5_1/__init__.py +95 -0
- hl7apy/v2_5_1/datatypes.py +962 -0
- hl7apy/v2_5_1/fields.py +2129 -0
- hl7apy/v2_5_1/groups.py +3263 -0
- hl7apy/v2_5_1/messages.py +1798 -0
- hl7apy/v2_5_1/segments.py +2408 -0
- hl7apy/v2_5_1/tables.py +5271 -0
- hl7apy/v2_6/__init__.py +94 -0
- hl7apy/v2_6/base_datatypes.py +29 -0
- hl7apy/v2_6/datatypes.py +965 -0
- hl7apy/v2_6/fields.py +2470 -0
- hl7apy/v2_6/groups.py +3611 -0
- hl7apy/v2_6/messages.py +2082 -0
- hl7apy/v2_6/segments.py +2811 -0
- hl7apy/v2_6/tables.py +5266 -0
- hl7apy/v2_7/__init__.py +97 -0
- hl7apy/v2_7/base_datatypes.py +132 -0
- hl7apy/v2_7/datatypes.py +1043 -0
- hl7apy/v2_7/fields.py +2544 -0
- hl7apy/v2_7/groups.py +4233 -0
- hl7apy/v2_7/messages.py +1989 -0
- hl7apy/v2_7/segments.py +2896 -0
- hl7apy/v2_7/tables.py +5892 -0
- hl7apy/v2_8/__init__.py +97 -0
- hl7apy/v2_8/datatypes.py +991 -0
- hl7apy/v2_8/fields.py +2664 -0
- hl7apy/v2_8/groups.py +4606 -0
- hl7apy/v2_8/messages.py +2060 -0
- hl7apy/v2_8/segments.py +3043 -0
- hl7apy/v2_8/tables.py +6006 -0
- hl7apy/v2_8_1/__init__.py +97 -0
- hl7apy/v2_8_1/datatypes.py +991 -0
- hl7apy/v2_8_1/fields.py +2705 -0
- hl7apy/v2_8_1/groups.py +4552 -0
- hl7apy/v2_8_1/messages.py +1959 -0
- hl7apy/v2_8_1/segments.py +3048 -0
- hl7apy/v2_8_1/tables.py +6006 -0
- hl7apy/v2_8_2/__init__.py +97 -0
- hl7apy/v2_8_2/datatypes.py +1000 -0
- hl7apy/v2_8_2/fields.py +2743 -0
- hl7apy/v2_8_2/groups.py +4566 -0
- hl7apy/v2_8_2/messages.py +1967 -0
- hl7apy/v2_8_2/segments.py +3115 -0
- hl7apy/v2_8_2/tables.py +6170 -0
- hl7apy/validation.py +314 -0
- hl7apy-1.4.0b1.data/scripts/hl7apy_profile_parser +197 -0
- hl7apy-1.4.0b1.dist-info/METADATA +109 -0
- hl7apy-1.4.0b1.dist-info/RECORD +100 -0
- hl7apy-1.4.0b1.dist-info/WHEEL +5 -0
- hl7apy-1.4.0b1.dist-info/licenses/LICENSE +18 -0
- hl7apy-1.4.0b1.dist-info/top_level.txt +1 -0
hl7apy/__init__.py
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2012-2018, CRS4
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
5
|
+
# this software and associated documentation files (the "Software"), to deal in
|
|
6
|
+
# the Software without restriction, including without limitation the rights to
|
|
7
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
8
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
|
9
|
+
# subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
# copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
16
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
17
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
18
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
19
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
20
|
+
|
|
21
|
+
import importlib
|
|
22
|
+
import os
|
|
23
|
+
import pickle
|
|
24
|
+
from collections.abc import MutableMapping
|
|
25
|
+
from importlib.metadata import PackageNotFoundError
|
|
26
|
+
from importlib.metadata import version as _get_version
|
|
27
|
+
|
|
28
|
+
from hl7apy.consts import DEFAULT_ENCODING_CHARS, DEFAULT_ENCODING_CHARS_27, DEFAULT_VERSION, VALIDATION_LEVEL
|
|
29
|
+
from hl7apy.exceptions import InvalidEncodingChars, UnknownValidationLevel, UnsupportedVersion
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
__version__ = _get_version('hl7apy')
|
|
33
|
+
except PackageNotFoundError: # not installed, e.g. used directly from a source checkout
|
|
34
|
+
__version__ = 'unknown'
|
|
35
|
+
__author__ = 'Daniela Ghironi, Vittorio Meloni, Alessandro Sulis, Federico Caboni'
|
|
36
|
+
__author_email__ = '<ghiron@gmail.com>, <vittorio.meloni@crs4.it>, <alessandro.sulis@crs4.it>, <federico.caboni@me.com>'
|
|
37
|
+
__url__ = 'https://crs4.github.io/hl7apy/'
|
|
38
|
+
|
|
39
|
+
_DEFAULT_ENCODING_CHARS = DEFAULT_ENCODING_CHARS
|
|
40
|
+
_DEFAULT_ENCODING_CHARS_27 = DEFAULT_ENCODING_CHARS_27
|
|
41
|
+
_DEFAULT_VERSION = DEFAULT_VERSION
|
|
42
|
+
_DEFAULT_VALIDATION_LEVEL = VALIDATION_LEVEL.TOLERANT
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def check_encoding_chars(encoding_chars):
|
|
46
|
+
"""
|
|
47
|
+
Validate the given encoding chars
|
|
48
|
+
|
|
49
|
+
:type encoding_chars: ``dict``
|
|
50
|
+
:param encoding_chars: the encoding chars (see :func:`hl7apy.set_default_encoding_chars`)
|
|
51
|
+
:raises: :exc:`hl7apy.exceptions.InvalidEncodingChars` if the given encoding chars are not valid
|
|
52
|
+
"""
|
|
53
|
+
if not isinstance(encoding_chars, MutableMapping):
|
|
54
|
+
raise InvalidEncodingChars
|
|
55
|
+
required = {'FIELD', 'COMPONENT', 'SUBCOMPONENT', 'REPETITION', 'ESCAPE'}
|
|
56
|
+
missing = required - set(encoding_chars.keys())
|
|
57
|
+
if missing:
|
|
58
|
+
raise InvalidEncodingChars('Missing required encoding chars')
|
|
59
|
+
|
|
60
|
+
values = [v for k, v in encoding_chars.items() if k in required]
|
|
61
|
+
if len(values) > len(set(values)):
|
|
62
|
+
raise InvalidEncodingChars('Found duplicate encoding chars')
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def check_validation_level(validation_level):
|
|
66
|
+
"""
|
|
67
|
+
Validate the given validation level
|
|
68
|
+
|
|
69
|
+
:type validation_level: ``int``
|
|
70
|
+
:param validation_level: validation level (see :class:`hl7apy.consts.VALIDATION_LEVEL`)
|
|
71
|
+
:raises: :exc:`hl7apy.exceptions.UnknownValidationLevel` if the given validation level is unsupported
|
|
72
|
+
"""
|
|
73
|
+
if validation_level not in (VALIDATION_LEVEL.QUIET, VALIDATION_LEVEL.STRICT, VALIDATION_LEVEL.TOLERANT):
|
|
74
|
+
raise UnknownValidationLevel
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def check_version(version):
|
|
78
|
+
"""
|
|
79
|
+
Validate the given version number
|
|
80
|
+
|
|
81
|
+
:type version: ``str``
|
|
82
|
+
:param version: the version to validate (e.g. ``2.6``)
|
|
83
|
+
:raises: :class:`hl7apy.exceptions.UnsupportedVersion` if the given version is unsupported
|
|
84
|
+
"""
|
|
85
|
+
if version not in SUPPORTED_LIBRARIES:
|
|
86
|
+
raise UnsupportedVersion(version)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_default_encoding_chars(version=None):
|
|
90
|
+
"""
|
|
91
|
+
Get the default encoding chars
|
|
92
|
+
|
|
93
|
+
:rtype: ``dict``
|
|
94
|
+
:returns: the encoding chars (see :func:`hl7apy.set_default_encoding_chars`)
|
|
95
|
+
|
|
96
|
+
>>> print(get_default_encoding_chars('2.6')['FIELD'])
|
|
97
|
+
|
|
|
98
|
+
"""
|
|
99
|
+
if version and version >= '2.7':
|
|
100
|
+
return _DEFAULT_ENCODING_CHARS_27
|
|
101
|
+
return _DEFAULT_ENCODING_CHARS
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def get_default_version():
|
|
105
|
+
"""
|
|
106
|
+
Get the default version
|
|
107
|
+
|
|
108
|
+
:rtype: ``str``
|
|
109
|
+
:returns: the default version
|
|
110
|
+
|
|
111
|
+
>>> print(get_default_version())
|
|
112
|
+
2.5
|
|
113
|
+
"""
|
|
114
|
+
return _DEFAULT_VERSION
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def get_default_validation_level():
|
|
118
|
+
"""
|
|
119
|
+
Get the default validation level
|
|
120
|
+
|
|
121
|
+
:rtype: ``str``
|
|
122
|
+
:returns: the default validation level
|
|
123
|
+
|
|
124
|
+
>>> print(get_default_validation_level())
|
|
125
|
+
2
|
|
126
|
+
"""
|
|
127
|
+
return _DEFAULT_VALIDATION_LEVEL
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def set_default_validation_level(validation_level):
|
|
131
|
+
"""
|
|
132
|
+
Set the given validation level as default
|
|
133
|
+
|
|
134
|
+
:type validation_level: ``int``
|
|
135
|
+
:param validation_level: validation level (see :class:`hl7apy.consts.VALIDATION_LEVEL`)
|
|
136
|
+
:raises: :exc:`hl7apy.exceptions.UnknownValidationLevel` if the given validation level is unsupported
|
|
137
|
+
|
|
138
|
+
>>> set_default_validation_level(3) # doctest: +IGNORE_EXCEPTION_DETAIL
|
|
139
|
+
Traceback (most recent call last):
|
|
140
|
+
...
|
|
141
|
+
UnknownValidationLevel
|
|
142
|
+
>>> set_default_validation_level(VALIDATION_LEVEL.TOLERANT)
|
|
143
|
+
>>> print(get_default_validation_level())
|
|
144
|
+
2
|
|
145
|
+
"""
|
|
146
|
+
check_validation_level(validation_level)
|
|
147
|
+
|
|
148
|
+
global _DEFAULT_VALIDATION_LEVEL
|
|
149
|
+
|
|
150
|
+
_DEFAULT_VALIDATION_LEVEL = validation_level
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def set_default_version(version):
|
|
154
|
+
"""
|
|
155
|
+
Set the given version as default
|
|
156
|
+
|
|
157
|
+
:type version: ``str``
|
|
158
|
+
:param version: the new default version (e.g. ``2.6``)
|
|
159
|
+
:raises: :class:`hl7apy.exceptions.UnsupportedVersion` if the given version is unsupported
|
|
160
|
+
|
|
161
|
+
>>> set_default_version('22') # doctest: +IGNORE_EXCEPTION_DETAIL
|
|
162
|
+
Traceback (most recent call last):
|
|
163
|
+
...
|
|
164
|
+
UnsupportedVersion: The version 22 is not supported
|
|
165
|
+
>>> set_default_version('2.3')
|
|
166
|
+
>>> print(get_default_version())
|
|
167
|
+
2.3
|
|
168
|
+
"""
|
|
169
|
+
check_version(version)
|
|
170
|
+
|
|
171
|
+
global _DEFAULT_VERSION
|
|
172
|
+
|
|
173
|
+
_DEFAULT_VERSION = version
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def set_default_encoding_chars(encoding_chars):
|
|
177
|
+
"""
|
|
178
|
+
Set the given encoding chars as default
|
|
179
|
+
|
|
180
|
+
:type encoding_chars: ``dict``
|
|
181
|
+
:param encoding_chars: the new encoding chars
|
|
182
|
+
:raises: :class:`hl7apy.exceptions.InvalidEncodingChars` if the given encoding chars are not valid
|
|
183
|
+
|
|
184
|
+
The *encoding_chars* dictionary should contain the following keys:
|
|
185
|
+
|
|
186
|
+
+--------------+-----------------+
|
|
187
|
+
|Key |Default |
|
|
188
|
+
+==============+=================+
|
|
189
|
+
|GROUP |``\\r`` |
|
|
190
|
+
+--------------+-----------------+
|
|
191
|
+
|SEGMENT |``\\r`` |
|
|
192
|
+
+--------------+-----------------+
|
|
193
|
+
|FIELD |``|`` |
|
|
194
|
+
+--------------+-----------------+
|
|
195
|
+
|COMPONENT |``^`` |
|
|
196
|
+
+--------------+-----------------+
|
|
197
|
+
|SUBCOMPONENT |``&`` |
|
|
198
|
+
+--------------+-----------------+
|
|
199
|
+
|REPETITION |``~`` |
|
|
200
|
+
+--------------+-----------------+
|
|
201
|
+
|ESCAPE |``\\`` |
|
|
202
|
+
+--------------+-----------------+
|
|
203
|
+
|
|
204
|
+
>>> set_default_encoding_chars({'FIELD': '!'}) # doctest: +IGNORE_EXCEPTION_DETAIL
|
|
205
|
+
Traceback (most recent call last):
|
|
206
|
+
...
|
|
207
|
+
InvalidEncodingChars: Missing required encoding chars
|
|
208
|
+
>>> set_default_encoding_chars({'FIELD': '!', 'COMPONENT': 'C', 'SUBCOMPONENT': 'S', \
|
|
209
|
+
'REPETITION': 'R', 'ESCAPE': '\\\\'})
|
|
210
|
+
>>> print(get_default_encoding_chars('2.5')['FIELD'])
|
|
211
|
+
!
|
|
212
|
+
"""
|
|
213
|
+
check_encoding_chars(encoding_chars)
|
|
214
|
+
|
|
215
|
+
encoding_chars.update({'GROUP': '\r', 'SEGMENT': '\r'})
|
|
216
|
+
|
|
217
|
+
global _DEFAULT_ENCODING_CHARS
|
|
218
|
+
|
|
219
|
+
_DEFAULT_ENCODING_CHARS = encoding_chars
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def load_library(version):
|
|
223
|
+
"""
|
|
224
|
+
Load the correct module according to the version
|
|
225
|
+
|
|
226
|
+
:type version: ``str``
|
|
227
|
+
:param version: the version of the library to be loaded (e.g. '2.6')
|
|
228
|
+
:rtype: module object
|
|
229
|
+
"""
|
|
230
|
+
check_version(version)
|
|
231
|
+
module_name = SUPPORTED_LIBRARIES[version]
|
|
232
|
+
lib = importlib.import_module(module_name)
|
|
233
|
+
return lib
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def load_reference(name, element_type, version):
|
|
237
|
+
"""
|
|
238
|
+
Look for an element of the given type, name and version and return its reference structure
|
|
239
|
+
|
|
240
|
+
:type element_type: ``str``
|
|
241
|
+
:param element_type: the element type to look for (e.g. 'Segment')
|
|
242
|
+
:type name: ``str``
|
|
243
|
+
:param name: the element name to look for (e.g. 'MSH')
|
|
244
|
+
:type version: ``str``
|
|
245
|
+
:param version: the version of the library where to search the element (e.g. '2.6')
|
|
246
|
+
:rtype: ``dict``
|
|
247
|
+
:return: a dictionary describing the element structure
|
|
248
|
+
:raise: ``KeyError`` if the element has not been found
|
|
249
|
+
|
|
250
|
+
The returned dictionary will contain the following keys:
|
|
251
|
+
|
|
252
|
+
+--------------+--------------------------------------------+
|
|
253
|
+
|Key |Value |
|
|
254
|
+
+==============+============================================+
|
|
255
|
+
|cls |an :class:`hl7apy.core.Element` subclass |
|
|
256
|
+
+--------------+--------------------------------------------+
|
|
257
|
+
|name |the Element name (e.g. PID) |
|
|
258
|
+
+--------------+--------------------------------------------+
|
|
259
|
+
|ref |a tuple of one of the following format: |
|
|
260
|
+
| | |
|
|
261
|
+
| |('leaf', <datatype>, <longName>, <table>) |
|
|
262
|
+
| |('sequence', (<child>, (<min>, <max>), ...))|
|
|
263
|
+
+--------------+--------------------------------------------+
|
|
264
|
+
|
|
265
|
+
>>> load_reference('UNKNOWN', 'Segment', '2.5') # doctest: +IGNORE_EXCEPTION_DETAIL
|
|
266
|
+
Traceback (most recent call last):
|
|
267
|
+
...
|
|
268
|
+
ChildNotFound: No child named UNKNOWN
|
|
269
|
+
>>> r = load_reference('ADT_A01', 'Message', '2.5')
|
|
270
|
+
>>> print(r[0])
|
|
271
|
+
sequence
|
|
272
|
+
>>> r = load_reference('MSH_3', 'Field', '2.5')
|
|
273
|
+
>>> print(r[0])
|
|
274
|
+
sequence
|
|
275
|
+
"""
|
|
276
|
+
lib = load_library(version)
|
|
277
|
+
ref = lib.get(name, element_type)
|
|
278
|
+
return ref
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def find_reference(name, element_types, version):
|
|
282
|
+
"""
|
|
283
|
+
Look for an element of the given name and version into the given types and return its reference structure
|
|
284
|
+
|
|
285
|
+
:type name: ``str``
|
|
286
|
+
:param name: the element name to look for (e.g. 'MSH')
|
|
287
|
+
:type types: ``list`` or ``tuple``
|
|
288
|
+
:param types: the element classes where to look for the element (e.g. (Group, Segment))
|
|
289
|
+
:type version: ``str``
|
|
290
|
+
:param version: the version of the library where to search the element (e.g. '2.6')
|
|
291
|
+
:rtype: ``dict``
|
|
292
|
+
:return: a dictionary describing the element structure
|
|
293
|
+
:raise: :class:`hl7apy.exceptions.ChildNotFound` if the element has not been found
|
|
294
|
+
|
|
295
|
+
>>> from hl7apy.core import Message, Segment
|
|
296
|
+
>>> find_reference('UNKNOWN', (Segment, ), '2.5') # doctest: +IGNORE_EXCEPTION_DETAIL
|
|
297
|
+
Traceback (most recent call last):
|
|
298
|
+
...
|
|
299
|
+
ChildNotFound: No child named UNKNOWN
|
|
300
|
+
>>> find_reference('ADT_A01', (Segment,), '2.5') # doctest: +IGNORE_EXCEPTION_DETAIL
|
|
301
|
+
Traceback (most recent call last):
|
|
302
|
+
...
|
|
303
|
+
ChildNotFound: No child named ADT_A01
|
|
304
|
+
>>> r = find_reference('ADT_A01', (Message,), '2.5')
|
|
305
|
+
>>> print('%s %s' % (r['name'], r['cls']))
|
|
306
|
+
ADT_A01 <class 'hl7apy.core.Message'>
|
|
307
|
+
"""
|
|
308
|
+
lib = load_library(version)
|
|
309
|
+
ref = lib.find(name, element_types)
|
|
310
|
+
return ref
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def load_message_profile(path):
|
|
314
|
+
with open(path, 'rb') as f:
|
|
315
|
+
mp = pickle.load(f)
|
|
316
|
+
|
|
317
|
+
return mp
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
def _discover_libraries():
|
|
321
|
+
current_dir = os.path.dirname(__file__)
|
|
322
|
+
return {o[1:].replace("_", "."): "hl7apy.{}".format(o) for o in os.listdir(current_dir) if o.startswith("v2_")}
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
SUPPORTED_LIBRARIES = _discover_libraries()
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
if __name__ == '__main__':
|
|
329
|
+
import doctest
|
|
330
|
+
|
|
331
|
+
doctest.testmod()
|