schrodinger.infra.unusable_module_importer module

A module that can replace imports with dummy modules. For example

>>> from schrodinger.infra import unusable_module_importer
>>> unusable_module_importer.enable_dummy_maestro_imports()
>>> from schrodinger.maestro import maestro
>>> bool(maestro)
False
>>> maestro.WORKSPACE_CHANGED_EVERYTHING
MaestroNotAvailableError: Cannot access
    schrodinger.maestro.maestro.WORKSPACE_CHANGED_EVERYTHING outside of
    Maestro

or

>>> from schrodinger.infra import unusable_module_importer
>>> unusable_module_importer.enable_dummy_non_post_test_imports()
>>> from schrodinger.application.prime.packages import antibody
>>> antibody.get_antibody_data_dir()
ProductNotAvailableError: Cannot access
    schrodinger.application.prime.packages.antibody.get_antibody_data_dir
    when running tests without --post-test
exception schrodinger.infra.unusable_module_importer.ProductNotAvailableError

Bases: AttributeError

Error indicating that a product is not available and there was an attempt to use it.

exception schrodinger.infra.unusable_module_importer.MaestroNotAvailableError

Bases: schrodinger.infra.unusable_module_importer.ProductNotAvailableError

Error indicating that Maestro is not available and there was an attempt to use it.

class schrodinger.infra.unusable_module_importer.UnusableModuleLoader

Bases: importlib._abc.Loader

A module loader that loads DummyModule instances instead of the real module.

Variables

_REASON – The reason that the real module was not available

classmethod create_module(spec)

Return a module to initialize and into which to load.

This method should raise ImportError if anything prevents it from creating a new module. It may return None to indicate that the spec should create the new module.

static exec_module(module)
classmethod get_code(fullname)
class schrodinger.infra.unusable_module_importer.NonPostTestUnusableModuleLoader

Bases: schrodinger.infra.unusable_module_importer.UnusableModuleLoader

class schrodinger.infra.unusable_module_importer.MissingProductUnusableModuleLoader

Bases: schrodinger.infra.unusable_module_importer.UnusableModuleLoader

class schrodinger.infra.unusable_module_importer.DummyModule(module_name: str, spec: typing.Optional[_frozen_importlib.ModuleSpec] = None, reason: str = '', loader: typing.Type[importlib._abc.Loader] = <class 'schrodinger.infra.unusable_module_importer.UnusableModuleLoader'>)

Bases: object

Used to replace modules from non-mmshare products when the product is not available. Casts to bool return False to allow portions of scripts to be protected by “if my_module:”. Raises an explanatory error if the calling module tries to access any attribute.

Variables

_EXCEPTION_CLASS – The exception type to raise if a user tries to access an attribute of this module.

__init__(module_name: str, spec: typing.Optional[_frozen_importlib.ModuleSpec] = None, reason: str = '', loader: typing.Type[importlib._abc.Loader] = <class 'schrodinger.infra.unusable_module_importer.UnusableModuleLoader'>)
Parameters
  • module_name – The name fo the module that this object is standing in for.

  • spec – The module spec. Required if this module represents a package. Optional otherwise.

  • reason – The reason that the real module was not available.

  • loader – The loader class used to load this instance.

class schrodinger.infra.unusable_module_importer.DummyMaestroModule(module_name: str, spec: typing.Optional[_frozen_importlib.ModuleSpec] = None, reason: str = '', loader: typing.Type[importlib._abc.Loader] = <class 'schrodinger.infra.unusable_module_importer.UnusableModuleLoader'>)

Bases: schrodinger.infra.unusable_module_importer.DummyModule

Used to replace maestro modules (e.g. schrodinger.maestro.maestro) when running outside of Maestro. Casts to bool return False to allow portions of scripts to be protected by “if maestro:”. Raises an explanatory error if the calling module tries to access any attribute.

class schrodinger.infra.unusable_module_importer.AbstractUnusableModuleFinder

Bases: importlib.abc.MetaPathFinder

A meta-path finder (see https://docs.python.org/3/reference/import.html#the-meta-path) that imports DummyModule instances. Subclasses should redefine UNUSABLE_PACKAGES to specify which packages should be replaced with dummy modules.

Variables
  • UNUSABLE_PACKAGES – A set of fully-qualified Python package names that we should intercept the imports of. Imports for any modules within these packages will also be intercepted. Formatted as, e.g., schrodinger.application.prime.packages or schrodinger.forcefield.packages

  • MISSING_PRODUCTS_ONLY – If True, this class will only affect imports when the product is missing (i.e. there’s no $SCHRODINGER/<product>-v* directory). Note that if this value is True, this class will never affect schrodinger.maestro imports.

  • LOADER – The loader class to use to load dummy modules.

  • PACKAGE_TO_PRODUCT_NAME – A dictionary mapping package names (e.g. “prime” from schrodinger.application.prime.packages) to the product name used in the $SCHRODINGER subdirectory for the product (e.g. “psp” from psp-v7.1). For any package names not found in this dictionary, it will be assumed that the package name and product name are the same.

UNUSABLE_PACKAGES: Set[str] = frozenset({})
MISSING_PRODUCTS_ONLY: bool = False
LOADER

alias of schrodinger.infra.unusable_module_importer.UnusableModuleLoader

PACKAGE_TO_PRODUCT_NAME: Dict[str, str] = {'forcefield': 'ffld', 'prime': 'psp'}
__init__()
find_spec(fullname, path, target=None)
setForceDummy(force_dummy: Set[str])

Update the set of products that will use dummy imports even if product_installed says that the product is present. (Buildinger uses this to avoid importing from packages that are in the process of being built or that failed to build successfully.)

Parameters

force_dummy – A set of product names

class schrodinger.infra.unusable_module_importer.MaestroUnusableModuleFinder

Bases: schrodinger.infra.unusable_module_importer.AbstractUnusableModuleFinder

A meta-path finder that replaces schrodinger.maestro.whatever modules with DummyMaestroModule instances.

UNUSABLE_PACKAGES: Set[str] = {'schrodinger.maestro'}
class schrodinger.infra.unusable_module_importer.NonPostTestUnusableModuleFinder

Bases: schrodinger.infra.unusable_module_importer.AbstractUnusableModuleFinder

A meta-path finder for use in non-post-test unit test runs (i.e. neither –post-test nor –post-test-only was passed to py.test). This finder replaces schrodinger.maestro.whatever modules with DummyMaestroModule instances and replaces all schrodinger.application.product_name.packages modules with DummyModules.

Note that UNUSABLE_PACKAGES is populated the first time find_spec is called. This is done to avoid triggering unneeded i/o calls when unusable_module_importer is imported. (We use several glob.glob() calls to find the package directories.)

UNUSABLE_PACKAGES: Set[str] = None
LOADER

alias of schrodinger.infra.unusable_module_importer.NonPostTestUnusableModuleLoader

find_spec(fullname, path, target=None)
class schrodinger.infra.unusable_module_importer.MissingProductUnusableModuleFinder

Bases: schrodinger.infra.unusable_module_importer.NonPostTestUnusableModuleFinder

A meta-path finder that replaces schrodinger.application.product_name.packages modules with DummyModules if and only if the product is missing (i.e. there’s no $SCHRODINGER/<product>-v* directory)

Note that, as with NonPostTestUnusableModuleFinder, UNUSABLE_PACKAGES is populated the first time find_spec is called.

MISSING_PRODUCTS_ONLY: bool = True
LOADER

alias of schrodinger.infra.unusable_module_importer.MissingProductUnusableModuleLoader

schrodinger.infra.unusable_module_importer.get_schrodinger_package_dirs()

Get directories under the schrodinger module that contain code from product repositories outside of mmshare

schrodinger.infra.unusable_module_importer.enable_dummy_maestro_imports()

Replace all schrodinger.maestro.module_name imports with dummy modules. Intended for use when running outside of Maestro.

schrodinger.infra.unusable_module_importer.disable_dummy_maestro_imports()

Remove the effects of enable_dummy_maestro_imports for any future imports.

schrodinger.infra.unusable_module_importer.enable_dummy_non_post_test_imports()

Replace all schrodinger.maestro.module_name and schrodinger.application.product.packages imports with dummy modules, even if the product is installed. Intended for use in non-post-test unit test runs (i.e. neither –post-test nor –post-test-only was passed to py.test).

schrodinger.infra.unusable_module_importer.disable_dummy_non_post_test_imports()

Remove the effects of enable_dummy_non_post_test_imports for any future imports.

schrodinger.infra.unusable_module_importer.enable_dummy_missing_product_imports()

For any product that is missing, replace schrodinger.application.product.packages imports with dummy modules. Note that this function does not affect schrodinger.maestro imports.

schrodinger.infra.unusable_module_importer.disable_dummy_missing_product_imports()

Remove the effects of enable_dummy_missing_product_imports for any future imports.

schrodinger.infra.unusable_module_importer.force_dummy_missing_product_imports(force_dummy: Set[str])

Force the MissingProductUnusableModuleFinder (i.e. the finder installed by enable_dummy_missing_product_imports) to treat the specified products as missing even if they’re present, i.e. always use dummy imports for those products. (Buildinger uses this to avoid importing from packages that are in the process of being built or that failed to build successfully.)

Parameters

force_dummy – A set of product names