Repository: getappmap/appmap-python (language: python)

Issue:
Module already imported so can't be rewritten
### Project

https://github.com/pallets/flask

### Install procedure

* Create virtualenv
* `pip install -e .`
* pytest (runs normally)

```
$ pip list | grep appmap
appmap              2.0.1
```

* pytest

```
(venv) (base) ➜  pallets-flask git:(main) ✗ appmap-python pytest
Error processing line 1 of /Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/distutils-precedence.pth:

  Traceback (most recent call last):
    File "/usr/local/Cellar/python@3.10/3.10.11/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site.py", line 186, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
    File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
    File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 613, in __call__
      return self._self_wrapper(self.__wrapped__, instance,
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/importer.py", line 240, in wrapped_exec_module
      Importer.do_import(*args, **kwargs)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/importer.py", line 209, in do_import
      instrument_functions(fc)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/importer.py", line 187, in instrument_functions
      wrapt.wrap_function_wrapper(filterable.obj, fn_name, new_fn)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 956, in wrap_function_wrapper
      return wrap_object(module, name, FunctionWrapper, (wrapper,))
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 902, in wrap_object
      (parent, attribute, original) = resolve_path(module, name)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 890, in resolve_path
      original = lookup_attribute(parent, attribute)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 886, in lookup_attribute
      return getattr(parent, attribute)
  AttributeError: type object 'DistutilsMetaFinder' has no attribute 'spec_for_test'

Remainder of file ignored
Error processing line 1 of /Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/distutils-precedence.pth:

  Traceback (most recent call last):
    File "/usr/local/Cellar/python@3.10/3.10.11/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site.py", line 186, in addpackage
      exec(line)
    File "<string>", line 1, in <module>
    File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
    File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
    File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 613, in __call__
      return self._self_wrapper(self.__wrapped__, instance,
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/importer.py", line 240, in wrapped_exec_module
      Importer.do_import(*args, **kwargs)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/importer.py", line 209, in do_import
      instrument_functions(fc)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/importer.py", line 187, in instrument_functions
      wrapt.wrap_function_wrapper(filterable.obj, fn_name, new_fn)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 956, in wrap_function_wrapper
      return wrap_object(module, name, FunctionWrapper, (wrapper,))
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 902, in wrap_object
      (parent, attribute, original) = resolve_path(module, name)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 890, in resolve_path
      original = lookup_attribute(parent, attribute)
    File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 886, in lookup_attribute
      return getattr(parent, attribute)
  AttributeError: type object 'DistutilsMetaFinder' has no attribute 'spec_for_test'

Remainder of file ignored
Traceback (most recent call last):
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/bin/pytest", line 8, in <module>
    sys.exit(console_main())
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 622, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 206, in console_main
    code = main()
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 622, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 159, in main
    config = _prepareconfig(args, plugins)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 622, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 346, in _prepareconfig
    config = pluginmanager.hook.pytest_cmdline_parse(
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/pluggy/_hooks.py", line 513, in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/pluggy/_manager.py", line 120, in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 622, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/pluggy/_callers.py", line 139, in _multicall
    raise exception.with_traceback(exception.__traceback__)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/pluggy/_callers.py", line 122, in _multicall
    teardown.throw(exception)  # type: ignore[union-attr]
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/helpconfig.py", line 106, in pytest_cmdline_parse
    config = yield
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/pluggy/_callers.py", line 103, in _multicall
    res = hook_impl.function(*args)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1152, in pytest_cmdline_parse
    self.parse(args)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1501, in parse
    self._preparse(args, addopts=addopts)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1383, in _preparse
    self._consider_importhook(args)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1285, in _consider_importhook
    self._mark_plugins_for_rewrite(hook)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1306, in _mark_plugins_for_rewrite
    hook.mark_rewrite(name)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/assertion/rewrite.py", line 267, in mark_rewrite
    self._warn_already_imported(name)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/assertion/rewrite.py", line 274, in _warn_already_imported
    self.config.issue_config_time_warning(
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/wrapt/wrappers.py", line 712, in __call__
    return self._self_wrapper(self.__wrapped__, self._self_instance,
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 129, in instrumented_fn
    return call_instrumented(f, instance, args, kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_appmap/instrument.py", line 82, in call_instrumented
    return f.fn(*args, **kwargs)
  File "/Users/kgilpin/source/land-of-apps/pallets-flask/venv/lib/python3.10/site-packages/_pytest/config/__init__.py", line 1539, in issue_config_time_warning
    warnings.warn(warning, stacklevel=stacklevel)
pytest.PytestAssertRewriteWarning: Module already imported so cannot be rewritten: _appmap
```


Discussion / hints:

Fix patch:
diff --git a/_appmap/__init__.py b/_appmap/__init__.py
index c98d0cfc..94e6c59f 100644
--- a/_appmap/__init__.py
+++ b/_appmap/__init__.py
@@ -1,3 +1,5 @@
+"""PYTEST_DONT_REWRITE"""
+
 from . import configuration, event, importer, metadata, recorder, recording, web_framework
 from . import env as appmapenv
 from .py_version_check import check_py_version
diff --git a/appmap/__init__.py b/appmap/__init__.py
index 2ddac2b9..a1638b17 100644
--- a/appmap/__init__.py
+++ b/appmap/__init__.py
@@ -1,4 +1,6 @@
-"""AppMap recorder for Python"""
+"""AppMap recorder for Python
+PYTEST_DONT_REWRITE
+"""
 import os
 
 # Note that we need to guard these imports with a conditional, rather than


Test patch:
diff --git a/ci/smoketest.sh b/ci/smoketest.sh
index ebd9f31c..79ad567f 100755
--- a/ci/smoketest.sh
+++ b/ci/smoketest.sh
@@ -17,7 +17,8 @@ cat /tmp/appmap.yml
 
 python -m appmap.command.appmap_agent_validate
 
-$RUNNER pytest -k test_hello_world
+# Promote warnings to errors, so we'll fail if pytest warns it can't rewrite appmap
+$RUNNER pytest -Werror -k test_hello_world
 
 if [[ -f tmp/appmap/pytest/simple_test_simple_UnitTestTest_test_hello_world.appmap.json ]]; then
   echo 'Success'