cdxcore 0.1.5__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.
- cdxcore/__init__.py +15 -0
- cdxcore/config.py +1633 -0
- cdxcore/crman.py +105 -0
- cdxcore/deferred.py +220 -0
- cdxcore/dynaplot.py +1155 -0
- cdxcore/filelock.py +430 -0
- cdxcore/jcpool.py +411 -0
- cdxcore/logger.py +319 -0
- cdxcore/np.py +1098 -0
- cdxcore/npio.py +270 -0
- cdxcore/prettydict.py +388 -0
- cdxcore/prettyobject.py +64 -0
- cdxcore/sharedarray.py +285 -0
- cdxcore/subdir.py +2963 -0
- cdxcore/uniquehash.py +970 -0
- cdxcore/util.py +1041 -0
- cdxcore/verbose.py +403 -0
- cdxcore/version.py +402 -0
- cdxcore-0.1.5.dist-info/METADATA +1418 -0
- cdxcore-0.1.5.dist-info/RECORD +30 -0
- cdxcore-0.1.5.dist-info/WHEEL +5 -0
- cdxcore-0.1.5.dist-info/licenses/LICENSE +21 -0
- cdxcore-0.1.5.dist-info/top_level.txt +4 -0
- conda/conda_exists.py +10 -0
- conda/conda_modify_yaml.py +42 -0
- tests/_cdxbasics.py +1086 -0
- tests/test_uniquehash.py +469 -0
- tests/test_util.py +329 -0
- up/git_message.py +7 -0
- up/pip_modify_setup.py +55 -0
cdxcore/logger.py
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Basic log file logic
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .util import _fmt, prnt, write
|
|
6
|
+
import sys as sys
|
|
7
|
+
import logging as logging
|
|
8
|
+
import traceback as traceback
|
|
9
|
+
import datetime as datetime
|
|
10
|
+
|
|
11
|
+
_prnt = prnt
|
|
12
|
+
_write = write
|
|
13
|
+
|
|
14
|
+
class Logger(object):
|
|
15
|
+
"""
|
|
16
|
+
Simple utility object to decorate loggers, plus:
|
|
17
|
+
- infor, warning, () also accept named argument formatting ie "The error is %(message)self" instead of positional %
|
|
18
|
+
- added Exceptn function which logs an error before returning an exception.
|
|
19
|
+
It also make sure an exception is only tracked once.
|
|
20
|
+
The point of this class is to be able to write
|
|
21
|
+
import base.logger as logger
|
|
22
|
+
_log = logger.getLogger(__file__)
|
|
23
|
+
...
|
|
24
|
+
_log.verify( some_condition_we_want_met, "Error: cannot find %s", message)
|
|
25
|
+
and it will keep a log of that exception.
|
|
26
|
+
|
|
27
|
+
Exceptions independent of logging level
|
|
28
|
+
|
|
29
|
+
verify( cond, text, *args, **kwargs )
|
|
30
|
+
If cond is not met, raise an exception with util.fmt( text, *args, **kwargs )
|
|
31
|
+
|
|
32
|
+
throw_if(cond, text, *args, **kwargs )
|
|
33
|
+
If cond is met, raise an exception with util.fmt( text, *args, **kwargs )
|
|
34
|
+
|
|
35
|
+
throw( text, *args, **kwargs )
|
|
36
|
+
Raise an exception with fmt( text, *args, **kwargs )
|
|
37
|
+
|
|
38
|
+
Unconditional logging
|
|
39
|
+
|
|
40
|
+
debug( text, *args, **kwargs )
|
|
41
|
+
info( text, *args, **kwargs )
|
|
42
|
+
warning( text, *args, **kwargs )
|
|
43
|
+
error( text, *args, **kwargs )
|
|
44
|
+
debug( text, *args, **kwargs )
|
|
45
|
+
|
|
46
|
+
Conditional logging functions, verify version
|
|
47
|
+
|
|
48
|
+
verify_debug( cond, text, *args, **kwargs )
|
|
49
|
+
verify_info( cond, text, *args, **kwargs )
|
|
50
|
+
verify_warning( cond, text, *args, **kwargs )
|
|
51
|
+
|
|
52
|
+
verify( cond, text, *args, **kwargs )
|
|
53
|
+
|
|
54
|
+
Conditional logging functions, if version
|
|
55
|
+
|
|
56
|
+
debug_if( text, *args, **kwargs )
|
|
57
|
+
info_if( text, *args, **kwargs )
|
|
58
|
+
warning_if( text, *args, **kwargs )
|
|
59
|
+
|
|
60
|
+
throw_if( text, *args, **kwargs )
|
|
61
|
+
|
|
62
|
+
prnt_if( text, *args, **kwargs ) # with EOL
|
|
63
|
+
write_if( text, *args, **kwargs ) # without EOL
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
CRITICAL = logging.CRITICAL
|
|
67
|
+
ERROR = logging.ERROR
|
|
68
|
+
WARNING = logging.WARNING
|
|
69
|
+
INFO = logging.INFO
|
|
70
|
+
DEBUG = logging.DEBUG
|
|
71
|
+
NOTSET = logging.NOTSET
|
|
72
|
+
|
|
73
|
+
def __init__(self,topic : str):
|
|
74
|
+
assert topic !="", "Logger cannot be empty"
|
|
75
|
+
setupAppLogging() # ensure system is ready
|
|
76
|
+
i = topic.rfind('/')
|
|
77
|
+
if i == -1:
|
|
78
|
+
i = topic.rfind('\\')
|
|
79
|
+
if i != -1 and i<len(topic)-1:
|
|
80
|
+
topic = topic[i+1:]
|
|
81
|
+
self.logger = logging.getLogger(topic)
|
|
82
|
+
|
|
83
|
+
# Exception support
|
|
84
|
+
# -----------------
|
|
85
|
+
|
|
86
|
+
class LogException(Exception):
|
|
87
|
+
""" Placeholder exception class we use to identify our own exceptions """
|
|
88
|
+
|
|
89
|
+
def __init__(self,text : str):
|
|
90
|
+
Exception.__init__(self,text)
|
|
91
|
+
|
|
92
|
+
def Exceptn(self, text : str, *args, **kwargs ):
|
|
93
|
+
"""
|
|
94
|
+
Returns an exception object with 'text' % kwargs and stores an 'error' message
|
|
95
|
+
If an exception is present, it will be printed, too.
|
|
96
|
+
If the base logger logs 'debug' information, the call stack will be printed as well
|
|
97
|
+
|
|
98
|
+
Usage:
|
|
99
|
+
raise _log.Exceptn("Something happened")
|
|
100
|
+
"""
|
|
101
|
+
text = _fmt(text,args,kwargs)
|
|
102
|
+
(typ, val, trc) = sys.exc_info()
|
|
103
|
+
|
|
104
|
+
# are we already throwing our own exception?
|
|
105
|
+
if typ is Logger.LogException:
|
|
106
|
+
return val # --> already logged --> keep raising the exception but don't do anything
|
|
107
|
+
|
|
108
|
+
# new exception?
|
|
109
|
+
if typ is None:
|
|
110
|
+
assert val is None and trc is None, "*** Internal error"
|
|
111
|
+
self.error( text )
|
|
112
|
+
return Logger.LogException("*** LogException: " + text)
|
|
113
|
+
|
|
114
|
+
# another exception is being thrown.
|
|
115
|
+
# we re-cast this as one of our own.
|
|
116
|
+
if text[-1] == ".":
|
|
117
|
+
text = text + " " + str(val)
|
|
118
|
+
else:
|
|
119
|
+
text = text + ". " + str(val)
|
|
120
|
+
|
|
121
|
+
# in debug, add trace information
|
|
122
|
+
if self.logger.getEffectiveLevel() <= logging.WARNING:
|
|
123
|
+
text = text.rstrip()
|
|
124
|
+
txt = traceback.format_exception(typ,val,trc,limit = 100)
|
|
125
|
+
for t in txt:
|
|
126
|
+
text += "\n " + t[:-1]
|
|
127
|
+
self.error( text )
|
|
128
|
+
|
|
129
|
+
# return an exception with the corresponding text
|
|
130
|
+
return Logger.LogException("*** LogException: " + text)
|
|
131
|
+
|
|
132
|
+
# logging() replacemets
|
|
133
|
+
# ---------------------
|
|
134
|
+
|
|
135
|
+
def debug(self, text, *args, **kwargs ):
|
|
136
|
+
""" Reports debug information with new style formatting """
|
|
137
|
+
if self.logger.getEffectiveLevel() <= logging.DEBUG and len(text) > 0:
|
|
138
|
+
self.logger.debug(_fmt(text,args,kwargs))
|
|
139
|
+
|
|
140
|
+
def info(self, text, *args, **kwargs ):
|
|
141
|
+
""" Reports information with new style formatting """
|
|
142
|
+
if self.logger.getEffectiveLevel() <= logging.INFO and len(text) > 0:
|
|
143
|
+
self.logger.info(_fmt(text,args,kwargs))
|
|
144
|
+
|
|
145
|
+
def warning(self, text, *args, **kwargs ):
|
|
146
|
+
""" Reports a warning with new style formatting """
|
|
147
|
+
if self.logger.getEffectiveLevel() <= logging.WARNING and len(text) > 0:
|
|
148
|
+
self.logger.warning(_fmt(text,args,kwargs))
|
|
149
|
+
warn = warning
|
|
150
|
+
|
|
151
|
+
def error(self, text, *args, **kwargs ):
|
|
152
|
+
""" Reports an error with new style formatting """
|
|
153
|
+
if self.logger.getEffectiveLevel() <= logging.ERROR and len(text) > 0:
|
|
154
|
+
self.logger.error(_fmt(text,args,kwargs))
|
|
155
|
+
|
|
156
|
+
def critical(self, text, *args, **kwargs ):
|
|
157
|
+
""" Reports a critial occcurance with new style formatting """
|
|
158
|
+
if self.logger.getEffectiveLevel() <= logging.CRITICAL and len(text) > 0:
|
|
159
|
+
self.logger.critical(_fmt(text,args,kwargs))
|
|
160
|
+
|
|
161
|
+
def throw( self, text, *args, **kwargs ):
|
|
162
|
+
""" Raise an exception """
|
|
163
|
+
raise self.Exceptn(text,*args,**kwargs)
|
|
164
|
+
|
|
165
|
+
@staticmethod
|
|
166
|
+
def prnt( text, *args, **kwargs ):
|
|
167
|
+
""" Simple print, with EOL """
|
|
168
|
+
_prnt(_fmt(text,args,kwargs))
|
|
169
|
+
|
|
170
|
+
@staticmethod
|
|
171
|
+
def write(text, *args, **kwargs ):
|
|
172
|
+
""" Simple print, without EOL """
|
|
173
|
+
_write(_fmt(text,args,kwargs))
|
|
174
|
+
|
|
175
|
+
# run time utilities with validity check
|
|
176
|
+
# --------------------------------------
|
|
177
|
+
|
|
178
|
+
def verify(self, cond, text, *args, **kwargs ):
|
|
179
|
+
"""
|
|
180
|
+
Verifies 'cond'. Raises an exception if 'cond' is not met with the specified text.
|
|
181
|
+
Usage:
|
|
182
|
+
_log.verify( i>0, "i must be positive, found %d", i)
|
|
183
|
+
"""
|
|
184
|
+
if not cond:
|
|
185
|
+
self.throw(text,*args,**kwargs)
|
|
186
|
+
|
|
187
|
+
def verify_warning(self, cond, text, *args, **kwargs ):
|
|
188
|
+
"""
|
|
189
|
+
Verifies 'cond'. If true, writes a warning and then continues
|
|
190
|
+
Usage
|
|
191
|
+
_log.verify_warning( i>0, "i must be positive, found %d", i)
|
|
192
|
+
"""
|
|
193
|
+
if not cond:
|
|
194
|
+
self.warning(text, *args, **kwargs )
|
|
195
|
+
|
|
196
|
+
verify_warn = verify_warning
|
|
197
|
+
|
|
198
|
+
def verify_info(self, cond, text, *args, **kwargs ):
|
|
199
|
+
""" Verifies 'cond'. If true, writes log information and then continues """
|
|
200
|
+
if not cond:
|
|
201
|
+
self.info(text, *args, **kwargs )
|
|
202
|
+
|
|
203
|
+
def verify_debug(self, cond, text, *args, **kwargs ):
|
|
204
|
+
""" Verifies 'cond'. If true, writes log debug and then continues """
|
|
205
|
+
if not cond:
|
|
206
|
+
self.debug(text, *args, **kwargs )
|
|
207
|
+
|
|
208
|
+
# if-action
|
|
209
|
+
# ---------
|
|
210
|
+
|
|
211
|
+
def throw_if(self, cond, text, *args, **kwargs ):
|
|
212
|
+
""" Raises an exception if 'cond' is true. This is the reverse of verify() """
|
|
213
|
+
if cond:
|
|
214
|
+
raise self.Exceptn(text,*args,**kwargs)
|
|
215
|
+
raise_if = throw_if
|
|
216
|
+
|
|
217
|
+
def warning_if(self, cond, text, *args, **kwargs ):
|
|
218
|
+
""" If 'cond' is true, writes a warning. Opposite condition than verify_warning """
|
|
219
|
+
if cond:
|
|
220
|
+
self.warning(text,*args,**kwargs)
|
|
221
|
+
warn_if = warning_if
|
|
222
|
+
|
|
223
|
+
def info_if(self, cond, text, *args, **kwargs ):
|
|
224
|
+
""" If 'cond' is true, writes information 'info'. Opposite condition than verify_info """
|
|
225
|
+
if cond:
|
|
226
|
+
self.info(text,*args,**kwargs)
|
|
227
|
+
|
|
228
|
+
def debug_if(self, cond, text, *args, **kwargs ):
|
|
229
|
+
""" If 'cond' is true, writes debug 'info'. Opposite condition than verify_debug """
|
|
230
|
+
if cond:
|
|
231
|
+
self.debug(text,*args,**kwargs)
|
|
232
|
+
|
|
233
|
+
@staticmethod
|
|
234
|
+
def prnt_if(cond, text, *args, **kwargs ):
|
|
235
|
+
""" If 'cond' is True, prnt() text. Python 2.7 """
|
|
236
|
+
if cond:
|
|
237
|
+
Logger.prnt(text,*args,**kwargs)
|
|
238
|
+
|
|
239
|
+
@staticmethod
|
|
240
|
+
def write_if(cond, text, *args, **kwargs ):
|
|
241
|
+
""" If 'cond' is True, prnt() text """
|
|
242
|
+
if cond:
|
|
243
|
+
Logger.write(text,*args,**kwargs)
|
|
244
|
+
|
|
245
|
+
# interface into logging
|
|
246
|
+
# ----------------------
|
|
247
|
+
|
|
248
|
+
def setLevel(self, level):
|
|
249
|
+
""" logging.setLevel """
|
|
250
|
+
self.logger.setLevel(level)
|
|
251
|
+
|
|
252
|
+
def getEffectiveLevel(self):
|
|
253
|
+
""" logging.getEffectiveLevel """
|
|
254
|
+
return self.logger.getEffectiveLevel()
|
|
255
|
+
|
|
256
|
+
# ====================================================================================================
|
|
257
|
+
# setupAppLogging
|
|
258
|
+
# ---------------
|
|
259
|
+
# Defines logging at stderr and file level.
|
|
260
|
+
# ====================================================================================================
|
|
261
|
+
|
|
262
|
+
GLOBAL_LOG_DATA = "cdxbasics.logger"
|
|
263
|
+
|
|
264
|
+
class RootLog(object):
|
|
265
|
+
def __init__(self, root):
|
|
266
|
+
self.handler = root
|
|
267
|
+
self.fileName = None
|
|
268
|
+
|
|
269
|
+
rootLog = RootLog( logging.getLogger() ) # root level logger
|
|
270
|
+
|
|
271
|
+
def setupAppLogging( levelPrint : int = logging.ERROR,
|
|
272
|
+
levelFile : int = None
|
|
273
|
+
):
|
|
274
|
+
"""
|
|
275
|
+
Application wide logging control - basically sets a log file path
|
|
276
|
+
This function will only called once.
|
|
277
|
+
Put this function into your root import
|
|
278
|
+
|
|
279
|
+
Parameters
|
|
280
|
+
----------
|
|
281
|
+
levelPrint : printing level https://docs.python.org/3/library/logging.html
|
|
282
|
+
levelFile : file level. Set to None to not write to file.
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
data = globals().get(GLOBAL_LOG_DATA,None)
|
|
286
|
+
if data is None:
|
|
287
|
+
# logging for std derror
|
|
288
|
+
logging.basicConfig(level=min(levelPrint,levelFile) if not levelFile is None else levelPrint)
|
|
289
|
+
fmtt = logging.Formatter(fmt="%(asctime)self %(levelname)-10s: %(message)self" )
|
|
290
|
+
stdErr = logging.StreamHandler(sys.stdout)
|
|
291
|
+
stdErr.setLevel(levelPrint )
|
|
292
|
+
rootLog.handler.addHandler( stdErr )
|
|
293
|
+
data = {'strm':stdErr }
|
|
294
|
+
|
|
295
|
+
if not levelFile is None:
|
|
296
|
+
# file system
|
|
297
|
+
import os
|
|
298
|
+
import os.path
|
|
299
|
+
import tempfile
|
|
300
|
+
stamp = datetime.datetime.now().strftime("%Y-%m-%d_%S%M%H")
|
|
301
|
+
pid = os.getpid() # note: process name is 'python.exe'
|
|
302
|
+
tmpDir = tempfile.gettempdir()
|
|
303
|
+
logFile = os.path.join(tmpDir,"py_logger_" + stamp + "_" + str(pid) + ".log")
|
|
304
|
+
|
|
305
|
+
fileE = None
|
|
306
|
+
try:
|
|
307
|
+
fileE = logging.FileHandler(logFile)
|
|
308
|
+
fileE.setFormatter(fmtt)
|
|
309
|
+
fileE.setLevel( levelFile )
|
|
310
|
+
rootLog.handler.addHandler( fileE )
|
|
311
|
+
data = {'strm':stdErr, 'file':fileE, 'logFileName':logFile }
|
|
312
|
+
except:
|
|
313
|
+
pass
|
|
314
|
+
|
|
315
|
+
globals()[GLOBAL_LOG_DATA] = data
|
|
316
|
+
|
|
317
|
+
rootLog.fileName = data.get('logFileName', None)
|
|
318
|
+
return data
|
|
319
|
+
|