Skip to content

Commit 543b13d

Browse files
committed
Format files
1 parent 97ba97e commit 543b13d

File tree

2 files changed

+642
-376
lines changed

2 files changed

+642
-376
lines changed

Lib/profile/sample.py

Lines changed: 71 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -168,27 +168,53 @@ def _print_top_functions(stats_list, title, key_func, format_line, n=3):
168168

169169
# Aggregate stats by fully qualified function name (ignoring line numbers)
170170
func_aggregated = {}
171-
for func, prim_calls, total_calls, total_time, cumulative_time, callers in stats_list:
171+
for (
172+
func,
173+
prim_calls,
174+
total_calls,
175+
total_time,
176+
cumulative_time,
177+
callers,
178+
) in stats_list:
172179
# Use filename:function_name as the key to get fully qualified name
173180
qualified_name = f"{func[0]}:{func[2]}"
174181
if qualified_name not in func_aggregated:
175-
func_aggregated[qualified_name] = [0, 0, 0, 0] # prim_calls, total_calls, total_time, cumulative_time
182+
func_aggregated[qualified_name] = [
183+
0,
184+
0,
185+
0,
186+
0,
187+
] # prim_calls, total_calls, total_time, cumulative_time
176188
func_aggregated[qualified_name][0] += prim_calls
177189
func_aggregated[qualified_name][1] += total_calls
178190
func_aggregated[qualified_name][2] += total_time
179191
func_aggregated[qualified_name][3] += cumulative_time
180192

181193
# Convert aggregated data back to list format for processing
182194
aggregated_stats = []
183-
for qualified_name, (prim_calls, total_calls, total_time, cumulative_time) in func_aggregated.items():
195+
for qualified_name, (
196+
prim_calls,
197+
total_calls,
198+
total_time,
199+
cumulative_time,
200+
) in func_aggregated.items():
184201
# Parse the qualified name back to filename and function name
185202
if ":" in qualified_name:
186203
filename, func_name = qualified_name.rsplit(":", 1)
187204
else:
188205
filename, func_name = "", qualified_name
189206
# Create a dummy func tuple with filename and function name for display
190207
dummy_func = (filename, "", func_name)
191-
aggregated_stats.append((dummy_func, prim_calls, total_calls, total_time, cumulative_time, {}))
208+
aggregated_stats.append(
209+
(
210+
dummy_func,
211+
prim_calls,
212+
total_calls,
213+
total_time,
214+
cumulative_time,
215+
{},
216+
)
217+
)
192218

193219
# Most time-consuming functions (by total time)
194220
def format_time_consuming(stat):
@@ -294,30 +320,29 @@ def sample(
294320
else:
295321
collector.export(filename)
296322

323+
297324
def _validate_collapsed_format_args(args, parser):
298325
# Check for incompatible pstats options
299326
invalid_opts = []
300-
327+
301328
# Get list of pstats-specific options
302-
pstats_options = {
303-
'sort': None,
304-
'limit': None,
305-
'no_summary': False
306-
}
329+
pstats_options = {"sort": None, "limit": None, "no_summary": False}
307330

308331
# Find the default values from the argument definitions
309332
for action in parser._actions:
310-
if action.dest in pstats_options and hasattr(action, 'default'):
333+
if action.dest in pstats_options and hasattr(action, "default"):
311334
pstats_options[action.dest] = action.default
312335

313336
# Check if any pstats-specific options were provided by comparing with defaults
314337
for opt, default in pstats_options.items():
315338
if getattr(args, opt) != default:
316-
invalid_opts.append(opt.replace('no_', ''))
317-
339+
invalid_opts.append(opt.replace("no_", ""))
340+
318341
if invalid_opts:
319-
parser.error(f"The following options are only valid with --pstats format: {', '.join(invalid_opts)}")
320-
342+
parser.error(
343+
f"The following options are only valid with --pstats format: {', '.join(invalid_opts)}"
344+
)
345+
321346
# Set default output filename for collapsed format
322347
if not args.outfile:
323348
args.outfile = f"collapsed.{args.pid}.txt"
@@ -329,14 +354,14 @@ def main():
329354
description=(
330355
"Sample a process's stack frames and generate profiling data.\n"
331356
"Supports two output formats:\n"
332-
" - pstats: Detailed profiling statistics with sorting options\n"
357+
" - pstats: Detailed profiling statistics with sorting options\n"
333358
" - collapsed: Stack traces for generating flamegraphs\n"
334359
"\n"
335360
"Examples:\n"
336361
" # Profile process 1234 for 10 seconds with default settings\n"
337362
" python -m profile.sample 1234\n"
338363
"\n"
339-
" # Profile with custom interval and duration, save to file\n"
364+
" # Profile with custom interval and duration, save to file\n"
340365
" python -m profile.sample -i 50 -d 30 -o profile.stats 1234\n"
341366
"\n"
342367
" # Generate collapsed stacks for flamegraph\n"
@@ -354,34 +379,33 @@ def main():
354379
" # Profile all threads and save collapsed stacks\n"
355380
" python -m profile.sample -a --collapsed -o stacks.txt 1234"
356381
),
357-
formatter_class=argparse.RawDescriptionHelpFormatter
382+
formatter_class=argparse.RawDescriptionHelpFormatter,
358383
)
359384

360385
# Required arguments
361-
parser.add_argument(
362-
"pid",
363-
type=int,
364-
help="Process ID to sample"
365-
)
386+
parser.add_argument("pid", type=int, help="Process ID to sample")
366387

367388
# Sampling options
368389
sampling_group = parser.add_argument_group("Sampling configuration")
369390
sampling_group.add_argument(
370-
"-i", "--interval",
391+
"-i",
392+
"--interval",
371393
type=int,
372394
default=100,
373-
help="Sampling interval in microseconds (default: 100)"
395+
help="Sampling interval in microseconds (default: 100)",
374396
)
375397
sampling_group.add_argument(
376-
"-d", "--duration",
398+
"-d",
399+
"--duration",
377400
type=int,
378401
default=10,
379-
help="Sampling duration in seconds (default: 10)"
402+
help="Sampling duration in seconds (default: 10)",
380403
)
381404
sampling_group.add_argument(
382-
"-a", "--all-threads",
405+
"-a",
406+
"--all-threads",
383407
action="store_true",
384-
help="Sample all threads in the process instead of just the main thread"
408+
help="Sample all threads in the process instead of just the main thread",
385409
)
386410

387411
# Output format selection
@@ -393,20 +417,21 @@ def main():
393417
const="pstats",
394418
dest="format",
395419
default="pstats",
396-
help="Generate pstats output (default)"
420+
help="Generate pstats output (default)",
397421
)
398422
output_format.add_argument(
399423
"--collapsed",
400-
action="store_const",
424+
action="store_const",
401425
const="collapsed",
402426
dest="format",
403-
help="Generate collapsed stack traces for flamegraphs"
427+
help="Generate collapsed stack traces for flamegraphs",
404428
)
405-
429+
406430
output_group.add_argument(
407-
"-o", "--outfile",
431+
"-o",
432+
"--outfile",
408433
help="Save output to a file (if omitted, prints to stdout for pstats, "
409-
"or saves to collapsed.<pid>.txt for collapsed format)"
434+
"or saves to collapsed.<pid>.txt for collapsed format)",
410435
)
411436

412437
# pstats-specific options
@@ -417,55 +442,56 @@ def main():
417442
action="store_const",
418443
const=0,
419444
dest="sort",
420-
help="Sort by number of calls"
445+
help="Sort by number of calls",
421446
)
422447
sort_group.add_argument(
423448
"--sort-time",
424449
action="store_const",
425450
const=1,
426451
dest="sort",
427-
help="Sort by total time"
452+
help="Sort by total time",
428453
)
429454
sort_group.add_argument(
430455
"--sort-cumulative",
431456
action="store_const",
432457
const=2,
433458
dest="sort",
434459
default=2,
435-
help="Sort by cumulative time (default)"
460+
help="Sort by cumulative time (default)",
436461
)
437462
sort_group.add_argument(
438463
"--sort-percall",
439464
action="store_const",
440465
const=3,
441466
dest="sort",
442-
help="Sort by time per call"
467+
help="Sort by time per call",
443468
)
444469
sort_group.add_argument(
445470
"--sort-cumpercall",
446471
action="store_const",
447472
const=4,
448473
dest="sort",
449-
help="Sort by cumulative time per call"
474+
help="Sort by cumulative time per call",
450475
)
451476
sort_group.add_argument(
452477
"--sort-name",
453478
action="store_const",
454479
const=5,
455480
dest="sort",
456-
help="Sort by function name"
481+
help="Sort by function name",
457482
)
458483

459484
pstats_group.add_argument(
460-
"-l", "--limit",
485+
"-l",
486+
"--limit",
461487
type=int,
462488
help="Limit the number of rows in the output",
463489
default=15,
464490
)
465491
pstats_group.add_argument(
466492
"--no-summary",
467493
action="store_true",
468-
help="Disable the summary section in the output"
494+
help="Disable the summary section in the output",
469495
)
470496

471497
args = parser.parse_args()
@@ -485,5 +511,7 @@ def main():
485511
show_summary=not args.no_summary,
486512
output_format=args.format,
487513
)
514+
515+
488516
if __name__ == "__main__":
489517
main()

0 commit comments

Comments
 (0)