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