Skip to content

bpo-21862: Add -m option to cProfile for profiling modules#4297

Merged
pitrou merged 4 commits into
python:masterfrom
CuriousLearner:fix-issue21862
Nov 8, 2017
Merged

bpo-21862: Add -m option to cProfile for profiling modules#4297
pitrou merged 4 commits into
python:masterfrom
CuriousLearner:fix-issue21862

Conversation

@CuriousLearner
Copy link
Copy Markdown
Member

@CuriousLearner CuriousLearner commented Nov 6, 2017

Copy link
Copy Markdown
Contributor

@ncoghlan ncoghlan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change mostly looks good to me from a runpy perspective - just a minor suggestion for a possible simplification of the invocation.

Comment thread Lib/cProfile.py
code = "runpy.run_module(modname, run_name='__main__')"
globs = {
'runpy': runpy,
'modname': args[0]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A potential simplification here:

code = f"run_module({modname}, run_name='__main__')"
globs = {
    'run_module': runpy.run_module
}

What's currently there isn't wrong, but I think the above would be slightly clearer.

Setting alter_sys=True would also be an option, but cProfile doesn't do that for regular scripts, so I don't see any particular reason for it to do it for modules.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll fix that and also add NEWS entry :)

Copy link
Copy Markdown
Member Author

@CuriousLearner CuriousLearner Nov 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @ncoghlan !

So, one of the thing I tried from your code snippet was this:

        if options.module:
            modname = args[0]
            code = f"run_module({modname}, run_name='__main__')"
            globs = {
                'run_module': runpy.run_module
            }

and if I run ./python.exe -m cProfile -m timeit -n 1 to test it, it throws NameError for timeit. But this is not the case without f-strings. I'm unable to understand this behaviour. Can you please help?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the case if I avoid using f-string and provide the context of running the module as globals to the runctx method. So, I'm not sure, what is wrong. Help would be much appreciated.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think modname would need to be fed through repr(), e.g. f"run_module({modname!r}, run_name='__main__')".
That said, I think your original code is fine and I don't find @ncoghlan's suggestion more readable :-)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pitrou is right, and the missing !r was just a bug in my suggested code. However, there's merit in the idea of using just one mechanism for passing values in (the globs dict) rather than two (string interpolation and the globs dict).

So while I still think it makes sense to pass in a reference to the run_module itself, rather than one to the runpy module, I withdraw the suggestion of using string interpolation to pass in the module name to run.

Comment thread Doc/library/profile.rst
the output by. This only applies when ``-o`` is not supplied.

``-m`` specifies that a module is being profiled instead of a script.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can add a versionadded tag just after this for the -m option.

Comment thread Doc/library/profile.rst Outdated
script. For example::

python -m cProfile [-o output_file] [-s sort_order] myscript.py
python -m cProfile [-o output_file] [-s sort_order] [-m module] myscript.py
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that -m module and myscript.py are exclusive. So the doc could/should be spelled (-m module | myscript.py).

Comment thread Lib/test/test_cprofile.py Outdated
assert_python_failure('-m', 'cProfile', '-m')

# Test failure for not-existent module
assert_python_failure('-m', 'cProfile', 'random_module_xyz.py')
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be:

assert_python_failure('-m', 'cProfile', '-m', 'random_module_xyz')

@CuriousLearner
Copy link
Copy Markdown
Member Author

@ncoghlan @pitrou ,

I've addressed your reviews. Can you please have a look now? :)

@CuriousLearner
Copy link
Copy Markdown
Member Author

CuriousLearner commented Nov 8, 2017

Thanks for fixing the tidbits @pitrou

@pitrou
Copy link
Copy Markdown
Member

pitrou commented Nov 8, 2017

You're welcome. Sometimes it's faster than having to go back and forth :-)

@pitrou pitrou merged commit 7973e27 into python:master Nov 8, 2017
embray pushed a commit to embray/cpython that referenced this pull request Nov 9, 2017
* bpo-21862: Add -m option to cProfile for profiling modules
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants