Patch one or more modules to ensure they exist. A module name with multiple paths (e.g. gevent.monkey) will ensure all parent modules are also patched (``gevent`` + ``gevent.monkey``). Example:: >>> with conftest.module_exists('gevent.monkey'): ... gevent.monkey.p
(*modules)
| 735 | |
| 736 | @contextmanager |
| 737 | def module_exists(*modules): |
| 738 | """Patch one or more modules to ensure they exist. |
| 739 | A module name with multiple paths (e.g. gevent.monkey) will |
| 740 | ensure all parent modules are also patched (``gevent`` + |
| 741 | ``gevent.monkey``). |
| 742 | Example:: |
| 743 | >>> with conftest.module_exists('gevent.monkey'): |
| 744 | ... gevent.monkey.patch_all = Mock(name='patch_all') |
| 745 | ... ... |
| 746 | """ |
| 747 | gen = [] |
| 748 | old_modules = [] |
| 749 | for module in modules: |
| 750 | if isinstance(module, str): |
| 751 | module = types.ModuleType(module) |
| 752 | gen.append(module) |
| 753 | if module.__name__ in sys.modules: |
| 754 | old_modules.append(sys.modules[module.__name__]) |
| 755 | sys.modules[module.__name__] = module |
| 756 | name = module.__name__ |
| 757 | if '.' in name: |
| 758 | parent, _, attr = name.rpartition('.') |
| 759 | setattr(sys.modules[parent], attr, module) |
| 760 | try: |
| 761 | yield |
| 762 | finally: |
| 763 | for module in gen: |
| 764 | sys.modules.pop(module.__name__, None) |
| 765 | for module in old_modules: |
| 766 | sys.modules[module.__name__] = module |
| 767 | |
| 768 | |
| 769 | def _bind(f, o): |