cdxcore 0.1.6__py3-none-any.whl → 0.1.9__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.

Potentially problematic release.


This version of cdxcore might be problematic. Click here for more details.

tests/test_config.py ADDED
@@ -0,0 +1,502 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Tue Apr 14 21:24:52 2020
4
+ @author: hansb
5
+ """
6
+
7
+
8
+ import unittest as unittest
9
+ import dataclasses as dataclasses
10
+ import sys as sys
11
+ import os as os
12
+ import pickle as pickle
13
+ import tempfile as tempfile
14
+ import shutil as shutil
15
+ sys.setrecursionlimit(100)
16
+
17
+ def import_local():
18
+ """
19
+ In order to be able to run our tests manually from the 'tests' directory
20
+ we force import from the local package.
21
+ We also force reloading all modules to make sure we are not running old code.
22
+ """
23
+ me = "cdxcore"
24
+ import os
25
+ import sys
26
+ cwd = os.getcwd()
27
+ if cwd[-len(me):] == me:
28
+ return
29
+ assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
30
+ assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
31
+ sys.path.insert( 0, cwd[:-6] )
32
+
33
+ # reload modules
34
+ import importlib as imp
35
+ modules = sys.modules.copy()
36
+ for name, mdata in modules.items():
37
+ if name[:len(me)] == me:
38
+ imp.reload(mdata)
39
+ print("Reloaded", name)
40
+ import_local()
41
+
42
+ from cdxcore.config import Config, Int, Float
43
+ from cdxcore.pretty import PrettyObject as pdct
44
+ from cdxcore.uniquehash import unique_hash16
45
+
46
+ class Test(unittest.TestCase):
47
+
48
+ def test_config(self):
49
+
50
+ config = Config(x=0., z=-1.)
51
+ x = config("x", 10., float, "test x")
52
+ self.assertEqual( x, 0. )
53
+ y = config("y", 10., float, "test y")
54
+ self.assertEqual( y, 10. )
55
+
56
+ with self.assertRaises(Exception):
57
+ # 'z' was not read
58
+ config.done()
59
+
60
+ # calling twice with different values
61
+ config = Config(x=0.)
62
+ x = config("x", 1., float, "test x")
63
+ x = config("x", 1., float, "test x") # ok: same parameters
64
+ with self.assertRaises(Exception):
65
+ x = config("x", 1., Float<0.5, "test x") # not ok: Float condition
66
+ with self.assertRaises(Exception):
67
+ x = config("x", 2., float, "test x") # not ok: different default
68
+ config.done()
69
+
70
+ # test usage per access method:
71
+ # __call__('a')
72
+ # get('a')
73
+ # get_default('a', ...)
74
+ # all register usage;
75
+ # get_raw('a')
76
+ # ['a']
77
+ # do not.
78
+ config = Config(a=1)
79
+ _ = config.get("a")
80
+ self.assertTrue( not 'a' in config.not_done )
81
+ config = Config(a=1)
82
+ _ = config.get_default("a", 0)
83
+ self.assertTrue( not 'a' in config.not_done )
84
+ config = Config(a=1)
85
+ _ = config("a")
86
+ self.assertTrue( not 'a' in config.not_done )
87
+ config = Config(a=1)
88
+ _ = config("a", 0)
89
+ self.assertTrue( not 'a' in config.not_done )
90
+
91
+ config = Config(a=1)
92
+ _ = config.get_raw('a')
93
+ self.assertTrue( 'a' in config.not_done )
94
+ config = Config(a=1)
95
+ _ = config['a']
96
+ self.assertTrue( 'a' in config.not_done )
97
+
98
+ # test sub configs
99
+ config = Config()
100
+ config.x = 1
101
+ config.a = "a"
102
+ config.sub.x = 2.
103
+
104
+ self.assertEqual(1., config("x", 0., float, "x"))
105
+ self.assertEqual("a", config("a", None, str, "a"))
106
+ self.assertEqual(2, config.sub("x", 0, int, "x"))
107
+ self.assertTrue( isinstance( config.sub, Config ) )
108
+ config.done()
109
+
110
+ # test detach
111
+ config = Config()
112
+ config.sub.x = 1
113
+ with self.assertRaises(Exception):
114
+ config.done() # 'sub.x' not read
115
+
116
+ config = Config()
117
+ config.sub.x = 1
118
+ sub = config.sub.detach()
119
+ config.done() # ok
120
+ _ = sub("x", 1)
121
+ config.done() # fine now
122
+
123
+ # test list (_Enum)
124
+ config = Config(t="a", q="q")
125
+ _ = config("t", "b", ['a', 'b', 'c'] )
126
+ self.assertEqual(_, 'a')
127
+ with self.assertRaises(Exception):
128
+ _ = config("q", "b", ['a', 'b', 'c'] ) # exception: 'q' not in set
129
+
130
+ # test tuple (_Alt)
131
+ config = Config(t="a")
132
+ _ = config("t", "b", (None, str) )
133
+ self.assertEqual(_, 'a')
134
+ config = Config(t=None)
135
+ _ = config("t", "b", (None, str) )
136
+ self.assertEqual(_, None)
137
+ with self.assertRaises(Exception):
138
+ config = Config(t="a")
139
+ _ = config("t", 1, (None, int) )
140
+ self.assertEqual(_, None)
141
+ config = Config()
142
+ _ = config("t", "b", (None, ['a','b']) )
143
+ self.assertEqual(_, 'b')
144
+ config = Config(t=2)
145
+ _ = config("t", 1, (Int>=1, Int<=1) )
146
+ self.assertEqual(_, 2)
147
+ config = Config()
148
+ _ = config("t", 3, (Int>=1, Int<=1) )
149
+ self.assertEqual(_, 3)
150
+ with self.assertRaises(Exception):
151
+ config = Config()
152
+ _ = config("t", 0, (Int>=1, Int<=-1) )
153
+ with self.assertRaises(Exception):
154
+ config = Config(t=0)
155
+ _ = config("t", 3, (Int>=1, Int<=-1) )
156
+
157
+ # combined conditons
158
+ config = Config(x=1., y=1.)
159
+
160
+ x = config("x", 1., ( Float>=0.) & (Float<=1.), "test x")
161
+ with self.assertRaises(Exception):
162
+ # test that violated condition is caught
163
+ y = config("y", 1., ( Float>=0.) & (Float<1.), "test y")
164
+
165
+ config = Config(x=1., y=1.)
166
+ with self.assertRaises(NotImplementedError):
167
+ # left hand must be > or >=
168
+ y = config("y", 1., ( Float<=0.) & (Float<1.), "test x")
169
+ config = Config(x=1., y=1.)
170
+ with self.assertRaises(NotImplementedError):
171
+ # right hand must be < or <=
172
+ y = config("y", 1., ( Float>=0.) & (Float>1.), "test x")
173
+
174
+ # test int
175
+ config = Config(x=1)
176
+ x = config("x", 0, ( Int>=0 ) & ( Int<=1), "int test")
177
+ config = Config(x=1)
178
+ with self.assertRaises(NotImplementedError):
179
+ # cannot mix types
180
+ x = config("x", 1., ( Float>=0.) & (Int<=1), "test x")
181
+
182
+ # test deleting children
183
+ config = Config()
184
+ config.a.x = 1
185
+ config.b.x = 2
186
+ config.c.x = 3
187
+ config.delete_children( 'a' )
188
+ l = sorted( config.children )
189
+ self.assertEqual(l, ['b', 'c'])
190
+ config = Config()
191
+ config.a.x = 1
192
+ config.b.x = 2
193
+ config.c.x = 3
194
+ config.delete_children( ['a','b'] )
195
+ l = sorted( config.children )
196
+ self.assertEqual(l, ['c'])
197
+
198
+ # test conversion to dictionaries
199
+ config = Config()
200
+ config.x = 1
201
+ config.y = 2
202
+ config.sub.x = 10
203
+ config.sub.y = 20
204
+ inp_dict = config.input_dict()
205
+
206
+ test = pdct()
207
+ test.x = 1
208
+ test.y = 2
209
+ test.sub = pdct()
210
+ test.sub.x = 10
211
+ test.sub.y = 20
212
+
213
+ self.assertEqual( test, inp_dict)
214
+
215
+ # clean_copy
216
+ config = Config()
217
+ config.gym.user_version = 1
218
+ config.gym.world_character_id = 2
219
+ config.gym.vol_model.type = "decoder"
220
+ _ = config.clean_copy()
221
+
222
+ """
223
+ test = PrettyDict()
224
+ test.x = config("x", 1)
225
+ test.y = config("y", 22)
226
+ test.z = config("z", 33)
227
+ test.sub = PrettyDict()
228
+ test.sub.x = config.sub("x", 10)
229
+ test.sub.y = config.sub("y", 222)
230
+ test.sub.z = config.sub("z", 333)
231
+ usd_dict = config.usage_dict()
232
+ self.assertEqual( usd_dict, test )
233
+ """
234
+
235
+ # test keys()
236
+
237
+ config = Config()
238
+ config.a = 1
239
+ config.x.b = 2
240
+ keys = list(config)
241
+ sorted(keys)
242
+ self.assertEqual( keys, ['a'])
243
+ keys = list(config.keys())
244
+ sorted(keys)
245
+ self.assertEqual( keys, ['a'])
246
+
247
+ # test update
248
+
249
+ config = Config()
250
+ config.a = 1
251
+ config.x.a = 1
252
+ config.z.a =1
253
+
254
+ config2 = Config()
255
+ config2.b = 2
256
+ config2.x.a = 2
257
+ config2.x.b = 2
258
+ config2.y.b = 2
259
+ config2.z = 2
260
+ config.update( config2 )
261
+ ur1 = config.input_report()
262
+
263
+ econfig = Config()
264
+ econfig.a = 1
265
+ econfig.b = 2
266
+ econfig.x.a = 2
267
+ econfig.x.b = 2
268
+ econfig.y.b = 2
269
+ econfig.z = 2
270
+ ur2 = econfig.input_report()
271
+ self.assertEqual( ur1, ur2 )
272
+
273
+ config = Config()
274
+ config.a = 1
275
+ config.x.a = 1
276
+
277
+ d = dict(b=2,x=dict(a=2,b=2),y=dict(b=2),z=2)
278
+ config.update(d)
279
+ ur2 = econfig.input_report()
280
+ self.assertEqual( ur1, ur2 )
281
+
282
+ # test str and repr
283
+
284
+ config = Config()
285
+ config.x = 1
286
+ config.y = 2
287
+ config.sub.x = 10
288
+ config.sub.y = 20
289
+
290
+ self.assertEqual( str(config), "config{'x': 1, 'y': 2, 'sub': {'x': 10, 'y': 20}}")
291
+ self.assertEqual( repr(config), "Config( **{'x': 1, 'y': 2, 'sub': {'x': 10, 'y': 20}}, config_name='config' )")
292
+
293
+ # test recorded usage
294
+
295
+ config = Config()
296
+ config.x = 1
297
+ config.sub.a = 1
298
+ config.det.o = 1
299
+
300
+ _ = config("x", 11)
301
+ _ = config("y", 22)
302
+ _ = config.sub("a", 11)
303
+ _ = config.sub("b", 22)
304
+ det = config.det.detach() # shares the same recorder !
305
+ _ = det("o", 11)
306
+ _ = det("p", 22)
307
+
308
+ self.assertEqual( config.get_recorded("x"), 1)
309
+ self.assertEqual( config.get_recorded("y"), 22)
310
+ self.assertEqual( config.sub.get_recorded("a"), 1)
311
+ self.assertEqual( config.sub.get_recorded("b"), 22)
312
+ self.assertEqual( config.det.get_recorded("o"), 1)
313
+ self.assertEqual( config.det.get_recorded("p"), 22)
314
+
315
+ # unique ID
316
+
317
+ config = Config()
318
+ # world
319
+ config.world.samples = 10000
320
+ config.world.steps = 20
321
+ config.world.black_scholes = True
322
+ config.world.rvol = 0.2 # 20% volatility
323
+ config.world.drift = 0. # real life drift
324
+ config.world.cost_s = 0.
325
+ # gym
326
+ config.gym.objective.utility = "cvar"
327
+ config.gym.objective.lmbda = 1.
328
+ config.gym.agent.network.depth = 6
329
+ config.gym.agent.network.width = 40
330
+ config.gym.agent.network.activation = "softplus"
331
+ # trainer
332
+ config.trainer.train.optimizer = "adam"
333
+ config.trainer.train.batch_size = None
334
+ config.trainer.train.epochs = 400
335
+ config.trainer.caching.epoch_freq = 10
336
+ config.trainer.caching.mode = "on"
337
+ config.trainer.visual.epoch_refresh = 1
338
+ config.trainer.visual.time_refresh = 10
339
+ config.trainer.visual.confidence_pcnt_lo = 0.25
340
+ config.trainer.visual.confidence_pcnt_hi = 0.75
341
+
342
+ id1 = config.unique_hash()
343
+
344
+ config = Config()
345
+ # world
346
+ config.world.samples = 10000
347
+ config.world.steps = 20
348
+ config.world.black_scholes = True
349
+ config.world.rvol = 0.2 # 20% volatility
350
+ config.world.drift = 0. # real life drift
351
+ config.world.cost_s = 0.
352
+ # gym
353
+ config.gym.objective.utility = "cvar"
354
+ config.gym.objective.lmbda = 1.
355
+ config.gym.agent.network.depth = 5 # <====== changed this
356
+ config.gym.agent.network.width = 40
357
+ config.gym.agent.network.activation = "softplus"
358
+ # trainer
359
+ config.trainer.train.optimizer = "adam"
360
+ config.trainer.train.batch_size = None
361
+ config.trainer.train.epochs = 400
362
+ config.trainer.caching.epoch_freq = 10
363
+ config.trainer.caching.mode = "on"
364
+ config.trainer.visual.epoch_refresh = 1
365
+ config.trainer.visual.time_refresh = 10
366
+ config.trainer.visual.confidence_pcnt_lo = 0.25
367
+ config.trainer.visual.confidence_pcnt_hi = 0.75
368
+
369
+ id2 = config.unique_hash()
370
+ self.assertNotEqual(id1,id2)
371
+ self.assertEqual(id2,"cfef59b69770d0a973342ad68f38fba2")
372
+
373
+ _ = config.nothing("get_nothing", 0) # this triggered a new ID in old versions
374
+
375
+ id3 = config.unique_hash()
376
+ self.assertEqual(id2,id3)
377
+
378
+ idempty = Config().unique_hash()
379
+ self.assertEqual(idempty,"64550d6ffe2c0a01a14aba1eade0200c")
380
+ self.assertNotEqual(idempty,id3)
381
+
382
+ # pickle test
383
+
384
+ binary = pickle.dumps(config)
385
+ restored = pickle.loads(binary)
386
+ idrest = restored.unique_hash()
387
+ self.assertEqual(idrest,id2)
388
+
389
+ # unique ID test
390
+
391
+ config1 = Config()
392
+ config1.x = 1
393
+ config1.sub.y = 2
394
+ config2 = Config()
395
+ config2.x = 1
396
+ config2.sub.y = 3
397
+ self.assertNotEqual( unique_hash16(config1), unique_hash16(config2) )
398
+
399
+ config1 = Config()
400
+ config1.x = 1
401
+ config1.sub.y = 2
402
+ config2 = Config()
403
+ config2.x = 2
404
+ config2.sub.y = 2
405
+ self.assertNotEqual( unique_hash16(config1), unique_hash16(config2) )
406
+
407
+ config1 = Config()
408
+ config1.x = 1
409
+ config1.sub.y = 2
410
+ config2 = Config()
411
+ config2.x = 1
412
+ config2.sub.y = 2
413
+ self.assertEqual( unique_hash16(config1), unique_hash16(config2) )
414
+
415
+ # unique_hash16() ignores protected and private members
416
+ config1 = Config()
417
+ config1.x = 1
418
+ config1.sub._y = 2
419
+ config2 = Config()
420
+ config2.x = 1
421
+ config2.sub._y = 3
422
+ self.assertEqual( unique_hash16(config1), unique_hash16(config2) )
423
+
424
+ def test_detach(self):
425
+ """ testing detach/copy/clean_cooy """
426
+
427
+ config = Config(a=1,b=2)
428
+ config.child.x = 1
429
+ _ = config("a", 2)
430
+ c1 = config.detach()
431
+ with self.assertRaises(Exception):
432
+ _ = c1("a", 1) # different default
433
+ _ = c1("b", 3)
434
+ with self.assertRaises(Exception):
435
+ _ = config("b", 2) # different default
436
+
437
+ config = Config(a=1,b=2)
438
+ config.child.x = 1
439
+ _ = config("a", 2)
440
+ c1 = config.copy()
441
+ with self.assertRaises(Exception):
442
+ _ = c1("a", 1) # different default
443
+ _ = c1("b", 3)
444
+ _ = config("b", 2) # different default - ok
445
+
446
+ config = Config(a=1,b=2)
447
+ config.child.x = 1
448
+ _ = config("a", 2)
449
+ c1 = config.clean_copy()
450
+ _ = c1("a", 1) # different default - ok
451
+ _ = c1("b", 3)
452
+ _ = config("b", 2) # different default - ok
453
+
454
+ def test_dataclass(self):
455
+
456
+ @dataclasses.dataclass
457
+ class A:
458
+ i : int = 0
459
+ config : Config = Config().as_field()
460
+
461
+ def f(self):
462
+ return self.config("a", 1, int, "Test")
463
+
464
+ a = A()
465
+ self.assertEqual(a.f(),1)
466
+ c = Config()
467
+ a = A(i=2,config=Config(c))
468
+ self.assertEqual(a.f(),1)
469
+ c = Config(a=2)
470
+ a = A(i=2,config=Config(c))
471
+ self.assertEqual(a.f(),2)
472
+ a = A(i=2,config=Config(a=2))
473
+ self.assertEqual(a.f(),2)
474
+
475
+ def test_io(self):
476
+
477
+ config = Config(x=1)
478
+ config.child.y = 2
479
+ config._test = 33
480
+
481
+ try:
482
+ tmp_dir = tempfile.mkdtemp()
483
+ self.assertNotEqual(tmp_dir[-1],"/")
484
+ self.assertNotEqual(tmp_dir[-1],"\\")
485
+ tmp_file = tmp_dir + "/test_pretty_object.pck"
486
+
487
+ with open(tmp_file, "wb") as f:
488
+ pickle.dump(config,f)
489
+
490
+ with open(tmp_file, "rb") as f:
491
+ config2 = pickle.load(f)
492
+ self.assertEqual(config,config2)
493
+
494
+ os.remove(tmp_file)
495
+ finally:
496
+ shutil.rmtree(tmp_dir)
497
+
498
+
499
+ if __name__ == '__main__':
500
+ unittest.main()
501
+
502
+
tests/test_crman.py ADDED
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Tue Apr 14 21:24:52 2020
4
+ @author: hansb
5
+ """
6
+
7
+ import unittest as unittest
8
+
9
+ def import_local():
10
+ """
11
+ In order to be able to run our tests manually from the 'tests' directory
12
+ we force import from the local package.
13
+ We also force reloading all modules to make sure we are not running old code.
14
+ """
15
+ me = "cdxcore"
16
+ import os
17
+ import sys
18
+ cwd = os.getcwd()
19
+ if cwd[-len(me):] == me:
20
+ return
21
+ assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
22
+ assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
23
+ sys.path.insert( 0, cwd[:-6] )
24
+
25
+ # reload modules
26
+ import importlib as imp
27
+ modules = sys.modules.copy()
28
+ for name, mdata in modules.items():
29
+ if name[:len(me)] == me:
30
+ imp.reload(mdata)
31
+ print("Reloaded", name)
32
+ import_local()
33
+
34
+ from cdxcore.crman import CRMan
35
+
36
+ class Test(unittest.TestCase):
37
+
38
+ def test_crman(self):
39
+
40
+ crman = CRMan()
41
+ self.assertEqual( crman("test"), "test" )
42
+ self.assertEqual( crman("test"), "\r \r\x1b[2K\rtesttest" )
43
+ self.assertEqual( crman("\rxxxx"), "\r \r\x1b[2K\rxxxx" )
44
+ self.assertEqual( crman("yyyy\n"), "\r \r\x1b[2K\rxxxxyyyy\n" )
45
+ self.assertEqual( crman("ab\rcde\nxyz\r01\nt"), "cde\n01\nt" )
46
+
47
+ self.assertEqual( crman.current, "t" )
48
+ crman.reset()
49
+ self.assertEqual( crman.current, "" )
50
+
51
+ if __name__ == '__main__':
52
+ unittest.main()
53
+
54
+
tests/test_err.py ADDED
@@ -0,0 +1,86 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on Tue Apr 14 21:24:52 2020
4
+ @author: hansb
5
+ """
6
+
7
+ import unittest as unittest
8
+ import warnings as warnings
9
+
10
+ def import_local():
11
+ """
12
+ In order to be able to run our tests manually from the 'tests' directory
13
+ we force import from the local package.
14
+ We also force reloading all modules to make sure we are not running old code.
15
+ """
16
+ me = "cdxcore"
17
+ import os
18
+ import sys
19
+ cwd = os.getcwd()
20
+ if cwd[-len(me):] == me:
21
+ return
22
+ assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
23
+ assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
24
+ sys.path.insert( 0, cwd[:-6] )
25
+
26
+ # reload modules
27
+ import importlib as imp
28
+ modules = sys.modules.copy()
29
+ for name, mdata in modules.items():
30
+ if name[:len(me)] == me:
31
+ imp.reload(mdata)
32
+ print("Reloaded", name)
33
+ import_local()
34
+
35
+ from cdxcore.err import fmt, error, verify, warn, warn_if
36
+
37
+ class Test(unittest.TestCase):
38
+
39
+ def test_fmt(self):
40
+
41
+ self.assertEqual(fmt("number %d %d",1,2),"number 1 2")
42
+ self.assertEqual(fmt("number %(two)d %(one)d",one=1,two=2),"number 2 1")
43
+ self.assertEqual(fmt("number {two:d} {one:d}",one=1,two=2),"number 2 1")
44
+ self.assertEqual(fmt("number {two:s} {one:d}",one=1,two="II"),"number II 1")
45
+ with self.assertRaises(KeyError):
46
+ fmt("one {two/2:d} also one {one:d}",one=1,two=2)
47
+ one_ = 1
48
+ two_ = 2
49
+ self.assertEqual(fmt(lambda : f"one {one_} also one {two_//2}"),"one 1 also one 1")
50
+ self.assertEqual(fmt(lambda one, two: f"one {one} also one {two//2}", one=1, two=2),"one 1 also one 1")
51
+
52
+ with self.assertRaises(KeyError):
53
+ fmt("number %(two)d %(one)d",one=1)
54
+ with self.assertRaises(TypeError):
55
+ fmt("number %d %d",1)
56
+ with self.assertRaises(TypeError):
57
+ fmt("number %d %d",1,2,3)
58
+ with self.assertRaises(TypeError):
59
+ fmt("number $(one)d",1)
60
+ with self.assertRaises(ValueError):
61
+ fmt("number %d %(one)d",2,one=1)
62
+
63
+ with self.assertRaises(ValueError):
64
+ error("one {one} two {two}", one=1, two=2, exception=ValueError)
65
+ with self.assertRaises(TypeError):
66
+ error("one {one} two {two}", one=1, two=2, exception=TypeError)
67
+ with self.assertRaises(TypeError):
68
+ verify(False,"one {one} two {two}", one=1, two=2, exception=TypeError)
69
+ verify(True,"one {one} two {two}", one=1, two=2, exception=TypeError)
70
+
71
+ with warnings.catch_warnings():
72
+ warnings.filterwarnings("error", category=UserWarning)
73
+ warnings.filterwarnings("error", category=RuntimeWarning)
74
+
75
+ with self.assertRaises(UserWarning):
76
+ warn("one {one} two {two}", one=1, two=2, warning=UserWarning)
77
+ with self.assertRaises(RuntimeWarning):
78
+ warn("one {one} two {two}", one=1, two=2, warning=RuntimeWarning)
79
+ with self.assertRaises(RuntimeWarning):
80
+ warn_if(True,"one {one} two {two}", one=1, two=2, warning=RuntimeWarning)
81
+ warn_if(False,"one {one} two {two}", one=1, two=2, warning=RuntimeWarning)
82
+
83
+ if __name__ == '__main__':
84
+ unittest.main()
85
+
86
+