#
##
## 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