TSVZ 3.10__tar.gz → 3.12__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: TSVZ
3
- Version: 3.10
3
+ Version: 3.12
4
4
  Summary: An simple in memory wrapper around a TSV file to function as a database
5
5
  Home-page: https://github.com/yufei-pan/TSVZ
6
6
  Author: Yufei Pan
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: TSVZ
3
- Version: 3.10
3
+ Version: 3.12
4
4
  Summary: An simple in memory wrapper around a TSV file to function as a database
5
5
  Home-page: https://github.com/yufei-pan/TSVZ
6
6
  Author: Yufei Pan
@@ -1,4 +1,9 @@
1
1
  #!/usr/bin/env python3
2
+ # /// script
3
+ # requires-python = ">=3.6"
4
+ # dependencies = [
5
+ # ]
6
+ # ///
2
7
  import os , sys
3
8
  from collections import OrderedDict , deque
4
9
  import time
@@ -6,12 +11,19 @@ import atexit
6
11
  import threading
7
12
  import re
8
13
 
14
+ RESOURCE_LIB_AVAILABLE = True
15
+ try:
16
+ import resource
17
+ except:
18
+ RESOURCE_LIB_AVAILABLE = False
19
+
9
20
  if os.name == 'nt':
10
21
  import msvcrt
11
22
  elif os.name == 'posix':
12
23
  import fcntl
13
24
 
14
- version = '3.10'
25
+ version = '3.12'
26
+ __version__ = version
15
27
  author = 'pan@zopyr.us'
16
28
 
17
29
  DEFAULT_DELIMITER = '\t'
@@ -90,6 +102,125 @@ def pretty_format_table(data, delimiter = DEFAULT_DELIMITER):
90
102
  outTable.append(row_format.format(*row))
91
103
  return '\n'.join(outTable) + '\n'
92
104
 
105
+ def format_bytes(size, use_1024_bytes=None, to_int=False, to_str=False,str_format='.2f'):
106
+ """
107
+ Format the size in bytes to a human-readable format or vice versa.
108
+
109
+ Args:
110
+ size (int or str): The size in bytes or a string representation of the size.
111
+ use_1024_bytes (bool, optional): Whether to use 1024 bytes as the base for conversion. If None, it will be determined automatically. Default is None.
112
+ to_int (bool, optional): Whether to convert the size to an integer. Default is False.
113
+ to_str (bool, optional): Whether to convert the size to a string representation. Default is False.
114
+ str_format (str, optional): The format string to use when converting the size to a string. Default is '.2f'.
115
+
116
+ Returns:
117
+ int or str: The formatted size based on the provided arguments.
118
+
119
+ Examples:
120
+ >>> format_bytes(1500)
121
+ '1.50 KB'
122
+ >>> format_bytes('1.5 GiB', to_int=True)
123
+ 1610612736
124
+ """
125
+ if to_int or isinstance(size, str):
126
+ if isinstance(size, int):
127
+ return size
128
+ elif isinstance(size, str):
129
+ # Use regular expression to split the numeric part from the unit, handling optional whitespace
130
+ match = re.match(r"(\d+(\.\d+)?)\s*([a-zA-Z]*)", size)
131
+ if not match:
132
+ print("Invalid size format. Expected format: 'number [unit]', e.g., '1.5 GiB' or '1.5GiB'")
133
+ print(f"Got: {size}")
134
+ return 0
135
+ number, _, unit = match.groups()
136
+ number = float(number)
137
+ unit = unit.strip().lower().rstrip('b')
138
+ # Define the unit conversion dictionary
139
+ if unit.endswith('i'):
140
+ # this means we treat the unit as 1024 bytes if it ends with 'i'
141
+ use_1024_bytes = True
142
+ elif use_1024_bytes is None:
143
+ use_1024_bytes = False
144
+ unit = unit.rstrip('i')
145
+ if use_1024_bytes:
146
+ power = 2**10
147
+ else:
148
+ power = 10**3
149
+ unit_labels = {'': 0, 'k': 1, 'm': 2, 'g': 3, 't': 4, 'p': 5}
150
+ if unit not in unit_labels:
151
+ print(f"Invalid unit '{unit}'. Expected one of {list(unit_labels.keys())}")
152
+ return 0
153
+ # Calculate the bytes
154
+ return int(number * (power ** unit_labels[unit]))
155
+ else:
156
+ try:
157
+ return int(size)
158
+ except Exception as e:
159
+ return 0
160
+ elif to_str or isinstance(size, int) or isinstance(size, float):
161
+ if isinstance(size, str):
162
+ try:
163
+ size = size.lower().strip().rstrip('b')
164
+ size = float(size)
165
+ except Exception as e:
166
+ return size
167
+ # size is in bytes
168
+ if use_1024_bytes or use_1024_bytes is None:
169
+ power = 2**10
170
+ n = 0
171
+ power_labels = {0 : '', 1: 'Ki', 2: 'Mi', 3: 'Gi', 4: 'Ti', 5: 'Pi'}
172
+ while size > power:
173
+ size /= power
174
+ n += 1
175
+ return f"{size:{str_format}} {power_labels[n]}"
176
+ else:
177
+ power = 10**3
178
+ n = 0
179
+ power_labels = {0 : '', 1: 'K', 2: 'M', 3: 'G', 4: 'T', 5: 'P'}
180
+ while size > power:
181
+ size /= power
182
+ n += 1
183
+ return f"{size:{str_format}} {power_labels[n]}"
184
+ else:
185
+ try:
186
+ return format_bytes(float(size), use_1024_bytes)
187
+ except Exception as e:
188
+ import traceback
189
+ print(f"Error: {e}")
190
+ print(traceback.format_exc())
191
+ print(f"Invalid size: {size}")
192
+ return 0
193
+
194
+ def get_resource_usage(return_dict = False):
195
+ try:
196
+ if RESOURCE_LIB_AVAILABLE:
197
+ rawResource = resource.getrusage(resource.RUSAGE_SELF)
198
+ resourceDict = {}
199
+ resourceDict['user mode time'] = f'{rawResource.ru_utime} seconds'
200
+ resourceDict['system mode time'] = f'{rawResource.ru_stime} seconds'
201
+ resourceDict['max resident set size'] = f'{format_bytes(rawResource.ru_maxrss * 1024)}B'
202
+ resourceDict['shared memory size'] = f'{format_bytes(rawResource.ru_ixrss * 1024)}B'
203
+ resourceDict['unshared memory size'] = f'{format_bytes(rawResource.ru_idrss * 1024)}B'
204
+ resourceDict['unshared stack size'] = f'{format_bytes(rawResource.ru_isrss * 1024)}B'
205
+ resourceDict['cached page hits'] = f'{rawResource.ru_minflt}'
206
+ resourceDict['missed page hits'] = f'{rawResource.ru_majflt}'
207
+ resourceDict['swapped out page count'] = f'{rawResource.ru_nswap}'
208
+ resourceDict['block input operations'] = f'{rawResource.ru_inblock}'
209
+ resourceDict['block output operations'] = f'{rawResource.ru_oublock}'
210
+ resourceDict['IPC messages sent'] = f'{rawResource.ru_msgsnd}'
211
+ resourceDict['IPC messages received'] = f'{rawResource.ru_msgrcv}'
212
+ resourceDict['signals received'] = f'{rawResource.ru_nsignals}'
213
+ resourceDict['voluntary context sw'] = f'{rawResource.ru_nvcsw}'
214
+ resourceDict['involuntary context sw'] = f'{rawResource.ru_nivcsw}'
215
+ if return_dict:
216
+ return resourceDict
217
+ return '\n'.join(['\t'.join(line) for line in resourceDict.items()])
218
+ except Exception as e:
219
+ print(f"Error: {e}")
220
+ if return_dict:
221
+ return {}
222
+ return ''
223
+
93
224
  def __teePrintOrNot(message,level = 'info',teeLogger = None):
94
225
  """
95
226
  Prints the given message or logs it using the provided teeLogger.
@@ -573,6 +704,9 @@ class TSVZed(OrderedDict):
573
704
  except Exception as e:
574
705
  print(message,flush=True)
575
706
 
707
+ def getResourseUsage(self,return_dict = False):
708
+ return get_resource_usage(return_dict = return_dict)
709
+
576
710
  def __init__ (self,fileName,teeLogger = None,header = '',createIfNotExist = True,verifyHeader = True,rewrite_on_load = True,rewrite_on_exit = False,rewrite_interval = 0, append_check_delay = 0.01,monitor_external_changes = True,verbose = False,encoding = 'utf8',delimiter = ...,defualts = [],strict = False):
577
711
  super().__init__()
578
712
  self.version = version
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes