appmap 2.1.1__tar.gz → 2.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. {appmap-2.1.1 → appmap-2.1.2}/PKG-INFO +1 -1
  2. {appmap-2.1.1 → appmap-2.1.2}/_appmap/instrument.py +6 -1
  3. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/example_class.py +3 -0
  4. appmap-2.1.2/_appmap/test/data/pytest-instrumented/appmap.yml +12 -0
  5. appmap-2.1.2/_appmap/test/data/pytest-instrumented/test_instrumented.py +16 -0
  6. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/helpers.py +15 -3
  7. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_events.py +33 -0
  8. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_test_frameworks.py +13 -2
  9. appmap-2.1.2/appmap.pth +1 -0
  10. {appmap-2.1.1 → appmap-2.1.2}/pyproject.toml +1 -1
  11. {appmap-2.1.1 → appmap-2.1.2}/LICENSE +0 -0
  12. {appmap-2.1.1 → appmap-2.1.2}/README.md +0 -0
  13. {appmap-2.1.1 → appmap-2.1.2}/_appmap/__init__.py +0 -0
  14. {appmap-2.1.1 → appmap-2.1.2}/_appmap/configuration.py +0 -0
  15. {appmap-2.1.1 → appmap-2.1.2}/_appmap/django.py +0 -0
  16. {appmap-2.1.1 → appmap-2.1.2}/_appmap/env.py +0 -0
  17. {appmap-2.1.1 → appmap-2.1.2}/_appmap/event.py +0 -0
  18. {appmap-2.1.1 → appmap-2.1.2}/_appmap/fastapi.py +0 -0
  19. {appmap-2.1.1 → appmap-2.1.2}/_appmap/flask.py +0 -0
  20. {appmap-2.1.1 → appmap-2.1.2}/_appmap/generation.py +0 -0
  21. {appmap-2.1.1 → appmap-2.1.2}/_appmap/importer.py +0 -0
  22. {appmap-2.1.1 → appmap-2.1.2}/_appmap/labels.py +0 -0
  23. {appmap-2.1.1 → appmap-2.1.2}/_appmap/metadata.py +0 -0
  24. {appmap-2.1.1 → appmap-2.1.2}/_appmap/noappmap.py +0 -0
  25. {appmap-2.1.1 → appmap-2.1.2}/_appmap/py_version_check.py +0 -0
  26. {appmap-2.1.1 → appmap-2.1.2}/_appmap/recorder.py +0 -0
  27. {appmap-2.1.1 → appmap-2.1.2}/_appmap/recording.py +0 -0
  28. {appmap-2.1.1 → appmap-2.1.2}/_appmap/remote_recording.py +0 -0
  29. {appmap-2.1.1 → appmap-2.1.2}/_appmap/singleton.py +0 -0
  30. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/__init__.py +0 -0
  31. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/appmap_test_base.py +0 -0
  32. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/bin/server_runner +0 -0
  33. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/conftest.py +0 -0
  34. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-all-paths-malformed.yml +0 -0
  35. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-broken.yml +0 -0
  36. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-class.yml +0 -0
  37. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-empty-path.yml +0 -0
  38. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-exclude-fn.yml +0 -0
  39. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-func.yml +0 -0
  40. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-malformed-path.yml +0 -0
  41. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap-no-pyyaml.yml +0 -0
  42. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap.yml +0 -0
  43. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap_testing/__init__.py +0 -0
  44. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/appmap_testing/django_simplelazyobject.py +0 -0
  45. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config/src/package/__init__.py +0 -0
  46. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config/test/__init__.py +0 -0
  47. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config/test/foo.py +0 -0
  48. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-exclude/.hide/hidden_mod/__init__.py +0 -0
  49. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-exclude/node_modules/node_mod/__init__.py +0 -0
  50. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-exclude/src/package/__init__.py +0 -0
  51. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-exclude/test/__init__.py +0 -0
  52. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-exclude/venv/venv_mod/__init__.py +0 -0
  53. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-up/appmap.yml +0 -0
  54. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-up/project/p1/__init__.py +0 -0
  55. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/config-up/project/p2/sub1/__init__.py +0 -0
  56. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/appmap.yml +0 -0
  57. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/djangoapp/__init__.py +0 -0
  58. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/djangoapp/djangoapp.py +0 -0
  59. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/djangoapp/hello_world.html +0 -0
  60. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/djangoapp/middleware.py +0 -0
  61. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/djangoapp/settings.py +0 -0
  62. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/djangoapp/settings_dev.py +0 -0
  63. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/djangoapp/urls.py +0 -0
  64. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/init/sitecustomize.py +0 -0
  65. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/manage.py +0 -0
  66. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/pytest.ini +0 -0
  67. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/test/__init__.py +0 -0
  68. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/test/test_app.py +0 -0
  69. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/django/test/test_unittest_setup.py +0 -0
  70. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/expected.appmap.json +0 -0
  71. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/fastapi/appmap.yml +0 -0
  72. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/fastapi/fastapiapp/__init__.py +0 -0
  73. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/fastapi/fastapiapp/main.py +0 -0
  74. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/fastapi/init/sitecustomize.py +0 -0
  75. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/fastapi/test_app.py +0 -0
  76. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask/appmap.yml +0 -0
  77. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask/flaskapp.py +0 -0
  78. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask/init/sitecustomize.py +0 -0
  79. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask/templates/test.html +0 -0
  80. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask/test_app.py +0 -0
  81. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask-instrumented/appmap.yml +0 -0
  82. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask-instrumented/flaskapp.py +0 -0
  83. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask-instrumented/init/sitecustomize.py +0 -0
  84. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/flask-instrumented/test_app.py +0 -0
  85. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/package1/__init__.py +0 -0
  86. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/package1/package2/__init__.py +0 -0
  87. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/package1/package2/__main__.py +0 -0
  88. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/package1/package2/mod1.py +0 -0
  89. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/params.py +0 -0
  90. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/appmap.yml +0 -0
  91. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/expected/pytest-numpy1.appmap.json +0 -0
  92. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/expected/pytest-numpy2.appmap.json +0 -0
  93. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/expected/status_errored.metadata.json +0 -0
  94. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/expected/status_failed.metadata.json +0 -0
  95. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/expected/status_xfailed.metadata.json +0 -0
  96. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/simple.py +0 -0
  97. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/test_noappmap.py +0 -0
  98. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/pytest/test_simple.py +0 -0
  99. {appmap-2.1.1/_appmap/test/data/trial → appmap-2.1.2/_appmap/test/data/pytest-instrumented}/init/sitecustomize.py +0 -0
  100. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/remote.appmap.json +0 -0
  101. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/trial/.gitignore +0 -0
  102. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/trial/appmap.yml +0 -0
  103. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/trial/expected/pytest.appmap.json +0 -0
  104. {appmap-2.1.1/_appmap/test/data/unittest → appmap-2.1.2/_appmap/test/data/trial}/init/sitecustomize.py +0 -0
  105. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/trial/test/__init__.py +0 -0
  106. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/trial/test/test_deferred.py +0 -0
  107. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/appmap.yml +0 -0
  108. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/expected/pytest.appmap.json +0 -0
  109. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/expected/status_errored.metadata.json +0 -0
  110. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/expected/status_failed.metadata.json +0 -0
  111. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/expected/status_xfailed.metadata.json +0 -0
  112. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/expected/status_xsucceeded.metadata.json +0 -0
  113. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/expected/unittest.appmap.json +0 -0
  114. /appmap-2.1.1/appmap.pth → /appmap-2.1.2/_appmap/test/data/unittest/init/sitecustomize.py +0 -0
  115. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/simple/__init__.py +0 -0
  116. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/simple/test_noappmap.py +0 -0
  117. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/data/unittest/simple/test_simple.py +0 -0
  118. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/normalize.py +0 -0
  119. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_command.py +0 -0
  120. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_configuration.py +0 -0
  121. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_describe_value.py +0 -0
  122. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_django.py +0 -0
  123. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_django_simplelazyobject.py +0 -0
  124. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_env.py +0 -0
  125. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_fastapi.py +0 -0
  126. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_flask.py +0 -0
  127. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_generation.py +0 -0
  128. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_http.py +0 -0
  129. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_importer.py +0 -0
  130. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_labels.py +0 -0
  131. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_metadata.py +0 -0
  132. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_params.py +0 -0
  133. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_properties.py +0 -0
  134. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_recording.py +0 -0
  135. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_runner.py +0 -0
  136. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_sqlalchemy.py +0 -0
  137. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/test_util.py +0 -0
  138. {appmap-2.1.1 → appmap-2.1.2}/_appmap/test/web_framework.py +0 -0
  139. {appmap-2.1.1 → appmap-2.1.2}/_appmap/testing_framework.py +0 -0
  140. {appmap-2.1.1 → appmap-2.1.2}/_appmap/trace_logger.py +0 -0
  141. {appmap-2.1.1 → appmap-2.1.2}/_appmap/unittest.py +0 -0
  142. {appmap-2.1.1 → appmap-2.1.2}/_appmap/utils.py +0 -0
  143. {appmap-2.1.1 → appmap-2.1.2}/_appmap/web_framework.py +0 -0
  144. {appmap-2.1.1 → appmap-2.1.2}/appmap/__init__.py +0 -0
  145. {appmap-2.1.1 → appmap-2.1.2}/appmap/command/__init__.py +0 -0
  146. {appmap-2.1.1 → appmap-2.1.2}/appmap/command/appmap_agent_init.py +0 -0
  147. {appmap-2.1.1 → appmap-2.1.2}/appmap/command/appmap_agent_status.py +0 -0
  148. {appmap-2.1.1 → appmap-2.1.2}/appmap/command/appmap_agent_validate.py +0 -0
  149. {appmap-2.1.1 → appmap-2.1.2}/appmap/command/runner.py +0 -0
  150. {appmap-2.1.1 → appmap-2.1.2}/appmap/django.py +0 -0
  151. {appmap-2.1.1 → appmap-2.1.2}/appmap/fastapi.py +0 -0
  152. {appmap-2.1.1 → appmap-2.1.2}/appmap/flask.py +0 -0
  153. {appmap-2.1.1 → appmap-2.1.2}/appmap/http.py +0 -0
  154. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/__init__.py +0 -0
  155. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/crypto.yml +0 -0
  156. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/django.yml +0 -0
  157. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/flask.yml +0 -0
  158. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/formats.yml +0 -0
  159. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/http.yml +0 -0
  160. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/jobs.yml +0 -0
  161. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/jwt.yml +0 -0
  162. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/logger.yml +0 -0
  163. {appmap-2.1.1 → appmap-2.1.2}/appmap/labeling/random.yml +0 -0
  164. {appmap-2.1.1 → appmap-2.1.2}/appmap/pytest.py +0 -0
  165. {appmap-2.1.1 → appmap-2.1.2}/appmap/sqlalchemy.py +0 -0
  166. {appmap-2.1.1 → appmap-2.1.2}/appmap/unittest.py +0 -0
  167. {appmap-2.1.1 → appmap-2.1.2}/appmap/uvicorn.py +0 -0
  168. {appmap-2.1.1 → appmap-2.1.2}/vendor/_appmap/wrapt/LICENSE +0 -0
  169. {appmap-2.1.1 → appmap-2.1.2}/vendor/_appmap/wrapt/__init__.py +0 -0
  170. {appmap-2.1.1 → appmap-2.1.2}/vendor/_appmap/wrapt/arguments.py +0 -0
  171. {appmap-2.1.1 → appmap-2.1.2}/vendor/_appmap/wrapt/decorators.py +0 -0
  172. {appmap-2.1.1 → appmap-2.1.2}/vendor/_appmap/wrapt/importer.py +0 -0
  173. {appmap-2.1.1 → appmap-2.1.2}/vendor/_appmap/wrapt/wrappers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: appmap
3
- Version: 2.1.1
3
+ Version: 2.1.2
4
4
  Summary: Create AppMap files by recording a Python application.
5
5
  Home-page: https://github.com/applandinc/appmap-python
6
6
  License: MIT
@@ -101,7 +101,12 @@ def call_instrumented(f, instance, args, kwargs):
101
101
  return ret
102
102
  except AppMapLimitExceeded:
103
103
  raise
104
- except Exception: # noqa: E722
104
+ # Some applications make use of exceptions that aren't descended from Exception. For example,
105
+ # pytest's OutcomeException, used to indicate the outcome of a test case, is a child of
106
+ # BaseException.
107
+ #
108
+ # We need to catch *any* exception raised, to ensure that we add the appropriate ExceptionEvent.
109
+ except BaseException: # noqa: E722
105
110
  elapsed_time = time.time() - start_time
106
111
  Recorder.add_event(
107
112
  event.ExceptionEvent(
@@ -5,6 +5,7 @@ and called. Used for testing appmap instrumentation.
5
5
 
6
6
  import time
7
7
  from functools import lru_cache, wraps
8
+ from typing import NoReturn
8
9
 
9
10
  import appmap
10
11
 
@@ -155,6 +156,8 @@ class ExampleClass(Super, ClassMethodMixin):
155
156
 
156
157
  write_only = property(None, set_write_only, del_write_only, "Write-only")
157
158
 
159
+ def raise_base_exception(self) -> NoReturn:
160
+ raise BaseException("not derived from Exception") # pylint: disable=broad-exception-raised
158
161
 
159
162
  def modfunc():
160
163
  return "Hello world!"
@@ -0,0 +1,12 @@
1
+ name: Simple
2
+ packages:
3
+ - path: simple
4
+ - path: _pytest
5
+ exclude:
6
+ # - _py.path
7
+ - compat.safe_getattr
8
+ - config.PytestPluginManager
9
+ - fixtures.getfixturemarker
10
+ - config.argparsing
11
+ - config.Config.rootpath
12
+ - path: pytest
@@ -0,0 +1,16 @@
1
+ import pytest
2
+
3
+ # Copied from pytest-dev/pytest. When recorded, this test case will raise an OutcomeException
4
+ # (specifically _pytest.outcomes.Skipped).
5
+ def test_skipped(pytester):
6
+ pytester.makeconftest(
7
+ """
8
+ import pytest
9
+ def pytest_ignore_collect():
10
+ pytest.skip("intentional")
11
+ """
12
+ )
13
+ pytester.makepyfile("def test_hello(): pass")
14
+ result = pytester.runpytest_inprocess()
15
+ assert result.ret == pytest.ExitCode.NO_TESTS_COLLECTED
16
+ result.stdout.fnmatch_lines(["*1 skipped*"])
@@ -44,7 +44,19 @@ def check_call_stack(events):
44
44
  if e.get("event") == "call":
45
45
  stack.append(e)
46
46
  elif e.get("event") == "return":
47
- assert len(stack) > 0, "return without call"
47
+ assert len(stack) > 0, f"return without call, {e.get('id')}"
48
48
  call = stack.pop()
49
- assert call.get("id") == e.get("parent_id")
50
- assert len(stack) == 0, "leftover events"
49
+ assert call.get("id") == e.get(
50
+ "parent_id"
51
+ ), f"parent mismatch, {call.get('id')} != {e.get('parent_id')}"
52
+ assert len(stack) == 0, f"leftover events, {len(stack)}"
53
+
54
+
55
+ if __name__ == "__main__":
56
+ import json
57
+ from pathlib import Path
58
+ import sys
59
+
60
+ with Path(sys.argv[1]).open(encoding="utf-8") as f:
61
+ appmap = json.load(f)
62
+ check_call_stack(appmap["events"])
@@ -117,3 +117,36 @@ class TestEvents:
117
117
  assert [e.method_id for e in r.events if e.event == "call" and hasattr(e, "method_id")] == [
118
118
  "return_self"
119
119
  ]
120
+
121
+ # There should be an exception return event generated even when the raised exception is a
122
+ # BaseException.
123
+ def test_exception_event_with_base_exception(self):
124
+ r = appmap.Recording()
125
+ with r:
126
+ # pylint: disable=import-outside-toplevel
127
+ from example_class import ExampleClass
128
+
129
+ try:
130
+ ExampleClass().raise_base_exception()
131
+ except BaseException: # pylint: disable=broad-exception-caught
132
+ pass
133
+ assert check_call_return_stack_order(r.events), "Unbalanced call stack"
134
+
135
+
136
+ def check_call_return_stack_order(events):
137
+ stack = []
138
+ for e in events:
139
+ if e.event == "call":
140
+ stack.append(e)
141
+ elif e.event == "return":
142
+ if len(stack) > 0:
143
+ call = stack.pop()
144
+ if call.id != e.parent_id:
145
+ return False
146
+ else:
147
+ return False
148
+ if len(stack) == 0:
149
+ return True
150
+
151
+ return False
152
+
@@ -10,10 +10,10 @@ from abc import ABC, abstractmethod
10
10
  from pathlib import Path
11
11
 
12
12
  import pytest
13
+
13
14
  from _appmap import recording
14
- from _appmap.test.helpers import package_version
15
15
 
16
- from ..test.helpers import DictIncluding
16
+ from .helpers import DictIncluding, check_call_stack, package_version
17
17
  from .normalize import normalize_appmap
18
18
 
19
19
 
@@ -155,6 +155,17 @@ def test_write_appmap(recorder_outdir):
155
155
  expected_shortname = longname[:235] + "-5d6e10d.appmap.json"
156
156
  assert (recorder_outdir / expected_shortname).read_text().startswith('{"version"')
157
157
 
158
+ @pytest.mark.example_dir("pytest-instrumented")
159
+ @pytest.mark.appmap_enabled
160
+ def test_pytest_instrumented(testdir):
161
+ result = testdir.runpytest("-svv", "-p", "pytester", "test_instrumented.py")
162
+ result.assert_outcomes(passed=1)
163
+ appmap_file = testdir.path / "tmp" / "appmap" / "pytest" / "test_skipped.appmap.json"
164
+ appmap = json.load(appmap_file.open())
165
+ events = appmap["events"]
166
+ assert len(events) > 0
167
+ check_call_stack(events)
168
+
158
169
 
159
170
  def verify_expected_appmap(testdir, suffix=""):
160
171
  appmap_json = list(testdir.output().glob("*test_hello_world.appmap.json"))
@@ -0,0 +1 @@
1
+ import appmap
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "appmap"
3
- version = "2.1.1"
3
+ version = "2.1.2"
4
4
  description = "Create AppMap files by recording a Python application."
5
5
  readme = "README.md"
6
6
  authors = [
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes