appmap 2.1.9__tar.gz → 3.0.0__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.
- appmap-3.0.0/.gitignore +26 -0
- appmap-3.0.0/PKG-INFO +223 -0
- {appmap-2.1.9 → appmap-3.0.0}/README.md +44 -42
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/env.py +14 -2
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/event.py +29 -22
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/instrument.py +15 -4
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/example_class.py +4 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/expected.appmap.json +9 -9
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/expected/pytest-numpy1-no-test-cases.appmap.json +4 -4
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/expected/pytest-numpy1.appmap.json +4 -4
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/expected/pytest-numpy2-no-test-cases.appmap.json +4 -4
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/expected/pytest-numpy2.appmap.json +4 -4
- appmap-3.0.0/_appmap/test/data/pytest/expected/status_xsucceeded.metadata.json +1 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/expected/pytest.appmap.json +11 -9
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/expected/unittest-no-test-cases.appmap.json +5 -5
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/expected/unittest.appmap.json +11 -9
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_describe_value.py +19 -5
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_events.py +56 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_http.py +2 -2
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_labels.py +17 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_params.py +7 -5
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/web_framework.py +8 -8
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/web_framework.py +1 -1
- {appmap-2.1.9 → appmap-3.0.0}/appmap/__init__.py +2 -2
- appmap-3.0.0/pyproject.toml +139 -0
- appmap-3.0.0/vendor/_appmap/wrapt/LICENSE +24 -0
- appmap-3.0.0/vendor/_appmap/wrapt/__init__.py +27 -0
- appmap-3.0.0/vendor/_appmap/wrapt/arguments.py +38 -0
- appmap-3.0.0/vendor/_appmap/wrapt/decorators.py +541 -0
- appmap-3.0.0/vendor/_appmap/wrapt/importer.py +293 -0
- appmap-3.0.0/vendor/_appmap/wrapt/wrappers.py +1100 -0
- appmap-3.0.0/vendor/patches/wrapt.patch +297 -0
- appmap-3.0.0/vendor/vendor.txt +1 -0
- appmap-2.1.9/PKG-INFO +0 -167
- appmap-2.1.9/pyproject.toml +0 -126
- {appmap-2.1.9 → appmap-3.0.0}/LICENSE +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/configuration.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/django.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/fastapi.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/flask.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/generation.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/importer.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/labels.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/metadata.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/noappmap.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/py_version_check.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/recorder.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/recording.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/remote_recording.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/singleton.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/appmap_test_base.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/bin/server_runner +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/conftest.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-all-paths-malformed.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-broken.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-class.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-empty-path.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-exclude-fn.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-func.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-malformed-path.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap-no-pyyaml.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap_testing/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/appmap_testing/django_simplelazyobject.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config/src/package/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config/test/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config/test/foo.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-exclude/.hide/hidden_mod/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-exclude/node_modules/node_mod/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-exclude/src/package/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-exclude/test/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-exclude/venv/venv_mod/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-up/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-up/project/p1/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/config-up/project/p2/sub1/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/djangoapp/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/djangoapp/djangoapp.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/djangoapp/hello_world.html +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/djangoapp/middleware.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/djangoapp/settings.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/djangoapp/settings_dev.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/djangoapp/urls.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/init/sitecustomize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/manage.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/pytest.ini +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/test/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/test/test_app.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/test/test_request.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/django/test/test_unittest_setup.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/fastapi/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/fastapi/fastapiapp/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/fastapi/fastapiapp/main.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/fastapi/init/sitecustomize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/fastapi/test_app.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask/flaskapp.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask/init/sitecustomize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask/templates/test.html +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask/test_app.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask-instrumented/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask-instrumented/flaskapp.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask-instrumented/init/sitecustomize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/flask-instrumented/test_app.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/package1/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/package1/package2/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/package1/package2/__main__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/package1/package2/mod1.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/params.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/properties_class.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/appmap-no-test-cases.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/expected/status_errored.metadata.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/expected/status_failed.metadata.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/expected/status_xfailed.metadata.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/simple.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/tests/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/tests/test_noappmap.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest/tests/test_simple.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest-instrumented/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest-instrumented/init/sitecustomize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/pytest-instrumented/test_instrumented.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/remote.appmap.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/.gitignore +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/appmap-no-test-cases.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/expected/pytest-no-test-cases.appmap.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/expected/pytest.appmap.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/init/sitecustomize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/test/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/trial/test/test_deferred.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/appmap-no-test-cases.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/appmap.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/expected/status_errored.metadata.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/expected/status_failed.metadata.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/expected/status_xfailed.metadata.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/expected/status_xsucceeded.metadata.json +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/init/sitecustomize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/simple/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/simple/test_noappmap.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/data/unittest/simple/test_simple.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/helpers.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/normalize.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_command.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_configuration.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_django.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_django_simplelazyobject.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_env.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_fastapi.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_flask.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_generation.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_importer.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_metadata.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_properties.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_recording.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_runner.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_sqlalchemy.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_test_frameworks.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/test/test_util.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/testing_framework.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/trace_logger.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/unittest.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/_appmap/utils.py +0 -0
- {appmap-2.1.9/vendor → appmap-3.0.0}/_appmap/wrapt/LICENSE +0 -0
- {appmap-2.1.9/vendor → appmap-3.0.0}/_appmap/wrapt/__init__.py +0 -0
- {appmap-2.1.9/vendor → appmap-3.0.0}/_appmap/wrapt/arguments.py +0 -0
- {appmap-2.1.9/vendor → appmap-3.0.0}/_appmap/wrapt/decorators.py +0 -0
- {appmap-2.1.9/vendor → appmap-3.0.0}/_appmap/wrapt/importer.py +0 -0
- {appmap-2.1.9/vendor → appmap-3.0.0}/_appmap/wrapt/wrappers.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/command/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/command/appmap_agent_init.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/command/appmap_agent_status.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/command/appmap_agent_validate.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/command/runner.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/django.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/fastapi.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/flask.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/http.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/__init__.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/crypto.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/django.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/flask.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/formats.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/http.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/jobs.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/jwt.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/logger.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/labeling/random.yml +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/pytest.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/sqlalchemy.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/unittest.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap/uvicorn.py +0 -0
- {appmap-2.1.9 → appmap-3.0.0}/appmap.pth +0 -0
appmap-3.0.0/.gitignore
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.envrc
|
|
2
|
+
.tool-versions
|
|
3
|
+
|
|
4
|
+
poetry.lock
|
|
5
|
+
uv.lock
|
|
6
|
+
|
|
7
|
+
__pycache__/
|
|
8
|
+
*.py[cod]
|
|
9
|
+
*$py.class
|
|
10
|
+
*.so
|
|
11
|
+
|
|
12
|
+
.python-version
|
|
13
|
+
|
|
14
|
+
/dist/
|
|
15
|
+
.venv/
|
|
16
|
+
|
|
17
|
+
htmlcov/
|
|
18
|
+
|
|
19
|
+
.vscode/
|
|
20
|
+
|
|
21
|
+
/.tox
|
|
22
|
+
/node_modules
|
|
23
|
+
/ruff.toml
|
|
24
|
+
|
|
25
|
+
appmap.log
|
|
26
|
+
*.sqlite3
|
appmap-3.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: appmap
|
|
3
|
+
Version: 3.0.0
|
|
4
|
+
Summary: Create AppMap files by recording a Python application.
|
|
5
|
+
Project-URL: Homepage, https://github.com/applandinc/appmap-python
|
|
6
|
+
Author-email: Alan Potter <alan@app.land>, Viraj Kanwade <viraj.kanwade@forgeahead.io>, Rafał Rzepecki <rafal@app.land>
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Framework :: Django
|
|
11
|
+
Classifier: Framework :: Django :: 3.2
|
|
12
|
+
Classifier: Framework :: Flask
|
|
13
|
+
Classifier: Framework :: Pytest
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Topic :: Software Development
|
|
17
|
+
Classifier: Topic :: Software Development :: Debuggers
|
|
18
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
19
|
+
Requires-Python: >=3.8
|
|
20
|
+
Requires-Dist: importlib-resources>=5.4.0
|
|
21
|
+
Requires-Dist: inflection>=0.3.0
|
|
22
|
+
Requires-Dist: packaging>=19.0
|
|
23
|
+
Requires-Dist: pyyaml>=5.3.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: asgiref<4.0,>=3.7.2; extra == 'dev'
|
|
26
|
+
Requires-Dist: black<25.0,>=24.2.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: coverage<6.0,>=5.3; extra == 'dev'
|
|
28
|
+
Requires-Dist: django; extra == 'dev'
|
|
29
|
+
Requires-Dist: fastapi<1.0,>=0.110.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: flake8<4.0,>=3.8.4; extra == 'dev'
|
|
31
|
+
Requires-Dist: flask; extra == 'dev'
|
|
32
|
+
Requires-Dist: httpretty<2.0,>=1.0.5; extra == 'dev'
|
|
33
|
+
Requires-Dist: httpx<1.0,>=0.27.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: incremental<24.7.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: isort<6.0,>=5.10.1; extra == 'dev'
|
|
36
|
+
Requires-Dist: numpy<2.0,>=1.24.4; (python_version < '3.9') and extra == 'dev'
|
|
37
|
+
Requires-Dist: numpy>=2.0; (python_version >= '3.9') and extra == 'dev'
|
|
38
|
+
Requires-Dist: pprintpp<1.0,>=0.4.0; extra == 'dev'
|
|
39
|
+
Requires-Dist: psutil<7.0,>=6.0.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pyfakefs<6.0,>=5.3.5; extra == 'dev'
|
|
41
|
+
Requires-Dist: pylint<4.0,>=3.0; extra == 'dev'
|
|
42
|
+
Requires-Dist: pytest-console-scripts<2.0,>=1.4.1; extra == 'dev'
|
|
43
|
+
Requires-Dist: pytest-django<5.0,>=4.7; extra == 'dev'
|
|
44
|
+
Requires-Dist: pytest-env<2.0,>=1.1.3; extra == 'dev'
|
|
45
|
+
Requires-Dist: pytest-mock<4.0,>=3.5.1; extra == 'dev'
|
|
46
|
+
Requires-Dist: pytest-randomly<4.0,>=3.5.0; extra == 'dev'
|
|
47
|
+
Requires-Dist: pytest-shell-utilities<2.0,>=1.8.0; extra == 'dev'
|
|
48
|
+
Requires-Dist: pytest-xdist<4.0,>=3.6.1; extra == 'dev'
|
|
49
|
+
Requires-Dist: pytest-xprocess<1.0,>=0.23.0; extra == 'dev'
|
|
50
|
+
Requires-Dist: pytest<8.0,>=7.3.2; extra == 'dev'
|
|
51
|
+
Requires-Dist: python-decouple<4.0,>=3.5; extra == 'dev'
|
|
52
|
+
Requires-Dist: requests<3.0,>=2.25.1; extra == 'dev'
|
|
53
|
+
Requires-Dist: ruff<1.0,>=0.5.3; extra == 'dev'
|
|
54
|
+
Requires-Dist: sqlalchemy; extra == 'dev'
|
|
55
|
+
Requires-Dist: tox-gh-actions<4.0,>=3.0; extra == 'dev'
|
|
56
|
+
Requires-Dist: tox-uv<2.0,>=1.0; extra == 'dev'
|
|
57
|
+
Requires-Dist: tox<5.0,>=4.0; extra == 'dev'
|
|
58
|
+
Requires-Dist: twisted<23.0,>=22.4.0; extra == 'dev'
|
|
59
|
+
Requires-Dist: urllib3<2,>=1; extra == 'dev'
|
|
60
|
+
Requires-Dist: uvicorn<1.0,>=0.27.1; extra == 'dev'
|
|
61
|
+
Provides-Extra: test
|
|
62
|
+
Requires-Dist: asgiref<4.0,>=3.7.2; extra == 'test'
|
|
63
|
+
Requires-Dist: django; extra == 'test'
|
|
64
|
+
Requires-Dist: fastapi<1.0,>=0.110.0; extra == 'test'
|
|
65
|
+
Requires-Dist: flask; extra == 'test'
|
|
66
|
+
Requires-Dist: httpretty<2.0,>=1.0.5; extra == 'test'
|
|
67
|
+
Requires-Dist: httpx<1.0,>=0.27.0; extra == 'test'
|
|
68
|
+
Requires-Dist: incremental<24.7.0; extra == 'test'
|
|
69
|
+
Requires-Dist: numpy<2.0,>=1.24.4; (python_version < '3.9') and extra == 'test'
|
|
70
|
+
Requires-Dist: numpy>=2.0; (python_version >= '3.9') and extra == 'test'
|
|
71
|
+
Requires-Dist: psutil<7.0,>=6.0.0; extra == 'test'
|
|
72
|
+
Requires-Dist: pyfakefs<6.0,>=5.3.5; extra == 'test'
|
|
73
|
+
Requires-Dist: pytest-console-scripts<2.0,>=1.4.1; extra == 'test'
|
|
74
|
+
Requires-Dist: pytest-django<5.0,>=4.7; extra == 'test'
|
|
75
|
+
Requires-Dist: pytest-env<2.0,>=1.1.3; extra == 'test'
|
|
76
|
+
Requires-Dist: pytest-mock<4.0,>=3.5.1; extra == 'test'
|
|
77
|
+
Requires-Dist: pytest-randomly<4.0,>=3.5.0; extra == 'test'
|
|
78
|
+
Requires-Dist: pytest-shell-utilities<2.0,>=1.8.0; extra == 'test'
|
|
79
|
+
Requires-Dist: pytest-xdist<4.0,>=3.6.1; extra == 'test'
|
|
80
|
+
Requires-Dist: pytest-xprocess<1.0,>=0.23.0; extra == 'test'
|
|
81
|
+
Requires-Dist: pytest<8.0,>=7.3.2; extra == 'test'
|
|
82
|
+
Requires-Dist: python-decouple<4.0,>=3.5; extra == 'test'
|
|
83
|
+
Requires-Dist: requests<3.0,>=2.25.1; extra == 'test'
|
|
84
|
+
Requires-Dist: sqlalchemy; extra == 'test'
|
|
85
|
+
Requires-Dist: twisted<23.0,>=22.4.0; extra == 'test'
|
|
86
|
+
Requires-Dist: urllib3<2,>=1; extra == 'test'
|
|
87
|
+
Requires-Dist: uvicorn<1.0,>=0.27.1; extra == 'test'
|
|
88
|
+
Description-Content-Type: text/markdown
|
|
89
|
+
|
|
90
|
+
- [About](#about)
|
|
91
|
+
- [Usage](#usage)
|
|
92
|
+
- [Development](#development)
|
|
93
|
+
- [Getting the code](#getting-the-code)
|
|
94
|
+
- [Python version support](#python-version-support)
|
|
95
|
+
- [Dependency management](#dependency-management)
|
|
96
|
+
- [wrapt](#wrapt)
|
|
97
|
+
- [Linting](#linting)
|
|
98
|
+
- [Testing](#testing)
|
|
99
|
+
- [pytest](#pytest)
|
|
100
|
+
- [tox](#tox)
|
|
101
|
+
- [Code Coverage](#code-coverage)
|
|
102
|
+
|
|
103
|
+
# About
|
|
104
|
+
`appmap-python` is a Python package for recording
|
|
105
|
+
[AppMaps](https://github.com/applandinc/appmap) of your code. "AppMap" is a data format
|
|
106
|
+
which records code structure (modules, classes, and methods), code execution events
|
|
107
|
+
(function calls and returns), and code metadata (repo name, repo URL, commit SHA, labels,
|
|
108
|
+
etc). It's more granular than a performance profile, but it's less granular than a full
|
|
109
|
+
debug trace. It's designed to be optimal for understanding the design intent and structure
|
|
110
|
+
of code and key data flows.
|
|
111
|
+
|
|
112
|
+
# Usage
|
|
113
|
+
|
|
114
|
+
Visit the [AppMap for Python](https://appland.com/docs/reference/appmap-python.html) reference page on AppLand.com for a complete reference guide.
|
|
115
|
+
|
|
116
|
+
# Development
|
|
117
|
+
|
|
118
|
+
[](https://travis-ci.com/getappmap/appmap-python)
|
|
119
|
+
|
|
120
|
+
## Getting the code
|
|
121
|
+
Clone the repo to begin development.
|
|
122
|
+
|
|
123
|
+
```shell
|
|
124
|
+
% git clone https://github.com/applandinc/appmap-python.git
|
|
125
|
+
Cloning into 'appmap-python'...
|
|
126
|
+
remote: Enumerating objects: 167, done.
|
|
127
|
+
remote: Counting objects: 100% (167/167), done.
|
|
128
|
+
remote: Compressing objects: 100% (100/100), done.
|
|
129
|
+
remote: Total 962 (delta 95), reused 116 (delta 61), pack-reused 795
|
|
130
|
+
Receiving objects: 100% (962/962), 217.31 KiB | 4.62 MiB/s, done.
|
|
131
|
+
Resolving deltas: 100% (653/653), done.
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Python version support
|
|
135
|
+
As a package intended to be installed in as many environments as possible, `appmap-python`
|
|
136
|
+
needs to avoid using features of Python or the standard library that were added after the
|
|
137
|
+
oldest version currently supported (see the
|
|
138
|
+
[supported versions](https://appland.com/docs/reference/appmap-python.html#supported-versions)).
|
|
139
|
+
|
|
140
|
+
## Dependency management
|
|
141
|
+
|
|
142
|
+
[uv](https://docs.astral.sh/uv/) is used for dependency management and provides fast package installation:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
# Install uv (macOS/Linux)
|
|
146
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
147
|
+
|
|
148
|
+
# Install dependencies
|
|
149
|
+
cd appmap-python
|
|
150
|
+
uv sync --all-extras
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### wrapt
|
|
154
|
+
The one dependency that is not managed using `uv` is `wrapt`. Because it's possible that
|
|
155
|
+
projects that use `appmap` may also need an unmodified version of `wrapt` (e.g. `pylint` depends on
|
|
156
|
+
`astroid`, which in turn depends on `wrapt`), we use
|
|
157
|
+
[vendoring](https://github.com/pradyunsg/vendoring) to vendor `wrapt`.
|
|
158
|
+
|
|
159
|
+
To update `wrapt`, use `tox` (described below) to run the `vendoring` environment.
|
|
160
|
+
|
|
161
|
+
## Linting
|
|
162
|
+
[pylint](https://www.pylint.org/) for linting:
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
cd appmap-python
|
|
166
|
+
uv run tox -e lint
|
|
167
|
+
|
|
168
|
+
# Or run pylint directly
|
|
169
|
+
uv run pylint appmap
|
|
170
|
+
|
|
171
|
+
--------------------------------------------------------------------
|
|
172
|
+
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
## Testing
|
|
177
|
+
### pytest
|
|
178
|
+
|
|
179
|
+
[pytest](https://docs.pytest.org/en/stable/) for testing:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
cd appmap-python
|
|
183
|
+
|
|
184
|
+
# Run all tests
|
|
185
|
+
APPMAP_DISPLAY_PARAMS=true uv run appmap-python pytest
|
|
186
|
+
|
|
187
|
+
# Run tests with a specific Python version
|
|
188
|
+
APPMAP_DISPLAY_PARAMS=true uv run --python 3.9 appmap-python pytest
|
|
189
|
+
|
|
190
|
+
# Run tests in parallel
|
|
191
|
+
APPMAP_DISPLAY_PARAMS=true uv run appmap-python pytest -n auto
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### tox
|
|
195
|
+
The `tox` configuration provides the ability to run the tests for all supported versions of Python and web frameworks (Django, Flask, SQLAlchemy).
|
|
196
|
+
|
|
197
|
+
With `uv`, you don't need to pre-install Python versions - `uv` will automatically download and manage them:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
cd appmap-python
|
|
201
|
+
|
|
202
|
+
# Run full test matrix (all Python versions and frameworks)
|
|
203
|
+
uv run tox
|
|
204
|
+
|
|
205
|
+
# Run tests for a specific Python version
|
|
206
|
+
uv run tox -e py312-web
|
|
207
|
+
|
|
208
|
+
# Run tests for specific framework
|
|
209
|
+
uv run tox -e py312-django5
|
|
210
|
+
|
|
211
|
+
# Update vendored wrapt dependency
|
|
212
|
+
uv run tox -e vendoring sync
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Code Coverage
|
|
216
|
+
[coverage](https://coverage.readthedocs.io/) for coverage:
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
cd appmap-python
|
|
220
|
+
uv run coverage run -m pytest
|
|
221
|
+
uv run coverage html
|
|
222
|
+
open htmlcov/index.html
|
|
223
|
+
```
|
|
@@ -50,16 +50,19 @@ oldest version currently supported (see the
|
|
|
50
50
|
|
|
51
51
|
## Dependency management
|
|
52
52
|
|
|
53
|
-
[
|
|
53
|
+
[uv](https://docs.astral.sh/uv/) is used for dependency management and provides fast package installation:
|
|
54
54
|
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
```bash
|
|
56
|
+
# Install uv (macOS/Linux)
|
|
57
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
58
|
+
|
|
59
|
+
# Install dependencies
|
|
60
|
+
cd appmap-python
|
|
61
|
+
uv sync --all-extras
|
|
59
62
|
```
|
|
60
63
|
|
|
61
64
|
### wrapt
|
|
62
|
-
The one dependency that is not managed using `
|
|
65
|
+
The one dependency that is not managed using `uv` is `wrapt`. Because it's possible that
|
|
63
66
|
projects that use `appmap` may also need an unmodified version of `wrapt` (e.g. `pylint` depends on
|
|
64
67
|
`astroid`, which in turn depends on `wrapt`), we use
|
|
65
68
|
[vendoring](https://github.com/pradyunsg/vendoring) to vendor `wrapt`.
|
|
@@ -69,64 +72,63 @@ To update `wrapt`, use `tox` (described below) to run the `vendoring` environmen
|
|
|
69
72
|
## Linting
|
|
70
73
|
[pylint](https://www.pylint.org/) for linting:
|
|
71
74
|
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
```bash
|
|
76
|
+
cd appmap-python
|
|
77
|
+
uv run tox -e lint
|
|
78
|
+
|
|
79
|
+
# Or run pylint directly
|
|
80
|
+
uv run pylint appmap
|
|
75
81
|
|
|
76
82
|
--------------------------------------------------------------------
|
|
77
83
|
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
|
|
78
|
-
|
|
79
84
|
```
|
|
80
85
|
|
|
81
|
-
[Note that the current configuration has a threshold set which must be met for the Travis build to
|
|
82
|
-
pass. To make this easier to achieve, a number of checks have both been disabled. They should be
|
|
83
|
-
reenabled as soon as possible.]
|
|
84
|
-
|
|
85
86
|
|
|
86
87
|
## Testing
|
|
87
88
|
### pytest
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
[requirements-dev.txt](requirements-dev.txt) before running tests. See the explanation in
|
|
91
|
-
[pyproject.toml](pyproject.toml) for details.
|
|
90
|
+
[pytest](https://docs.pytest.org/en/stable/) for testing:
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
```bash
|
|
93
|
+
cd appmap-python
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
# Run all tests
|
|
96
|
+
APPMAP_DISPLAY_PARAMS=true uv run appmap-python pytest
|
|
97
97
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
# Run tests with a specific Python version
|
|
99
|
+
APPMAP_DISPLAY_PARAMS=true uv run --python 3.9 appmap-python pytest
|
|
100
|
+
|
|
101
|
+
# Run tests in parallel
|
|
102
|
+
APPMAP_DISPLAY_PARAMS=true uv run appmap-python pytest -n auto
|
|
102
103
|
```
|
|
103
104
|
|
|
104
105
|
### tox
|
|
105
|
-
|
|
106
|
-
supported versions of Python and Django.
|
|
106
|
+
The `tox` configuration provides the ability to run the tests for all supported versions of Python and web frameworks (Django, Flask, SQLAlchemy).
|
|
107
107
|
|
|
108
|
-
`
|
|
109
|
-
the test environments. [pyenv](https://github.com/pyenv/pyenv) is an easy way to manage
|
|
110
|
-
multiple versions of Python, and the [xxenv-latest
|
|
111
|
-
plugin](https://github.com/momo-lab/xxenv-latest) can help get all the latest versions.
|
|
108
|
+
With `uv`, you don't need to pre-install Python versions - `uv` will automatically download and manage them:
|
|
112
109
|
|
|
110
|
+
```bash
|
|
111
|
+
cd appmap-python
|
|
113
112
|
|
|
113
|
+
# Run full test matrix (all Python versions and frameworks)
|
|
114
|
+
uv run tox
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
# Run tests for a specific Python version
|
|
117
|
+
uv run tox -e py312-web
|
|
118
|
+
|
|
119
|
+
# Run tests for specific framework
|
|
120
|
+
uv run tox -e py312-django5
|
|
121
|
+
|
|
122
|
+
# Update vendored wrapt dependency
|
|
123
|
+
uv run tox -e vendoring sync
|
|
122
124
|
```
|
|
123
125
|
|
|
124
126
|
## Code Coverage
|
|
125
127
|
[coverage](https://coverage.readthedocs.io/) for coverage:
|
|
126
128
|
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
129
|
+
```bash
|
|
130
|
+
cd appmap-python
|
|
131
|
+
uv run coverage run -m pytest
|
|
132
|
+
uv run coverage html
|
|
133
|
+
open htmlcov/index.html
|
|
132
134
|
```
|
|
@@ -45,8 +45,16 @@ class Env(metaclass=SingletonMeta):
|
|
|
45
45
|
# them.
|
|
46
46
|
enabled = self._env.get("_APPMAP", None)
|
|
47
47
|
self._enabled = enabled is not None and enabled.lower() != "false"
|
|
48
|
-
display_params = self._env.get("_APPMAP_DISPLAY_PARAMS",
|
|
49
|
-
|
|
48
|
+
display_params = self._env.get("_APPMAP_DISPLAY_PARAMS", "labeled").lower()
|
|
49
|
+
if display_params == "true":
|
|
50
|
+
self._display_params = True
|
|
51
|
+
self._display_labeled_params = True
|
|
52
|
+
elif display_params == "false":
|
|
53
|
+
self._display_params = False
|
|
54
|
+
self._display_labeled_params = False
|
|
55
|
+
else: # "labeled" or "auto" or anything else defaults to labeled
|
|
56
|
+
self._display_params = False
|
|
57
|
+
self._display_labeled_params = True
|
|
50
58
|
|
|
51
59
|
logger = logging.getLogger(__name__)
|
|
52
60
|
# The user shouldn't set APPMAP_OUTPUT_DIR, but some tests depend on being able to use it.
|
|
@@ -134,6 +142,10 @@ class Env(metaclass=SingletonMeta):
|
|
|
134
142
|
def display_params(self):
|
|
135
143
|
return self._display_params
|
|
136
144
|
|
|
145
|
+
@property
|
|
146
|
+
def display_labeled_params(self):
|
|
147
|
+
return self._display_labeled_params
|
|
148
|
+
|
|
137
149
|
def getLogger(self, name) -> trace_logger.TraceLogger:
|
|
138
150
|
return cast(trace_logger.TraceLogger, logging.getLogger(name))
|
|
139
151
|
|
|
@@ -45,15 +45,16 @@ class _EventIds:
|
|
|
45
45
|
cls._next_thread_id = 0
|
|
46
46
|
|
|
47
47
|
|
|
48
|
-
def display_string(val):
|
|
48
|
+
def display_string(val, display_value=False):
|
|
49
49
|
# If we're asked to display parameters, make a best-effort attempt
|
|
50
|
-
# to get a string value for the parameter
|
|
51
|
-
# display is disabled, or repr() has
|
|
52
|
-
# from the class and id.
|
|
50
|
+
# to get a string value for the parameter. str types are returned as-is;
|
|
51
|
+
# other types use repr(). If parameter display is disabled, or repr() has
|
|
52
|
+
# raised, just formulate a value from the class and id.
|
|
53
53
|
value = None
|
|
54
|
-
if
|
|
54
|
+
if display_value:
|
|
55
55
|
try:
|
|
56
|
-
|
|
56
|
+
# Use issubclass(type()) instead of isinstance() to avoid side effects on lazy objects
|
|
57
|
+
value = val if issubclass(type(val), str) else repr(val)
|
|
57
58
|
except Exception: # pylint: disable=broad-except
|
|
58
59
|
pass
|
|
59
60
|
|
|
@@ -79,7 +80,7 @@ def _is_list_or_dict(val_type):
|
|
|
79
80
|
return issubclass(val_type, list), issubclass(val_type, dict)
|
|
80
81
|
|
|
81
82
|
|
|
82
|
-
def _describe_schema(name, val, depth, max_depth):
|
|
83
|
+
def _describe_schema(name, val, depth, max_depth, display_value=False):
|
|
83
84
|
|
|
84
85
|
val_type = type(val)
|
|
85
86
|
|
|
@@ -88,6 +89,9 @@ def _describe_schema(name, val, depth, max_depth):
|
|
|
88
89
|
ret["name"] = name
|
|
89
90
|
ret["class"] = fqname(val_type)
|
|
90
91
|
|
|
92
|
+
if not display_value:
|
|
93
|
+
return ret
|
|
94
|
+
|
|
91
95
|
islist, isdict = _is_list_or_dict(val_type)
|
|
92
96
|
if not (islist or isdict) or (depth >= max_depth and isdict):
|
|
93
97
|
return ret
|
|
@@ -100,7 +104,10 @@ def _describe_schema(name, val, depth, max_depth):
|
|
|
100
104
|
elts = val.items()
|
|
101
105
|
schema_key = "properties"
|
|
102
106
|
|
|
103
|
-
schema = [
|
|
107
|
+
schema = [
|
|
108
|
+
_describe_schema(k, v, depth + 1, max_depth, display_value=display_value)
|
|
109
|
+
for k, v in elts
|
|
110
|
+
]
|
|
104
111
|
# schema will be [None] if depth is exceeded, don't use it
|
|
105
112
|
if any(schema):
|
|
106
113
|
ret[schema_key] = schema
|
|
@@ -108,15 +115,14 @@ def _describe_schema(name, val, depth, max_depth):
|
|
|
108
115
|
return ret
|
|
109
116
|
|
|
110
117
|
|
|
111
|
-
def describe_value(name, val, max_depth=5):
|
|
112
|
-
ret =
|
|
118
|
+
def describe_value(name, val, max_depth=5, display_value=False):
|
|
119
|
+
ret = _describe_schema(name, val, 0, max_depth, display_value=display_value)
|
|
120
|
+
ret.update({
|
|
113
121
|
"object_id": id(val),
|
|
114
|
-
"value": display_string(val),
|
|
115
|
-
}
|
|
116
|
-
if Env.current.display_params:
|
|
117
|
-
ret.update(_describe_schema(name, val, 0, max_depth))
|
|
122
|
+
"value": display_string(val, display_value=display_value),
|
|
123
|
+
})
|
|
118
124
|
|
|
119
|
-
if any(_is_list_or_dict(type(val))):
|
|
125
|
+
if display_value and any(_is_list_or_dict(type(val))):
|
|
120
126
|
ret["size"] = len(val)
|
|
121
127
|
|
|
122
128
|
return ret
|
|
@@ -170,9 +176,9 @@ class Param:
|
|
|
170
176
|
def __repr__(self):
|
|
171
177
|
return "<Param name: %s kind: %s>" % (self.name, self.kind)
|
|
172
178
|
|
|
173
|
-
def to_dict(self, value):
|
|
179
|
+
def to_dict(self, value, display_value=False):
|
|
174
180
|
ret = {"kind": self.kind}
|
|
175
|
-
ret.update(describe_value(self.name, value))
|
|
181
|
+
ret.update(describe_value(self.name, value, display_value=display_value))
|
|
176
182
|
return ret
|
|
177
183
|
|
|
178
184
|
def _get_name_parts(filterable):
|
|
@@ -247,7 +253,7 @@ class CallEvent(Event):
|
|
|
247
253
|
return [Param(p) for p in sig.parameters.values()]
|
|
248
254
|
|
|
249
255
|
@staticmethod
|
|
250
|
-
def set_params(params, instance, args, kwargs):
|
|
256
|
+
def set_params(params, instance, args, kwargs, display_value=False):
|
|
251
257
|
# pylint: disable=too-many-branches
|
|
252
258
|
# Note that set_params expects args and kwargs as a tuple and
|
|
253
259
|
# dict, respectively. It operates on them as collections, so
|
|
@@ -295,7 +301,7 @@ class CallEvent(Event):
|
|
|
295
301
|
# If all the parameter types are handled, this
|
|
296
302
|
# shouldn't ever happen...
|
|
297
303
|
raise RuntimeError("Unknown parameter with desc %s" % (repr(p)))
|
|
298
|
-
ret.append(p.to_dict(value))
|
|
304
|
+
ret.append(p.to_dict(value, display_value=display_value))
|
|
299
305
|
return ret
|
|
300
306
|
|
|
301
307
|
@property
|
|
@@ -405,8 +411,9 @@ class MessageEvent(Event): # pylint: disable=too-few-public-methods
|
|
|
405
411
|
|
|
406
412
|
@message_parameters.setter
|
|
407
413
|
def message_parameters(self, params):
|
|
414
|
+
display_params = Env.current.display_params
|
|
408
415
|
for name, value in params.items():
|
|
409
|
-
message_object = describe_value(name, value)
|
|
416
|
+
message_object = describe_value(name, value, display_value=display_params)
|
|
410
417
|
self.message.append(message_object)
|
|
411
418
|
|
|
412
419
|
|
|
@@ -497,13 +504,13 @@ class ReturnEvent(Event):
|
|
|
497
504
|
class FuncReturnEvent(ReturnEvent):
|
|
498
505
|
__slots__ = ["return_value"]
|
|
499
506
|
|
|
500
|
-
def __init__(self, parent_id, elapsed, return_value):
|
|
507
|
+
def __init__(self, parent_id, elapsed, return_value, display_value=False):
|
|
501
508
|
super().__init__(parent_id, elapsed)
|
|
502
509
|
# Import here to prevent circular dependency
|
|
503
510
|
# pylint: disable=import-outside-toplevel
|
|
504
511
|
from _appmap.instrument import recording_disabled # noqa: F401
|
|
505
512
|
with recording_disabled():
|
|
506
|
-
self.return_value = describe_value(None, return_value)
|
|
513
|
+
self.return_value = describe_value(None, return_value, display_value=display_value)
|
|
507
514
|
|
|
508
515
|
|
|
509
516
|
class HttpResponseEvent(ReturnEvent):
|
|
@@ -70,7 +70,7 @@ def saved_shallow_rule():
|
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
_InstrumentedFn = namedtuple(
|
|
73
|
-
"_InstrumentedFn", "fn fntype instrumented_fn make_call_event params"
|
|
73
|
+
"_InstrumentedFn", "fn fntype instrumented_fn make_call_event params display_params"
|
|
74
74
|
)
|
|
75
75
|
|
|
76
76
|
|
|
@@ -84,7 +84,9 @@ def call_instrumented(f, instance, args, kwargs):
|
|
|
84
84
|
|
|
85
85
|
with recording_disabled():
|
|
86
86
|
logger.trace("%s args %s kwargs %s", f.fn, args, kwargs)
|
|
87
|
-
params = CallEvent.set_params(
|
|
87
|
+
params = CallEvent.set_params(
|
|
88
|
+
f.params, instance, args, kwargs, display_value=f.display_params
|
|
89
|
+
)
|
|
88
90
|
call_event = f.make_call_event(parameters=params)
|
|
89
91
|
Recorder.add_event(call_event)
|
|
90
92
|
call_event_id = call_event.id
|
|
@@ -95,7 +97,8 @@ def call_instrumented(f, instance, args, kwargs):
|
|
|
95
97
|
elapsed_time = time.time() - start_time
|
|
96
98
|
|
|
97
99
|
return_event = event.FuncReturnEvent(
|
|
98
|
-
return_value=ret, parent_id=call_event_id, elapsed=elapsed_time
|
|
100
|
+
return_value=ret, parent_id=call_event_id, elapsed=elapsed_time,
|
|
101
|
+
display_value=f.display_params
|
|
99
102
|
)
|
|
100
103
|
Recorder.add_event(return_event)
|
|
101
104
|
return ret
|
|
@@ -120,9 +123,16 @@ def instrument(filterable):
|
|
|
120
123
|
"""return an instrumented function"""
|
|
121
124
|
logger.debug("hooking %s", filterable.fqname)
|
|
122
125
|
|
|
126
|
+
# note this has to happen before CallEvent.make, which clears this attribute
|
|
127
|
+
has_labels = hasattr(filterable.obj, "_appmap_labels")
|
|
128
|
+
|
|
123
129
|
make_call_event = event.CallEvent.make(filterable)
|
|
124
130
|
params = CallEvent.make_params(filterable)
|
|
125
131
|
|
|
132
|
+
display_params = Env.current.display_params or (
|
|
133
|
+
has_labels and Env.current.display_labeled_params
|
|
134
|
+
)
|
|
135
|
+
|
|
126
136
|
# django depends on being able to find the cache_clear attribute
|
|
127
137
|
# on functions. (You can see this by trying to map
|
|
128
138
|
# https://github.com/chicagopython/chypi.org.) Make sure it gets
|
|
@@ -132,7 +142,8 @@ def instrument(filterable):
|
|
|
132
142
|
def instrumented_fn(wrapped, instance, args, kwargs):
|
|
133
143
|
with saved_shallow_rule():
|
|
134
144
|
f = _InstrumentedFn(
|
|
135
|
-
wrapped, filterable.fntype, instrumented_fn, make_call_event, params
|
|
145
|
+
wrapped, filterable.fntype, instrumented_fn, make_call_event, params,
|
|
146
|
+
display_params
|
|
136
147
|
)
|
|
137
148
|
return call_instrumented(f, instance, args, kwargs)
|
|
138
149
|
|
|
@@ -56,6 +56,10 @@ class ExampleClass(Super, ClassMethodMixin):
|
|
|
56
56
|
def labeled_method(self):
|
|
57
57
|
return "super important"
|
|
58
58
|
|
|
59
|
+
@appmap.labels("super", "important")
|
|
60
|
+
def labeled_method_with_param(self, p):
|
|
61
|
+
return p
|
|
62
|
+
|
|
59
63
|
@staticmethod
|
|
60
64
|
@wrap_fn
|
|
61
65
|
def wrapped_static_method():
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
{
|
|
24
24
|
"return_value": {
|
|
25
25
|
"class": "builtins.str",
|
|
26
|
-
"value": "
|
|
26
|
+
"value": "ExampleClass.static_method\n...\n"
|
|
27
27
|
},
|
|
28
28
|
"parent_id": 1,
|
|
29
29
|
"id": 2,
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
{
|
|
50
50
|
"return_value": {
|
|
51
51
|
"class": "builtins.str",
|
|
52
|
-
"value": "
|
|
52
|
+
"value": "ClassMethodMixin#class_method, cls ExampleClass"
|
|
53
53
|
},
|
|
54
54
|
"parent_id": 3,
|
|
55
55
|
"id": 4,
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
{
|
|
76
76
|
"return_value": {
|
|
77
77
|
"class": "builtins.str",
|
|
78
|
-
"value": "
|
|
78
|
+
"value": "Super#instance_method"
|
|
79
79
|
},
|
|
80
80
|
"parent_id": 5,
|
|
81
81
|
"id": 6,
|
|
@@ -127,7 +127,7 @@
|
|
|
127
127
|
"name": "data",
|
|
128
128
|
"kind": "req",
|
|
129
129
|
"class": "builtins.str",
|
|
130
|
-
"value": "
|
|
130
|
+
"value": "ExampleClass.call_yaml"
|
|
131
131
|
}
|
|
132
132
|
],
|
|
133
133
|
"id": 10,
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
"name": "data",
|
|
145
145
|
"kind": "req",
|
|
146
146
|
"class": "builtins.str",
|
|
147
|
-
"value": "
|
|
147
|
+
"value": "ExampleClass.call_yaml"
|
|
148
148
|
},
|
|
149
149
|
{
|
|
150
150
|
"name": "stream",
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
{
|
|
177
177
|
"return_value": {
|
|
178
178
|
"class": "builtins.str",
|
|
179
|
-
"value": "
|
|
179
|
+
"value": "ExampleClass.call_yaml\n...\n"
|
|
180
180
|
},
|
|
181
181
|
"parent_id": 11,
|
|
182
182
|
"id": 12,
|
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
"name": "data",
|
|
191
191
|
"kind": "req",
|
|
192
192
|
"class": "builtins.str",
|
|
193
|
-
"value": "
|
|
193
|
+
"value": "ExampleClass.call_yaml"
|
|
194
194
|
},
|
|
195
195
|
{
|
|
196
196
|
"name": "stream",
|
|
@@ -222,7 +222,7 @@
|
|
|
222
222
|
{
|
|
223
223
|
"return_value": {
|
|
224
224
|
"class": "builtins.str",
|
|
225
|
-
"value": "
|
|
225
|
+
"value": "ExampleClass.call_yaml\n...\n"
|
|
226
226
|
},
|
|
227
227
|
"parent_id": 13,
|
|
228
228
|
"id": 14,
|
|
@@ -334,4 +334,4 @@
|
|
|
334
334
|
]
|
|
335
335
|
}
|
|
336
336
|
]
|
|
337
|
-
}
|
|
337
|
+
}
|