appmap 2.0.3__tar.gz → 2.0.4__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 (164) hide show
  1. {appmap-2.0.3 → appmap-2.0.4}/PKG-INFO +1 -1
  2. {appmap-2.0.3 → appmap-2.0.4}/_appmap/instrument.py +3 -1
  3. {appmap-2.0.3 → appmap-2.0.4}/_appmap/recorder.py +20 -0
  4. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/pytest/expected/pytest.appmap.json +81 -37
  5. appmap-2.0.4/_appmap/test/data/pytest/simple.py +18 -0
  6. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_generation.py +20 -0
  7. {appmap-2.0.3 → appmap-2.0.4}/pyproject.toml +1 -1
  8. appmap-2.0.3/_appmap/test/data/pytest/simple.py +0 -9
  9. {appmap-2.0.3 → appmap-2.0.4}/LICENSE +0 -0
  10. {appmap-2.0.3 → appmap-2.0.4}/README.md +0 -0
  11. {appmap-2.0.3 → appmap-2.0.4}/_appmap/__init__.py +0 -0
  12. {appmap-2.0.3 → appmap-2.0.4}/_appmap/configuration.py +0 -0
  13. {appmap-2.0.3 → appmap-2.0.4}/_appmap/django.py +0 -0
  14. {appmap-2.0.3 → appmap-2.0.4}/_appmap/env.py +0 -0
  15. {appmap-2.0.3 → appmap-2.0.4}/_appmap/event.py +0 -0
  16. {appmap-2.0.3 → appmap-2.0.4}/_appmap/fastapi.py +0 -0
  17. {appmap-2.0.3 → appmap-2.0.4}/_appmap/flask.py +0 -0
  18. {appmap-2.0.3 → appmap-2.0.4}/_appmap/generation.py +0 -0
  19. {appmap-2.0.3 → appmap-2.0.4}/_appmap/importer.py +0 -0
  20. {appmap-2.0.3 → appmap-2.0.4}/_appmap/labels.py +0 -0
  21. {appmap-2.0.3 → appmap-2.0.4}/_appmap/metadata.py +0 -0
  22. {appmap-2.0.3 → appmap-2.0.4}/_appmap/noappmap.py +0 -0
  23. {appmap-2.0.3 → appmap-2.0.4}/_appmap/py_version_check.py +0 -0
  24. {appmap-2.0.3 → appmap-2.0.4}/_appmap/recording.py +0 -0
  25. {appmap-2.0.3 → appmap-2.0.4}/_appmap/remote_recording.py +0 -0
  26. {appmap-2.0.3 → appmap-2.0.4}/_appmap/singleton.py +0 -0
  27. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/__init__.py +0 -0
  28. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/appmap_test_base.py +0 -0
  29. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/bin/server_runner +0 -0
  30. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/conftest.py +0 -0
  31. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-all-paths-malformed.yml +0 -0
  32. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-broken.yml +0 -0
  33. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-class.yml +0 -0
  34. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-empty-path.yml +0 -0
  35. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-exclude-fn.yml +0 -0
  36. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-func.yml +0 -0
  37. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-malformed-path.yml +0 -0
  38. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap-no-pyyaml.yml +0 -0
  39. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap.yml +0 -0
  40. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap_testing/__init__.py +0 -0
  41. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/appmap_testing/django_simplelazyobject.py +0 -0
  42. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config/src/package/__init__.py +0 -0
  43. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config/test/__init__.py +0 -0
  44. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config/test/foo.py +0 -0
  45. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-exclude/.hide/hidden_mod/__init__.py +0 -0
  46. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-exclude/node_modules/node_mod/__init__.py +0 -0
  47. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-exclude/src/package/__init__.py +0 -0
  48. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-exclude/test/__init__.py +0 -0
  49. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-exclude/venv/venv_mod/__init__.py +0 -0
  50. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-up/appmap.yml +0 -0
  51. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-up/project/p1/__init__.py +0 -0
  52. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/config-up/project/p2/sub1/__init__.py +0 -0
  53. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/appmap.yml +0 -0
  54. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/djangoapp/__init__.py +0 -0
  55. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/djangoapp/djangoapp.py +0 -0
  56. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/djangoapp/hello_world.html +0 -0
  57. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/djangoapp/middleware.py +0 -0
  58. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/djangoapp/settings.py +0 -0
  59. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/djangoapp/settings_dev.py +0 -0
  60. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/djangoapp/urls.py +0 -0
  61. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/init/sitecustomize.py +0 -0
  62. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/manage.py +0 -0
  63. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/pytest.ini +0 -0
  64. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/test/__init__.py +0 -0
  65. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/django/test/test_app.py +0 -0
  66. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/example_class.py +0 -0
  67. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/expected.appmap.json +0 -0
  68. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/fastapi/appmap.yml +0 -0
  69. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/fastapi/fastapiapp/__init__.py +0 -0
  70. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/fastapi/fastapiapp/main.py +0 -0
  71. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/fastapi/init/sitecustomize.py +0 -0
  72. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/fastapi/test_app.py +0 -0
  73. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/flask/appmap.yml +0 -0
  74. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/flask/flaskapp.py +0 -0
  75. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/flask/init/sitecustomize.py +0 -0
  76. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/flask/templates/test.html +0 -0
  77. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/flask/test_app.py +0 -0
  78. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/package1/__init__.py +0 -0
  79. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/package1/package2/__init__.py +0 -0
  80. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/package1/package2/__main__.py +0 -0
  81. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/package1/package2/mod1.py +0 -0
  82. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/params.py +0 -0
  83. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/pytest/appmap.yml +0 -0
  84. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/pytest/expected/status_errored.metadata.json +0 -0
  85. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/pytest/expected/status_failed.metadata.json +0 -0
  86. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/pytest/expected/status_xfailed.metadata.json +0 -0
  87. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/pytest/test_noappmap.py +0 -0
  88. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/pytest/test_simple.py +0 -0
  89. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/remote.appmap.json +0 -0
  90. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/trial/.gitignore +0 -0
  91. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/trial/appmap.yml +0 -0
  92. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/trial/expected/pytest.appmap.json +0 -0
  93. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/trial/init/sitecustomize.py +0 -0
  94. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/trial/test/__init__.py +0 -0
  95. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/trial/test/test_deferred.py +0 -0
  96. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/appmap.yml +0 -0
  97. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/expected/pytest.appmap.json +0 -0
  98. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/expected/status_errored.metadata.json +0 -0
  99. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/expected/status_failed.metadata.json +0 -0
  100. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/expected/status_xfailed.metadata.json +0 -0
  101. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/expected/status_xsucceeded.metadata.json +0 -0
  102. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/expected/unittest.appmap.json +0 -0
  103. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/init/sitecustomize.py +0 -0
  104. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/simple/__init__.py +0 -0
  105. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/simple/test_noappmap.py +0 -0
  106. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/data/unittest/simple/test_simple.py +0 -0
  107. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/helpers.py +0 -0
  108. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/normalize.py +0 -0
  109. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_command.py +0 -0
  110. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_configuration.py +0 -0
  111. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_describe_value.py +0 -0
  112. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_django.py +0 -0
  113. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_django_simplelazyobject.py +0 -0
  114. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_env.py +0 -0
  115. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_events.py +0 -0
  116. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_fastapi.py +0 -0
  117. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_flask.py +0 -0
  118. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_http.py +0 -0
  119. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_importer.py +0 -0
  120. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_labels.py +0 -0
  121. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_metadata.py +0 -0
  122. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_params.py +0 -0
  123. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_recording.py +0 -0
  124. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_runner.py +0 -0
  125. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_sqlalchemy.py +0 -0
  126. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_test_frameworks.py +0 -0
  127. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/test_util.py +0 -0
  128. {appmap-2.0.3 → appmap-2.0.4}/_appmap/test/web_framework.py +0 -0
  129. {appmap-2.0.3 → appmap-2.0.4}/_appmap/testing_framework.py +0 -0
  130. {appmap-2.0.3 → appmap-2.0.4}/_appmap/trace_logger.py +0 -0
  131. {appmap-2.0.3 → appmap-2.0.4}/_appmap/unittest.py +0 -0
  132. {appmap-2.0.3 → appmap-2.0.4}/_appmap/utils.py +0 -0
  133. {appmap-2.0.3 → appmap-2.0.4}/_appmap/web_framework.py +0 -0
  134. {appmap-2.0.3 → appmap-2.0.4}/appmap/__init__.py +0 -0
  135. {appmap-2.0.3 → appmap-2.0.4}/appmap/command/__init__.py +0 -0
  136. {appmap-2.0.3 → appmap-2.0.4}/appmap/command/appmap_agent_init.py +0 -0
  137. {appmap-2.0.3 → appmap-2.0.4}/appmap/command/appmap_agent_status.py +0 -0
  138. {appmap-2.0.3 → appmap-2.0.4}/appmap/command/appmap_agent_validate.py +0 -0
  139. {appmap-2.0.3 → appmap-2.0.4}/appmap/command/runner.py +0 -0
  140. {appmap-2.0.3 → appmap-2.0.4}/appmap/django.py +0 -0
  141. {appmap-2.0.3 → appmap-2.0.4}/appmap/fastapi.py +0 -0
  142. {appmap-2.0.3 → appmap-2.0.4}/appmap/flask.py +0 -0
  143. {appmap-2.0.3 → appmap-2.0.4}/appmap/http.py +0 -0
  144. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/__init__.py +0 -0
  145. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/crypto.yml +0 -0
  146. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/django.yml +0 -0
  147. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/flask.yml +0 -0
  148. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/formats.yml +0 -0
  149. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/http.yml +0 -0
  150. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/jobs.yml +0 -0
  151. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/jwt.yml +0 -0
  152. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/logger.yml +0 -0
  153. {appmap-2.0.3 → appmap-2.0.4}/appmap/labeling/random.yml +0 -0
  154. {appmap-2.0.3 → appmap-2.0.4}/appmap/pytest.py +0 -0
  155. {appmap-2.0.3 → appmap-2.0.4}/appmap/sqlalchemy.py +0 -0
  156. {appmap-2.0.3 → appmap-2.0.4}/appmap/unittest.py +0 -0
  157. {appmap-2.0.3 → appmap-2.0.4}/appmap/uvicorn.py +0 -0
  158. {appmap-2.0.3 → appmap-2.0.4}/appmap.pth +0 -0
  159. {appmap-2.0.3 → appmap-2.0.4}/vendor/_appmap/wrapt/LICENSE +0 -0
  160. {appmap-2.0.3 → appmap-2.0.4}/vendor/_appmap/wrapt/__init__.py +0 -0
  161. {appmap-2.0.3 → appmap-2.0.4}/vendor/_appmap/wrapt/arguments.py +0 -0
  162. {appmap-2.0.3 → appmap-2.0.4}/vendor/_appmap/wrapt/decorators.py +0 -0
  163. {appmap-2.0.3 → appmap-2.0.4}/vendor/_appmap/wrapt/importer.py +0 -0
  164. {appmap-2.0.3 → appmap-2.0.4}/vendor/_appmap/wrapt/wrappers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: appmap
3
- Version: 2.0.3
3
+ Version: 2.0.4
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
@@ -6,7 +6,7 @@ from contextlib import contextmanager
6
6
  from . import event
7
7
  from .env import Env
8
8
  from .event import CallEvent
9
- from .recorder import Recorder
9
+ from .recorder import Recorder, AppMapTooManyEvents
10
10
  from .utils import appmap_tls
11
11
 
12
12
  logger = Env.current.getLogger(__name__)
@@ -97,6 +97,8 @@ def call_instrumented(f, instance, args, kwargs):
97
97
  )
98
98
  Recorder.add_event(return_event)
99
99
  return ret
100
+ except AppMapTooManyEvents:
101
+ raise
100
102
  except Exception: # noqa: E722
101
103
  elapsed_time = time.time() - start_time
102
104
  Recorder.add_event(
@@ -10,6 +10,17 @@ logger = Env.current.getLogger(__name__)
10
10
  # pylint: disable=global-statement
11
11
  _default_recorder = None
12
12
 
13
+ # Allow the user to suggest a limit on the number of events that should be added to a Recorder.
14
+ # Depending on how exceptions get processed by the framework, there may be some more added, but it
15
+ # shouldn't be an enormous number.
16
+ _MAX_EVENTS = Env.current.get("APPMAP_MAX_EVENTS")
17
+ if _MAX_EVENTS is not None:
18
+ _MAX_EVENTS = int(_MAX_EVENTS)
19
+
20
+
21
+ class AppMapTooManyEvents(RuntimeError):
22
+ """Thrown when a recorder has more than APPMAP_MAX_EVENTS"""
23
+
13
24
 
14
25
  class Recorder(ABC):
15
26
  """
@@ -18,6 +29,8 @@ class Recorder(ABC):
18
29
  Note that the abstract methods have implementations for use by subclasses.
19
30
  """
20
31
 
32
+ _aborting = False
33
+
21
34
  @property
22
35
  @abstractmethod
23
36
  def events(self):
@@ -104,6 +117,7 @@ class Recorder(ABC):
104
117
  return [perthread, _default_recorder]
105
118
 
106
119
  def clear(self):
120
+ Recorder._aborting = False
107
121
  self._events = []
108
122
 
109
123
  def __init__(self, enabled=False):
@@ -130,7 +144,13 @@ class Recorder(ABC):
130
144
 
131
145
  @abstractmethod
132
146
  def _add_event(self, event):
147
+ if Recorder._aborting:
148
+ return
149
+
133
150
  self._events.append(event)
151
+ if _MAX_EVENTS is not None and len(self._events) > _MAX_EVENTS:
152
+ Recorder._aborting = True
153
+ raise AppMapTooManyEvents()
134
154
 
135
155
  @staticmethod
136
156
  def _initialize():
@@ -8,95 +8,133 @@
8
8
  "name": "appmap",
9
9
  "url": "https://github.com/applandinc/appmap-python"
10
10
  },
11
+ "source_location": "test_simple.py:5",
12
+ "name": "hello world",
13
+ "feature": "Hello world",
11
14
  "app": "Simple",
12
15
  "recorder": {
13
16
  "name": "pytest",
14
17
  "type": "tests"
15
18
  },
16
- "source_location": "test_simple.py:5",
17
- "name": "hello world",
18
- "feature": "Hello world",
19
19
  "test_status": "succeeded"
20
20
  },
21
21
  "events": [
22
22
  {
23
- "defined_class": "simple.Simple",
24
- "method_id": "hello_world",
25
- "path": "simple.py",
26
- "lineno": 8,
27
23
  "static": false,
28
24
  "receiver": {
29
- "class": "simple.Simple",
30
25
  "kind": "req",
26
+ "value": "<simple.Simple object at 0xabcdef>",
31
27
  "name": "self",
32
- "value": "<simple.Simple object at 0xabcdef>"
28
+ "class": "simple.Simple"
33
29
  },
34
30
  "parameters": [],
35
31
  "id": 1,
36
32
  "event": "call",
37
- "thread_id": 1
33
+ "thread_id": 1,
34
+ "defined_class": "simple.Simple",
35
+ "method_id": "hello_world",
36
+ "path": "simple.py",
37
+ "lineno": 16
38
38
  },
39
39
  {
40
+ "static": false,
41
+ "receiver": {
42
+ "kind": "req",
43
+ "value": "<simple.Simple object at 0xabcdef>",
44
+ "name": "self",
45
+ "class": "simple.Simple"
46
+ },
47
+ "parameters": [],
48
+ "id": 2,
49
+ "event": "call",
50
+ "thread_id": 1,
40
51
  "defined_class": "simple.Simple",
41
- "method_id": "hello",
52
+ "method_id": "get_non_json_serializable",
42
53
  "path": "simple.py",
43
- "lineno": 2,
54
+ "lineno": 13
55
+ },
56
+ {
44
57
  "static": false,
45
58
  "receiver": {
46
- "class": "simple.Simple",
47
59
  "kind": "req",
60
+ "value": "<simple.Simple object at 0xabcdef>",
48
61
  "name": "self",
49
- "value": "<simple.Simple object at 0xabcdef>"
62
+ "class": "simple.Simple"
50
63
  },
51
64
  "parameters": [],
52
- "id": 2,
65
+ "id": 3,
53
66
  "event": "call",
54
- "thread_id": 1
67
+ "thread_id": 1,
68
+ "defined_class": "simple.Simple",
69
+ "method_id": "hello",
70
+ "path": "simple.py",
71
+ "lineno": 7
55
72
  },
56
73
  {
57
74
  "return_value": {
58
- "class": "builtins.str",
59
- "value": "'Hello'"
75
+ "value": "'Hello'",
76
+ "class": "builtins.str"
60
77
  },
61
- "parent_id": 2,
62
- "id": 3,
78
+ "parent_id": 3,
79
+ "id": 4,
63
80
  "event": "return",
64
81
  "thread_id": 1
65
82
  },
66
83
  {
67
- "defined_class": "simple.Simple",
68
- "method_id": "world",
69
- "path": "simple.py",
70
- "lineno": 5,
71
84
  "static": false,
72
85
  "receiver": {
73
- "class": "simple.Simple",
74
86
  "kind": "req",
87
+ "value": "<simple.Simple object at 0xabcdef>",
75
88
  "name": "self",
76
- "value": "<simple.Simple object at 0xabcdef>"
89
+ "class": "simple.Simple"
77
90
  },
78
91
  "parameters": [],
79
- "id": 4,
92
+ "id": 5,
80
93
  "event": "call",
94
+ "thread_id": 1,
95
+ "defined_class": "simple.Simple",
96
+ "method_id": "world",
97
+ "path": "simple.py",
98
+ "lineno": 10
99
+ },
100
+ {
101
+ "return_value": {
102
+ "value": "'world!'",
103
+ "class": "builtins.str"
104
+ },
105
+ "parent_id": 5,
106
+ "id": 6,
107
+ "event": "return",
81
108
  "thread_id": 1
82
109
  },
83
110
  {
84
111
  "return_value": {
85
- "class": "builtins.str",
86
- "value": "'world!'"
112
+ "value": "{0: 'Hello', 1: 'world!'}",
113
+ "class": "builtins.dict",
114
+ "properties": [
115
+ {
116
+ "name": "0",
117
+ "class": "builtins.str"
118
+ },
119
+ {
120
+ "name": "1",
121
+ "class": "builtins.str"
122
+ }
123
+ ],
124
+ "size": 2
87
125
  },
88
- "parent_id": 4,
89
- "id": 5,
126
+ "parent_id": 2,
127
+ "id": 7,
90
128
  "event": "return",
91
129
  "thread_id": 1
92
130
  },
93
131
  {
94
132
  "return_value": {
95
- "class": "builtins.str",
96
- "value": "'Hello world!'"
133
+ "value": "'Hello world!'",
134
+ "class": "builtins.str"
97
135
  },
98
136
  "parent_id": 1,
99
- "id": 6,
137
+ "id": 8,
100
138
  "event": "return",
101
139
  "thread_id": 1
102
140
  }
@@ -110,22 +148,28 @@
110
148
  "name": "Simple",
111
149
  "type": "class",
112
150
  "children": [
151
+ {
152
+ "name": "get_non_json_serializable",
153
+ "type": "function",
154
+ "location": "simple.py:13",
155
+ "static": false
156
+ },
113
157
  {
114
158
  "name": "hello",
115
159
  "type": "function",
116
- "location": "simple.py:2",
160
+ "location": "simple.py:7",
117
161
  "static": false
118
162
  },
119
163
  {
120
164
  "name": "hello_world",
121
165
  "type": "function",
122
- "location": "simple.py:8",
166
+ "location": "simple.py:16",
123
167
  "static": false
124
168
  },
125
169
  {
126
170
  "name": "world",
127
171
  "type": "function",
128
- "location": "simple.py:5",
172
+ "location": "simple.py:10",
129
173
  "static": false
130
174
  }
131
175
  ]
@@ -0,0 +1,18 @@
1
+ import numpy
2
+
3
+ zero = numpy.int64(0)
4
+ one = numpy.int64(1)
5
+
6
+ class Simple:
7
+ def hello(self):
8
+ return "Hello"
9
+
10
+ def world(self):
11
+ return "world!"
12
+
13
+ def get_non_json_serializable(self):
14
+ return { zero: self.hello(), one: self.world() }
15
+
16
+ def hello_world(self):
17
+ result = self.get_non_json_serializable()
18
+ return "%s %s" % (result[zero], result[one])
@@ -1,5 +1,10 @@
1
+ import json
1
2
  import pytest
2
3
 
4
+ import numpy as np
5
+
6
+ from _appmap.generation import AppMapEncoder
7
+
3
8
 
4
9
  @pytest.mark.appmap_enabled
5
10
  @pytest.mark.usefixtures("with_data_dir")
@@ -48,3 +53,18 @@ class TestGeneration:
48
53
  return ret
49
54
 
50
55
  verify_example_appmap(check_comment, "instance_method")
56
+
57
+ class TestAppMapEncoder:
58
+ def test_np_int64_type(self):
59
+ data = {
60
+ "value": np.int64(42),
61
+ }
62
+ json_str = json.dumps(data, cls=AppMapEncoder)
63
+ assert '{"value": "42"}' == json_str
64
+
65
+ def test_np_array_type(self):
66
+ data = {
67
+ "value": np.array([0, 1, 2, 3])
68
+ }
69
+ json_str = json.dumps(data, cls=AppMapEncoder)
70
+ assert '{"value": "[0 1 2 3]"}' == json_str
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "appmap"
3
- version = "2.0.3"
3
+ version = "2.0.4"
4
4
  description = "Create AppMap files by recording a Python application."
5
5
  readme = "README.md"
6
6
  authors = [
@@ -1,9 +0,0 @@
1
- class Simple:
2
- def hello(self):
3
- return "Hello"
4
-
5
- def world(self):
6
- return "world!"
7
-
8
- def hello_world(self):
9
- return "%s %s" % (self.hello(), self.world())
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
File without changes