encommon 0.13.1__py3-none-any.whl → 0.15.0__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.
Files changed (63) hide show
  1. encommon/__init__.py +2 -7
  2. encommon/colors/__init__.py +14 -0
  3. encommon/colors/color.py +518 -0
  4. encommon/colors/test/__init__.py +6 -0
  5. encommon/colors/test/test_color.py +189 -0
  6. encommon/config/config.py +83 -30
  7. encommon/config/files.py +16 -13
  8. encommon/config/logger.py +10 -5
  9. encommon/config/params.py +47 -31
  10. encommon/config/paths.py +15 -12
  11. encommon/config/test/__init__.py +1 -1
  12. encommon/config/test/test_config.py +15 -17
  13. encommon/config/test/test_files.py +8 -7
  14. encommon/config/test/test_logger.py +21 -15
  15. encommon/config/test/test_paths.py +12 -11
  16. encommon/config/utils.py +9 -3
  17. encommon/conftest.py +33 -22
  18. encommon/crypts/params.py +46 -11
  19. encommon/crypts/test/test_crypts.py +5 -5
  20. encommon/crypts/test/test_hashes.py +2 -1
  21. encommon/times/__init__.py +5 -3
  22. encommon/times/common.py +4 -3
  23. encommon/times/params.py +103 -45
  24. encommon/times/parse.py +39 -12
  25. encommon/times/test/test_duration.py +3 -2
  26. encommon/times/test/test_parse.py +16 -9
  27. encommon/times/test/test_time.py +123 -0
  28. encommon/times/test/test_timer.py +5 -4
  29. encommon/times/test/test_timers.py +10 -9
  30. encommon/times/test/test_unitime.py +23 -0
  31. encommon/times/test/test_window.py +4 -3
  32. encommon/times/test/test_windows.py +7 -6
  33. encommon/times/{times.py → time.py} +129 -22
  34. encommon/times/timer.py +10 -10
  35. encommon/times/timers.py +3 -3
  36. encommon/times/unitime.py +57 -0
  37. encommon/times/window.py +31 -31
  38. encommon/times/windows.py +10 -10
  39. encommon/types/__init__.py +20 -2
  40. encommon/types/classes.py +84 -0
  41. encommon/types/lists.py +33 -0
  42. encommon/types/notate.py +2 -1
  43. encommon/types/strings.py +34 -4
  44. encommon/types/test/test_classes.py +74 -0
  45. encommon/types/test/test_empty.py +2 -1
  46. encommon/types/test/test_lists.py +23 -0
  47. encommon/types/test/test_strings.py +15 -3
  48. encommon/types/types.py +20 -0
  49. encommon/utils/__init__.py +4 -0
  50. encommon/utils/paths.py +5 -6
  51. encommon/utils/sample.py +118 -41
  52. encommon/utils/stdout.py +53 -7
  53. encommon/utils/test/test_paths.py +3 -3
  54. encommon/utils/test/test_sample.py +128 -29
  55. encommon/utils/test/test_stdout.py +92 -28
  56. encommon/version.txt +1 -1
  57. {encommon-0.13.1.dist-info → encommon-0.15.0.dist-info}/METADATA +1 -1
  58. encommon-0.15.0.dist-info/RECORD +84 -0
  59. {encommon-0.13.1.dist-info → encommon-0.15.0.dist-info}/WHEEL +1 -1
  60. encommon/times/test/test_times.py +0 -89
  61. encommon-0.13.1.dist-info/RECORD +0 -73
  62. {encommon-0.13.1.dist-info → encommon-0.15.0.dist-info}/LICENSE +0 -0
  63. {encommon-0.13.1.dist-info → encommon-0.15.0.dist-info}/top_level.txt +0 -0
@@ -13,12 +13,13 @@ from typing import TYPE_CHECKING
13
13
  from pytest import fixture
14
14
  from pytest import mark
15
15
 
16
- from ..times import Times
16
+ from ..time import Time
17
17
  from ..window import Window
18
18
  from ..window import window_croniter
19
19
  from ..window import window_interval
20
20
  from ...types import inrepr
21
21
  from ...types import instr
22
+ from ...types import lattrs
22
23
 
23
24
  if TYPE_CHECKING:
24
25
  from ..common import PARSABLE
@@ -51,7 +52,7 @@ def test_Window(
51
52
  """
52
53
 
53
54
 
54
- attrs = list(window.__dict__)
55
+ attrs = lattrs(window)
55
56
 
56
57
  assert attrs == [
57
58
  '_Window__window',
@@ -169,7 +170,7 @@ def test_Window_cover(
169
170
  assert window.walked
170
171
 
171
172
 
172
- anchor = Times('-0s@s')
173
+ anchor = Time('-0s@s')
173
174
 
174
175
 
175
176
  window = Window(
@@ -9,7 +9,6 @@ is permitted, for more information consult the project license file.
9
9
 
10
10
  from pathlib import Path
11
11
  from time import sleep
12
- from typing import Any
13
12
 
14
13
  from pytest import fixture
15
14
  from pytest import raises
@@ -18,8 +17,10 @@ from ..params import WindowParams
18
17
  from ..params import WindowsParams
19
18
  from ..windows import Windows
20
19
  from ..windows import WindowsTable
20
+ from ...types import DictStrAny
21
21
  from ...types import inrepr
22
22
  from ...types import instr
23
+ from ...types import lattrs
23
24
 
24
25
 
25
26
 
@@ -35,7 +36,7 @@ def windows(
35
36
  """
36
37
 
37
38
 
38
- source: dict[str, Any] = {
39
+ source: DictStrAny = {
39
40
  'one': WindowParams(
40
41
  window='* * * * *',
41
42
  start=310,
@@ -104,7 +105,7 @@ def test_Windows(
104
105
  """
105
106
 
106
107
 
107
- attrs = list(windows.__dict__)
108
+ attrs = lattrs(windows)
108
109
 
109
110
  assert attrs == [
110
111
  '_Windows__params',
@@ -128,15 +129,15 @@ def test_Windows(
128
129
  windows)
129
130
 
130
131
 
131
- assert windows.params is not None
132
+ assert windows.params
132
133
 
133
134
  assert windows.store[:6] == 'sqlite'
134
135
 
135
136
  assert windows.group == 'default'
136
137
 
137
- assert windows.store_engine is not None
138
+ assert windows.store_engine
138
139
 
139
- assert windows.store_session is not None
140
+ assert windows.store_session
140
141
 
141
142
  assert windows.start == (
142
143
  '1970-01-01T00:05:10Z')
@@ -9,6 +9,7 @@ is permitted, for more information consult the project license file.
9
9
 
10
10
  from contextlib import suppress
11
11
  from datetime import datetime
12
+ from datetime import time as dtime
12
13
  from datetime import timedelta
13
14
  from typing import Optional
14
15
 
@@ -23,14 +24,63 @@ from .utils import strftime
23
24
 
24
25
 
25
26
 
26
- class Times:
27
+ class Time:
27
28
  """
28
29
  Interact with various time functions through one wrapper.
29
30
 
31
+ .. testsetup::
32
+ >>> time = Time('1/1/2000 12:00am')
33
+
34
+ Example
35
+ -------
36
+ >>> time = Time('1/1/2000 12:00am')
37
+ >>> time.stamp()
38
+ '2000-01-01T00:00:00.000000+0000'
39
+ >>> time.stamp('%m/%d/%Y')
40
+ '01/01/2000'
41
+
42
+ Example
43
+ -------
44
+ >>> time.epoch
45
+ 946684800.0
46
+ >>> time.time
47
+ datetime.time(0, 0)
48
+ >>> time.simple
49
+ '2000-01-01T00:00:00+0000'
50
+ >>> time.human
51
+ '01/01/2000 12:00AM UTC'
52
+
53
+ Example
54
+ -------
55
+ >>> time.before
56
+ Time('1999-12-31T23:59:59.999999+0000')
57
+ >>> time.after
58
+ Time('2000-01-01T00:00:00.000001+0000')
59
+
60
+ Example
61
+ -------
62
+ >>> time.shift('-1d')
63
+ Time('1999-12-31T00:00:00.000000+0000')
64
+
65
+ Example
66
+ -------
67
+ >>> time.shifz('US/Central')
68
+ Time('1999-12-31T18:00:00.000000-0600')
69
+
70
+ Example
71
+ -------
72
+ >>> time = Time('-1s')
73
+ >>> int(time.since)
74
+ 1
75
+
30
76
  Example
31
77
  -------
32
- >>> Times('1/1/2000 12:00am')
33
- Times('2000-01-01T00:00:00.000000+0000')
78
+ >>> time1 = Time('1/1/2000 12:00am')
79
+ >>> time2 = Time('1/1/2000 12:00am')
80
+ >>> time1 - time2
81
+ 0.0
82
+ >>> time1 + time2
83
+ 1893369600.0
34
84
 
35
85
  :param source: Time in various forms that will be parsed.
36
86
  :param anchor: Optional relative time; for snap notation.
@@ -40,7 +90,6 @@ class Times:
40
90
  """
41
91
 
42
92
  __source: datetime
43
- __hashed: int
44
93
 
45
94
 
46
95
  def __init__(
@@ -62,8 +111,6 @@ class Times:
62
111
  tzname=tzname)
63
112
 
64
113
  self.__source = parsed
65
- self.__hashed = int(
66
- self.mpoch * 1000)
67
114
 
68
115
 
69
116
  def __repr__(
@@ -75,7 +122,7 @@ class Times:
75
122
  :returns: String representation for values from instance.
76
123
  """
77
124
 
78
- return f"Times('{self.subsec}')"
125
+ return f"Time('{self.subsec}')"
79
126
 
80
127
 
81
128
  def __hash__(
@@ -87,7 +134,9 @@ class Times:
87
134
  :returns: Boolean indicating outcome from the operation.
88
135
  """
89
136
 
90
- return int(1e9 + self.__hashed)
137
+ hashed = int(self.mpoch)
138
+
139
+ return int(1e9 + hashed)
91
140
 
92
141
 
93
142
  def __str__(
@@ -291,6 +340,19 @@ class Times:
291
340
  return source.timestamp()
292
341
 
293
342
 
343
+ @property
344
+ def spoch(
345
+ self,
346
+ ) -> int:
347
+ """
348
+ Return the seconds since the Unix epoch for the instance.
349
+
350
+ :returns: Seconds since the Unix epoch for the instance.
351
+ """
352
+
353
+ return int(self.epoch)
354
+
355
+
294
356
  @property
295
357
  def mpoch(
296
358
  self,
@@ -304,14 +366,27 @@ class Times:
304
366
  return self.epoch * 1000
305
367
 
306
368
 
369
+ @property
370
+ def time(
371
+ self,
372
+ ) -> dtime:
373
+ """
374
+ Return the value for the attribute from class instance.
375
+
376
+ :returns: Value for the attribute from class instance.
377
+ """
378
+
379
+ return self.__source.time()
380
+
381
+
307
382
  @property
308
383
  def simple(
309
384
  self,
310
385
  ) -> str:
311
386
  """
312
- Return the timestamp using provided format for instance.
387
+ Return the value for the attribute from class instance.
313
388
 
314
- :returns: Timestamp using provided format for instance.
389
+ :returns: Value for the attribute from class instance.
315
390
  """
316
391
 
317
392
  return self.stamp(STAMP_SIMPLE)
@@ -322,9 +397,9 @@ class Times:
322
397
  self,
323
398
  ) -> str:
324
399
  """
325
- Return the timestamp using provided format for instance.
400
+ Return the value for the attribute from class instance.
326
401
 
327
- :returns: Timestamp using provided format for instance.
402
+ :returns: Value for the attribute from class instance.
328
403
  """
329
404
 
330
405
  return self.stamp(STAMP_SUBSEC)
@@ -335,9 +410,9 @@ class Times:
335
410
  self,
336
411
  ) -> str:
337
412
  """
338
- Return the timestamp using provided format for instance.
413
+ Return the value for the attribute from class instance.
339
414
 
340
- :returns: Timestamp using provided format for instance.
415
+ :returns: Value for the attribute from class instance.
341
416
  """
342
417
 
343
418
  return self.stamp(STAMP_HUMAN)
@@ -372,7 +447,7 @@ class Times:
372
447
  @property
373
448
  def before(
374
449
  self,
375
- ) -> 'Times':
450
+ ) -> 'Time':
376
451
  """
377
452
  Return new object containing time just before the time.
378
453
 
@@ -384,13 +459,13 @@ class Times:
384
459
  source -= timedelta(
385
460
  microseconds=1)
386
461
 
387
- return Times(source)
462
+ return Time(source)
388
463
 
389
464
 
390
465
  @property
391
466
  def after(
392
467
  self,
393
- ) -> 'Times':
468
+ ) -> 'Time':
394
469
  """
395
470
  Return new object containing time just after the time.
396
471
 
@@ -402,7 +477,7 @@ class Times:
402
477
  source += timedelta(
403
478
  microseconds=1)
404
479
 
405
- return Times(source)
480
+ return Time(source)
406
481
 
407
482
 
408
483
  def stamp(
@@ -423,15 +498,20 @@ class Times:
423
498
 
424
499
  tzinfo = findtz(tzname)
425
500
 
426
- parsed = source.astimezone(tzinfo)
501
+ if tzname is not None:
427
502
 
428
- return strftime(parsed, format)
503
+ source = (
504
+ source
505
+ .astimezone(tzinfo))
506
+
507
+ return strftime(
508
+ source, format)
429
509
 
430
510
 
431
511
  def shift(
432
512
  self,
433
513
  notate: str,
434
- ) -> 'Times':
514
+ ) -> 'Time':
435
515
  """
436
516
  Return the new instance of object shifted using snaptime.
437
517
 
@@ -441,4 +521,31 @@ class Times:
441
521
 
442
522
  source = self.__source
443
523
 
444
- return Times(notate, anchor=source)
524
+ return Time(
525
+ notate, anchor=source)
526
+
527
+
528
+ def shifz(
529
+ self,
530
+ tzname: str,
531
+ ) -> 'Time':
532
+ """
533
+ Return the new instance of object shifted using datetime.
534
+
535
+ :param tzname: Name of the timezone associated to source.
536
+ This is not relevant in timezone included in source.
537
+ :returns: New instance of the class using shifted time.
538
+ """
539
+
540
+ source = self.__source
541
+
542
+ tzinfo = findtz(tzname)
543
+
544
+ if tzname is not None:
545
+
546
+ source = (
547
+ source
548
+ .astimezone(tzinfo))
549
+
550
+ return Time(
551
+ source, tzname=tzname)
encommon/times/timer.py CHANGED
@@ -11,7 +11,7 @@ from typing import Optional
11
11
 
12
12
  from .common import NUMERIC
13
13
  from .common import PARSABLE
14
- from .times import Times
14
+ from .time import Time
15
15
 
16
16
 
17
17
 
@@ -36,7 +36,7 @@ class Timer:
36
36
  """
37
37
 
38
38
  __timer: float
39
- __times: Times
39
+ __time: Time
40
40
 
41
41
 
42
42
  def __init__(
@@ -50,10 +50,10 @@ class Timer:
50
50
  """
51
51
 
52
52
  timer = float(timer)
53
- start = Times(start)
53
+ start = Time(start)
54
54
 
55
55
  self.__timer = timer
56
- self.__times = start
56
+ self.__time = start
57
57
 
58
58
 
59
59
  @property
@@ -70,16 +70,16 @@ class Timer:
70
70
 
71
71
 
72
72
  @property
73
- def times(
73
+ def time(
74
74
  self,
75
- ) -> Times:
75
+ ) -> Time:
76
76
  """
77
77
  Return the value for the attribute from class instance.
78
78
 
79
79
  :returns: Value for the attribute from class instance.
80
80
  """
81
81
 
82
- return self.__times
82
+ return self.__time
83
83
 
84
84
 
85
85
  @property
@@ -92,7 +92,7 @@ class Timer:
92
92
  :returns: Seconds that have elapsed since the interval.
93
93
  """
94
94
 
95
- return self.times.since
95
+ return self.time.since
96
96
 
97
97
 
98
98
  @property
@@ -141,7 +141,7 @@ class Timer:
141
141
  :param value: Override the time updated for timer value.
142
142
  """
143
143
 
144
- value = Times(
144
+ value = Time(
145
145
  value or 'now')
146
146
 
147
- self.__times = value
147
+ self.__time = value
encommon/times/timers.py CHANGED
@@ -21,8 +21,8 @@ from sqlalchemy.orm import sessionmaker
21
21
 
22
22
  from .common import PARSABLE
23
23
  from .params import TimersParams
24
+ from .time import Time
24
25
  from .timer import Timer
25
- from .times import Times
26
26
 
27
27
  if TYPE_CHECKING:
28
28
  from .params import TimerParams
@@ -322,12 +322,12 @@ class Timers:
322
322
 
323
323
  for unique, timer in items:
324
324
 
325
- update = Times('now')
325
+ update = Time('now')
326
326
 
327
327
  append = TimersTable(
328
328
  group=group,
329
329
  unique=unique,
330
- last=timer.times.subsec,
330
+ last=timer.time.subsec,
331
331
  update=update.subsec)
332
332
 
333
333
  session.merge(append)
@@ -0,0 +1,57 @@
1
+ """
2
+ Functions and routines associated with Enasis Network Common Library.
3
+
4
+ This file is part of Enasis Network software eco-system. Distribution
5
+ is permitted, for more information consult the project license file.
6
+ """
7
+
8
+
9
+
10
+ from re import match as re_match
11
+
12
+ from .parse import since_time
13
+
14
+
15
+
16
+ def unitime(
17
+ input: int | float | str,
18
+ ) -> int:
19
+ """
20
+ Return the seconds in integer format for provided input.
21
+
22
+ Example
23
+ -------
24
+ >>> unitime('1d')
25
+ 86400
26
+ >>> unitime('1y')
27
+ 31536000
28
+ >>> unitime('1w3d4h')
29
+ 878400
30
+
31
+ :param input: Input that will be converted into seconds.
32
+ :returns: Seconds in integer format for provided input.
33
+ """
34
+
35
+ notate = r'^(\d+(s|m|h|d|w|y))*$'
36
+ strint = r'^\d+$'
37
+ strflt = r'^\d+\.\d+$'
38
+
39
+ if isinstance(input, str):
40
+
41
+ if re_match(notate, input):
42
+ input = since_time(
43
+ 'now', f'+{input}')
44
+
45
+ elif re_match(strint, input):
46
+ input = int(input)
47
+
48
+ elif re_match(strflt, input):
49
+ input = int(
50
+ input.split('.')[0])
51
+
52
+ if isinstance(input, float):
53
+ input = int(input)
54
+
55
+ assert isinstance(input, int)
56
+
57
+ return input
encommon/times/window.py CHANGED
@@ -17,7 +17,7 @@ from croniter import croniter
17
17
  from .common import PARSABLE
18
18
  from .common import SCHEDULE
19
19
  from .parse import parse_time
20
- from .times import Times
20
+ from .time import Time
21
21
 
22
22
 
23
23
 
@@ -42,13 +42,13 @@ class Window:
42
42
  """
43
43
 
44
44
  __window: SCHEDULE
45
- __start: Times
46
- __stop: Times
47
- __anchor: Times
45
+ __start: Time
46
+ __stop: Time
47
+ __anchor: Time
48
48
  __delay: float
49
49
 
50
- __wlast: Times
51
- __wnext: Times
50
+ __wlast: Time
51
+ __wnext: Time
52
52
 
53
53
 
54
54
  def __init__(
@@ -67,9 +67,9 @@ class Window:
67
67
  anchor = anchor or start
68
68
 
69
69
  window = copy(window)
70
- start = Times(start)
71
- stop = Times(stop)
72
- anchor = Times(anchor)
70
+ start = Time(start)
71
+ stop = Time(stop)
72
+ anchor = Time(anchor)
73
73
  delay = float(delay)
74
74
 
75
75
  assert stop > start
@@ -114,40 +114,40 @@ class Window:
114
114
  @property
115
115
  def start(
116
116
  self,
117
- ) -> Times:
117
+ ) -> Time:
118
118
  """
119
119
  Return the value for the attribute from class instance.
120
120
 
121
121
  :returns: Value for the attribute from class instance.
122
122
  """
123
123
 
124
- return Times(self.__start)
124
+ return Time(self.__start)
125
125
 
126
126
 
127
127
  @property
128
128
  def stop(
129
129
  self,
130
- ) -> Times:
130
+ ) -> Time:
131
131
  """
132
132
  Return the value for the attribute from class instance.
133
133
 
134
134
  :returns: Value for the attribute from class instance.
135
135
  """
136
136
 
137
- return Times(self.__stop)
137
+ return Time(self.__stop)
138
138
 
139
139
 
140
140
  @property
141
141
  def anchor(
142
142
  self,
143
- ) -> Times:
143
+ ) -> Time:
144
144
  """
145
145
  Return the value for the attribute from class instance.
146
146
 
147
147
  :returns: Value for the attribute from class instance.
148
148
  """
149
149
 
150
- return Times(self.__anchor)
150
+ return Time(self.__anchor)
151
151
 
152
152
 
153
153
  @property
@@ -166,51 +166,51 @@ class Window:
166
166
  @property
167
167
  def last(
168
168
  self,
169
- ) -> Times:
169
+ ) -> Time:
170
170
  """
171
171
  Return the value for the attribute from class instance.
172
172
 
173
173
  :returns: Value for the attribute from class instance.
174
174
  """
175
175
 
176
- return Times(self.__wlast)
176
+ return Time(self.__wlast)
177
177
 
178
178
 
179
179
  @property
180
180
  def next(
181
181
  self,
182
- ) -> Times:
182
+ ) -> Time:
183
183
  """
184
184
  Return the value for the attribute from class instance.
185
185
 
186
186
  :returns: Value for the attribute from class instance.
187
187
  """
188
188
 
189
- return Times(self.__wnext)
189
+ return Time(self.__wnext)
190
190
 
191
191
 
192
192
  @property
193
193
  def soonest(
194
194
  self,
195
- ) -> Times:
195
+ ) -> Time:
196
196
  """
197
197
  Return the value for the attribute from class instance.
198
198
 
199
199
  :returns: Value for the attribute from class instance.
200
200
  """
201
- return Times(Times() - self.delay)
201
+ return Time(Time() - self.delay)
202
202
 
203
203
 
204
204
  @property
205
205
  def latest(
206
206
  self,
207
- ) -> Times:
207
+ ) -> Time:
208
208
  """
209
209
  Return the value for the attribute from class instance.
210
210
 
211
211
  :returns: Value for the attribute from class instance.
212
212
  """
213
- return Times(self.stop - self.delay)
213
+ return Time(self.stop - self.delay)
214
214
 
215
215
 
216
216
  @property
@@ -230,7 +230,7 @@ class Window:
230
230
  self,
231
231
  anchor: PARSABLE,
232
232
  backward: bool = False,
233
- ) -> tuple[Times, Times]:
233
+ ) -> tuple[Time, Time]:
234
234
  """
235
235
  Determine next and last windows for window using anchor.
236
236
 
@@ -299,7 +299,7 @@ class Window:
299
299
  :param value: Override the time updated for window value.
300
300
  """
301
301
 
302
- value = Times(
302
+ value = Time(
303
303
  value or 'now')
304
304
 
305
305
  wlast, wnext = (
@@ -314,7 +314,7 @@ def window_croniter( # noqa: CFQ004
314
314
  schedule: str,
315
315
  anchor: PARSABLE,
316
316
  backward: bool = False,
317
- ) -> tuple[Times, Times]:
317
+ ) -> tuple[Time, Time]:
318
318
  """
319
319
  Determine next and previous times for cronjob schedule.
320
320
 
@@ -365,8 +365,8 @@ def window_croniter( # noqa: CFQ004
365
365
 
366
366
 
367
367
  return (
368
- Times(wlast),
369
- Times(wnext))
368
+ Time(wlast),
369
+ Time(wnext))
370
370
 
371
371
 
372
372
 
@@ -374,7 +374,7 @@ def window_interval(
374
374
  schedule: dict[str, int],
375
375
  anchor: PARSABLE,
376
376
  backward: bool = False,
377
- ) -> tuple[Times, Times]:
377
+ ) -> tuple[Time, Time]:
378
378
  """
379
379
  Determine next and previous times for interval schedule.
380
380
 
@@ -403,5 +403,5 @@ def window_interval(
403
403
 
404
404
 
405
405
  return (
406
- Times(wlast),
407
- Times(wnext))
406
+ Time(wlast),
407
+ Time(wnext))