Conditions | 31 |
Total Lines | 165 |
Code Lines | 102 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like logger.isolog() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | #!/usr/bin/env python |
||
226 | def isolog(*what, **kwargs): |
||
227 | """Logs all non keyword arguments. |
||
228 | |||
229 | :param tuple/str what: Loggable objects (i.e. they have a string |
||
230 | representation) |
||
231 | :param int lvl: Debug message level |
||
232 | :param str emitter: Optional log source, where this can't be determined |
||
233 | automatically |
||
234 | :param str sourceloc: Give specific source code location hints, used |
||
235 | internally |
||
236 | :param int frameref: Specify a non default frame for tracebacks |
||
237 | :param bool tb: Include a traceback |
||
238 | :param bool nc: Do not use color |
||
239 | :param bool exc: Switch to better handle exceptions, use if logging in an |
||
240 | except clause |
||
241 | |||
242 | """ |
||
243 | |||
244 | global count |
||
245 | global verbosity |
||
246 | |||
247 | lvl = kwargs.get("lvl", info) |
||
248 | |||
249 | if lvl < verbosity["global"]: |
||
250 | return |
||
251 | |||
252 | def assemble_things(things) -> str: |
||
253 | result = "" |
||
254 | |||
255 | for thing in things: |
||
256 | result += " " |
||
257 | if kwargs.get("pretty", False) and not isinstance(thing, str): |
||
258 | result += "\n" + pprint.pformat(thing) |
||
259 | else: |
||
260 | result += str(thing) |
||
261 | |||
262 | return result |
||
263 | |||
264 | def write_to_log(message: str): |
||
265 | global logfile |
||
266 | |||
267 | while True: |
||
268 | try: |
||
269 | f = open(logfile, "a") |
||
270 | f.write(message + "\n") |
||
271 | f.flush() |
||
272 | f.close() |
||
273 | |||
274 | break |
||
275 | except IOError: |
||
276 | global log_emergency |
||
277 | print("Cannot open logfile '%s' for writing" % logfile) |
||
278 | |||
279 | if log_emergency is True: |
||
280 | print( |
||
281 | "Safe temporary logging is not working either, " |
||
282 | "giving up on file logging" |
||
283 | ) |
||
284 | break |
||
285 | |||
286 | logfile = os.path.join( |
||
287 | tempfile.mkdtemp(prefix="isomer_"), |
||
288 | "emergency_log" |
||
289 | ) |
||
290 | print("Logging to temporary logfile '%s'" % logfile) |
||
291 | log_emergency = True |
||
292 | |||
293 | continue |
||
294 | |||
295 | def write_to_console(message: str): |
||
296 | try: |
||
297 | print(message) |
||
298 | except UnicodeEncodeError as e: |
||
299 | print(message.encode("utf-8")) |
||
300 | isolog("Bad encoding encountered on previous message:", e, lvl=error) |
||
301 | except BlockingIOError: |
||
302 | isolog("Too long log line encountered:", message[:20], lvl=warn) |
||
303 | |||
304 | # Count all messages (missing numbers give a hint at too high log level) |
||
305 | count += 1 |
||
306 | |||
307 | emitter = kwargs.get("emitter", "UNKNOWN") |
||
308 | traceback = kwargs.get("tb", False) |
||
309 | frame_ref = kwargs.get("frame_ref", 0) |
||
310 | no_color = kwargs.get("nc", False) |
||
311 | exception = kwargs.get("exc", False) |
||
312 | |||
313 | timestamp = time.time() |
||
314 | runtime = timestamp - start |
||
315 | callee = None |
||
316 | |||
317 | if exception: |
||
318 | exc_type, exc_obj, exc_tb = sys.exc_info() # NOQA |
||
319 | |||
320 | if verbosity["global"] <= debug or traceback: |
||
321 | # Automatically log the current function details. |
||
322 | |||
323 | if "sourceloc" not in kwargs: |
||
324 | frame = kwargs.get("frame", frame_ref) |
||
325 | |||
326 | # Get the previous frame in the stack, otherwise it would |
||
327 | # be this function |
||
328 | current_frame = inspect.currentframe() |
||
329 | while frame > 0: |
||
330 | frame -= 1 |
||
331 | current_frame = current_frame.f_back |
||
332 | |||
333 | func = current_frame.f_code |
||
334 | # Dump the message + the name of this function to the log. |
||
335 | |||
336 | if exception: |
||
337 | # noinspection PyUnboundLocalVariable |
||
338 | line_no = exc_tb.tb_lineno |
||
|
|||
339 | if lvl <= error: |
||
340 | lvl = error |
||
341 | else: |
||
342 | line_no = func.co_firstlineno |
||
343 | |||
344 | callee = "[%.10s@%s:%i]" % (func.co_name, func.co_filename, line_no) |
||
345 | else: |
||
346 | callee = kwargs["sourceloc"] |
||
347 | |||
348 | now = datetime.datetime.now().isoformat() |
||
349 | msg = "[%s]:[%s]:%s:%.5f:%3i: [%5s]" % ( |
||
350 | now, |
||
351 | process_identifier, |
||
352 | level_data[lvl][0], |
||
353 | runtime, |
||
354 | count, |
||
355 | emitter, |
||
356 | ) |
||
357 | |||
358 | if callee: |
||
359 | if not uncut and lvl > 10: |
||
360 | msg += "%-60s" % callee |
||
361 | else: |
||
362 | msg += "%s" % callee |
||
363 | |||
364 | content = assemble_things(what) |
||
365 | msg += content |
||
366 | |||
367 | if exception: |
||
368 | msg += "\n" + "".join(format_exception(exc_type, exc_obj, exc_tb)) |
||
369 | |||
370 | if is_muted(msg): |
||
371 | return |
||
372 | |||
373 | if not uncut and lvl > 10 and len(msg) > 1000: |
||
374 | msg = msg[:1000] |
||
375 | |||
376 | if lvl >= verbosity["file"]: |
||
377 | write_to_log(msg) |
||
378 | |||
379 | if is_marked(msg): |
||
380 | lvl = hilight |
||
381 | |||
382 | if lvl >= verbosity["console"]: |
||
383 | output = str(msg) |
||
384 | if color and not no_color: |
||
385 | output = level_data[lvl][1] + output + terminator |
||
386 | write_to_console(output) |
||
387 | |||
388 | if live: |
||
389 | item = [now, lvl, runtime, count, emitter, str(content)] |
||
390 | LiveLog.append(item) |
||
391 |