Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option: Warnings and/or Deprecation Warnings Raise RuntimeError #822

Merged
merged 20 commits into from
Apr 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/reference_guides/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,26 @@ additional loggers can be added if desired. The standard loggers are:
If changes to the logger configuration dictionary are made after importing
``idaes`` a call to ``idaes.reconfig()`` is required for it to take effect.

warning_to_exception
~~~~~~~~~~~~~~~~~~~~

If this option is True, any log messages at level warning or above will be
converted to a RuntimeError exception. This can be used to ensure a model doesn't
generate warnings. It can also be used to generate a traceback for warnings, which
can provide additional debugging information.

Changes require ``idaes.reconfig()``. The default setting is ``False``.

depracation_to_exception
~~~~~~~~~~~~~~~~~~~~~~~~

If this option is True, any log messages at level warning or above that contain
"deprecation," "deprecate," or "deprecated" will be converted to a RuntimeError
exception. This can be used to ensure a model doesn't use any deprecated models
or methods.

Changes require ``idaes.reconfig()``. The default setting is ``False``.

use_idaes_solvers
~~~~~~~~~~~~~~~~~

Expand Down
48 changes: 48 additions & 0 deletions idaes/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,24 @@ def _new_idaes_config_block():
the idaes configuration system to function improperly.
"""
cfg = pyomo.common.config.ConfigBlock("idaes", implicit=True)
cfg.declare(
"warning_to_exception",
pyomo.common.config.ConfigValue(
domain=bool,
default=False,
description="Convert any logged warnings or errors to exceptions",
doc="Convert any logged warnings or errors to exceptions"
),
)
cfg.declare(
"deprecation_to_exception",
pyomo.common.config.ConfigValue(
domain=bool,
default=False,
description="Convert any logged deprecation warnings to exceptions",
doc="Convert any logged deprecation warnings to exceptions"
),
)
cfg.declare(
"logging",
pyomo.common.config.ConfigBlock(
Expand Down Expand Up @@ -412,8 +430,38 @@ def write_config(path, cfg=None):
json.dump(cfg.value(), f, cls=ConfigBlockJSONEncoder, indent=4)


class _WarningToExceptionFilter(logging.Filter):
"""Filter applied to IDAES loggers returned by this module."""

@staticmethod
def filter(record):
if record.levelno >= logging.WARNING:
raise RuntimeError(
f"Logged Warning converted to exception: {record.msg}")


class _DeprecationToExceptionFilter(logging.Filter):
"""Filter applied to IDAES loggers returned by this module."""

@staticmethod
def filter(record):
if record.levelno >= logging.WARNING:
if "deprecat" in record.msg.lower():
raise RuntimeError(
f"Logged deprecation converted to exception: {record.msg}")


def reconfig(cfg):
logging.config.dictConfig(cfg.logging.value())
_log = logging.getLogger("idaes")
if cfg.deprecation_to_exception:
_log.addFilter(_DeprecationToExceptionFilter)
else:
_log.removeFilter(_DeprecationToExceptionFilter)
if cfg.warning_to_exception:
_log.addFilter(_WarningToExceptionFilter)
else:
_log.removeFilter(_WarningToExceptionFilter)
setup_environment(bin_directory, cfg.use_idaes_solvers)


Expand Down
19 changes: 19 additions & 0 deletions idaes/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import os
import pytest
import idaes
import logging

class TestIdaesConfigure(object):

Expand Down Expand Up @@ -71,3 +72,21 @@ def test_canonical_distro():
assert idaes.config.canonical_distro("Ubuntu1804") == "ubuntu1804"
assert idaes.config.canonical_distro("Windows") == "windows"
assert idaes.config.canonical_distro("daRwin") == "darwin"

@pytest.mark.unit
def test_warning_to_except():
with idaes.temporary_config_ctx():
with pytest.raises(RuntimeError):
_log = logging.getLogger("idaes")
idaes.cfg.warning_to_exception = True
idaes.reconfig()
_log.warning("Hey! Don't do that.")

@pytest.mark.unit
def test_deprecate_to_except():
with idaes.temporary_config_ctx():
with pytest.raises(RuntimeError):
_log = logging.getLogger("idaes")
idaes.cfg.deprecation_to_exception = True
idaes.reconfig()
_log.warning("DEPRECATED: Hey! Don't use that.")