python / python/cpython

pstats.Stats.get_stats_profile can't handle functions with the same name

Offen
#126,850 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

stdlib type-bug
Vorherrschende Sprache
Python
Sterne
77.2k
Forks
35.9k
PR-Merge-Kennzahlen
PR-Kennzahlen ausstehend

Beschreibung

Bug report

Bug description:

MCVE

import cProfile
import time
import pstats


class A:
    def foo(self):
        time.sleep(1)


class B:
    def foo(self):
        time.sleep(2)


pr = cProfile.Profile()
pr.enable()
A().foo()
B().foo()
pr.create_stats()

ps = pstats.Stats(pr).sort_stats("cumtime")
ps.print_stats(5)

when I ran this in a jupyter notebook, this outputted:

         61 function calls in 3.003 seconds

   Ordered by: cumulative time
   List reduced from 21 to 5 due to restriction <5>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        3    0.000    0.000    3.003    1.001 /usr/local/my_venv/lib/python3.10/site-packages/IPython/core/interactiveshell.py:3424(run_code)
        3    0.000    0.000    3.002    1.001 {built-in method builtins.exec}
        2    3.002    1.501    3.002    1.501 {built-in method time.sleep}
        1    0.000    0.000    2.002    2.002 /usr/tmp/ipykernel_104016/1099215389.py:12(foo)
        1    0.000    0.000    1.000    1.000 /usr/tmp/ipykernel_104016/1099215389.py:7(foo)

which correctly shows two different versions of a function called foo. However, due to the API design of get_stats_profile, only one of the functions will be stored in the dict FunctionProfile.func_profiles, the one which is last in the insertion order, which in this case since I sorted by cumtime will be A.foo:

print(ps.get_stats_profile().func_profiles["foo"])

outputs:

FunctionProfile(ncalls='1', tottime=0.0, percall_tottime=0.0, cumtime=1.0, percall_cumtime=1.0, file_name='/usr/tmp/ipykernel_104016/1099215389.py', line_number=7)

Maybe get_stats_profile should key the func_profile dictionary on something that's actually unique per profile entry, like filename:lineno(function)?

CPython versions tested on:

3.10

Operating systems tested on:

Linux

Linked PRs
  • gh-149618

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne bei pstats.Stats.get_stats_profile und untersuche, wie FunctionProfile.func_profiles befüllt und mit Schlüsseln versehen wird. Reproduziere die bereitgestellte MCVE mit A.foo und B.foo und überprüfe anschließend, dass beide gleichnamigen Funktionen in den zurückgegebenen Profildaten unterscheidbar bleiben.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
python
Bereich
tooling
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.