Skip to content

Commit

Permalink
feat: Added "force" error handling method to Logger.add_level.
Browse files Browse the repository at this point in the history
  • Loading branch information
MPCodeWriter21 committed Dec 8, 2023
1 parent 68117c5 commit 06e1086
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 48 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ Help this project by [Donation](DONATE.md)
Changes
-----------

### 2.8.0a0
### 2.8.0a0-2

+ Ability to add new methods to the Logger object for each custom level.
+ Update python version
+ Added "force" error handling method to `Logger.add_level`.

### 2.7.1

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ pip install git+https://github.com/MPCodeWriter21/log21
Changes
-------

### 2.8.0a0
### 2.8.0a0-2

+ Ability to add new methods to the Logger object for each custom level.
+ Update python version
+ Added "force" error handling method to `Logger.add_level`.

[Full CHANGELOG](https://github.com/MPCodeWriter21/log21/blob/master/CHANGELOG.md)

Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ dependencies = [
"webcolors",
"docstring-parser"
]
version = "2.8.0a1"
version = "2.8.0a2"

[tool.setuptools.packages.find]
where = ["src"]
Expand All @@ -43,9 +43,9 @@ dev = ["yapf", "isort", "docformatter", "pylint", "json5", "pytest"]
max-line-length = 88

disable = [
"protected-access",
"too-few-public-methods",
"too-many-arguments",
"protected-access",
"too-many-locals",
"fixme",
]
Expand Down
95 changes: 52 additions & 43 deletions src/log21/Logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ def isEnabledFor(self, level):
def log(self, level: int, *msg, args: tuple = (), end='\n', **kwargs):
"""Log 'msg % args' with the integer severity 'level'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.log(level, "We have a %s", args=("mysterious problem",),
exc_info=1)
logger.log(level, "We have a %s", args=("mysterious problem",), exc_info=1)
"""
msg = ' '.join([str(m) for m in msg]) + end
if not isinstance(level, int):
Expand All @@ -70,11 +69,10 @@ def log(self, level: int, *msg, args: tuple = (), end='\n', **kwargs):
def debug(self, *msg, args: tuple = (), end='\n', **kwargs):
"""Log 'msg % args' with severity 'DEBUG'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.debug("Houston, we have a %s", args=("thorny problem",),
exc_info=1)
logger.debug("Houston, we have a %s", args=("thorny problem",), exc_info=1)
"""
if self.isEnabledFor(DEBUG):
msg = ' '.join([str(m) for m in msg]) + end
Expand All @@ -83,11 +81,10 @@ def debug(self, *msg, args: tuple = (), end='\n', **kwargs):
def info(self, *msg, args: tuple = (), end='\n', **kwargs):
"""Log 'msg % args' with severity 'INFO'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.info("Houston, we have an %s", args=("interesting
problem",), exc_info=1)
logger.info("Houston, we have an %s", args=("interesting problem",), exc_info=1)
"""
if self.isEnabledFor(INFO):
msg = ' '.join([str(m) for m in msg]) + end
Expand All @@ -96,11 +93,10 @@ def info(self, *msg, args: tuple = (), end='\n', **kwargs):
def warning(self, *msg, args: tuple = (), end='\n', **kwargs):
"""Log 'msg % args' with severity 'WARNING'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.warning("Houston, we have a %s", args=("bit of a
problem",), exc_info=1)
logger.warning("Houston, we have a %s", args=("bit of a problem",), exc_info=1)
"""
if self.isEnabledFor(WARNING):
msg = ' '.join([str(m) for m in msg]) + end
Expand All @@ -111,11 +107,10 @@ def warning(self, *msg, args: tuple = (), end='\n', **kwargs):
def write(self, *msg, args: tuple = (), end='', **kwargs):
"""Log 'msg % args' with severity 'WARNING'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.write("Houston, we have a %s", args=("bit of a
problem",), exc_info=1)
logger.write("Houston, we have a %s", args=("bit of a problem",), exc_info=1)
"""
if self.isEnabledFor(WARNING):
msg = ' '.join([str(m) for m in msg]) + end
Expand All @@ -124,29 +119,26 @@ def write(self, *msg, args: tuple = (), end='', **kwargs):
def error(self, *msg, args: tuple = (), end='\n', **kwargs):
"""Log 'msg % args' with severity 'ERROR'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.error("Houston, we have a %s", args=("major problem",),
exc_info=1)
logger.error("Houston, we have a %s", args=("major problem",), exc_info=1)
"""
if self.isEnabledFor(ERROR):
msg = ' '.join([str(m) for m in msg]) + end
self._log(ERROR, msg, args, **kwargs)

def exception(self, *msg, args: tuple = (), exc_info=True, **kwargs):
"""Convenience method for logging an ERROR with exception
information."""
"""Convenience method for logging an ERROR with exception information."""
self.error(*msg, args=args, exc_info=exc_info, **kwargs)

def critical(self, *msg, args: tuple = (), end='\n', **kwargs):
"""Log 'msg % args' with severity 'CRITICAL'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.critical("Houston, we have a %s", args=("major
disaster",), exc_info=1)
logger.critical("Houston, we have a %s", args=("major disaster",), exc_info=1)
"""
if self.isEnabledFor(CRITICAL):
msg = ' '.join([str(m) for m in msg]) + end
Expand All @@ -157,20 +149,19 @@ def critical(self, *msg, args: tuple = (), end='\n', **kwargs):
def print(self, *msg, args: tuple = (), end='\n', **kwargs):
"""Log 'msg % args'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
logger.print("Houston, we have a %s", args=("major disaster",),
exc_info=1)
logger.print("Houston, we have a %s", args=("major disaster",), exc_info=1)
"""
msg = ' '.join([str(m) for m in msg]) + end
self._log(PRINT, msg, args, **kwargs)

def input(self, *msg, args: tuple = (), end='', **kwargs):
"""Log 'msg % args'.
To pass exception information, use the keyword argument exc_info
with a true value, e.g.
To pass exception information, use the keyword argument exc_info with a true
value, e.g.
age = logger.input("Enter your age: ")
"""
Expand Down Expand Up @@ -222,13 +213,27 @@ def add_level(
self,
level: int,
name: str,
errors: _Literal['raise', 'ignore', 'handle'] = 'raise'
errors: _Literal["raise", "ignore", "handle", "force"] = "raise"
) -> str:
"""Adds a new method to the logger with a specific level and name.
:param level: The level of the new method.
:param name: The name of the new method.
:param errors: The action to take if the level already exists.
+ ``raise`` (default): Raise an exception if anything goes wrong.
+ ``ignore``: Do nothing.
+ ``handle``: Handle the situation if a method with the same ``name``
already exists. Adds a number to the name to avoid the conflict.
+ ``force``: Add the new level with the specified level even if a
method with the same ``name`` already exists.
:raises TypeError: If ``level`` is not an integer.
:raises TypeError: If ``name`` is not a string.
:raises ValueError: If ``errors`` is not one of "raise", "ignore", "handle",
or "force".
:raises ValueError: If ``name`` starts with a number.
:raises ValueError: If ``name`` is not a valid identifier.
:raises AttributeError: If ``errors`` is "raise" and a method with the
same ``name`` already exists.
:return: The name of the new method.
"""

Expand All @@ -241,14 +246,18 @@ def raise_(error: BaseException):
raise_(TypeError('level must be an integer'))
if not isinstance(name, str):
raise_(TypeError('name must be a string'))
if errors not in ('raise', 'ignore', 'handle'):
raise_(ValueError('errors must be one of "raise", "ignore", or "handle"'))
if errors not in ('raise', 'ignore', 'handle', 'force'):
raise_(
ValueError(
'errors must be one of "raise", "ignore", "handle", "force"'
)
)

name = _re.sub(r'\s', '_', name)
if _re.match(r'[0-9].*', name):
raise_(ValueError('level name cannot start with a number'))
raise_(ValueError(f'level name cannot start with a number: "{name}"'))
if not _re.fullmatch(r'[a-zA-Z_][a-zA-Z0-9_]*', name):
raise_(ValueError('level name must be a valid identifier'))
raise_(ValueError(f'level name must be a valid identifier: "{name}"'))

if hasattr(self, name):
if errors == 'raise':
Expand All @@ -258,7 +267,7 @@ def raise_(error: BaseException):
if errors == 'handle':
return self.add_level(level, _add_one(name), errors)

def log_for_level(self, level: int, *msg, args: tuple = (), end='\n', **kwargs):
def log_for_level(self, *msg, args: tuple = (), end='\n', **kwargs):
self.log(level, *msg, args=args, end=end, **kwargs)

setattr(self, name, _MethodType(log_for_level, self))
Expand All @@ -267,7 +276,7 @@ def log_for_level(self, level: int, *msg, args: tuple = (), end='\n', **kwargs):
def add_levels(
self,
level_names: Mapping[int, str],
errors: _Literal['raise', 'ignore', 'handle'] = 'raise'
errors: _Literal["raise", "ignore", "handle", "force"] = "raise"
) -> None:
"""Adds new methods to the logger with specific levels and names.
Expand Down
2 changes: 1 addition & 1 deletion src/log21/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from log21.LoggingWindow import LoggingWindow, LoggingWindowHandler
from log21.StreamHandler import StreamHandler, ColorizingStreamHandler

__version__ = "2.8.0a1"
__version__ = "2.8.0a2"
__author__ = "CodeWriter21 (Mehrad Pooryoussof)"
__github__ = "Https://GitHub.com/MPCodeWriter21/log21"
__all__ = [
Expand Down

0 comments on commit 06e1086

Please sign in to comment.