Source code for debug

#
##
##  SPDX-FileCopyrightText: © 2007-2024 Benedict Verhegghe <bverheg@gmail.com>
##  SPDX-License-Identifier: GPL-3.0-or-later
##
##  This file is part of pyFormex 3.5  (Thu Feb  8 19:11:13 CET 2024)
##  pyFormex is a tool for generating, manipulating and transforming 3D
##  geometrical models by sequences of mathematical operations.
##  Home page: https://pyformex.org
##  Project page: https://savannah.nongnu.org/projects/pyformex/
##  Development: https://gitlab.com/bverheg/pyformex
##  Distributed under the GNU General Public License version 3 or later.
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program.  If not, see http://www.gnu.org/licenses/.
##
"""Control debug and verbosity output.

"""
import enum
import pyformex as pf

__all__ = ['DEBUG', 'debugon', 'verbosity']


try:
    # Python3.12 defaults enum.Flag boundary to 'strict', reset it
    kargs = {'boundary': enum.FlagBoundary.CONFORM}
except AttributeError:
    # Python < 3.11 did not have the FlagBoundary
    kargs = {}


[docs]class DEBUG(enum.Flag, **kargs): """A class with debug items. This class holds the defined debug items as attributes. Each debug topic is a binary value with a single bit set (a power of 2). Debug items can be combined with & (AND), | (OR) and ^ (XOR). Two extra values are defined: NONE switches off all debugging, ALL activates all debug items. Examples -------- List all existing debug items: >>> for v in DEBUG: ... if v not in (DEBUG.NONE, DEBUG.ALL): ... print(v) DEBUG.INFO DEBUG.WARNING DEBUG.CONFIG DEBUG.DETECT DEBUG.HELP DEBUG.MEM DEBUG.SCRIPT DEBUG.GUI DEBUG.MENU DEBUG.DRAW DEBUG.CANVAS DEBUG.OPENGL DEBUG.LIB DEBUG.MOUSE DEBUG.APPS DEBUG.IMAGE DEBUG.PICK DEBUG.MISC DEBUG.ABQ DEBUG.WIDGET DEBUG.PROJECT DEBUG.WEBGL DEBUG.MULTI DEBUG.LEGACY DEBUG.PLUGIN DEBUG.UNICODE DEBUG.FONT DEBUG.PGF DEBUG.VTK DEBUG.DOCTEST >>> print((DEBUG.INFO | DEBUG.CONFIG | DEBUG.LIB) & DEBUG.ALL) DEBUG.INFO|CONFIG|LIB """ NONE = 0 (INFO, WARNING, CONFIG, DETECT, HELP, MEM, SCRIPT, GUI, MENU, DRAW, CANVAS, OPENGL, LIB, MOUSE, APPS, IMAGE, PICK, MISC, ABQ, WIDGET, PROJECT, WEBGL, MULTI, LEGACY, PLUGIN, UNICODE, FONT, PGF, VTK, DOCTEST, ) = (2**i for i in range(30)) # If we allow the strict boundary, we can not use the -1 # if sys.version_info.minor < 11: # For newer Python, define this later ALL = -1
[docs] @classmethod def item(cls, name): """Convert a string to a DEBUG item The string is case insensitive. Raises ------ ValueError If the name is not a DEBUG item. """ try: return cls[name.upper()] except KeyError: raise ValueError(f"No such {cls.__name__} item: {name}")
[docs] @classmethod def level(cls, names): """Return the combined debug level for a list of debug items Raises ------ ValueError If any of the names is not a DEBUG item. """ from operator import or_ from functools import reduce return reduce(or_, [cls.item(name) for name in names])
# If we use the 'strict' boundary in Python >= 3.12, we can define ALL here # if sys.version_info.minor >= 11: # # DEBUG.ALL = DEBUG(DEBUG._flag_mask_)
[docs]def debugon(topics): """Return True if any of specified debug topics is in options.debuglevel. Parameters ---------- topics: :class:`DEBUG` A DEBUG topic or any combination of them. Returns ------- bool: True if any of the flags in topics is in options.debuglevel. This is effectively the bool value of the binary AND of topics and options.debuglevel. Note ---- Testing if flag1 or flag2 is as easy as ``debugon(flag1 | flag2)`` If you need to test that multiple flags are in options.debuglevel, use ``debugon(flag1) & debugon(flag2)`` Examples -------- >>> pf.options.debuglevel = DEBUG.INFO | DEBUG.OPENGL | DEBUG.GUI | DEBUG.MENU >>> debugon(DEBUG.WARNING | DEBUG.OPENGL) True >>> debugon(DEBUG.WARNING & DEBUG.OPENGL) False >>> debugon(DEBUG.WARNING & DEBUG.OPENGL | DEBUG.GUI) True >>> debugon(DEBUG.OPENGL) & debugon(DEBUG.GUI) True >>> debugon(DEBUG.ALL) True >>> pf.options.debuglevel = DEBUG.NONE >>> debugon(DEBUG.ALL) False """ return bool(pf.options.debuglevel & topics)
[docs]def verbosity(verbose): """Check that verbosity is equal or higher than given value""" return pf.options.verbose >= verbose
# End