immlib 1.0.0.dev2__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.
- immlib/__init__.py +131 -0
- immlib/_init.py +108 -0
- immlib/_version.py +235 -0
- immlib/doc/__init__.py +38 -0
- immlib/doc/_core.py +311 -0
- immlib/iolib/__init__.py +29 -0
- immlib/iolib/_core.py +720 -0
- immlib/pathlib/__init__.py +69 -0
- immlib/pathlib/_cache.py +152 -0
- immlib/pathlib/_core.py +869 -0
- immlib/pathlib/_osf.py +538 -0
- immlib/test/__init__.py +16 -0
- immlib/test/__main__.py +10 -0
- immlib/test/doc/__init__.py +6 -0
- immlib/test/doc/test_core.py +91 -0
- immlib/test/iolib/__init__.py +7 -0
- immlib/test/iolib/test_core.py +81 -0
- immlib/test/pathlib/__init__.py +11 -0
- immlib/test/pathlib/test_core.py +146 -0
- immlib/test/pathlib/test_osf.py +54 -0
- immlib/test/types/__init__.py +5 -0
- immlib/test/types/test_core.py +110 -0
- immlib/test/util/__init__.py +11 -0
- immlib/test/util/test_core.py +681 -0
- immlib/test/util/test_numeric.py +1374 -0
- immlib/test/util/test_quantity.py +218 -0
- immlib/test/util/test_url.py +51 -0
- immlib/test/workflow/__init__.py +9 -0
- immlib/test/workflow/test_core.py +418 -0
- immlib/test/workflow/test_plantype.py +248 -0
- immlib/types/__init__.py +29 -0
- immlib/types/_core.py +333 -0
- immlib/util/__init__.py +283 -0
- immlib/util/_core.py +2524 -0
- immlib/util/_numeric.py +2651 -0
- immlib/util/_quantity.py +523 -0
- immlib/util/_url.py +114 -0
- immlib/workflow/__init__.py +48 -0
- immlib/workflow/_core.py +1635 -0
- immlib/workflow/_plantype.py +334 -0
- immlib-1.0.0.dev2.dist-info/METADATA +76 -0
- immlib-1.0.0.dev2.dist-info/RECORD +45 -0
- immlib-1.0.0.dev2.dist-info/WHEEL +5 -0
- immlib-1.0.0.dev2.dist-info/licenses/LICENSE +21 -0
- immlib-1.0.0.dev2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,681 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
################################################################################
|
|
3
|
+
# immlib/test/util/test_core.py
|
|
4
|
+
|
|
5
|
+
"""Tests of the core utilities module in immlib: i.e., tests for the code in the
|
|
6
|
+
immlib.util._core module.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Dependencies #################################################################
|
|
11
|
+
|
|
12
|
+
from unittest import TestCase
|
|
13
|
+
|
|
14
|
+
import numpy as np
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Tests ########################################################################
|
|
18
|
+
|
|
19
|
+
class TestUtilCore(TestCase):
|
|
20
|
+
"""Tests the immlib.util._core module."""
|
|
21
|
+
|
|
22
|
+
# String Functions #########################################################
|
|
23
|
+
def test_is_str(self):
|
|
24
|
+
from immlib import is_str
|
|
25
|
+
# is_str is just a wrapper for isinstance(obj, str).
|
|
26
|
+
self.assertTrue(is_str('abc'))
|
|
27
|
+
self.assertTrue(is_str(''))
|
|
28
|
+
self.assertFalse(is_str(100))
|
|
29
|
+
self.assertFalse(is_str(None))
|
|
30
|
+
def test_strnorm(self):
|
|
31
|
+
from immlib import strnorm
|
|
32
|
+
# There are a lot of string encoding details that should probably be
|
|
33
|
+
# tested carefully here, but for now, we're mostly concerned that the
|
|
34
|
+
# most basic strings get normalized properly.
|
|
35
|
+
self.assertEqual('abc', strnorm('abc'))
|
|
36
|
+
self.assertEqual('abc', strnorm('aBc', case=True))
|
|
37
|
+
def test_strcmp(self):
|
|
38
|
+
from immlib import strcmp
|
|
39
|
+
# strcmp is, at its simplest, just a string-comparison function.
|
|
40
|
+
self.assertEqual(0, strcmp('abc', 'abc'))
|
|
41
|
+
self.assertEqual(-1, strcmp('abc', 'bca'))
|
|
42
|
+
self.assertEqual(1, strcmp('bca', 'abc'))
|
|
43
|
+
# There are a few bells and whistles for strcmp, thought. First, the
|
|
44
|
+
# case option lets you decide whether to ignore case (via strnorm).
|
|
45
|
+
self.assertEqual(-1, strcmp('ABC', 'abc'))
|
|
46
|
+
self.assertEqual(0, strcmp('ABC', 'abc', case=False))
|
|
47
|
+
# The strip option lets one ignore whitespace on either side of the
|
|
48
|
+
# arguments.
|
|
49
|
+
self.assertEqual(-1, strcmp(' abc', 'abc '))
|
|
50
|
+
self.assertEqual(0, strcmp(' abc', 'abc ', strip=True))
|
|
51
|
+
self.assertEqual(-1, strcmp('_abc', 'abc__', strip=True))
|
|
52
|
+
self.assertEqual(0, strcmp('_abc', 'abc__', strip='_'))
|
|
53
|
+
# The split argument lets you split on whitespace then compare the
|
|
54
|
+
# individual split parts (i.e., this option should make all strings that
|
|
55
|
+
# are identical up to the amount of whitespace should be equal).
|
|
56
|
+
self.assertEqual(1, strcmp('abc def ghi', ' abc def ghi '))
|
|
57
|
+
self.assertEqual(0, strcmp('abc def ghi', ' abc def ghi ', split=True))
|
|
58
|
+
self.assertEqual(0, strcmp('abc_def_ghi', 'abc_def_ghi', split='_'))
|
|
59
|
+
self.assertEqual(-1, strcmp('abc def ghi', ' bbc def ghi ', split=True))
|
|
60
|
+
self.assertEqual(1, strcmp('abc eef ghi', ' abc def ghi ', split=True))
|
|
61
|
+
self.assertEqual(0, strcmp('a b c d', 'a b c d', split=True))
|
|
62
|
+
self.assertEqual(1, strcmp('a b c d', 'a b c', split=True))
|
|
63
|
+
self.assertEqual(-1, strcmp('a b c', 'a b c d', split=True))
|
|
64
|
+
self.assertEqual(0, strcmp('abc def ghi', ' abc def ghi ', split=True))
|
|
65
|
+
# In some cases, we can split and strip:
|
|
66
|
+
self.assertEqual(
|
|
67
|
+
strcmp('abc_def_ghi', '_abc_def_ghi_', split='_', strip='_'),
|
|
68
|
+
0)
|
|
69
|
+
# If one of the arguments isn't a string, strcmp returns None.
|
|
70
|
+
self.assertIsNone(strcmp(None, 10))
|
|
71
|
+
def test_streq(self):
|
|
72
|
+
from immlib import streq
|
|
73
|
+
# streq is just a string equality predicate function.
|
|
74
|
+
self.assertTrue(streq('abc', 'abc'))
|
|
75
|
+
self.assertFalse(streq('abc', 'def'))
|
|
76
|
+
# The case option can tell it to ignore case.
|
|
77
|
+
self.assertFalse(streq('ABC', 'abc'))
|
|
78
|
+
self.assertTrue(streq('ABC', 'abc', case=False))
|
|
79
|
+
# The strip option can be used to ignore trailing/leading whitespace.
|
|
80
|
+
self.assertFalse(streq(' abc', 'abc '))
|
|
81
|
+
self.assertTrue(streq(' abc', 'abc ', strip=True))
|
|
82
|
+
# The split argument lets you split on whitespace then compare the
|
|
83
|
+
# individual split parts (i.e., this option should make all strings that
|
|
84
|
+
# are identical up to the amount of whitespace should be equal).
|
|
85
|
+
self.assertFalse(streq('abc def ghi', ' abc def ghi '))
|
|
86
|
+
self.assertTrue(streq('abc def ghi', ' abc def ghi ', split=True))
|
|
87
|
+
# Nonstring arguments return None.
|
|
88
|
+
self.assertIsNone(streq(None, 'abc'))
|
|
89
|
+
def test_strends(self):
|
|
90
|
+
from immlib import strends
|
|
91
|
+
# strends is just a string equality predicate function.
|
|
92
|
+
self.assertTrue(strends('abcdef', 'def'))
|
|
93
|
+
self.assertFalse(strends('abcdef', 'bcd'))
|
|
94
|
+
# The case option can tell it to ignore case.
|
|
95
|
+
self.assertFalse(strends('ABCDEF', 'def'))
|
|
96
|
+
self.assertTrue(strends('ABCDEF', 'def', case=False))
|
|
97
|
+
# The strip option can be used to ignore trailing/leading whitespace.
|
|
98
|
+
self.assertFalse(strends(' abcdef ', 'def '))
|
|
99
|
+
self.assertTrue(strends(' abcdef ', 'def ', strip=True))
|
|
100
|
+
# Nonstring arguments return None.
|
|
101
|
+
self.assertIsNone(strends(None, 'abc'))
|
|
102
|
+
def test_strstarts(self):
|
|
103
|
+
from immlib import strstarts
|
|
104
|
+
# strstarts is just a string equality predicate function.
|
|
105
|
+
self.assertTrue(strstarts('abcdef', 'abc'))
|
|
106
|
+
self.assertFalse(strstarts('abcdef', 'bcd'))
|
|
107
|
+
# The case option can tell it to ignore case.
|
|
108
|
+
self.assertFalse(strstarts('ABCDEF', 'abc'))
|
|
109
|
+
self.assertTrue(strstarts('ABCDEF', 'abc', case=False))
|
|
110
|
+
# The strip option can be used to ignore trailing/leading whitespace.
|
|
111
|
+
self.assertFalse(strstarts(' abcdef ', ' abc'))
|
|
112
|
+
self.assertTrue(strstarts(' abcdef ', ' abc', strip=True))
|
|
113
|
+
# Nonstring arguments return None.
|
|
114
|
+
self.assertIsNone(strstarts(None, 'abc'))
|
|
115
|
+
def test_strissym(self):
|
|
116
|
+
from immlib import strissym
|
|
117
|
+
# strissym tests whether a string is both a string and a valid Python
|
|
118
|
+
# symbol.
|
|
119
|
+
self.assertTrue(strissym('abc'))
|
|
120
|
+
self.assertTrue(strissym('def123'))
|
|
121
|
+
self.assertTrue(strissym('_10xyz'))
|
|
122
|
+
self.assertFalse(strissym('abc def'))
|
|
123
|
+
self.assertFalse(strissym(' abcdef '))
|
|
124
|
+
self.assertFalse(strissym('a-b'))
|
|
125
|
+
self.assertFalse(strissym('10'))
|
|
126
|
+
# Keywords are allowed.
|
|
127
|
+
self.assertTrue(strissym('for'))
|
|
128
|
+
self.assertTrue(strissym('and'))
|
|
129
|
+
# Non-strings return Nonee.
|
|
130
|
+
self.assertFalse(strissym(None))
|
|
131
|
+
self.assertFalse(strissym(10))
|
|
132
|
+
def test_striskey(self):
|
|
133
|
+
from immlib import striskey
|
|
134
|
+
# striskey tests whether a string is (1) a string, (2) a valid Python
|
|
135
|
+
# symbol, and (3) an existing Python keyword.
|
|
136
|
+
self.assertTrue(striskey('for'))
|
|
137
|
+
self.assertTrue(striskey('and'))
|
|
138
|
+
self.assertTrue(striskey('None'))
|
|
139
|
+
self.assertFalse(striskey('abc'))
|
|
140
|
+
self.assertFalse(striskey('def123'))
|
|
141
|
+
self.assertFalse(striskey('_10xyz'))
|
|
142
|
+
self.assertFalse(striskey('abc def'))
|
|
143
|
+
self.assertFalse(striskey(' abcdef '))
|
|
144
|
+
self.assertFalse(striskey('a-b'))
|
|
145
|
+
self.assertFalse(striskey('10'))
|
|
146
|
+
# Non-strings return None.
|
|
147
|
+
self.assertIsNone(striskey(None))
|
|
148
|
+
self.assertIsNone(striskey(10))
|
|
149
|
+
def test_strisvar(self):
|
|
150
|
+
from immlib import strisvar
|
|
151
|
+
# strisvar tests whether a string is (1) a string, (2) a valid Python
|
|
152
|
+
# symbol, and (3) an *not* existing Python keyword.
|
|
153
|
+
self.assertFalse(strisvar('for'))
|
|
154
|
+
self.assertFalse(strisvar('and'))
|
|
155
|
+
self.assertFalse(strisvar('None'))
|
|
156
|
+
self.assertTrue(strisvar('abc'))
|
|
157
|
+
self.assertTrue(strisvar('def123'))
|
|
158
|
+
self.assertTrue(strisvar('_10xyz'))
|
|
159
|
+
self.assertFalse(strisvar('abc def'))
|
|
160
|
+
self.assertFalse(strisvar(' abcdef '))
|
|
161
|
+
self.assertFalse(strisvar('a-b'))
|
|
162
|
+
self.assertFalse(strisvar('10'))
|
|
163
|
+
# Non-strings return Nonee.
|
|
164
|
+
self.assertIsNone(strisvar(None))
|
|
165
|
+
self.assertIsNone(strisvar(10))
|
|
166
|
+
|
|
167
|
+
# Freeze/Thaw Utilities ####################################################
|
|
168
|
+
def test_frozenarray(self):
|
|
169
|
+
"Tests the frozenarray() and freezearray() functions."
|
|
170
|
+
from immlib.util import frozenarray, freezearray
|
|
171
|
+
from immlib import quant
|
|
172
|
+
import numpy as np
|
|
173
|
+
# frozenarray converts a read-write numpy array into a frozen one.
|
|
174
|
+
x = np.linspace(0, 1, 25)
|
|
175
|
+
y = frozenarray(x)
|
|
176
|
+
self.assertTrue(np.array_equal(x, y))
|
|
177
|
+
self.assertIsNot(x, y)
|
|
178
|
+
self.assertTrue(x.flags['WRITEABLE'])
|
|
179
|
+
self.assertFalse(y.flags['WRITEABLE'])
|
|
180
|
+
# If a frozenarray of an already frozen array is requested, the array is
|
|
181
|
+
# returned as-is.
|
|
182
|
+
self.assertIs(y, frozenarray(y))
|
|
183
|
+
# However, one can override this with the copy argument.
|
|
184
|
+
self.assertIsNot(y, frozenarray(y, copy=True))
|
|
185
|
+
# Typically a copy is made of the original array if it is not already
|
|
186
|
+
# frozen, but one can use freezearray to prevent copying.
|
|
187
|
+
z = frozenarray(x)
|
|
188
|
+
self.assertIsNot(z, x)
|
|
189
|
+
self.assertTrue(x.flags['WRITEABLE'])
|
|
190
|
+
freezearray(x)
|
|
191
|
+
self.assertFalse(x.flags['WRITEABLE'])
|
|
192
|
+
# frozenarray also works with sparse arrays.
|
|
193
|
+
import scipy.sparse as sps
|
|
194
|
+
x = sps.csr_array(
|
|
195
|
+
([1.0, 2.0, 3.5, 6.0], ([0,1,3,4], [3,4,2,1])),
|
|
196
|
+
shape=(5,5))
|
|
197
|
+
y = frozenarray(x)
|
|
198
|
+
self.assertIsNot(x, y)
|
|
199
|
+
self.assertIs(frozenarray(y), y)
|
|
200
|
+
self.assertIsNot(y, frozenarray(y, copy=True))
|
|
201
|
+
self.assertFalse(y.data.flags['WRITEABLE'])
|
|
202
|
+
self.assertTrue(x.data.flags['WRITEABLE'])
|
|
203
|
+
self.assertTrue(np.array_equal(x.data, y.data))
|
|
204
|
+
# As does freeze:
|
|
205
|
+
freezearray(x)
|
|
206
|
+
self.assertFalse(x.data.flags['WRITEABLE'])
|
|
207
|
+
# Both also work with quantities.
|
|
208
|
+
x = quant(
|
|
209
|
+
sps.csr_array(
|
|
210
|
+
([1.0, 2.0, 3.5, 6.0], ([0,1,3,4], [3,4,2,1])),
|
|
211
|
+
shape=(5,5)),
|
|
212
|
+
'mm')
|
|
213
|
+
y = frozenarray(x)
|
|
214
|
+
self.assertIsNot(x, y)
|
|
215
|
+
self.assertIs(frozenarray(y), y)
|
|
216
|
+
self.assertIsNot(y, frozenarray(y, copy=True))
|
|
217
|
+
self.assertFalse(y.m.data.flags['WRITEABLE'])
|
|
218
|
+
self.assertTrue(x.m.data.flags['WRITEABLE'])
|
|
219
|
+
self.assertTrue(np.array_equal(x.m.data, y.m.data))
|
|
220
|
+
freezearray(x)
|
|
221
|
+
self.assertFalse(x.m.data.flags['WRITEABLE'])
|
|
222
|
+
# We can also use frozenarray as a substitute for the array function:
|
|
223
|
+
x = frozenarray([1,2,3,4])
|
|
224
|
+
self.assertIsInstance(x, np.ndarray)
|
|
225
|
+
self.assertFalse(x.flags['WRITEABLE'])
|
|
226
|
+
self.assertTrue(np.array_equal(x, [1,2,3,4]))
|
|
227
|
+
# freezearray fails when given objects not compatible with arrays:
|
|
228
|
+
with self.assertRaises(TypeError):
|
|
229
|
+
freezearray(Ellipsis)
|
|
230
|
+
def test_to_pcoll(self):
|
|
231
|
+
from immlib.util import to_pcoll
|
|
232
|
+
from pcollections import pdict, plist, pset
|
|
233
|
+
x = pdict(a=1, b=2)
|
|
234
|
+
y = plist([1,3,4,5,6])
|
|
235
|
+
z = pset(['a', 'b', 'c'])
|
|
236
|
+
# to_pcoll leaves persistent collections untouched.
|
|
237
|
+
self.assertIs(to_pcoll(x), x)
|
|
238
|
+
self.assertIs(to_pcoll(y), y)
|
|
239
|
+
self.assertIs(to_pcoll(z), z)
|
|
240
|
+
# They convert equivalent non-persistent objects into persistent ones.
|
|
241
|
+
self.assertIsInstance(to_pcoll(dict(x)), pdict)
|
|
242
|
+
self.assertEqual(to_pcoll(dict(x)), x)
|
|
243
|
+
self.assertIsInstance(to_pcoll(list(y)), plist)
|
|
244
|
+
self.assertEqual(to_pcoll(list(y)), y)
|
|
245
|
+
self.assertIsInstance(to_pcoll(set(z)), pset)
|
|
246
|
+
self.assertEqual(to_pcoll(set(z)), z)
|
|
247
|
+
# If the argument isn't a valid collection, it raises an error.
|
|
248
|
+
with self.assertRaises(TypeError):
|
|
249
|
+
to_pcoll(10)
|
|
250
|
+
def test_to_tcoll(self):
|
|
251
|
+
from immlib.util import to_tcoll
|
|
252
|
+
from pcollections import pdict, plist, pset, tdict, tlist, tset
|
|
253
|
+
x = pdict(a=1, b=2)
|
|
254
|
+
y = plist([1,3,4,5,6])
|
|
255
|
+
z = pset(['a', 'b', 'c'])
|
|
256
|
+
# to_tcoll makes equal copies of the transient types.
|
|
257
|
+
tx = to_tcoll(x)
|
|
258
|
+
ty = to_tcoll(y)
|
|
259
|
+
tz = to_tcoll(z)
|
|
260
|
+
self.assertEqual(tx, x)
|
|
261
|
+
self.assertEqual(ty, y)
|
|
262
|
+
self.assertEqual(tz, z)
|
|
263
|
+
self.assertIsInstance(tx, tdict)
|
|
264
|
+
self.assertIsInstance(ty, tlist)
|
|
265
|
+
self.assertIsInstance(tz, tset)
|
|
266
|
+
# to_tcoll always makes a copy...
|
|
267
|
+
self.assertIsNot(tx, to_tcoll(tx))
|
|
268
|
+
# ...unless requested not to...
|
|
269
|
+
self.assertIs(tx, to_tcoll(tx, copy=False))
|
|
270
|
+
# They convert equivalent non-transient objects into transient ones.
|
|
271
|
+
self.assertIsInstance(to_tcoll(dict(x)), tdict)
|
|
272
|
+
self.assertEqual(to_tcoll(dict(x)), x)
|
|
273
|
+
self.assertIsInstance(to_tcoll(list(y)), tlist)
|
|
274
|
+
self.assertEqual(to_tcoll(list(y)), y)
|
|
275
|
+
self.assertIsInstance(to_tcoll(set(z)), tset)
|
|
276
|
+
self.assertEqual(to_tcoll(set(z)), z)
|
|
277
|
+
# If the argument isn't a valid collection, it raises an error.
|
|
278
|
+
with self.assertRaises(TypeError):
|
|
279
|
+
to_tcoll(10)
|
|
280
|
+
def test_to_mcoll(self):
|
|
281
|
+
from immlib.util import to_mcoll
|
|
282
|
+
from pcollections import pdict, plist, pset, tdict, tlist, tset
|
|
283
|
+
x = pdict(a=1, b=2)
|
|
284
|
+
y = plist([1,3,4,5,6])
|
|
285
|
+
z = pset(['a', 'b', 'c'])
|
|
286
|
+
# to_mcoll makes equal copies of the mutable types.
|
|
287
|
+
mx = to_mcoll(x)
|
|
288
|
+
my = to_mcoll(y)
|
|
289
|
+
mz = to_mcoll(z)
|
|
290
|
+
self.assertEqual(mx, x)
|
|
291
|
+
self.assertEqual(my, y)
|
|
292
|
+
self.assertEqual(mz, z)
|
|
293
|
+
self.assertIsInstance(mx, dict)
|
|
294
|
+
self.assertIsInstance(my, list)
|
|
295
|
+
self.assertIsInstance(mz, set)
|
|
296
|
+
# to_mcoll always makes a copy...
|
|
297
|
+
self.assertIsNot(mx, to_mcoll(mx))
|
|
298
|
+
# ...unless requested not to.
|
|
299
|
+
self.assertIs(mx, to_mcoll(mx, copy=False))
|
|
300
|
+
# They convert equivalent non-transient objects into transient ones.
|
|
301
|
+
self.assertIsInstance(to_mcoll(dict(x)), dict)
|
|
302
|
+
self.assertEqual(to_mcoll(dict(x)), x)
|
|
303
|
+
self.assertIsInstance(to_mcoll(list(y)), list)
|
|
304
|
+
self.assertEqual(to_mcoll(list(y)), y)
|
|
305
|
+
self.assertIsInstance(to_mcoll(set(z)), set)
|
|
306
|
+
self.assertEqual(to_mcoll(set(z)), z)
|
|
307
|
+
# If the argument isn't a valid collection, it raises an error.
|
|
308
|
+
with self.assertRaises(TypeError):
|
|
309
|
+
to_mcoll(10)
|
|
310
|
+
|
|
311
|
+
# Other Utilities ##########################################################
|
|
312
|
+
def test_predicates(self):
|
|
313
|
+
from immlib.util import (
|
|
314
|
+
is_acallable, is_lambda, is_asized, is_acontainer,
|
|
315
|
+
is_aiterable, is_aiterator, is_areversible, is_acoll,
|
|
316
|
+
is_abytes, is_bytes, is_ahashable, is_tuple, is_frozenset,
|
|
317
|
+
is_aseq, is_amseq, is_apseq,
|
|
318
|
+
is_aset, is_amset, is_apset,
|
|
319
|
+
is_amap, is_ammap, is_apmap,
|
|
320
|
+
is_list, is_plist, is_tlist, is_llist,
|
|
321
|
+
is_set, is_pset, is_tset,
|
|
322
|
+
is_dict, is_odict, is_ddict, is_pdict, is_tdict, is_ldict,
|
|
323
|
+
is_pcoll, is_tcoll, is_mcoll)
|
|
324
|
+
from pcollections import (
|
|
325
|
+
pset, tset, pdict, tdict, plist, tlist, ldict, llist)
|
|
326
|
+
from collections import (OrderedDict, defaultdict)
|
|
327
|
+
# For each of these we just do one True and one False example:
|
|
328
|
+
self.assertTrue(is_acallable(lambda:True))
|
|
329
|
+
self.assertFalse(is_acallable(10))
|
|
330
|
+
self.assertTrue(is_lambda(lambda:0))
|
|
331
|
+
self.assertFalse(is_lambda(10))
|
|
332
|
+
self.assertTrue(is_asized([]))
|
|
333
|
+
self.assertFalse(is_asized(0))
|
|
334
|
+
self.assertTrue(is_acontainer([]))
|
|
335
|
+
self.assertFalse(is_acontainer(None))
|
|
336
|
+
self.assertTrue(is_aiterable([]))
|
|
337
|
+
self.assertFalse(is_aiterable(None))
|
|
338
|
+
self.assertTrue(is_aiterator(iter('abc')))
|
|
339
|
+
self.assertFalse(is_aiterator('abc'))
|
|
340
|
+
self.assertTrue(is_areversible([]))
|
|
341
|
+
self.assertFalse(is_areversible(set([1,2,3])))
|
|
342
|
+
self.assertTrue(is_acoll([]))
|
|
343
|
+
self.assertFalse(is_acoll(10))
|
|
344
|
+
self.assertTrue(is_abytes(b'abc'))
|
|
345
|
+
self.assertFalse(is_abytes('abc'))
|
|
346
|
+
self.assertTrue(is_bytes(b'abc'))
|
|
347
|
+
self.assertFalse(is_bytes('abc'))
|
|
348
|
+
self.assertTrue(is_ahashable('abc'))
|
|
349
|
+
self.assertFalse(is_ahashable({}))
|
|
350
|
+
self.assertTrue(is_tuple((1,2,3)))
|
|
351
|
+
self.assertFalse(is_tuple([]))
|
|
352
|
+
self.assertTrue(is_frozenset(frozenset((1,2,3))))
|
|
353
|
+
self.assertFalse(is_frozenset(set()))
|
|
354
|
+
self.assertTrue(is_aseq([1,2,3]))
|
|
355
|
+
self.assertFalse(is_aseq({}))
|
|
356
|
+
self.assertTrue(is_amseq([]))
|
|
357
|
+
self.assertTrue(is_amseq(tlist()))
|
|
358
|
+
self.assertFalse(is_amseq(plist()))
|
|
359
|
+
self.assertTrue(is_apseq(plist()))
|
|
360
|
+
self.assertFalse(is_apseq(tlist()))
|
|
361
|
+
self.assertFalse(is_apseq([]))
|
|
362
|
+
self.assertTrue(is_aset(set()))
|
|
363
|
+
self.assertFalse(is_aset({}))
|
|
364
|
+
self.assertTrue(is_amset(tset()))
|
|
365
|
+
self.assertFalse(is_amset(pset()))
|
|
366
|
+
self.assertTrue(is_apset(pset()))
|
|
367
|
+
self.assertFalse(is_apset(set()))
|
|
368
|
+
self.assertTrue(is_amap(dict()))
|
|
369
|
+
self.assertFalse(is_amap([]))
|
|
370
|
+
self.assertTrue(is_ammap(tdict()))
|
|
371
|
+
self.assertFalse(is_ammap(pdict()))
|
|
372
|
+
self.assertTrue(is_apmap(pdict()))
|
|
373
|
+
self.assertFalse(is_apmap(dict()))
|
|
374
|
+
self.assertTrue(is_list([]))
|
|
375
|
+
self.assertFalse(is_list(llist()))
|
|
376
|
+
self.assertTrue(is_plist(plist()))
|
|
377
|
+
self.assertFalse(is_plist([]))
|
|
378
|
+
self.assertTrue(is_tlist(tlist()))
|
|
379
|
+
self.assertFalse(is_tlist([]))
|
|
380
|
+
self.assertTrue(is_llist(llist()))
|
|
381
|
+
self.assertFalse(is_llist(plist()))
|
|
382
|
+
self.assertTrue(is_set(set()))
|
|
383
|
+
self.assertFalse(is_set(pset()))
|
|
384
|
+
self.assertTrue(is_pset(pset()))
|
|
385
|
+
self.assertFalse(is_pset(tset()))
|
|
386
|
+
self.assertTrue(is_tset(tset()))
|
|
387
|
+
self.assertFalse(is_tset(set()))
|
|
388
|
+
self.assertTrue(is_dict(dict()))
|
|
389
|
+
self.assertFalse(is_dict(pdict()))
|
|
390
|
+
self.assertTrue(is_odict(OrderedDict()))
|
|
391
|
+
self.assertFalse(is_odict(dict()))
|
|
392
|
+
self.assertTrue(is_ddict(defaultdict(lambda:[])))
|
|
393
|
+
self.assertFalse(is_ddict(dict()))
|
|
394
|
+
self.assertTrue(is_pdict(pdict()))
|
|
395
|
+
self.assertFalse(is_pdict(dict()))
|
|
396
|
+
self.assertTrue(is_tdict(tdict()))
|
|
397
|
+
self.assertFalse(is_tdict(pdict()))
|
|
398
|
+
self.assertTrue(is_ldict(ldict()))
|
|
399
|
+
self.assertFalse(is_ldict(pdict()))
|
|
400
|
+
self.assertTrue(is_pcoll(pdict()))
|
|
401
|
+
self.assertFalse(is_pcoll([]))
|
|
402
|
+
self.assertTrue(is_tcoll(tset()))
|
|
403
|
+
self.assertFalse(is_tcoll(pset()))
|
|
404
|
+
self.assertTrue(is_mcoll({}))
|
|
405
|
+
self.assertFalse(is_mcoll(pdict()))
|
|
406
|
+
def test_hashsafe(self):
|
|
407
|
+
from immlib import hashsafe
|
|
408
|
+
# hashsafe returns hash(x) if x is hashable and None otherwise.
|
|
409
|
+
self.assertIsNone(hashsafe({}))
|
|
410
|
+
self.assertIsNone(hashsafe([1, 2, 3]))
|
|
411
|
+
self.assertIsNone(hashsafe(set(['a', 'b'])))
|
|
412
|
+
self.assertEqual(hash(10), hashsafe(10))
|
|
413
|
+
self.assertEqual(hash('abc'), hashsafe('abc'))
|
|
414
|
+
self.assertEqual(hash((1, 10, 100)), hashsafe((1, 10, 100)))
|
|
415
|
+
def test_can_hash(self):
|
|
416
|
+
from immlib import can_hash
|
|
417
|
+
# can_hash(x) returns True if hash(x) will successfully return a hash
|
|
418
|
+
# and returns False if such a call would raise an error.
|
|
419
|
+
self.assertTrue(can_hash(10))
|
|
420
|
+
self.assertTrue(can_hash('abc'))
|
|
421
|
+
self.assertTrue(can_hash((1, 10, 100)))
|
|
422
|
+
self.assertFalse(can_hash({}))
|
|
423
|
+
self.assertFalse(can_hash([1, 2, 3]))
|
|
424
|
+
self.assertFalse(can_hash(set(['a', 'b'])))
|
|
425
|
+
def test_itersafe(self):
|
|
426
|
+
from immlib import itersafe
|
|
427
|
+
# itersafe returns iter(x) if x is iterable and None otherwise.
|
|
428
|
+
self.assertIsNone(itersafe(10))
|
|
429
|
+
self.assertIsNone(itersafe(lambda x:x))
|
|
430
|
+
self.assertEqual(list(itersafe([1, 2, 3])), [1, 2, 3])
|
|
431
|
+
def test_can_iter(self):
|
|
432
|
+
from immlib import can_iter
|
|
433
|
+
# can_iter(x) returns True if iter(x) will successfully return an
|
|
434
|
+
# iterator and returns False if such a call would raise an error.
|
|
435
|
+
self.assertTrue(can_iter('abc'))
|
|
436
|
+
self.assertTrue(can_iter([]))
|
|
437
|
+
self.assertTrue(can_iter((1, 10, 100)))
|
|
438
|
+
self.assertFalse(can_iter(10))
|
|
439
|
+
self.assertFalse(can_iter(lambda x:x))
|
|
440
|
+
def test_get(self):
|
|
441
|
+
from immlib import get, nestget
|
|
442
|
+
# get just extracts things from simple containers; nestget does so from
|
|
443
|
+
# nested containers.
|
|
444
|
+
x = {'a': [1, 2, 3], 'b': [{'x':0, 'y':1}, {'x':10, 'y':11}]}
|
|
445
|
+
self.assertEqual(get(x, 'a'), [1,2,3])
|
|
446
|
+
self.assertEqual(nestget(x, 'a'), [1,2,3])
|
|
447
|
+
self.assertEqual(nestget(x, 'a', 1), 2)
|
|
448
|
+
with self.assertRaises(KeyError):
|
|
449
|
+
get(x, 'q')
|
|
450
|
+
with self.assertRaises(KeyError):
|
|
451
|
+
get(x['a'], 'q')
|
|
452
|
+
with self.assertRaises(KeyError):
|
|
453
|
+
get(x['a'], 10)
|
|
454
|
+
with self.assertRaises(KeyError):
|
|
455
|
+
nestget(x, 'a', 5)
|
|
456
|
+
with self.assertRaises(TypeError):
|
|
457
|
+
nestget(x, 'b', 0, 'x', 10)
|
|
458
|
+
with self.assertRaises(KeyError):
|
|
459
|
+
nestget(x, 'b', 'q')
|
|
460
|
+
with self.assertRaises(TypeError):
|
|
461
|
+
get(None, 'q')
|
|
462
|
+
self.assertEqual(get(x, 'q', default=...), ...)
|
|
463
|
+
self.assertEqual(nestget(x, 'b', 4, default=...), ...)
|
|
464
|
+
# Other errors that can be caused:
|
|
465
|
+
with self.assertRaises(TypeError):
|
|
466
|
+
get(x, 'a', other=10)
|
|
467
|
+
with self.assertRaises(TypeError):
|
|
468
|
+
nestget(x, 'a', other=10)
|
|
469
|
+
def test_maps(self):
|
|
470
|
+
from immlib.util import (
|
|
471
|
+
lazyvalmap, valmap, lazykeymap, keymap, lazyitemmap, itemmap,
|
|
472
|
+
dictmap, pdictmap, ldictmap)
|
|
473
|
+
from pcollections import pdict, ldict, lazy
|
|
474
|
+
d = dict(a=1, b=2, c=3)
|
|
475
|
+
make_ld = lambda:ldict(a=lazy(lambda:1), b=lazy(lambda:2), c=3)
|
|
476
|
+
# lazyvalmap
|
|
477
|
+
md = lazyvalmap(lambda x: x+1, d)
|
|
478
|
+
self.assertIsInstance(md, ldict)
|
|
479
|
+
self.assertTrue(md.is_lazy('a'))
|
|
480
|
+
self.assertFalse(md.is_ready('a'))
|
|
481
|
+
self.assertEqual(md['a'], 2)
|
|
482
|
+
self.assertTrue(md.is_ready('a'))
|
|
483
|
+
mmd = lazyvalmap(lambda x: x+1, md)
|
|
484
|
+
self.assertIsInstance(mmd, ldict)
|
|
485
|
+
self.assertTrue(mmd.is_lazy('a'))
|
|
486
|
+
self.assertTrue(md.is_lazy('b'))
|
|
487
|
+
self.assertFalse(mmd.is_ready('a'))
|
|
488
|
+
self.assertFalse(md.is_ready('b'))
|
|
489
|
+
self.assertEqual(mmd['a'], 3)
|
|
490
|
+
self.assertEqual(md, dict(a=2, b=3, c=4))
|
|
491
|
+
self.assertEqual(mmd, dict(a=3, b=4, c=5))
|
|
492
|
+
# valmap
|
|
493
|
+
ld = make_ld()
|
|
494
|
+
md = valmap(lambda x: x+1, d)
|
|
495
|
+
mld = valmap(lambda x: x+1, ld)
|
|
496
|
+
mpd = valmap(lambda x: x+1, pdict(d))
|
|
497
|
+
self.assertIs(type(md), dict)
|
|
498
|
+
self.assertIs(type(mpd), pdict)
|
|
499
|
+
self.assertIs(type(mld), ldict)
|
|
500
|
+
self.assertTrue(mld.is_lazy('a'))
|
|
501
|
+
self.assertEqual(mld['a'], 2)
|
|
502
|
+
self.assertTrue(mld.is_ready('a'))
|
|
503
|
+
self.assertEqual(md, dict(a=2, b=3, c=4))
|
|
504
|
+
self.assertEqual(mpd, dict(a=2, b=3, c=4))
|
|
505
|
+
self.assertEqual(mld, dict(a=2, b=3, c=4))
|
|
506
|
+
# lazykeymap
|
|
507
|
+
md = lazykeymap(lambda x:x, d)
|
|
508
|
+
self.assertIsInstance(md, ldict)
|
|
509
|
+
self.assertTrue(md.is_lazy('a'))
|
|
510
|
+
self.assertFalse(md.is_ready('a'))
|
|
511
|
+
self.assertEqual(md['a'], 'a')
|
|
512
|
+
self.assertTrue(md.is_ready('a'))
|
|
513
|
+
self.assertEqual(md, dict(a='a', b='b', c='c'))
|
|
514
|
+
# keymap
|
|
515
|
+
ld = make_ld()
|
|
516
|
+
md = keymap(lambda x: x, d)
|
|
517
|
+
mld = keymap(lambda x: x, ld)
|
|
518
|
+
mpd = keymap(lambda x: x, pdict(d))
|
|
519
|
+
self.assertIs(type(md), dict)
|
|
520
|
+
self.assertIs(type(mpd), pdict)
|
|
521
|
+
self.assertIs(type(mld), pdict)
|
|
522
|
+
self.assertEqual(mld['a'], 'a')
|
|
523
|
+
self.assertEqual(md, dict(a='a', b='b', c='c'))
|
|
524
|
+
self.assertEqual(mpd, dict(a='a', b='b', c='c'))
|
|
525
|
+
self.assertEqual(mld, dict(a='a', b='b', c='c'))
|
|
526
|
+
# lazyitemmap
|
|
527
|
+
md = lazyitemmap(lambda x,y: x*y, d)
|
|
528
|
+
self.assertIsInstance(md, ldict)
|
|
529
|
+
self.assertTrue(md.is_lazy('a'))
|
|
530
|
+
self.assertFalse(md.is_ready('a'))
|
|
531
|
+
self.assertEqual(md['a'], 'a')
|
|
532
|
+
self.assertTrue(md.is_ready('a'))
|
|
533
|
+
mmd = lazyitemmap(lambda x,y: x*y, ldict(d))
|
|
534
|
+
self.assertIsInstance(mmd, ldict)
|
|
535
|
+
self.assertTrue(mmd.is_lazy('a'))
|
|
536
|
+
self.assertTrue(md.is_lazy('b'))
|
|
537
|
+
self.assertFalse(mmd.is_ready('a'))
|
|
538
|
+
self.assertFalse(md.is_ready('b'))
|
|
539
|
+
self.assertEqual(mmd['a'], 'a')
|
|
540
|
+
self.assertEqual(md, dict(a='a', b='bb', c='ccc'))
|
|
541
|
+
self.assertEqual(mmd, dict(a='a', b='bb', c='ccc'))
|
|
542
|
+
# itemmap
|
|
543
|
+
ld = make_ld()
|
|
544
|
+
md = itemmap(lambda x,y: x*y, d)
|
|
545
|
+
mld = itemmap(lambda x,y: x*y, ld)
|
|
546
|
+
mpd = itemmap(lambda x,y: x*y, pdict(d))
|
|
547
|
+
self.assertIs(type(md), dict)
|
|
548
|
+
self.assertIs(type(mpd), pdict)
|
|
549
|
+
self.assertIs(type(mld), ldict)
|
|
550
|
+
self.assertTrue(mld.is_lazy('a'))
|
|
551
|
+
self.assertEqual(mld['a'], 'a')
|
|
552
|
+
self.assertTrue(mld.is_ready('a'))
|
|
553
|
+
self.assertEqual(md, dict(a='a', b='bb', c='ccc'))
|
|
554
|
+
self.assertEqual(mpd, dict(a='a', b='bb', c='ccc'))
|
|
555
|
+
self.assertEqual(mld, dict(a='a', b='bb', c='ccc'))
|
|
556
|
+
# dictmap
|
|
557
|
+
ks = list('abcdefghij')
|
|
558
|
+
ref = dict(zip(ks, range(10)))
|
|
559
|
+
d = dictmap(lambda k: ref[k] + 1, ks)
|
|
560
|
+
pd = pdictmap(lambda k: ref[k] + 1, ks)
|
|
561
|
+
ld = ldictmap(lambda k: ref[k] + 1, ks)
|
|
562
|
+
self.assertIs(type(pd), pdict)
|
|
563
|
+
self.assertIs(type(ld), ldict)
|
|
564
|
+
self.assertEqual(valmap(lambda x:x+1, ref), d)
|
|
565
|
+
self.assertEqual(valmap(lambda x:x+1, ref), pd)
|
|
566
|
+
self.assertTrue(ld.is_lazy('a'))
|
|
567
|
+
self.assertFalse(ld.is_ready('a'))
|
|
568
|
+
self.assertEqual(ld['a'], 1)
|
|
569
|
+
self.assertTrue(ld.is_ready('a'))
|
|
570
|
+
self.assertEqual(valmap(lambda x:x+1, ref), ld)
|
|
571
|
+
def test_merge(self):
|
|
572
|
+
from immlib.util import merge, rmerge
|
|
573
|
+
from pcollections import ldict, lazy
|
|
574
|
+
d1 = dict(a=1, b=2, c=3)
|
|
575
|
+
d2 = dict(b=3, c=4, d=5)
|
|
576
|
+
d3 = ldict(c=lazy(lambda:5), d=6, e=lazy(lambda:7))
|
|
577
|
+
d = merge(d1, d2, d3, a=0)
|
|
578
|
+
self.assertIs(type(d), ldict)
|
|
579
|
+
self.assertTrue(d.is_lazy('c'))
|
|
580
|
+
self.assertTrue(d.is_lazy('e'))
|
|
581
|
+
self.assertFalse(d.is_ready('c'))
|
|
582
|
+
self.assertFalse(d.is_ready('e'))
|
|
583
|
+
self.assertFalse(d.is_lazy('d'))
|
|
584
|
+
self.assertEqual(d['c'], 5)
|
|
585
|
+
self.assertTrue(d.is_ready('c'))
|
|
586
|
+
self.assertFalse(d.is_ready('e'))
|
|
587
|
+
self.assertEqual(d, dict(a=0, b=3, c=5, d=6, e=7))
|
|
588
|
+
d3 = ldict(c=lazy(lambda:5), d=6, e=lazy(lambda:7))
|
|
589
|
+
d = rmerge(d1, d2, d3, a=0)
|
|
590
|
+
self.assertIs(type(d), ldict)
|
|
591
|
+
self.assertFalse(d.is_lazy('c'))
|
|
592
|
+
self.assertTrue(d.is_lazy('e'))
|
|
593
|
+
self.assertFalse(d.is_ready('e'))
|
|
594
|
+
self.assertEqual(d['c'], 3)
|
|
595
|
+
self.assertEqual(d['e'], 7)
|
|
596
|
+
self.assertTrue(d.is_ready('e'))
|
|
597
|
+
self.assertEqual(d, dict(a=1, b=2, c=3, d=5, e=7))
|
|
598
|
+
def test_assoc(self):
|
|
599
|
+
from immlib.util import assoc, dissoc
|
|
600
|
+
from pcollections import pdict
|
|
601
|
+
with self.assertRaises(ValueError):
|
|
602
|
+
assoc({}, 'a')
|
|
603
|
+
with self.assertRaises(TypeError):
|
|
604
|
+
assoc('abc', 'a', 1)
|
|
605
|
+
with self.assertRaises(TypeError):
|
|
606
|
+
dissoc('abc', 'a')
|
|
607
|
+
d = dict(a=1, b=2, c=3)
|
|
608
|
+
self.assertEqual(assoc(d, d=4), dict(d, d=4))
|
|
609
|
+
self.assertEqual(assoc(d, 'd', 4), dict(d, d=4))
|
|
610
|
+
self.assertEqual(assoc(d, 'd', 4, e=5), dict(d, d=4, e=5))
|
|
611
|
+
self.assertIsNot(assoc(d, 'd', 4), d)
|
|
612
|
+
self.assertEqual(dissoc(d, 'b'), dict(a=1, c=3))
|
|
613
|
+
self.assertEqual(dissoc(d, 'b', 'c'), dict(a=1))
|
|
614
|
+
self.assertIsNot(dissoc(d, 'b'), d)
|
|
615
|
+
d = pdict(a=1, b=2, c=3)
|
|
616
|
+
self.assertEqual(assoc(d, d=4), dict(d, d=4))
|
|
617
|
+
self.assertEqual(assoc(d, 'd', 4), dict(d, d=4))
|
|
618
|
+
self.assertEqual(assoc(d, 'd', 4, e=5), dict(d, d=4, e=5))
|
|
619
|
+
self.assertIsNot(assoc(d, 'd', 4), d)
|
|
620
|
+
self.assertEqual(dissoc(d, 'b'), dict(a=1, c=3))
|
|
621
|
+
self.assertEqual(dissoc(d, 'b', 'c'), dict(a=1))
|
|
622
|
+
self.assertIsNot(dissoc(d, 'b'), d)
|
|
623
|
+
def test_lambdadict(self):
|
|
624
|
+
from immlib.util import lambdadict
|
|
625
|
+
from pcollections import ldict
|
|
626
|
+
d = lambdadict(a=1, b=2, c=lambda a,b: a+b)
|
|
627
|
+
self.assertIsInstance(d, ldict)
|
|
628
|
+
self.assertTrue(d.is_lazy('c'))
|
|
629
|
+
self.assertFalse(d.is_ready('c'))
|
|
630
|
+
self.assertEqual(d['c'], 3)
|
|
631
|
+
self.assertTrue(d.is_ready('c'))
|
|
632
|
+
self.assertEqual(d, dict(a=1, b=2, c=3))
|
|
633
|
+
def test_args(self):
|
|
634
|
+
from immlib.util import args, argfilter
|
|
635
|
+
# First test the args type:
|
|
636
|
+
(a, kw) = args(1, 2, 3, a=1, b=2)
|
|
637
|
+
self.assertEqual(a, (1,2,3))
|
|
638
|
+
self.assertEqual(kw, dict(a=1, b=2))
|
|
639
|
+
aa = args(1, 2, 3, a=1, b=2)
|
|
640
|
+
self.assertIs(type(aa), args)
|
|
641
|
+
self.assertEqual(aa, ((1,2,3), {'a':1,'b':2}))
|
|
642
|
+
bb = aa.copy(args=(2,3,4))
|
|
643
|
+
self.assertEqual(bb, ((2,3,4), {'a':1,'b':2}))
|
|
644
|
+
cc = aa.copy(kwargs={'c':3})
|
|
645
|
+
self.assertEqual(cc, ((1,2,3), {'c':3}))
|
|
646
|
+
# Next test the argfilter:
|
|
647
|
+
@argfilter
|
|
648
|
+
def fix_angle(angle, *, unit):
|
|
649
|
+
angle = np.asarray(angle)
|
|
650
|
+
if unit == 'degrees':
|
|
651
|
+
angle = np.pi / 180 * angle
|
|
652
|
+
elif unit != 'radians':
|
|
653
|
+
raise ValueError(f'unrecognized unit: {unit}')
|
|
654
|
+
return (angle,)
|
|
655
|
+
@fix_angle
|
|
656
|
+
def cos_halfangle(angle, unit='radians'):
|
|
657
|
+
return np.cos(angle / 2)
|
|
658
|
+
self.assertEqual(cos_halfangle(0), 1.0)
|
|
659
|
+
self.assertEqual(cos_halfangle(0, unit='degrees'), 1.0)
|
|
660
|
+
self.assertTrue(np.abs(cos_halfangle(np.pi)) < 1e-9)
|
|
661
|
+
self.assertTrue(np.abs(cos_halfangle(180, unit='degrees')) < 1e-9)
|
|
662
|
+
def test_unitregistry(self):
|
|
663
|
+
from immlib.util import unitregistry
|
|
664
|
+
from immlib import unit, units, mag, quant, default_ureg
|
|
665
|
+
with default_ureg(units):
|
|
666
|
+
q = quant(10.5, 'mm')
|
|
667
|
+
p = quant(55, 's')
|
|
668
|
+
self.assertIs(units, unitregistry(units))
|
|
669
|
+
self.assertIs(units, unitregistry(...))
|
|
670
|
+
self.assertIs(units, unitregistry(q))
|
|
671
|
+
self.assertIs(units, unitregistry(p))
|
|
672
|
+
self.assertIs(units, unitregistry(q.u))
|
|
673
|
+
self.assertIs(units, unitregistry(p.u))
|
|
674
|
+
with self.assertRaises(TypeError):
|
|
675
|
+
unitregistry(units, None, 1)
|
|
676
|
+
with self.assertRaises(TypeError):
|
|
677
|
+
unitregistry()
|
|
678
|
+
with self.assertRaises(TypeError):
|
|
679
|
+
unitregistry(units, None, 1)
|
|
680
|
+
|
|
681
|
+
|