austin-python 1.4.2__tar.gz → 1.5.1__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 (66) hide show
  1. {austin_python-1.4.2 → austin_python-1.5.1}/PKG-INFO +4 -3
  2. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/mojo.py +24 -12
  3. {austin_python-1.4.2 → austin_python-1.5.1}/pyproject.toml +2 -2
  4. austin_python-1.5.1/test/data/column.mojo +0 -0
  5. austin_python-1.5.1/test/data/column.py +20 -0
  6. austin_python-1.5.1/test/format/test_mojo.py +160 -0
  7. {austin_python-1.4.2 → austin_python-1.5.1}/test/test_threads.py +6 -19
  8. austin_python-1.4.2/test/format/test_mojo.py +0 -60
  9. {austin_python-1.4.2 → austin_python-1.5.1}/.flake8 +0 -0
  10. {austin_python-1.4.2 → austin_python-1.5.1}/.gitignore +0 -0
  11. {austin_python-1.4.2 → austin_python-1.5.1}/.readthedocs.yml +0 -0
  12. {austin_python-1.4.2 → austin_python-1.5.1}/AUTHORS +0 -0
  13. {austin_python-1.4.2 → austin_python-1.5.1}/CODE-OF-CONDUCT.md +0 -0
  14. {austin_python-1.4.2 → austin_python-1.5.1}/CONTRIBUTING.md +0 -0
  15. {austin_python-1.4.2 → austin_python-1.5.1}/COPYING +0 -0
  16. {austin_python-1.4.2 → austin_python-1.5.1}/ISSUE_TEMPLATE.md +0 -0
  17. {austin_python-1.4.2 → austin_python-1.5.1}/LICENSE.md +0 -0
  18. {austin_python-1.4.2 → austin_python-1.5.1}/MANIFEST.in +0 -0
  19. {austin_python-1.4.2 → austin_python-1.5.1}/PULL_REQUEST_TEMPLATE.md +0 -0
  20. {austin_python-1.4.2 → austin_python-1.5.1}/README.md +0 -0
  21. {austin_python-1.4.2 → austin_python-1.5.1}/austin/__init__.py +0 -0
  22. {austin_python-1.4.2 → austin_python-1.5.1}/austin/aio.py +0 -0
  23. {austin_python-1.4.2 → austin_python-1.5.1}/austin/cli.py +0 -0
  24. {austin_python-1.4.2 → austin_python-1.5.1}/austin/config.py +0 -0
  25. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/__init__.py +0 -0
  26. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/compress.py +0 -0
  27. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/pprof/__init__.py +0 -0
  28. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/pprof/__main__.py +0 -0
  29. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/pprof/profile.proto +0 -0
  30. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/pprof/profile_pb2.py +0 -0
  31. {austin_python-1.4.2 → austin_python-1.5.1}/austin/format/speedscope.py +0 -0
  32. {austin_python-1.4.2 → austin_python-1.5.1}/austin/simple.py +0 -0
  33. {austin_python-1.4.2 → austin_python-1.5.1}/austin/stats.py +0 -0
  34. {austin_python-1.4.2 → austin_python-1.5.1}/austin/threads.py +0 -0
  35. {austin_python-1.4.2 → austin_python-1.5.1}/austin/tools/diff.py +0 -0
  36. {austin_python-1.4.2 → austin_python-1.5.1}/austin/tools/resolve.py +0 -0
  37. {austin_python-1.4.2 → austin_python-1.5.1}/test/__init__.py +0 -0
  38. {austin_python-1.4.2 → austin_python-1.5.1}/test/conftest.py +0 -0
  39. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/austin.json +0 -0
  40. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/austin.out +0 -0
  41. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/austin.pprof +0 -0
  42. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/austinp.mojo +0 -0
  43. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/austinp.resolved.mojo +0 -0
  44. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/diff_a-b.austin +0 -0
  45. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/diff_a.austin +0 -0
  46. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/diff_b.austin +0 -0
  47. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/mp.austin +0 -0
  48. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/mp.mojo +0 -0
  49. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/test.austin +0 -0
  50. {austin_python-1.4.2 → austin_python-1.5.1}/test/data/test.mojo +0 -0
  51. {austin_python-1.4.2 → austin_python-1.5.1}/test/format/__init__.py +0 -0
  52. {austin_python-1.4.2 → austin_python-1.5.1}/test/format/test_compress.py +0 -0
  53. {austin_python-1.4.2 → austin_python-1.5.1}/test/format/test_pprof.py +0 -0
  54. {austin_python-1.4.2 → austin_python-1.5.1}/test/format/test_speedscope.py +0 -0
  55. {austin_python-1.4.2 → austin_python-1.5.1}/test/stats/test_austin_file_reader.py +0 -0
  56. {austin_python-1.4.2 → austin_python-1.5.1}/test/stats/test_austin_stats.py +0 -0
  57. {austin_python-1.4.2 → austin_python-1.5.1}/test/stats/test_frame.py +0 -0
  58. {austin_python-1.4.2 → austin_python-1.5.1}/test/stats/test_hierarchical_stats.py +0 -0
  59. {austin_python-1.4.2 → austin_python-1.5.1}/test/stats/test_sample.py +0 -0
  60. {austin_python-1.4.2 → austin_python-1.5.1}/test/test_aio.py +0 -0
  61. {austin_python-1.4.2 → austin_python-1.5.1}/test/test_cli.py +0 -0
  62. {austin_python-1.4.2 → austin_python-1.5.1}/test/test_config.py +0 -0
  63. {austin_python-1.4.2 → austin_python-1.5.1}/test/test_semver.py +0 -0
  64. {austin_python-1.4.2 → austin_python-1.5.1}/test/test_simple.py +0 -0
  65. {austin_python-1.4.2 → austin_python-1.5.1}/test/tools/test_diff.py +0 -0
  66. {austin_python-1.4.2 → austin_python-1.5.1}/test/tools/test_resolve.py +0 -0
@@ -1,12 +1,13 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: austin-python
3
- Version: 1.4.2
3
+ Version: 1.5.1
4
4
  Summary: Python wrapper for Austin, the CPython frame stack sampler.
5
5
  Project-URL: homepage, https://github.com/P403n1x87/austin-python
6
6
  Project-URL: documentation, https://austin-python.readthedocs.io
7
7
  Project-URL: repository, https://github.com/P403n1x87/austin-python
8
8
  Project-URL: issues, https://github.com/P403n1x87/austin-python/issues
9
9
  Author-email: "Gabriele N. Tornetta" <phoenix1987@gmail.com>
10
+ License-Expression: GPL-3.0-or-later
10
11
  License-File: AUTHORS
11
12
  License-File: COPYING
12
13
  License-File: LICENSE.md
@@ -20,9 +21,9 @@ Classifier: Programming Language :: Python :: 3.9
20
21
  Classifier: Programming Language :: Python :: 3.10
21
22
  Classifier: Programming Language :: Python :: 3.11
22
23
  Requires-Python: >=3.7
23
- Requires-Dist: protobuf~=3.12.2
24
+ Requires-Dist: protobuf~=3.12
24
25
  Requires-Dist: psutil>=5.7.0
25
- Requires-Dist: toml~=0.10.2
26
+ Requires-Dist: toml~=0.10
26
27
  Description-Content-Type: text/markdown
27
28
 
28
29
  <p align="center">
@@ -93,7 +93,7 @@ class MojoEvent:
93
93
  return ""
94
94
 
95
95
 
96
- @dataclass
96
+ @dataclass(frozen=True, eq=True)
97
97
  class MojoString(MojoEvent):
98
98
  """MOJO string."""
99
99
 
@@ -101,7 +101,7 @@ class MojoString(MojoEvent):
101
101
  value: str
102
102
 
103
103
 
104
- @dataclass
104
+ @dataclass(frozen=True, eq=True)
105
105
  class MojoStringReference(MojoEvent):
106
106
  """MOJO string reference."""
107
107
 
@@ -118,7 +118,7 @@ class MojoIdle(MojoEvent):
118
118
  pass
119
119
 
120
120
 
121
- @dataclass
121
+ @dataclass(frozen=True, eq=True)
122
122
  class MojoMetadata(MojoEvent):
123
123
  """MOJO metadata."""
124
124
 
@@ -130,7 +130,7 @@ class MojoMetadata(MojoEvent):
130
130
  return f"# {self.key}: {self.value}\n"
131
131
 
132
132
 
133
- @dataclass
133
+ @dataclass(frozen=True, eq=True)
134
134
  class MojoStack(MojoEvent):
135
135
  """MOJO stack."""
136
136
 
@@ -142,7 +142,7 @@ class MojoStack(MojoEvent):
142
142
  return f"P{self.pid};T{int(self.tid, 16)}"
143
143
 
144
144
 
145
- @dataclass
145
+ @dataclass(frozen=True, eq=True)
146
146
  class MojoFrame(MojoEvent):
147
147
  """MOJO frame."""
148
148
 
@@ -150,9 +150,12 @@ class MojoFrame(MojoEvent):
150
150
  filename: MojoStringReference
151
151
  scope: MojoStringReference
152
152
  line: int
153
+ line_end: int = 0
154
+ column: int = 0
155
+ column_end: int = 0
153
156
 
154
157
 
155
- @dataclass
158
+ @dataclass(frozen=True, eq=True)
156
159
  class MojoKernelFrame(MojoEvent):
157
160
  """MOJO kernel frame."""
158
161
 
@@ -163,7 +166,7 @@ class MojoKernelFrame(MojoEvent):
163
166
  return f";kernel:{self.scope}:0"
164
167
 
165
168
 
166
- @dataclass
169
+ @dataclass(frozen=True, eq=True)
167
170
  class MojoSpecialFrame(MojoEvent):
168
171
  """MOJO special frame."""
169
172
 
@@ -174,7 +177,7 @@ class MojoSpecialFrame(MojoEvent):
174
177
  return f";:{self.label}:"
175
178
 
176
179
 
177
- @dataclass
180
+ @dataclass(frozen=True, eq=True)
178
181
  class MojoFrameReference(MojoEvent):
179
182
  """MOJO frame reference."""
180
183
 
@@ -185,7 +188,7 @@ class MojoFrameReference(MojoEvent):
185
188
  return f";{self.frame.filename.to_austin()}:{self.frame.scope.to_austin()}:{self.frame.line}"
186
189
 
187
190
 
188
- @dataclass
191
+ @dataclass(frozen=True, eq=True)
189
192
  class MojoMetric(MojoEvent):
190
193
  """MOJO metric."""
191
194
 
@@ -197,7 +200,7 @@ class MojoMetric(MojoEvent):
197
200
  return f" {self.value}\n"
198
201
 
199
202
 
200
- @dataclass
203
+ @dataclass(frozen=True, eq=True)
201
204
  class MojoFullMetrics(MojoEvent):
202
205
  """MOJO full metrics."""
203
206
 
@@ -339,7 +342,16 @@ class MojoFile:
339
342
  scope = MojoStringReference(self._lookup_string())
340
343
  line = self.read_int()
341
344
 
342
- frame = MojoFrame(frame_key, filename, scope, line)
345
+ if self.mojo_version == 1:
346
+ line_end = column = column_end = 0
347
+ else:
348
+ line_end = self.read_int()
349
+ column = self.read_int()
350
+ column_end = self.read_int()
351
+
352
+ frame = MojoFrame(
353
+ frame_key, filename, scope, line, line_end, column, column_end
354
+ )
343
355
 
344
356
  self._frame_map[self.ref(frame_key)] = frame
345
357
 
@@ -421,7 +433,7 @@ class MojoFile:
421
433
 
422
434
  try:
423
435
  for event in t.cast(dict, self.__handlers__)[event_id](self):
424
- event.raw = bytes(self._last_bytes)
436
+ object.__setattr__(event, "raw", bytes(self._last_bytes))
425
437
  self._last_bytes.clear()
426
438
  yield event
427
439
  except KeyError as exc:
@@ -44,9 +44,9 @@ classifiers = [
44
44
 
45
45
  requires-python = ">=3.7"
46
46
  dependencies = [
47
- "protobuf~=3.12.2",
47
+ "protobuf~=3.12",
48
48
  "psutil>=5.7.0",
49
- "toml~=0.10.2",
49
+ "toml~=0.10",
50
50
  ]
51
51
 
52
52
  dynamic = ["version"]
@@ -0,0 +1,20 @@
1
+ from time import sleep
2
+
3
+ def lazy(n):
4
+ for _ in range(n):
5
+ sleep(0.1)
6
+ yield _
7
+
8
+
9
+ def fib(n):
10
+ a, b = 0, 1
11
+ for _ in range(n):
12
+ yield a
13
+ a, b = b, a + b
14
+
15
+ a = [
16
+ list(fib(_))
17
+ for _ in lazy(30)
18
+ ]
19
+
20
+ print(a)
@@ -0,0 +1,160 @@
1
+ # This file is part of "austin-python" which is released under GPL.
2
+ #
3
+ # See file LICENCE or go to http://www.gnu.org/licenses/ for full license
4
+ # details.
5
+ #
6
+ # austin-python is a Python wrapper around Austin, the CPython frame stack
7
+ # sampler.
8
+ #
9
+ # Copyright (c) 2018-2022 Gabriele N. Tornetta <phoenix1987@gmail.com>.
10
+ # All rights reserved.
11
+ #
12
+ # This program is free software: you can redistribute it and/or modify
13
+ # it under the terms of the GNU General Public License as published by
14
+ # the Free Software Foundation, either version 3 of the License, or
15
+ # (at your option) any later version.
16
+ #
17
+ # This program is distributed in the hope that it will be useful,
18
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
+ # GNU General Public License for more details.
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ import sys
25
+ import tempfile
26
+ from io import BytesIO
27
+ from pathlib import Path
28
+ from random import randint
29
+
30
+ import pytest
31
+
32
+ from austin.format.mojo import MojoFile, MojoFrame, MojoString, MojoStringReference
33
+ from austin.format.mojo import main
34
+ from austin.format.mojo import to_varint
35
+
36
+
37
+ HERE = Path(__file__).parent
38
+ DATA = HERE.parent / "data"
39
+
40
+
41
+ @pytest.mark.parametrize("case", ["test", "mp"])
42
+ def test_mojo_snapshot(case):
43
+ input = (DATA / case).with_suffix(".mojo")
44
+ output = Path(tempfile.NamedTemporaryFile().name).with_suffix(".austin")
45
+ expected = (DATA / case).with_suffix(".austin")
46
+
47
+ sys.argv = ["mojo2austin", str(input), str(output)]
48
+
49
+ main()
50
+
51
+ assert expected.read_text() == output.read_text()
52
+
53
+
54
+ def test_mojo_varint():
55
+ for _ in range(100_000):
56
+ n = randint(-4e9, 4e9)
57
+ buffer = BytesIO()
58
+ buffer.write(b"MOJ\0" + to_varint(n))
59
+ buffer.seek(0)
60
+ assert MojoFile(buffer).read_int() == n
61
+
62
+
63
+ def test_mojo_column_info():
64
+ with (DATA / "column.mojo").open("rb") as stream:
65
+ frames = {
66
+ _
67
+ for _ in MojoFile(stream).parse()
68
+ if isinstance(_, MojoFrame) and _.filename.string.value == "/tmp/column.py"
69
+ }
70
+ assert frames == {
71
+ MojoFrame(
72
+ key=1289736945696,
73
+ filename=MojoStringReference(
74
+ string=MojoString(key=20271280, value="/tmp/column.py")
75
+ ),
76
+ scope=MojoStringReference(
77
+ string=MojoString(key=28930616, value="<module>")
78
+ ),
79
+ line=15,
80
+ line_end=18,
81
+ column=5,
82
+ column_end=2,
83
+ ),
84
+ MojoFrame(
85
+ key=1293162643485,
86
+ filename=MojoStringReference(
87
+ string=MojoString(key=20271280, value="/tmp/column.py")
88
+ ),
89
+ scope=MojoStringReference(
90
+ string=MojoString(key=20364976, value="lazy")
91
+ ),
92
+ line=5,
93
+ line_end=5,
94
+ column=9,
95
+ column_end=19,
96
+ ),
97
+ MojoFrame(
98
+ key=1293180469286,
99
+ filename=MojoStringReference(
100
+ string=MojoString(key=20271280, value="/tmp/column.py")
101
+ ),
102
+ scope=MojoStringReference(string=MojoString(key=20357744, value="fib")),
103
+ line=11,
104
+ line_end=13,
105
+ column=5,
106
+ column_end=24,
107
+ ),
108
+ MojoFrame(
109
+ key=1276044640259,
110
+ filename=MojoStringReference(
111
+ string=MojoString(key=20271280, value="/tmp/column.py")
112
+ ),
113
+ scope=MojoStringReference(
114
+ string=MojoString(key=28930552, value="<listcomp>")
115
+ ),
116
+ line=15,
117
+ line_end=18,
118
+ column=5,
119
+ column_end=2,
120
+ ),
121
+ MojoFrame(
122
+ key=1289736945703,
123
+ filename=MojoStringReference(
124
+ string=MojoString(key=20271280, value="/tmp/column.py")
125
+ ),
126
+ scope=MojoStringReference(
127
+ string=MojoString(key=28930616, value="<module>")
128
+ ),
129
+ line=20,
130
+ line_end=20,
131
+ column=1,
132
+ column_end=9,
133
+ ),
134
+ MojoFrame(
135
+ key=1293162643483,
136
+ filename=MojoStringReference(
137
+ string=MojoString(key=20271280, value="/tmp/column.py")
138
+ ),
139
+ scope=MojoStringReference(
140
+ string=MojoString(key=20364976, value="lazy")
141
+ ),
142
+ line=5,
143
+ line_end=5,
144
+ column=9,
145
+ column_end=19,
146
+ ),
147
+ MojoFrame(
148
+ key=1276044640281,
149
+ filename=MojoStringReference(
150
+ string=MojoString(key=20271280, value="/tmp/column.py")
151
+ ),
152
+ scope=MojoStringReference(
153
+ string=MojoString(key=28930552, value="<listcomp>")
154
+ ),
155
+ line=16,
156
+ line_end=16,
157
+ column=5,
158
+ column_end=17,
159
+ ),
160
+ }
@@ -25,21 +25,9 @@ from pytest import raises
25
25
 
26
26
  from austin import AustinError
27
27
  from austin import AustinTerminated
28
- from austin.simple import SimpleAustin
29
28
  from austin.threads import ThreadedAustin
30
29
 
31
30
 
32
- def check_raises(exc):
33
- def _check_raises_decorator(f):
34
- def _check_raises_wrapper(*args, **kwargs):
35
- with raises(exc):
36
- f(*args, **kwargs)
37
-
38
- return _check_raises_wrapper
39
-
40
- return _check_raises_decorator
41
-
42
-
43
31
  class TestThreadedAustin(ThreadedAustin):
44
32
  __test__ = False
45
33
 
@@ -72,10 +60,6 @@ class TestThreadedAustin(ThreadedAustin):
72
60
  class InvalidBinaryThreadedAustin(ThreadedAustin):
73
61
  BINARY = "_austin"
74
62
 
75
- @check_raises(AustinError)
76
- def run(self, *args, **kwargs):
77
- super().run(*args, **kwargs)
78
-
79
63
 
80
64
  def test_threaded():
81
65
  austin = TestThreadedAustin()
@@ -109,8 +93,10 @@ def test_threaded_terminate():
109
93
 
110
94
 
111
95
  def test_threaded_invalid_binary():
112
- SimpleAustin.start = check_raises(AustinError)(SimpleAustin.start)
113
- InvalidBinaryThreadedAustin(sample_callback=lambda x: None).start(["python"])
96
+ austin = InvalidBinaryThreadedAustin(sample_callback=lambda x: None)
97
+ austin.start(["python"])
98
+ with raises(AustinError):
99
+ austin.join()
114
100
 
115
101
 
116
102
  def test_threaded_no_sample_callback():
@@ -121,4 +107,5 @@ def test_threaded_no_sample_callback():
121
107
  def test_threaded_bad_options():
122
108
  austin = TestThreadedAustin(terminate_callback=lambda *args: None)
123
109
  austin.start(["-I", "1000", "python", "-c", "for i in range(1000000): print(i)"])
124
- austin.join()
110
+ with raises(AustinError):
111
+ austin.join()
@@ -1,60 +0,0 @@
1
- # This file is part of "austin-python" which is released under GPL.
2
- #
3
- # See file LICENCE or go to http://www.gnu.org/licenses/ for full license
4
- # details.
5
- #
6
- # austin-python is a Python wrapper around Austin, the CPython frame stack
7
- # sampler.
8
- #
9
- # Copyright (c) 2018-2022 Gabriele N. Tornetta <phoenix1987@gmail.com>.
10
- # All rights reserved.
11
- #
12
- # This program is free software: you can redistribute it and/or modify
13
- # it under the terms of the GNU General Public License as published by
14
- # the Free Software Foundation, either version 3 of the License, or
15
- # (at your option) any later version.
16
- #
17
- # This program is distributed in the hope that it will be useful,
18
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
19
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
- # GNU General Public License for more details.
21
- # You should have received a copy of the GNU General Public License
22
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
23
-
24
- import sys
25
- import tempfile
26
- from io import BytesIO
27
- from pathlib import Path
28
- from random import randint
29
-
30
- import pytest
31
-
32
- from austin.format.mojo import MojoFile
33
- from austin.format.mojo import main
34
- from austin.format.mojo import to_varint
35
-
36
-
37
- HERE = Path(__file__).parent
38
- DATA = HERE.parent / "data"
39
-
40
-
41
- @pytest.mark.parametrize("case", ["test", "mp"])
42
- def test_mojo_snapshot(case):
43
- input = (DATA / case).with_suffix(".mojo")
44
- output = Path(tempfile.NamedTemporaryFile().name).with_suffix(".austin")
45
- expected = (DATA / case).with_suffix(".austin")
46
-
47
- sys.argv = ["mojo2austin", str(input), str(output)]
48
-
49
- main()
50
-
51
- assert expected.read_text() == output.read_text()
52
-
53
-
54
- def test_mojo_varint():
55
- for _ in range(100_000):
56
- n = randint(-4e9, 4e9)
57
- buffer = BytesIO()
58
- buffer.write(b"MOJ\0" + to_varint(n))
59
- buffer.seek(0)
60
- assert MojoFile(buffer).read_int() == n
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes