Skip to content

Commit 962fefb

Browse files
authored
Update xpflow.py
1 parent 68e2b57 commit 962fefb

File tree

1 file changed

+98
-12
lines changed

1 file changed

+98
-12
lines changed

xpflow.py

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,43 @@
44
import hashlib
55
import json
66
from sorcery import dict_of
7-
import os, sys, traceback
7+
import os, sys, traceback, psutil
8+
import functools
9+
import tqdm
10+
import logging
11+
12+
def without(d, key):
13+
if key not in d:
14+
return d
15+
new_d = d.copy()
16+
new_d.pop(key)
17+
return new_d
18+
19+
def is_interactive():
20+
import __main__ as main
21+
return not hasattr(main, '__file__')
822

923
def override(xp):
1024
import argparse, sys
1125
parser = argparse.ArgumentParser()
1226
_, unknown = parser.parse_known_args(sys.argv[1:])
1327
cmd_args_dict = dict(zip(unknown[:-1:2],unknown[1::2]))
1428
cmd_args_dict = {k.lstrip('-'): v for (k,v) in cmd_args_dict.items()}
15-
print(f"cmd_args: {cmd_args_dict}")
1629
for k,v in cmd_args_dict.items():
1730
if k in xp:
1831
xp[k]=type(xp[k])(v)
1932
return xp
2033

2134
class edict(EasyDict):
22-
def __hash__(self):
23-
json_dump = json.dumps(self, sort_keys=True, ensure_ascii=True)
24-
digest = hashlib.md5(json_dump.encode('utf-8')).hexdigest()
25-
identifier = int(digest, 16)
26-
return identifier
2735

36+
def __hash__(self):
37+
try:
38+
json_dump = json.dumps(self, sort_keys=True, ensure_ascii=True)
39+
digest = hashlib.md5(json_dump.encode('utf-8')).hexdigest()
40+
identifier = int(digest, 16)
41+
return identifier
42+
except:
43+
return 0
2844
class Xpl():
2945
def __init__(self,a,b):
3046
self.a=a
@@ -74,7 +90,8 @@ def edict(self):
7490
def __iter__(self):
7591
keys = self.keys()
7692
values_list = self._values()
77-
for values in values_list:
93+
history=[]
94+
for i, values in enumerate(values_list):
7895

7996
args = edict({})
8097
for a, v in zip(keys, values):
@@ -86,6 +103,9 @@ def __iter__(self):
86103
xp = selfi.edict()
87104
xp = override(xp)
88105
xp._hash = hash(xp)
106+
history+=[xp]
107+
if i==len(values_list)-1:
108+
xp._history=history
89109
yield xp
90110

91111
def first(self):
@@ -99,6 +119,8 @@ def __len__(self):
99119
return len([x for x in self])
100120

101121

122+
# Context managers:
123+
102124
class NoPrint:
103125
def __enter__(self):
104126
self._original_stdout = sys.stdout
@@ -108,11 +130,26 @@ def __exit__(self, exc_type, exc_val, exc_tb):
108130
sys.stdout.close()
109131
sys.stdout = self._original_stdout
110132

133+
class NoTqdm:
134+
def __enter__(self):
135+
tqdm.__init__ = functools.partialmethod(tqdm.__init__, disable=True)
136+
def __exit__(self, exc_type, exc_value, exc_traceback):
137+
tqdm.__init__ = functools.partialmethod(tqdm.__init__, disable=False)
138+
139+
140+
class NoLogging:
141+
def __enter__(self):
142+
self._old_logging_level = logging.root.manager.disable
143+
logging.disable(logging.CRITICAL)
144+
145+
def __exit__(self, exc_type, exc_value, traceback):
146+
logging.disable(self._old_logging_level)
147+
111148
class Catch:
112-
def __init__(self, exceptions=[], exit_fn=lambda:None):
149+
def __init__(self, exceptions=[], exit_fn=lambda:None,info=''):
113150
self.allowed_exceptions = exceptions
114-
self.encountered_expcetions=[]
115151
self.exit_fn=exit_fn
152+
self.info=info
116153
def __enter__(self):
117154
return self
118155

@@ -127,6 +164,55 @@ def __exit__(self, exception_type, exception_value, tb):
127164
_EXCEPTIONS=[]
128165

129166
if exception_type and (exception_type in self.allowed_exceptions or not self.allowed_exceptions):
130-
print(f"{exception_type.__name__} swallowed!",exception_value,traceback.print_tb(tb))
131-
_EXCEPTIONS+=[dict_of(exception_type,exception_value,tb)]
167+
print(f"{exception_type.__name__} swallowed!",str(self.info),exception_value,traceback.print_tb(tb))
168+
_EXCEPTIONS+=[dict_of(exception_type,exception_value,tb,info=self.info)]
132169
return True
170+
171+
172+
class Notifier:
173+
def __init__(self, exit_fn=lambda x:None):
174+
self.exit_fn=exit_fn
175+
def __enter__(self):
176+
return self
177+
def __exit__(self, *args):
178+
self.exit_fn(str(args))
179+
180+
class MeasureRAM:
181+
def __init__(self, id=None, logger=print):
182+
self.id = id
183+
self.logger = logger
184+
if self.logger==print:
185+
self.logger=type('logger', (object,), {'log':print})()
186+
187+
def __enter__(self):
188+
self.mem_before = psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024)
189+
190+
def __exit__(self, exc_type, exc_val, exc_tb):
191+
mem_after = psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024)
192+
variation_mb = (mem_after - self.mem_before)
193+
if self.logger:
194+
self.logger.log(dict_of(self.id,variation_mb))
195+
196+
class DisableOutput:
197+
def __init__(self):
198+
self.devnull = None
199+
200+
def __enter__(self):
201+
# Disable all output streams
202+
self.devnull = open(os.devnull, "w")
203+
self.old_stdout = sys.stdout
204+
self.old_stderr = sys.stderr
205+
sys.stdout = self.devnull
206+
sys.stderr = self.devnull
207+
logging.disable(logging.CRITICAL) # Disable all logging output
208+
return self
209+
210+
def __exit__(self, *args):
211+
# Re-enable the output streams
212+
sys.stdout = self.old_stdout
213+
sys.stderr = self.old_stderr
214+
self.devnull.close()
215+
logging.disable(logging.NOTSET) # Re-enable logging output
216+
217+
def write(self, *args, **kwargs):
218+
pass

0 commit comments

Comments
 (0)