appmap 2.0.9__tar.gz → 2.1.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-2.0.9 → appmap-2.1.0}/PKG-INFO +1 -1
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/event.py +12 -2
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/importer.py +42 -13
- appmap-2.1.0/_appmap/test/data/django/test/test_unittest_setup.py +11 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/example_class.py +47 -0
- appmap-2.0.9/_appmap/test/data/pytest/expected/pytest.appmap.json → appmap-2.1.0/_appmap/test/data/pytest/expected/pytest-numpy1.appmap.json +113 -51
- appmap-2.1.0/_appmap/test/data/pytest/expected/pytest-numpy2.appmap.json +242 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/pytest/expected/status_errored.metadata.json +1 -1
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/pytest/expected/status_failed.metadata.json +1 -1
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/pytest/expected/status_xfailed.metadata.json +1 -1
- appmap-2.1.0/_appmap/test/data/pytest/simple.py +19 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/pytest/test_simple.py +4 -2
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_django.py +6 -4
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_params.py +1 -1
- appmap-2.1.0/_appmap/test/test_properties.py +105 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_test_frameworks.py +14 -7
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/unittest.py +12 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/utils.py +4 -0
- {appmap-2.0.9 → appmap-2.1.0}/pyproject.toml +1 -1
- appmap-2.0.9/_appmap/test/data/pytest/simple.py +0 -18
- {appmap-2.0.9 → appmap-2.1.0}/LICENSE +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/README.md +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/configuration.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/django.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/env.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/fastapi.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/flask.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/generation.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/instrument.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/labels.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/metadata.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/noappmap.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/py_version_check.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/recorder.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/recording.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/remote_recording.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/singleton.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/appmap_test_base.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/bin/server_runner +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/conftest.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-all-paths-malformed.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-broken.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-class.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-empty-path.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-exclude-fn.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-func.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-malformed-path.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap-no-pyyaml.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap_testing/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/appmap_testing/django_simplelazyobject.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config/src/package/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config/test/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config/test/foo.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-exclude/.hide/hidden_mod/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-exclude/node_modules/node_mod/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-exclude/src/package/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-exclude/test/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-exclude/venv/venv_mod/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-up/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-up/project/p1/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/config-up/project/p2/sub1/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/djangoapp/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/djangoapp/djangoapp.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/djangoapp/hello_world.html +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/djangoapp/middleware.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/djangoapp/settings.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/djangoapp/settings_dev.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/djangoapp/urls.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/init/sitecustomize.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/manage.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/pytest.ini +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/test/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/django/test/test_app.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/expected.appmap.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/fastapi/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/fastapi/fastapiapp/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/fastapi/fastapiapp/main.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/fastapi/init/sitecustomize.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/fastapi/test_app.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/flask/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/flask/flaskapp.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/flask/init/sitecustomize.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/flask/templates/test.html +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/flask/test_app.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/package1/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/package1/package2/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/package1/package2/__main__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/package1/package2/mod1.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/params.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/pytest/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/pytest/test_noappmap.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/remote.appmap.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/trial/.gitignore +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/trial/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/trial/expected/pytest.appmap.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/trial/init/sitecustomize.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/trial/test/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/trial/test/test_deferred.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/appmap.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/expected/pytest.appmap.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/expected/status_errored.metadata.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/expected/status_failed.metadata.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/expected/status_xfailed.metadata.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/expected/status_xsucceeded.metadata.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/expected/unittest.appmap.json +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/init/sitecustomize.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/simple/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/simple/test_noappmap.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/data/unittest/simple/test_simple.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/helpers.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/normalize.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_command.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_configuration.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_describe_value.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_django_simplelazyobject.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_env.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_events.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_fastapi.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_flask.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_generation.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_http.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_importer.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_labels.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_metadata.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_recording.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_runner.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_sqlalchemy.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/test_util.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/test/web_framework.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/testing_framework.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/trace_logger.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/_appmap/web_framework.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/command/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/command/appmap_agent_init.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/command/appmap_agent_status.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/command/appmap_agent_validate.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/command/runner.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/django.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/fastapi.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/flask.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/http.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/crypto.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/django.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/flask.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/formats.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/http.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/jobs.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/jwt.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/logger.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/labeling/random.yml +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/pytest.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/sqlalchemy.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/unittest.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap/uvicorn.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/appmap.pth +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/vendor/_appmap/wrapt/LICENSE +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/vendor/_appmap/wrapt/__init__.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/vendor/_appmap/wrapt/arguments.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/vendor/_appmap/wrapt/decorators.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/vendor/_appmap/wrapt/importer.py +0 -0
- {appmap-2.0.9 → appmap-2.1.0}/vendor/_appmap/wrapt/wrappers.py +0 -0
|
@@ -176,7 +176,7 @@ class Param:
|
|
|
176
176
|
|
|
177
177
|
class CallEvent(Event):
|
|
178
178
|
# pylint: disable=method-cache-max-size-none
|
|
179
|
-
__slots__ = ["_fn", "_fqfn", "static", "receiver", "parameters", "labels"]
|
|
179
|
+
__slots__ = ["_fn", "_fqfn", "static", "receiver", "parameters", "labels", "auxtype"]
|
|
180
180
|
|
|
181
181
|
@staticmethod
|
|
182
182
|
def make(fn, fntype):
|
|
@@ -283,7 +283,10 @@ class CallEvent(Event):
|
|
|
283
283
|
@property
|
|
284
284
|
@lru_cache(maxsize=None)
|
|
285
285
|
def method_id(self):
|
|
286
|
-
|
|
286
|
+
ret = self._fqfn.fqfn[1]
|
|
287
|
+
if self.auxtype is not None:
|
|
288
|
+
ret = f"{ret} ({self.auxtype})"
|
|
289
|
+
return ret
|
|
287
290
|
|
|
288
291
|
@property
|
|
289
292
|
@lru_cache(maxsize=None)
|
|
@@ -319,6 +322,13 @@ class CallEvent(Event):
|
|
|
319
322
|
parameters = parameters[1:]
|
|
320
323
|
self.parameters = parameters
|
|
321
324
|
self.labels = labels
|
|
325
|
+
self.auxtype = None
|
|
326
|
+
if fntype & FnType.GET:
|
|
327
|
+
self.auxtype = "get"
|
|
328
|
+
elif fntype & FnType.SET:
|
|
329
|
+
self.auxtype = "set"
|
|
330
|
+
elif fntype & FnType.DEL:
|
|
331
|
+
self.auxtype = "del"
|
|
322
332
|
|
|
323
333
|
def to_dict(self, attrs=None):
|
|
324
334
|
ret = super().to_dict() # get the attrs defined in __slots__
|
|
@@ -37,14 +37,14 @@ class FilterableCls(Filterable):
|
|
|
37
37
|
class FilterableFn(
|
|
38
38
|
namedtuple(
|
|
39
39
|
"FilterableFn",
|
|
40
|
-
Filterable._fields + ("static_fn",),
|
|
40
|
+
Filterable._fields + ("static_fn", "auxtype"),
|
|
41
41
|
)
|
|
42
42
|
):
|
|
43
43
|
__slots__ = ()
|
|
44
44
|
|
|
45
|
-
def __new__(cls, scope, fn, static_fn):
|
|
45
|
+
def __new__(cls, scope, fn, static_fn, auxtype=None):
|
|
46
46
|
fqname = "%s.%s" % (scope.fqname, fn.__name__)
|
|
47
|
-
self = super(FilterableFn, cls).__new__(cls, scope.scope, fqname, fn, static_fn)
|
|
47
|
+
self = super(FilterableFn, cls).__new__(cls, scope.scope, fqname, fn, static_fn, auxtype)
|
|
48
48
|
return self
|
|
49
49
|
|
|
50
50
|
@property
|
|
@@ -52,7 +52,10 @@ class FilterableFn(
|
|
|
52
52
|
if self.scope == Scope.MODULE:
|
|
53
53
|
return FnType.MODULE
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
ret = FnType.classify(self.static_fn)
|
|
56
|
+
if self.auxtype is not None:
|
|
57
|
+
ret |= self.auxtype
|
|
58
|
+
return ret
|
|
56
59
|
|
|
57
60
|
|
|
58
61
|
class Filter(ABC): # pylint: disable=too-few-public-methods
|
|
@@ -122,19 +125,31 @@ def get_members(cls):
|
|
|
122
125
|
# instead iterate over dir(cls), we would see functions from
|
|
123
126
|
# superclasses, too. Those don't need to be instrumented here,
|
|
124
127
|
# they'll get taken care of when the superclass is imported.
|
|
125
|
-
|
|
128
|
+
functions = []
|
|
129
|
+
properties = {}
|
|
126
130
|
modname = cls.__module__ if hasattr(cls, "__module__") else cls.__name__
|
|
127
131
|
for key in cls.__dict__:
|
|
128
132
|
if key.startswith("__"):
|
|
129
133
|
continue
|
|
130
134
|
static_value = inspect.getattr_static(cls, key)
|
|
131
|
-
if
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
if isinstance(static_value, property):
|
|
136
|
+
properties[key] = (
|
|
137
|
+
static_value,
|
|
138
|
+
{
|
|
139
|
+
"fget": (static_value.fget, FnType.GET),
|
|
140
|
+
"fset": (static_value.fset, FnType.SET),
|
|
141
|
+
"fdel": (static_value.fdel, FnType.DEL),
|
|
142
|
+
},
|
|
143
|
+
)
|
|
144
|
+
else:
|
|
145
|
+
if not is_member_func(static_value):
|
|
146
|
+
continue
|
|
147
|
+
value = getattr(cls, key)
|
|
148
|
+
if value.__module__ != modname:
|
|
149
|
+
continue
|
|
150
|
+
functions.append((key, static_value, value))
|
|
151
|
+
|
|
152
|
+
return (functions, properties)
|
|
138
153
|
|
|
139
154
|
|
|
140
155
|
class Importer:
|
|
@@ -177,7 +192,7 @@ class Importer:
|
|
|
177
192
|
|
|
178
193
|
def instrument_functions(filterable, selected_functions=None):
|
|
179
194
|
logger.trace(" looking for members of %s", filterable.obj)
|
|
180
|
-
functions = get_members(filterable.obj)
|
|
195
|
+
functions, properties = get_members(filterable.obj)
|
|
181
196
|
logger.trace(" functions %s", functions)
|
|
182
197
|
|
|
183
198
|
for fn_name, static_fn, fn in functions:
|
|
@@ -185,6 +200,20 @@ class Importer:
|
|
|
185
200
|
new_fn = cls.instrument_function(fn_name, filterableFn, selected_functions)
|
|
186
201
|
if new_fn != fn:
|
|
187
202
|
wrapt.wrap_function_wrapper(filterable.obj, fn_name, new_fn)
|
|
203
|
+
# Now that we've instrumented all the functions, go through the properties and update
|
|
204
|
+
# them
|
|
205
|
+
for prop_name, (prop, prop_fns) in properties.items():
|
|
206
|
+
instrumented_fns = {}
|
|
207
|
+
for k, (fn, auxtype) in prop_fns.items():
|
|
208
|
+
if fn is None:
|
|
209
|
+
continue
|
|
210
|
+
filterableFn = FilterableFn(filterable, fn, fn, auxtype)
|
|
211
|
+
new_fn = cls.instrument_function(fn.__name__, filterableFn, selected_functions)
|
|
212
|
+
if new_fn != fn:
|
|
213
|
+
new_fn = wrapt.FunctionWrapper(fn, new_fn)
|
|
214
|
+
instrumented_fns[k] = new_fn
|
|
215
|
+
instrumented_fns["doc"] = prop.__doc__
|
|
216
|
+
setattr(filterable.obj, prop_name, property(**instrumented_fns))
|
|
188
217
|
|
|
189
218
|
# Import Config here, to avoid circular top-level imports.
|
|
190
219
|
from .configuration import Config # pylint: disable=import-outside-toplevel
|
|
@@ -113,6 +113,53 @@ class ExampleClass(Super, ClassMethodMixin):
|
|
|
113
113
|
def return_self(self):
|
|
114
114
|
return self
|
|
115
115
|
|
|
116
|
+
def __init__(self):
|
|
117
|
+
self._read_only = "read only"
|
|
118
|
+
self._fully_accessible = "fully accessible"
|
|
119
|
+
self._undecorated = "undecorated"
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def read_only(self):
|
|
123
|
+
"""Read-only"""
|
|
124
|
+
return self._read_only
|
|
125
|
+
|
|
126
|
+
@property
|
|
127
|
+
def fully_accessible(self):
|
|
128
|
+
"""Fully-accessible"""
|
|
129
|
+
return self._fully_accessible
|
|
130
|
+
|
|
131
|
+
@fully_accessible.setter
|
|
132
|
+
def fully_accessible(self, v):
|
|
133
|
+
self._fully_accessible = v
|
|
134
|
+
|
|
135
|
+
@fully_accessible.deleter
|
|
136
|
+
def fully_accessible(self):
|
|
137
|
+
del self._fully_accessible
|
|
138
|
+
|
|
139
|
+
def get_undecorated(self):
|
|
140
|
+
return self._undecorated
|
|
141
|
+
|
|
142
|
+
def set_undecorated(self, value):
|
|
143
|
+
self._undecorated = value
|
|
144
|
+
|
|
145
|
+
def delete_undecorated(self):
|
|
146
|
+
del self._undecorated
|
|
147
|
+
|
|
148
|
+
undecorated_property = property(get_undecorated, set_undecorated, delete_undecorated)
|
|
149
|
+
|
|
150
|
+
def set_write_only(self, v):
|
|
151
|
+
self._write_only = v
|
|
152
|
+
|
|
153
|
+
def del_write_only(self):
|
|
154
|
+
del self._write_only
|
|
155
|
+
|
|
156
|
+
write_only = property(None, set_write_only, del_write_only, "Write-only")
|
|
157
|
+
|
|
116
158
|
|
|
117
159
|
def modfunc():
|
|
118
160
|
return "Hello world!"
|
|
161
|
+
|
|
162
|
+
if __name__ == "__main__":
|
|
163
|
+
ec = ExampleClass()
|
|
164
|
+
ec.fully_accessible = "updated"
|
|
165
|
+
print(ec.fully_accessible)
|
|
@@ -8,75 +8,95 @@
|
|
|
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",
|
|
14
11
|
"app": "Simple",
|
|
15
12
|
"recorder": {
|
|
16
13
|
"name": "pytest",
|
|
17
14
|
"type": "tests"
|
|
18
15
|
},
|
|
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,
|
|
23
27
|
"static": false,
|
|
24
28
|
"receiver": {
|
|
29
|
+
"class": "simple.Simple",
|
|
25
30
|
"kind": "req",
|
|
26
|
-
"value": "<simple.Simple object at 0xabcdef>",
|
|
27
31
|
"name": "self",
|
|
28
|
-
"
|
|
32
|
+
"value": "<simple.Simple object at 0xabcdef>"
|
|
29
33
|
},
|
|
30
34
|
"parameters": [],
|
|
31
35
|
"id": 1,
|
|
32
36
|
"event": "call",
|
|
33
|
-
"thread_id": 1
|
|
34
|
-
"defined_class": "simple.Simple",
|
|
35
|
-
"method_id": "hello_world",
|
|
36
|
-
"path": "simple.py",
|
|
37
|
-
"lineno": 16
|
|
37
|
+
"thread_id": 1
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
|
+
"defined_class": "simple.Simple",
|
|
41
|
+
"method_id": "hello",
|
|
42
|
+
"path": "simple.py",
|
|
43
|
+
"lineno": 2,
|
|
40
44
|
"static": false,
|
|
41
45
|
"receiver": {
|
|
46
|
+
"class": "simple.Simple",
|
|
42
47
|
"kind": "req",
|
|
43
|
-
"value": "<simple.Simple object at 0xabcdef>",
|
|
44
48
|
"name": "self",
|
|
45
|
-
"
|
|
49
|
+
"value": "<simple.Simple object at 0xabcdef>"
|
|
46
50
|
},
|
|
47
51
|
"parameters": [],
|
|
48
52
|
"id": 2,
|
|
49
53
|
"event": "call",
|
|
50
|
-
"thread_id": 1
|
|
51
|
-
"defined_class": "simple.Simple",
|
|
52
|
-
"method_id": "get_non_json_serializable",
|
|
53
|
-
"path": "simple.py",
|
|
54
|
-
"lineno": 13
|
|
54
|
+
"thread_id": 1
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
|
+
"return_value": {
|
|
58
|
+
"class": "builtins.str",
|
|
59
|
+
"value": "'Hello'"
|
|
60
|
+
},
|
|
61
|
+
"parent_id": 2,
|
|
62
|
+
"id": 3,
|
|
63
|
+
"event": "return",
|
|
64
|
+
"thread_id": 1
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"defined_class": "simple.Simple",
|
|
68
|
+
"method_id": "world",
|
|
69
|
+
"path": "simple.py",
|
|
70
|
+
"lineno": 5,
|
|
57
71
|
"static": false,
|
|
58
72
|
"receiver": {
|
|
73
|
+
"class": "simple.Simple",
|
|
59
74
|
"kind": "req",
|
|
60
|
-
"value": "<simple.Simple object at 0xabcdef>",
|
|
61
75
|
"name": "self",
|
|
62
|
-
"
|
|
76
|
+
"value": "<simple.Simple object at 0xabcdef>"
|
|
63
77
|
},
|
|
64
78
|
"parameters": [],
|
|
65
|
-
"id":
|
|
79
|
+
"id": 4,
|
|
66
80
|
"event": "call",
|
|
67
|
-
"thread_id": 1
|
|
68
|
-
"defined_class": "simple.Simple",
|
|
69
|
-
"method_id": "hello",
|
|
70
|
-
"path": "simple.py",
|
|
71
|
-
"lineno": 7
|
|
81
|
+
"thread_id": 1
|
|
72
82
|
},
|
|
73
83
|
{
|
|
74
84
|
"return_value": {
|
|
75
|
-
"
|
|
76
|
-
"
|
|
85
|
+
"class": "builtins.str",
|
|
86
|
+
"value": "'world!'"
|
|
77
87
|
},
|
|
78
|
-
"parent_id":
|
|
79
|
-
"id":
|
|
88
|
+
"parent_id": 4,
|
|
89
|
+
"id": 5,
|
|
90
|
+
"event": "return",
|
|
91
|
+
"thread_id": 1
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"return_value": {
|
|
95
|
+
"class": "builtins.str",
|
|
96
|
+
"value": "'Hello world!'"
|
|
97
|
+
},
|
|
98
|
+
"parent_id": 1,
|
|
99
|
+
"id": 6,
|
|
80
100
|
"event": "return",
|
|
81
101
|
"thread_id": 1
|
|
82
102
|
},
|
|
@@ -89,27 +109,52 @@
|
|
|
89
109
|
"class": "simple.Simple"
|
|
90
110
|
},
|
|
91
111
|
"parameters": [],
|
|
92
|
-
"id":
|
|
112
|
+
"id": 7,
|
|
93
113
|
"event": "call",
|
|
94
114
|
"thread_id": 1,
|
|
95
115
|
"defined_class": "simple.Simple",
|
|
96
|
-
"method_id": "
|
|
116
|
+
"method_id": "show_numpy_dict",
|
|
97
117
|
"path": "simple.py",
|
|
98
|
-
"lineno":
|
|
118
|
+
"lineno": 11
|
|
99
119
|
},
|
|
100
120
|
{
|
|
101
|
-
"
|
|
102
|
-
|
|
103
|
-
"
|
|
121
|
+
"static": false,
|
|
122
|
+
"receiver": {
|
|
123
|
+
"kind": "req",
|
|
124
|
+
"value": "<simple.Simple object at 0xabcdef>",
|
|
125
|
+
"name": "self",
|
|
126
|
+
"class": "simple.Simple"
|
|
104
127
|
},
|
|
105
|
-
"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
128
|
+
"parameters": [
|
|
129
|
+
{
|
|
130
|
+
"kind": "req",
|
|
131
|
+
"value": "{0: 'zero', 1: 'one'}",
|
|
132
|
+
"name": "d",
|
|
133
|
+
"class": "builtins.dict",
|
|
134
|
+
"properties": [
|
|
135
|
+
{
|
|
136
|
+
"name": "0",
|
|
137
|
+
"class": "builtins.str"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"name": "1",
|
|
141
|
+
"class": "builtins.str"
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"size": 2
|
|
145
|
+
}
|
|
146
|
+
],
|
|
147
|
+
"id": 8,
|
|
148
|
+
"event": "call",
|
|
149
|
+
"thread_id": 1,
|
|
150
|
+
"defined_class": "simple.Simple",
|
|
151
|
+
"method_id": "get_numpy_dict",
|
|
152
|
+
"path": "simple.py",
|
|
153
|
+
"lineno": 18
|
|
109
154
|
},
|
|
110
155
|
{
|
|
111
156
|
"return_value": {
|
|
112
|
-
"value": "{0: '
|
|
157
|
+
"value": "{0: 'zero', 1: 'one'}",
|
|
113
158
|
"class": "builtins.dict",
|
|
114
159
|
"properties": [
|
|
115
160
|
{
|
|
@@ -123,18 +168,29 @@
|
|
|
123
168
|
],
|
|
124
169
|
"size": 2
|
|
125
170
|
},
|
|
126
|
-
"parent_id":
|
|
127
|
-
"id":
|
|
171
|
+
"parent_id": 8,
|
|
172
|
+
"id": 9,
|
|
128
173
|
"event": "return",
|
|
129
174
|
"thread_id": 1
|
|
130
175
|
},
|
|
131
176
|
{
|
|
132
177
|
"return_value": {
|
|
133
|
-
"value": "'
|
|
134
|
-
"class": "builtins.
|
|
178
|
+
"value": "{0: 'zero', 1: 'one'}",
|
|
179
|
+
"class": "builtins.dict",
|
|
180
|
+
"properties": [
|
|
181
|
+
{
|
|
182
|
+
"name": "0",
|
|
183
|
+
"class": "builtins.str"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"name": "1",
|
|
187
|
+
"class": "builtins.str"
|
|
188
|
+
}
|
|
189
|
+
],
|
|
190
|
+
"size": 2
|
|
135
191
|
},
|
|
136
|
-
"parent_id":
|
|
137
|
-
"id":
|
|
192
|
+
"parent_id": 7,
|
|
193
|
+
"id": 10,
|
|
138
194
|
"event": "return",
|
|
139
195
|
"thread_id": 1
|
|
140
196
|
}
|
|
@@ -149,27 +205,33 @@
|
|
|
149
205
|
"type": "class",
|
|
150
206
|
"children": [
|
|
151
207
|
{
|
|
152
|
-
"name": "
|
|
208
|
+
"name": "get_numpy_dict",
|
|
153
209
|
"type": "function",
|
|
154
|
-
"location": "simple.py:
|
|
210
|
+
"location": "simple.py:18",
|
|
155
211
|
"static": false
|
|
156
212
|
},
|
|
157
213
|
{
|
|
158
214
|
"name": "hello",
|
|
159
215
|
"type": "function",
|
|
160
|
-
"location": "simple.py:
|
|
216
|
+
"location": "simple.py:2",
|
|
161
217
|
"static": false
|
|
162
218
|
},
|
|
163
219
|
{
|
|
164
220
|
"name": "hello_world",
|
|
165
221
|
"type": "function",
|
|
166
|
-
"location": "simple.py:
|
|
222
|
+
"location": "simple.py:8",
|
|
223
|
+
"static": false
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"name": "show_numpy_dict",
|
|
227
|
+
"type": "function",
|
|
228
|
+
"location": "simple.py:11",
|
|
167
229
|
"static": false
|
|
168
230
|
},
|
|
169
231
|
{
|
|
170
232
|
"name": "world",
|
|
171
233
|
"type": "function",
|
|
172
|
-
"location": "simple.py:
|
|
234
|
+
"location": "simple.py:5",
|
|
173
235
|
"static": false
|
|
174
236
|
}
|
|
175
237
|
]
|