cavisson-pythonagent 0.0.1__py3-none-any.whl
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.
- cavisson_pythonagent-0.0.1.dist-info/METADATA +32 -0
- cavisson_pythonagent-0.0.1.dist-info/RECORD +180 -0
- cavisson_pythonagent-0.0.1.dist-info/WHEEL +5 -0
- cavisson_pythonagent-0.0.1.dist-info/licenses/LICENSE +19 -0
- cavisson_pythonagent-0.0.1.dist-info/top_level.txt +1 -0
- pythonagent/__init__.py +22 -0
- pythonagent/agent/__init__.py +219 -0
- pythonagent/agent/internal/__init__.py +1 -0
- pythonagent/agent/internal/agent.py +1651 -0
- pythonagent/agent/internal/framesinfo.py +152 -0
- pythonagent/agent/internal/heap_dump.py +39 -0
- pythonagent/agent/internal/intercept_module.py +70 -0
- pythonagent/agent/internal/logs.py +122 -0
- pythonagent/agent/internal/metadata/__init__.py +0 -0
- pythonagent/agent/internal/metadata/agent_meta_data.py +276 -0
- pythonagent/agent/internal/proc_compat.py +75 -0
- pythonagent/agent/internal/profile.py +47 -0
- pythonagent/agent/internal/provider.py +83 -0
- pythonagent/agent/internal/thread_dump.py +85 -0
- pythonagent/agent/internal/udp.py +245 -0
- pythonagent/agent/internal/udp_message.py +800 -0
- pythonagent/agent/probes/Instrumentation/__init__.py +340 -0
- pythonagent/agent/probes/Instrumentation/find.py +243 -0
- pythonagent/agent/probes/Instrumentation/module_version_resolver.py +155 -0
- pythonagent/agent/probes/Instrumentation/new_parser.py +64 -0
- pythonagent/agent/probes/Instrumentation/parser.py +129 -0
- pythonagent/agent/probes/__init__.py +219 -0
- pythonagent/agent/probes/base.py +303 -0
- pythonagent/agent/probes/cache/__init__.py +51 -0
- pythonagent/agent/probes/cache/redis.py +119 -0
- pythonagent/agent/probes/cache/redis_asyncio.py +83 -0
- pythonagent/agent/probes/coroutines/__init__.py +1 -0
- pythonagent/agent/probes/coroutines/asyncio.py +63 -0
- pythonagent/agent/probes/elasticdb/__init__.py +7 -0
- pythonagent/agent/probes/elasticdb/aelastic.py +54 -0
- pythonagent/agent/probes/frameworks/__init__.py +27 -0
- pythonagent/agent/probes/frameworks/agentprofiler.py +105 -0
- pythonagent/agent/probes/frameworks/aiohttp_web.py +155 -0
- pythonagent/agent/probes/frameworks/aisess.py +151 -0
- pythonagent/agent/probes/frameworks/asgi.py +340 -0
- pythonagent/agent/probes/frameworks/bottle.py +27 -0
- pythonagent/agent/probes/frameworks/cherry.py +25 -0
- pythonagent/agent/probes/frameworks/django.py +128 -0
- pythonagent/agent/probes/frameworks/falcon.py +21 -0
- pythonagent/agent/probes/frameworks/fastapi.py +35 -0
- pythonagent/agent/probes/frameworks/flask.py +30 -0
- pythonagent/agent/probes/frameworks/pyramid.py +56 -0
- pythonagent/agent/probes/frameworks/test.py +108 -0
- pythonagent/agent/probes/frameworks/tornado_async_web.py +117 -0
- pythonagent/agent/probes/frameworks/tornado_web.py +133 -0
- pythonagent/agent/probes/frameworks/wsgi.py +353 -0
- pythonagent/agent/probes/grpc/__init__.py +76 -0
- pythonagent/agent/probes/grpc/client_interceptor.py +132 -0
- pythonagent/agent/probes/grpc/server_interceptor.py +129 -0
- pythonagent/agent/probes/havoc/__init__.py +0 -0
- pythonagent/agent/probes/havoc/custom_memory_stress.py +186 -0
- pythonagent/agent/probes/havoc/custom_thread_stress.py +187 -0
- pythonagent/agent/probes/havoc/havoc_constants.py +218 -0
- pythonagent/agent/probes/havoc/havoc_manager.py +981 -0
- pythonagent/agent/probes/http/__init__.py +49 -0
- pythonagent/agent/probes/http/aiohttp_client.py +59 -0
- pythonagent/agent/probes/http/boto.py +12 -0
- pythonagent/agent/probes/http/httplib.py +110 -0
- pythonagent/agent/probes/http/httpx_client.py +116 -0
- pythonagent/agent/probes/http/requests.py +15 -0
- pythonagent/agent/probes/http/tornado_httpclient.py +85 -0
- pythonagent/agent/probes/http/urllib3.py +16 -0
- pythonagent/agent/probes/langchain/__init__.py +21 -0
- pythonagent/agent/probes/langchain/base_tool.py +95 -0
- pythonagent/agent/probes/langchain/langchain_community.py +136 -0
- pythonagent/agent/probes/langchain/langchain_core.py +32 -0
- pythonagent/agent/probes/langchain/langchain_openai.py +110 -0
- pythonagent/agent/probes/logging/__init__.py +106 -0
- pythonagent/agent/probes/message_brokers/__init__.py +4 -0
- pythonagent/agent/probes/message_brokers/pika.py +126 -0
- pythonagent/agent/probes/mongodb/__init__.py +6 -0
- pythonagent/agent/probes/mongodb/pymongo.py +286 -0
- pythonagent/agent/probes/openai/__init__.py +3 -0
- pythonagent/agent/probes/openai/openai.py +797 -0
- pythonagent/agent/probes/span.py +101 -0
- pythonagent/agent/probes/sql/__init__.py +13 -0
- pythonagent/agent/probes/sql/botocores3.py +51 -0
- pythonagent/agent/probes/sql/dbapi.py +285 -0
- pythonagent/agent/probes/sql/dynamodb.py +90 -0
- pythonagent/agent/probes/sql/mysql_connector.py +24 -0
- pythonagent/agent/probes/sql/mysql_connector_cext.py +24 -0
- pythonagent/agent/probes/sql/mysqldb.py +43 -0
- pythonagent/agent/probes/sql/psycopg2.py +174 -0
- pythonagent/agent/probes/sql/pymysql.py +25 -0
- pythonagent/bootstrap/__init__.py +0 -0
- pythonagent/bootstrap/cav_gunicorn.py +26 -0
- pythonagent/bootstrap/cavagent_lambda_wrapper.py +291 -0
- pythonagent/bootstrap/run.py +47 -0
- pythonagent/bootstrap/sitecustomize.py +287 -0
- pythonagent/cavisson/netdiagnostics/CavAgent/instrumentationprofile.json +26 -0
- pythonagent/cavisson/netdiagnostics/CavAgent/interceptor_points.txt +29 -0
- pythonagent/cavisson/netdiagnostics/python/CavAgent/instrumentationprofile.json +42 -0
- pythonagent/cavisson/netdiagnostics/python/CavAgent/interceptor_points.txt +29 -0
- pythonagent/cavisson/netdiagnostics/python/config/ndsettings.conf +6 -0
- pythonagent/config.py +279 -0
- pythonagent/find.py +72 -0
- pythonagent/find_mod_cls_name.py +54 -0
- pythonagent/lang.py +131 -0
- pythonagent/lib.py +91 -0
- pythonagent/main/__init__.py +0 -0
- pythonagent/main/pytrace/__init__.py +79 -0
- pythonagent/main/pytrace/commands/__init__.py +0 -0
- pythonagent/main/pytrace/commands/auto_discovery.py +25 -0
- pythonagent/main/pytrace/commands/run.py +401 -0
- pythonagent/main/pytrace/pytrace.py +133 -0
- pythonagent/main/wsgi.py +6 -0
- pythonagent/main.py +27 -0
- pythonagent/run.py +46 -0
- pythonagent/sqins.py +8 -0
- pythonagent/test.py +73 -0
- pythonagent/utils.py +168 -0
- pythonagent/vendor/__init__.py +0 -0
- pythonagent/vendor/pympler/__init__.py +1 -0
- pythonagent/vendor/pympler/asizeof.py +2810 -0
- pythonagent/vendor/pympler/charts.py +62 -0
- pythonagent/vendor/pympler/classtracker.py +590 -0
- pythonagent/vendor/pympler/classtracker_stats.py +780 -0
- pythonagent/vendor/pympler/garbagegraph.py +80 -0
- pythonagent/vendor/pympler/mprofile.py +97 -0
- pythonagent/vendor/pympler/muppy.py +275 -0
- pythonagent/vendor/pympler/panels.py +115 -0
- pythonagent/vendor/pympler/process.py +238 -0
- pythonagent/vendor/pympler/py.typed +0 -0
- pythonagent/vendor/pympler/refbrowser.py +451 -0
- pythonagent/vendor/pympler/refgraph.py +350 -0
- pythonagent/vendor/pympler/summary.py +321 -0
- pythonagent/vendor/pympler/tracker.py +267 -0
- pythonagent/vendor/pympler/util/__init__.py +0 -0
- pythonagent/vendor/pympler/util/bottle.py +3809 -0
- pythonagent/vendor/pympler/util/compat.py +23 -0
- pythonagent/vendor/pympler/util/stringutils.py +77 -0
- pythonagent/vendor/pympler/web.py +346 -0
- pythonagent/vendor/werkzeug/__init__.py +20 -0
- pythonagent/vendor/werkzeug/_compat.py +228 -0
- pythonagent/vendor/werkzeug/_internal.py +473 -0
- pythonagent/vendor/werkzeug/_reloader.py +341 -0
- pythonagent/vendor/werkzeug/datastructures.py +3120 -0
- pythonagent/vendor/werkzeug/debug/__init__.py +498 -0
- pythonagent/vendor/werkzeug/debug/console.py +218 -0
- pythonagent/vendor/werkzeug/debug/repr.py +297 -0
- pythonagent/vendor/werkzeug/debug/tbtools.py +628 -0
- pythonagent/vendor/werkzeug/exceptions.py +829 -0
- pythonagent/vendor/werkzeug/filesystem.py +64 -0
- pythonagent/vendor/werkzeug/formparser.py +584 -0
- pythonagent/vendor/werkzeug/http.py +1307 -0
- pythonagent/vendor/werkzeug/local.py +420 -0
- pythonagent/vendor/werkzeug/middleware/__init__.py +25 -0
- pythonagent/vendor/werkzeug/middleware/dispatcher.py +66 -0
- pythonagent/vendor/werkzeug/middleware/http_proxy.py +219 -0
- pythonagent/vendor/werkzeug/middleware/lint.py +408 -0
- pythonagent/vendor/werkzeug/middleware/profiler.py +132 -0
- pythonagent/vendor/werkzeug/middleware/proxy_fix.py +169 -0
- pythonagent/vendor/werkzeug/middleware/shared_data.py +293 -0
- pythonagent/vendor/werkzeug/posixemulation.py +117 -0
- pythonagent/vendor/werkzeug/routing.py +2210 -0
- pythonagent/vendor/werkzeug/security.py +249 -0
- pythonagent/vendor/werkzeug/serving.py +1117 -0
- pythonagent/vendor/werkzeug/test.py +1123 -0
- pythonagent/vendor/werkzeug/testapp.py +241 -0
- pythonagent/vendor/werkzeug/urls.py +1138 -0
- pythonagent/vendor/werkzeug/useragents.py +202 -0
- pythonagent/vendor/werkzeug/utils.py +778 -0
- pythonagent/vendor/werkzeug/wrappers/__init__.py +36 -0
- pythonagent/vendor/werkzeug/wrappers/accept.py +50 -0
- pythonagent/vendor/werkzeug/wrappers/auth.py +33 -0
- pythonagent/vendor/werkzeug/wrappers/base_request.py +673 -0
- pythonagent/vendor/werkzeug/wrappers/base_response.py +700 -0
- pythonagent/vendor/werkzeug/wrappers/common_descriptors.py +341 -0
- pythonagent/vendor/werkzeug/wrappers/cors.py +100 -0
- pythonagent/vendor/werkzeug/wrappers/etag.py +304 -0
- pythonagent/vendor/werkzeug/wrappers/json.py +145 -0
- pythonagent/vendor/werkzeug/wrappers/request.py +49 -0
- pythonagent/vendor/werkzeug/wrappers/response.py +84 -0
- pythonagent/vendor/werkzeug/wrappers/user_agent.py +14 -0
- pythonagent/vendor/werkzeug/wsgi.py +1000 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
werkzeug.debug.repr
|
|
4
|
+
~~~~~~~~~~~~~~~~~~~
|
|
5
|
+
|
|
6
|
+
This module implements object representations for debugging purposes.
|
|
7
|
+
Unlike the default repr these reprs expose a lot more information and
|
|
8
|
+
produce HTML instead of ASCII.
|
|
9
|
+
|
|
10
|
+
Together with the CSS and JavaScript files of the debugger this gives
|
|
11
|
+
a colorful and more compact output.
|
|
12
|
+
|
|
13
|
+
:copyright: 2007 Pallets
|
|
14
|
+
:license: BSD-3-Clause
|
|
15
|
+
"""
|
|
16
|
+
import codecs
|
|
17
|
+
import re
|
|
18
|
+
import sys
|
|
19
|
+
from collections import deque
|
|
20
|
+
from traceback import format_exception_only
|
|
21
|
+
|
|
22
|
+
from .._compat import integer_types
|
|
23
|
+
from .._compat import iteritems
|
|
24
|
+
from .._compat import PY2
|
|
25
|
+
from .._compat import string_types
|
|
26
|
+
from .._compat import text_type
|
|
27
|
+
from ..utils import escape
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
missing = object()
|
|
31
|
+
_paragraph_re = re.compile(r"(?:\r\n|\r|\n){2,}")
|
|
32
|
+
RegexType = type(_paragraph_re)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
HELP_HTML = """\
|
|
36
|
+
<div class=box>
|
|
37
|
+
<h3>%(title)s</h3>
|
|
38
|
+
<pre class=help>%(text)s</pre>
|
|
39
|
+
</div>\
|
|
40
|
+
"""
|
|
41
|
+
OBJECT_DUMP_HTML = """\
|
|
42
|
+
<div class=box>
|
|
43
|
+
<h3>%(title)s</h3>
|
|
44
|
+
%(repr)s
|
|
45
|
+
<table>%(items)s</table>
|
|
46
|
+
</div>\
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def debug_repr(obj):
|
|
51
|
+
"""Creates a debug repr of an object as HTML unicode string."""
|
|
52
|
+
return DebugReprGenerator().repr(obj)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def dump(obj=missing):
|
|
56
|
+
"""Print the object details to stdout._write (for the interactive
|
|
57
|
+
console of the web debugger.
|
|
58
|
+
"""
|
|
59
|
+
gen = DebugReprGenerator()
|
|
60
|
+
if obj is missing:
|
|
61
|
+
rv = gen.dump_locals(sys._getframe(1).f_locals)
|
|
62
|
+
else:
|
|
63
|
+
rv = gen.dump_object(obj)
|
|
64
|
+
sys.stdout._write(rv)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class _Helper(object):
|
|
68
|
+
"""Displays an HTML version of the normal help, for the interactive
|
|
69
|
+
debugger only because it requires a patched sys.stdout.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
def __repr__(self):
|
|
73
|
+
return "Type help(object) for help about object."
|
|
74
|
+
|
|
75
|
+
def __call__(self, topic=None):
|
|
76
|
+
if topic is None:
|
|
77
|
+
sys.stdout._write("<span class=help>%s</span>" % repr(self))
|
|
78
|
+
return
|
|
79
|
+
import pydoc
|
|
80
|
+
|
|
81
|
+
pydoc.help(topic)
|
|
82
|
+
rv = sys.stdout.reset()
|
|
83
|
+
if isinstance(rv, bytes):
|
|
84
|
+
rv = rv.decode("utf-8", "ignore")
|
|
85
|
+
paragraphs = _paragraph_re.split(rv)
|
|
86
|
+
if len(paragraphs) > 1:
|
|
87
|
+
title = paragraphs[0]
|
|
88
|
+
text = "\n\n".join(paragraphs[1:])
|
|
89
|
+
else: # pragma: no cover
|
|
90
|
+
title = "Help"
|
|
91
|
+
text = paragraphs[0]
|
|
92
|
+
sys.stdout._write(HELP_HTML % {"title": title, "text": text})
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
helper = _Helper()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def _add_subclass_info(inner, obj, base):
|
|
99
|
+
if isinstance(base, tuple):
|
|
100
|
+
for base in base:
|
|
101
|
+
if type(obj) is base:
|
|
102
|
+
return inner
|
|
103
|
+
elif type(obj) is base:
|
|
104
|
+
return inner
|
|
105
|
+
module = ""
|
|
106
|
+
if obj.__class__.__module__ not in ("__builtin__", "exceptions"):
|
|
107
|
+
module = '<span class="module">%s.</span>' % obj.__class__.__module__
|
|
108
|
+
return "%s%s(%s)" % (module, obj.__class__.__name__, inner)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class DebugReprGenerator(object):
|
|
112
|
+
def __init__(self):
|
|
113
|
+
self._stack = []
|
|
114
|
+
|
|
115
|
+
def _sequence_repr_maker(left, right, base=object(), limit=8): # noqa: B008, B902
|
|
116
|
+
def proxy(self, obj, recursive):
|
|
117
|
+
if recursive:
|
|
118
|
+
return _add_subclass_info(left + "..." + right, obj, base)
|
|
119
|
+
buf = [left]
|
|
120
|
+
have_extended_section = False
|
|
121
|
+
for idx, item in enumerate(obj):
|
|
122
|
+
if idx:
|
|
123
|
+
buf.append(", ")
|
|
124
|
+
if idx == limit:
|
|
125
|
+
buf.append('<span class="extended">')
|
|
126
|
+
have_extended_section = True
|
|
127
|
+
buf.append(self.repr(item))
|
|
128
|
+
if have_extended_section:
|
|
129
|
+
buf.append("</span>")
|
|
130
|
+
buf.append(right)
|
|
131
|
+
return _add_subclass_info(u"".join(buf), obj, base)
|
|
132
|
+
|
|
133
|
+
return proxy
|
|
134
|
+
|
|
135
|
+
list_repr = _sequence_repr_maker("[", "]", list)
|
|
136
|
+
tuple_repr = _sequence_repr_maker("(", ")", tuple)
|
|
137
|
+
set_repr = _sequence_repr_maker("set([", "])", set)
|
|
138
|
+
frozenset_repr = _sequence_repr_maker("frozenset([", "])", frozenset)
|
|
139
|
+
deque_repr = _sequence_repr_maker(
|
|
140
|
+
'<span class="module">collections.' "</span>deque([", "])", deque
|
|
141
|
+
)
|
|
142
|
+
del _sequence_repr_maker
|
|
143
|
+
|
|
144
|
+
def regex_repr(self, obj):
|
|
145
|
+
pattern = repr(obj.pattern)
|
|
146
|
+
if PY2:
|
|
147
|
+
pattern = pattern.decode("string-escape", "ignore")
|
|
148
|
+
else:
|
|
149
|
+
pattern = codecs.decode(pattern, "unicode-escape", "ignore")
|
|
150
|
+
if pattern[:1] == "u":
|
|
151
|
+
pattern = "ur" + pattern[1:]
|
|
152
|
+
else:
|
|
153
|
+
pattern = "r" + pattern
|
|
154
|
+
return u're.compile(<span class="string regex">%s</span>)' % pattern
|
|
155
|
+
|
|
156
|
+
def string_repr(self, obj, limit=70):
|
|
157
|
+
buf = ['<span class="string">']
|
|
158
|
+
r = repr(obj)
|
|
159
|
+
|
|
160
|
+
# shorten the repr when the hidden part would be at least 3 chars
|
|
161
|
+
if len(r) - limit > 2:
|
|
162
|
+
buf.extend(
|
|
163
|
+
(
|
|
164
|
+
escape(r[:limit]),
|
|
165
|
+
'<span class="extended">',
|
|
166
|
+
escape(r[limit:]),
|
|
167
|
+
"</span>",
|
|
168
|
+
)
|
|
169
|
+
)
|
|
170
|
+
else:
|
|
171
|
+
buf.append(escape(r))
|
|
172
|
+
|
|
173
|
+
buf.append("</span>")
|
|
174
|
+
out = u"".join(buf)
|
|
175
|
+
|
|
176
|
+
# if the repr looks like a standard string, add subclass info if needed
|
|
177
|
+
if r[0] in "'\"" or (r[0] in "ub" and r[1] in "'\""):
|
|
178
|
+
return _add_subclass_info(out, obj, (bytes, text_type))
|
|
179
|
+
|
|
180
|
+
# otherwise, assume the repr distinguishes the subclass already
|
|
181
|
+
return out
|
|
182
|
+
|
|
183
|
+
def dict_repr(self, d, recursive, limit=5):
|
|
184
|
+
if recursive:
|
|
185
|
+
return _add_subclass_info(u"{...}", d, dict)
|
|
186
|
+
buf = ["{"]
|
|
187
|
+
have_extended_section = False
|
|
188
|
+
for idx, (key, value) in enumerate(iteritems(d)):
|
|
189
|
+
if idx:
|
|
190
|
+
buf.append(", ")
|
|
191
|
+
if idx == limit - 1:
|
|
192
|
+
buf.append('<span class="extended">')
|
|
193
|
+
have_extended_section = True
|
|
194
|
+
buf.append(
|
|
195
|
+
'<span class="pair"><span class="key">%s</span>: '
|
|
196
|
+
'<span class="value">%s</span></span>'
|
|
197
|
+
% (self.repr(key), self.repr(value))
|
|
198
|
+
)
|
|
199
|
+
if have_extended_section:
|
|
200
|
+
buf.append("</span>")
|
|
201
|
+
buf.append("}")
|
|
202
|
+
return _add_subclass_info(u"".join(buf), d, dict)
|
|
203
|
+
|
|
204
|
+
def object_repr(self, obj):
|
|
205
|
+
r = repr(obj)
|
|
206
|
+
if PY2:
|
|
207
|
+
r = r.decode("utf-8", "replace")
|
|
208
|
+
return u'<span class="object">%s</span>' % escape(r)
|
|
209
|
+
|
|
210
|
+
def dispatch_repr(self, obj, recursive):
|
|
211
|
+
if obj is helper:
|
|
212
|
+
return u'<span class="help">%r</span>' % helper
|
|
213
|
+
if isinstance(obj, (integer_types, float, complex)):
|
|
214
|
+
return u'<span class="number">%r</span>' % obj
|
|
215
|
+
if isinstance(obj, string_types) or isinstance(obj, bytes):
|
|
216
|
+
return self.string_repr(obj)
|
|
217
|
+
if isinstance(obj, RegexType):
|
|
218
|
+
return self.regex_repr(obj)
|
|
219
|
+
if isinstance(obj, list):
|
|
220
|
+
return self.list_repr(obj, recursive)
|
|
221
|
+
if isinstance(obj, tuple):
|
|
222
|
+
return self.tuple_repr(obj, recursive)
|
|
223
|
+
if isinstance(obj, set):
|
|
224
|
+
return self.set_repr(obj, recursive)
|
|
225
|
+
if isinstance(obj, frozenset):
|
|
226
|
+
return self.frozenset_repr(obj, recursive)
|
|
227
|
+
if isinstance(obj, dict):
|
|
228
|
+
return self.dict_repr(obj, recursive)
|
|
229
|
+
if deque is not None and isinstance(obj, deque):
|
|
230
|
+
return self.deque_repr(obj, recursive)
|
|
231
|
+
return self.object_repr(obj)
|
|
232
|
+
|
|
233
|
+
def fallback_repr(self):
|
|
234
|
+
try:
|
|
235
|
+
info = "".join(format_exception_only(*sys.exc_info()[:2]))
|
|
236
|
+
except Exception: # pragma: no cover
|
|
237
|
+
info = "?"
|
|
238
|
+
if PY2:
|
|
239
|
+
info = info.decode("utf-8", "ignore")
|
|
240
|
+
return u'<span class="brokenrepr"><broken repr (%s)>' u"</span>" % escape(
|
|
241
|
+
info.strip()
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
def repr(self, obj):
|
|
245
|
+
recursive = False
|
|
246
|
+
for item in self._stack:
|
|
247
|
+
if item is obj:
|
|
248
|
+
recursive = True
|
|
249
|
+
break
|
|
250
|
+
self._stack.append(obj)
|
|
251
|
+
try:
|
|
252
|
+
try:
|
|
253
|
+
return self.dispatch_repr(obj, recursive)
|
|
254
|
+
except Exception:
|
|
255
|
+
return self.fallback_repr()
|
|
256
|
+
finally:
|
|
257
|
+
self._stack.pop()
|
|
258
|
+
|
|
259
|
+
def dump_object(self, obj):
|
|
260
|
+
repr = items = None
|
|
261
|
+
if isinstance(obj, dict):
|
|
262
|
+
title = "Contents of"
|
|
263
|
+
items = []
|
|
264
|
+
for key, value in iteritems(obj):
|
|
265
|
+
if not isinstance(key, string_types):
|
|
266
|
+
items = None
|
|
267
|
+
break
|
|
268
|
+
items.append((key, self.repr(value)))
|
|
269
|
+
if items is None:
|
|
270
|
+
items = []
|
|
271
|
+
repr = self.repr(obj)
|
|
272
|
+
for key in dir(obj):
|
|
273
|
+
try:
|
|
274
|
+
items.append((key, self.repr(getattr(obj, key))))
|
|
275
|
+
except Exception:
|
|
276
|
+
pass
|
|
277
|
+
title = "Details for"
|
|
278
|
+
title += " " + object.__repr__(obj)[1:-1]
|
|
279
|
+
return self.render_object_dump(items, title, repr)
|
|
280
|
+
|
|
281
|
+
def dump_locals(self, d):
|
|
282
|
+
items = [(key, self.repr(value)) for key, value in d.items()]
|
|
283
|
+
return self.render_object_dump(items, "Local variables in frame")
|
|
284
|
+
|
|
285
|
+
def render_object_dump(self, items, title, repr=None):
|
|
286
|
+
html_items = []
|
|
287
|
+
for key, value in items:
|
|
288
|
+
html_items.append(
|
|
289
|
+
"<tr><th>%s<td><pre class=repr>%s</pre>" % (escape(key), value)
|
|
290
|
+
)
|
|
291
|
+
if not html_items:
|
|
292
|
+
html_items.append("<tr><td><em>Nothing</em>")
|
|
293
|
+
return OBJECT_DUMP_HTML % {
|
|
294
|
+
"title": escape(title),
|
|
295
|
+
"repr": "<pre class=repr>%s</pre>" % repr if repr else "",
|
|
296
|
+
"items": "\n".join(html_items),
|
|
297
|
+
}
|