pyomo.common.dependencies

class pyomo.common.dependencies.ModuleUnavailable(name, message, version_error, import_error, package)[source]

Mock object that raises DeferredImportError upon attribute access

This object is returned by attempt_import() in lieu of the module in the case that the module import fails. Any attempts to access attributes on this object will raise a DeferredImportError exception.

Parameters:
  • name (str) – The module name that was being imported

  • message (str) – The string message to return in the raised exception

  • version_error (str) – A string to add to the message if the module failed to import because it did not match the required version

  • import_error (str) – A string to add to the message documenting the Exception raised when the module failed to import.

  • package (str) – The module name that originally attempted the import

mro()[source]

Return a type’s method resolution order.

log_import_warning(logger='pyomo', msg=None)[source]

Log the import error message to the specified logger

This will log the the import error message to the specified logger. If msg= is specified, it will override the default message passed to this instance of ModuleUnavailable.

generate_import_warning(logger='pyomo.common')[source]

DEPRECATED.

Deprecated since version 6.0: use log_import_warning()

class pyomo.common.dependencies.DeferredImportModule(indicator, deferred_submodules, submodule_name)[source]

Mock module object to support the deferred import of a module.

This object is returned by attempt_import() in lieu of the module when attempt_import() is called with defer_check=True. Any attempts to access attributes on this object will trigger the actual module import and return either the appropriate module attribute or else if the module import fails, raise a DeferredImportError exception.

mro()[source]

Return a type’s method resolution order.

pyomo.common.dependencies.UnavailableClass(unavailable_module)[source]

Function to generate an “unavailable” base class

This function returns a custom class that wraps the ModuleUnavailable instance returned by attempt_import() when the target module is not available. Any attempt to instantiate this class (or a class derived from it) or access a class attribute will raise the DeferredImportError from the wrapped ModuleUnavailable object.

Parameters:

unavailable_module (ModuleUnavailable) – The ModuleUnavailable instance (from attempt_import()) to use to generate the DeferredImportError.

Example

Declaring a class that inherits from an optional dependency:

>>> from pyomo.common.dependencies import attempt_import, UnavailableClass
>>> bogus, bogus_available = attempt_import('bogus_unavailable_class')
>>> class MyPlugin(bogus.plugin if bogus_available else UnavailableClass(bogus)):
...     pass

Attempting to instantiate the derived class generates an exception when the module is unavailable:

>>> MyPlugin()
Traceback (most recent call last):
   ...
pyomo.common.dependencies.DeferredImportError: The class 'MyPlugin' cannot be
created because a needed optional dependency was not found (import raised
ModuleNotFoundError: No module named 'bogus_unavailable_class')

As does attempting to access class attributes on the derived class:

>>> MyPlugin.create_instance()
Traceback (most recent call last):
   ...
pyomo.common.dependencies.DeferredImportError: The class attribute
'MyPlugin.create_instance' is not available because a needed optional
dependency was not found (import raised ModuleNotFoundError: No module
named 'bogus_unavailable_class')
class pyomo.common.dependencies.DeferredImportIndicator(name, error_message, catch_exceptions, minimum_version, original_globals, callback, importer, deferred_submodules)[source]

Placeholder indicating if an import was successful.

This object serves as a placeholder for the Boolean indicator if a deferred module import was successful. Casting this instance to bool will cause the import to be attempted. The actual import logic is here and not in the DeferredImportModule to reduce the number of attributes on the DeferredImportModule.

DeferredImportIndicator supports limited logical expressions using the & (and) and | (or) binary operators. Creating these expressions does not trigger the import of the corresponding DeferredImportModule instances, although casting the resulting expression to bool() will trigger any relevant imports.

pyomo.common.dependencies.attempt_import(name, error_message=None, only_catch_importerror=None, minimum_version=None, alt_names=None, callback=None, importer=None, defer_check=True, deferred_submodules=None, catch_exceptions=None)[source]

Attempt to import the specified module.

This will attempt to import the specified module, returning a (module, available) tuple. If the import was successful, module will be the imported module and available will be True. If the import results in an exception, then module will be an instance of ModuleUnavailable and available will be False

The following

>>> from pyomo.common.dependencies import attempt_import
>>> numpy, numpy_available = attempt_import('numpy')

Is roughly equivalent to

>>> from pyomo.common.dependencies import ModuleUnavailable
>>> try:
...     import numpy
...     numpy_available = True
... except ImportError as e:
...     numpy = ModuleUnavailable('numpy', 'Numpy is not available',
...                               '', str(e), globals()['__name__'])
...     numpy_available = False

The import can be “deferred” until the first time the code either attempts to access the module or checks the Boolean value of the available flag. This allows optional dependencies to be declared at the module scope but not imported until they are actually used by the module (thereby speeding up the initial package import). Deferred imports are handled by two helper classes (DeferredImportModule and DeferredImportIndicator). Upon actual import, DeferredImportIndicator.resolve() attempts to replace those objects (in both the local and original global namespaces) with the imported module and Boolean flag so that subsequent uses of the module do not incur any overhead due to the delayed import.

Parameters:
  • name (str) – The name of the module to import

  • error_message (str, optional) – The message for the exception raised by ModuleUnavailable

  • only_catch_importerror (bool, optional) – DEPRECATED: use catch_exceptions instead or only_catch_importerror. If True (the default), exceptions other than ImportError raised during module import will be reraised. If False, any exception will result in returning a ModuleUnavailable object. (deprecated in version 5.7.3)

  • minimum_version (str, optional) – The minimum acceptable module version (retrieved from module.__version__)

  • alt_names (list, optional) – DEPRECATED: alt_names no longer needs to be specified and is ignored. A list of common alternate names by which to look for this module in the globals() namespaces. For example, the alt_names for NumPy would be ['np']. (deprecated in version 6.0)

  • callback (function, optional) – A function with the signature “fcn(module, available)” that will be called after the import is first attempted.

  • importer (function, optional) – A function that will perform the import and return the imported module (or raise an ImportError). This is useful for cases where there are several equivalent modules and you want to import/return the first one that is available.

  • defer_check (bool, optional) – If True (the default), then the attempted import is deferred until the first use of either the module or the availability flag. The method will return instances of DeferredImportModule and DeferredImportIndicator.

  • deferred_submodules (Iterable[str], optional) – If provided, an iterable of submodule names within this module that can be accessed without triggering a deferred import of this module. For example, this module uses deferred_submodules=['pyplot', 'pylab'] for matplotlib.

  • catch_exceptions (Iterable[Exception], optional) – If provided, this is the list of exceptions that will be caught when importing the target module, resulting in attempt_import returning a ModuleUnavailable instance. The default is to only catch ImportError. This is useful when a module can regularly return additional exceptions during import.

Returns:

pyomo.common.dependencies.declare_deferred_modules_as_importable(globals_dict)[source]

Make all DeferredImportModules in globals_dict importable

This function will go throughout the specified globals_dict dictionary and add any instances of DeferredImportModule that it finds (and any of their deferred submodules) to sys.modules so that the modules can be imported through the globals_dict namespace.

For example, pyomo/common/dependencies.py declares:

>>> scipy, scipy_available = attempt_import(
...     'scipy', callback=_finalize_scipy,
...     deferred_submodules=['stats', 'sparse', 'spatial', 'integrate'])
>>> declare_deferred_modules_as_importable(globals())

Which enables users to use:

>>> import pyomo.common.dependencies.scipy.sparse as spa

If the deferred import has not yet been triggered, then the DeferredImportModule is returned and named spa. However, if the import has already been triggered, then spa will either be the scipy.sparse module, or a ModuleUnavailable instance.