14
14
from IPython .display import IFrame , display
15
15
16
16
from pyinstrument import Profiler , renderers
17
+ from pyinstrument .__main__ import _compute_render_options
17
18
from pyinstrument .frame import Frame
18
19
from pyinstrument .frame_ops import delete_frame_from_tree
19
20
from pyinstrument .processors import ProcessorOptions
21
+ from pyinstrument .renderers .console import ConsoleRenderer
22
+ from pyinstrument .renderers .html import HTMLRenderer
20
23
21
24
_active_profiler = None
22
25
@@ -76,6 +79,43 @@ def recreate_transformer(self, target_description: str):
76
79
)
77
80
78
81
@magic_arguments ()
82
+ @argument (
83
+ "-p" ,
84
+ "--render-option" ,
85
+ dest = "render_options" ,
86
+ action = "append" ,
87
+ metavar = "RENDER_OPTION" ,
88
+ type = str ,
89
+ help = (
90
+ "options to pass to the renderer, in the format 'flag_name' or 'option_name=option_value'. "
91
+ "For example, to set the option 'time', pass '-p time=percent_of_total'. To pass multiple "
92
+ "options, use the -p option multiple times. You can set processor options using dot-syntax, "
93
+ "like '-p processor_options.filter_threshold=0'. option_value is parsed as a JSON value or "
94
+ "a string."
95
+ ),
96
+ )
97
+ @argument (
98
+ "--show-regex" ,
99
+ dest = "show_regex" ,
100
+ action = "store" ,
101
+ metavar = "REGEX" ,
102
+ help = (
103
+ "regex matching the file paths whose frames to always show. "
104
+ "Useful if --show doesn't give enough control."
105
+ ),
106
+ )
107
+ @argument (
108
+ "--show" ,
109
+ dest = "show_fnmatch" ,
110
+ action = "store" ,
111
+ metavar = "EXPR" ,
112
+ help = (
113
+ "glob-style pattern matching the file paths whose frames to "
114
+ "show, regardless of --hide or --hide-regex. For example, use "
115
+ "--show '*/<library>/*' to show frames within a library that "
116
+ "would otherwise be hidden."
117
+ ),
118
+ )
79
119
@argument (
80
120
"--interval" ,
81
121
type = float ,
@@ -110,6 +150,26 @@ def recreate_transformer(self, target_description: str):
110
150
nargs = "*" ,
111
151
help = "When used as a line magic, the code to profile" ,
112
152
)
153
+ @argument (
154
+ "--hide" ,
155
+ dest = "hide_fnmatch" ,
156
+ action = "store" ,
157
+ metavar = "EXPR" ,
158
+ help = (
159
+ "glob-style pattern matching the file paths whose frames to hide. Defaults to "
160
+ "hiding non-application code"
161
+ ),
162
+ )
163
+ @argument (
164
+ "--hide-regex" ,
165
+ dest = "hide_regex" ,
166
+ action = "store" ,
167
+ metavar = "REGEX" ,
168
+ help = (
169
+ "regex matching the file paths whose frames to hide. Useful if --hide doesn't give "
170
+ "enough control."
171
+ ),
172
+ )
113
173
@no_var_expand
114
174
@line_cell_magic
115
175
def pyinstrument (self , line , cell = None ):
@@ -126,6 +186,12 @@ def pyinstrument(self, line, cell=None):
126
186
"""
127
187
global _active_profiler
128
188
args = parse_argstring (self .pyinstrument , line )
189
+
190
+ # 2024, always override this for now in IPython,
191
+ # we can make an option later if necessary
192
+ args .unicode = True
193
+ args .color = True
194
+
129
195
ip = get_ipython ()
130
196
131
197
if not ip :
@@ -175,10 +241,19 @@ def pyinstrument(self, line, cell=None):
175
241
)
176
242
return
177
243
178
- html_renderer = renderers .HTMLRenderer (
179
- show_all = args .show_all ,
180
- timeline = args .timeline ,
244
+ html_error , html_config = _compute_render_options (
245
+ args , renderer_class = HTMLRenderer , unicode_support = True , color_support = True
181
246
)
247
+ if html_error is not None :
248
+ raise ValueError (html_error )
249
+
250
+ text_error , text_config = _compute_render_options (
251
+ args , renderer_class = HTMLRenderer , unicode_support = True , color_support = True
252
+ )
253
+ if text_error is not None :
254
+ raise ValueError (text_error )
255
+
256
+ html_renderer = renderers .HTMLRenderer (show_all = args .show_all , timeline = args .timeline )
182
257
html_renderer .preprocessors .append (strip_ipython_frames_processor )
183
258
html_str = _active_profiler .output (html_renderer )
184
259
as_iframe = IFrame (
@@ -188,10 +263,7 @@ def pyinstrument(self, line, cell=None):
188
263
extras = ['style="resize: vertical"' , f'srcdoc="{ html .escape (html_str )} "' ],
189
264
)
190
265
191
- text_renderer = renderers .ConsoleRenderer (
192
- timeline = args .timeline ,
193
- show_all = args .show_all ,
194
- )
266
+ text_renderer = renderers .ConsoleRenderer (** text_config )
195
267
text_renderer .processors .append (strip_ipython_frames_processor )
196
268
197
269
as_text = _active_profiler .output (text_renderer )
0 commit comments