# Buggy code
def find_spec(self, fullname, path, target=None):
    if fullname in _DISTUTILS_PATCH and self.fullname is None:
        with self.lock:
            self.fullname = fullname
            try:
                spec = find_spec(fullname, path)
                if spec is not None:
                    old = spec.loader.exec_module

                    def exec_module(module):
                        old(module)
                        patch_dist(module)

                    spec.loader.exec_module = exec_module
                    return spec
            finally:
                self.fullname = None


# Traceback (AttributeError)
Traceback (most recent call last):
File "<frozen importlib._bootstrap>", line 888, in _find_spec
AttributeError: 'PymonkeyImportHook' object has no attribute 'find_spec'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/tmp/pymonkey/testing/pkg1/patchingmod_main.py", line 8, in <module>
exit(main())
File "/tmp/pymonkey/pymonkey.py", line 270, in entry
tuple(patches) + ('--', original_entry_point) + tuple(argv)
File "/tmp/pymonkey/pymonkey.py", line 258, in main
return entry.load()()
File "/tmp/pymonkey/.tox/py36/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2445, in load
return self.resolve()
File "/tmp/pymonkey/.tox/py36/lib/python3.6/site-packages/pkg_resources/__init__.py", line 2451, in resolve
module = __import__(self.module_name, fromlist=['__name__'], level=0)
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
File "/tmp/pymonkey/pymonkey.py", line 173, in load_module
module = importmod(fullname)
File "/tmp/pymonkey/pymonkey.py", line 94, in importmod
return __import__(mod, fromlist=[str('__name__')], level=0)
File "/tmp/pymonkey/testing/pkg2/targetmod.py", line 4, in <module>
import setuptools  # Some weird import hook
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
File "/tmp/pymonkey/pymonkey.py", line 173, in load_module
module = importmod(fullname)
File "/tmp/pymonkey/pymonkey.py", line 94, in importmod
return __import__(mod, fromlist=[str('__name__')], level=0)
File "/tmp/pymonkey/.tox/py36/lib/python3.6/site-packages/setuptools/__init__.py", line 5, in <module>
import distutils.core
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
File "/tmp/pymonkey/pymonkey.py", line 173, in load_module
module = importmod(fullname)
File "/tmp/pymonkey/pymonkey.py", line 94, in importmod
return __import__(mod, fromlist=[str('__name__')], level=0)
File "/usr/lib/python3.6/distutils/core.py", line 16, in <module>
from distutils.dist import Distribution
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 951, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 890, in _find_spec
File "<frozen importlib._bootstrap>", line 864, in _find_spec_legacy
File "/tmp/pymonkey/pymonkey.py", line 162, in find_module
elif self._module_exists(fullname, path):
File "/tmp/pymonkey/pymonkey.py", line 122, in _module_exists
getattr(entry, 'find_spec', _noop)(module, path) or
File "/tmp/pymonkey/.tox/py36/lib/python3.6/site-packages/_virtualenv.py", line 58, in find_spec
old = spec.loader.exec_module
AttributeError: 'PymonkeyImportHook' object has no attribute 'exec_module'

# Fixed code
def find_spec(self, fullname, path, target=None):
    if fullname in _DISTUTILS_PATCH and self.fullname is None:
        with self.lock:
            self.fullname = fullname
            try:
                spec = find_spec(fullname, path)
                if spec is not None:
                    # https://www.python.org/dev/peps/pep-0451/#how-loading-will-work
                    spec.loader = deepcopy(
                        spec.loader
                    )  # loaders may be shared, create new that also patches
                    func_name = (
                        "exec_module"
                        if hasattr(spec.loader, "exec_module")
                        else "load_module"
                    )
                    if func_name == "exec_module":  # new API

                        def patch_module_load(module):
                            old(module)
                            patch_dist(module)

                    else:  # legacy API

                        def patch_module_load(name):
                            module = old(name)
                            patch_dist(module)
                            return module

                    old = getattr(spec.loader, func_name)
                    setattr(spec.loader, func_name, patch_module_load)
                    return spec
            finally:
                self.fullname = None