Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

Commit

Permalink
Command-line interface work (still broken)
Browse files Browse the repository at this point in the history
 - MANIFEST.in updates
 - Copy generated man page to the existing location in /man/pycallgraph.1.
  • Loading branch information
gak committed Aug 5, 2013
1 parent 84991e8 commit ba37c48
Show file tree
Hide file tree
Showing 11 changed files with 172 additions and 113 deletions.
7 changes: 6 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
include Makefile
include LICENSE
include README.rst
include requirements
include test
include docs
include examples/*.py
include man/pycallgraph.1
include LICENSE
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ tests:
test pycallgraph

doc:
make -C docs html
make -C docs html man
cp docs/_build/man/pycallgraph.1 man/
docs/update_readme.py
191 changes: 111 additions & 80 deletions man/pycallgraph.1
Original file line number Diff line number Diff line change
@@ -1,88 +1,119 @@
.\" Hey, EMACS: -*- nroff -*-
.TH PYCALLGRAPH 1 "2008-07-08" "pycallgraph version 0.5.1" "User Commands"
.\" Some roff macros, for reference:
.\" .nh disable hyphenation
.\" .hy enable hyphenation
.\" .ad l left justify
.\" .ad b justify to both left and right margins
.\" .nf disable filling
.\" .fi enable filling
.\" .br insert line break
.\" .sp <n> insert n+1 empty lines
.\" for manpage-specific macros, see man(7)
.\" Man page generated from reStructuredText.
.
.TH "PYCALLGRAPH" "1" "August 05, 2013" "1.0.0" "Python Call Graph"
.SH NAME
pycallgraph \- command-line interface to pycallgraph
pycallgraph \- Python Call Graph
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.
.nr rst2man-indent-level 0
.
.de1 rstReportMargin
\\$1 \\n[an-margin]
level \\n[rst2man-indent-level]
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
-
\\n[rst2man-indent0]
\\n[rst2man-indent1]
\\n[rst2man-indent2]
..
.de1 INDENT
.\" .rstReportMargin pre:
. RS \\$1
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
. nr rst2man-indent-level +1
.\" .rstReportMargin post:
..
.de UNINDENT
. RE
.\" indent \\n[an-margin]
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
.nr rst2man-indent-level -1
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.SH SYNOPSIS
.B pycallgraph
[\fIOPTION\fR]... \fIpythonfile
.sp
pycallgraph [\fIOPTION\fP]... \fIOUTPUT_MODE\fP \fIpython_file.py\fP
.SH DESCRIPTION
This manual page documents \fBpycallgraph\fP.
This manual page was originally written for the Debian distribution.
.PP
\fIpycallgraph\fP is a program that creates call graphs for Python programs.
\fBpycallgraph\fP is the command line interface to \fIpycallgraph\fP's
\fImake_dot_graph\fP method, which generates a call graph and stores it as an
image in the specified image file.
.HP
\fB\-o\fR, \fB\-\-output-file
.IP
the file name of the output image. Default: pycallgraph.png
.HP
\fB\-f\fR, \fB\-\-image-format
.IP
the image format of imagefile. Default: png
.HP
\fB\-q\fR, \fB\-\-quiet
.IP
Suppress status output to the console.
.HP
\fB\-t\fR, \fB\-\-tool
.IP
the tool from \fIGraphViz\fP to use. Default: dot
.HP
\fB\-s\fR, \fB\-\-stdlib
.IP
include standard library functions in the trace. Default: False
.HP
\fB\-i\fR, \fB\-\-include
.IP
wildcard pattern of modules to include in the output. You can have multiple
include arguments
.HP
\fB\-e\fR, \fB\-\-exclude
.IP
wildcard pattern of modules to exclude in the output. You can have multiple
exclude arguments
.HP
\fB\-d\fR, \fB\-\-max\-depth
.IP
maximum stack depth to trace
.HP
\fB\-\-exclude\-timing
.IP
wildcard pattern of modules to exclude in time measurement. You can have
multiple exclude arguments
.HP
\fB\-\-include\-timing
.IP
wildcard pattern of modules to include in time measurement. You can have
multiple include arguments
.sp
pycallgraph is a program that creates call graph visualisation from Python scripts.
.sp
\fIOUTPUT_MODE\fP can be one of graphviz, gephi and ubigraph. \fIpython_file.py\fP is a python script that will be traced and afterwards, a call graph visualisation will be generated.
.SH ARGUMENTS
.INDENT 0.0
.TP
.B \-m <module>, \-\-module <module>
Run a module as a script.
.UNINDENT
.SH EXAMPLES
.PP
.sp
Create a call graph called pycallgraph.png on myprogram.py:
.IP
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
pycallgraph ./myprogram.py
.PP
Create a call graph of a standard Python installation script with command line
parameters:
.IP
pycallgraph \-\-output-file=setup.png \-\- setup.py \-\-dry\-run install
.PP
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Create a call graph of a standard Python installation script with command line parameters:
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
pycallgraph \-\-output\-file=setup.png \-\- setup.py \-\-dry\-run install
.ft P
.fi
.UNINDENT
.UNINDENT
.sp
Only see the module "distutils" within the execution of easy_install:
.IP
.INDENT 0.0
.INDENT 3.5
.sp
.nf
.ft C
pycallgraph \-\-include=distutils.* /usr/bin/easy_install
.SH AUTHORS
pycallgraph and pycallgraph were written by Gerald Kaszuba <pycallgraph@slowchop.com>.
.LP
This manual page was originally written by Jan Alonzo
<jmalonzo@unpluggable.com>, for the Debian GNU/Linux system.
.ft P
.fi
.UNINDENT
.UNINDENT
.SH AUTHOR
pycallgraph was written by Gerald Kaszuba <pycallgraph@slowchop.com>.

This manual page was originally written by Jan Alonzo <jmalonzo@unpluggable.com>, for the Debian GNU/Linux system.

.SH COPYRIGHT
2007-2013 Gerald Kaszuba, et al.
.\" Generated by docutils manpage writer.
.
37 changes: 26 additions & 11 deletions pycallgraph/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@ def __init__(self):

self.create_parser()

def add_module_arguments(self):
subparsers = self.parser.add_subparsers(help='sub-command help')
def add_module_arguments(self, usage):
subparsers = self.parser.add_subparsers(help='OUTPUT_TYPE')
parent_parser = self.create_parent_parser()

for outputter in outputters:
outputter.add_arguments(subparsers)
for outputter in outputters.itervalues():
outputter.add_arguments(subparsers, parent_parser, usage)

def get_output(self):
return outputters[self.output_type].from_config(self)

def parse_args(self, args=None):
self.parser.parse_args(args, namespace=self)
Expand All @@ -31,21 +35,32 @@ def create_parser(self):
'''Used by the pycallgraph command line interface to parse
arguments.
'''
usage = 'pycallgraph [options] OUTPUT_TYPE [output_options] -- ' \
'SCRIPT.py [ARG ...]'

self.parser = argparse.ArgumentParser(
# usage='%(prog)s [options] pythonfile.py',
description='Python Call Graph profiles a Python script and '
'generates a call graph visualisation.'
'generates a call graph visualisation.', usage=usage,
)

self.add_ungrouped_arguments()
self.add_filter_arguments()
self.add_module_arguments()
self.add_module_arguments(usage)

# This needs to be at/near the end of the argument definitions
self.parser.add_argument(
'command', metavar='pythonfile.py',
help='The python script to profile'
def create_parent_parser(self):
'''Mixing subparsers with positional arguments can be done with a
parents option. Found via: http://stackoverflow.com/a/11109863/11125
'''
parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument(
'command', metavar='SCRIPT',
help='The Python script file to profile',
)
parent_parser.add_argument(
'command_args', metavar='ARG', nargs='*',
help='Python script arguments.'
)
return parent_parser

def add_ungrouped_arguments(self):
self.parser.add_argument(
Expand Down
10 changes: 5 additions & 5 deletions pycallgraph/output/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from .pickle import PickleOutput
from .ubigraph import UbigraphOutput

outputters = [
GraphvizOutput,
PickleOutput,
UbigraphOutput,
]
outputters = collections.OrderedDict([
('graphviz', 'GraphvizOutput'),
('ubigraph', 'UbigraphOutput'),
('pickle', 'PickleOutput'),
])
3 changes: 2 additions & 1 deletion pycallgraph/output/graphviz.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ def __init__(self):
self.time_filter = None

@classmethod
def add_arguments(cls, subparsers):
def add_arguments(cls, subparsers, parent_parser, usage):
defaults = cls()

subparser = subparsers.add_parser(
'graphviz', help='Graphviz generation',
parents=[parent_parser], usage=usage,
)

subparser.add_argument(
Expand Down
3 changes: 2 additions & 1 deletion pycallgraph/output/pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ def __init__(self):
self.output_file = 'pycallgraph.dot'

@classmethod
def add_arguments(cls, subparsers):
def add_arguments(cls, subparsers, parent_parser, usage):
defaults = cls()

subparser = subparsers.add_parser(
'pickle',
help='Dump to a cPickle file for generation later',
parents=[parent_parser], usage=usage,
)

subparser.add_argument(
Expand Down
3 changes: 2 additions & 1 deletion pycallgraph/output/ubigraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ def update(self):
pass

@classmethod
def add_arguments(cls, subparsers):
def add_arguments(cls, subparsers, parent_parser, usage):
defaults = cls()

subparser = subparsers.add_parser(
'ubigraph',
help='Update an Ubigraph visualisation in real time',
parents=[parent_parser], usage=usage,
)

subparser.add_argument(
Expand Down
3 changes: 3 additions & 0 deletions pycallgraph/pycallgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ def __init__(self, outputs=None, config=None):
self.outputs = outputs

self.config = config or Config()
configured_ouput = self.config.get_output()
if configured_ouput:
self.outputs.append(configured_ouput)

self.reset()

Expand Down
23 changes: 12 additions & 11 deletions scripts/pycallgraph
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ config = Config()
config.parse_args()

if not config.quiet:
print('Python Call Graph v%s' % __version__)
print('Running with Python Call Graph v%s' % __version__)

# Create filter
if not config.include:
Expand All @@ -43,21 +43,23 @@ time_filter_func = GlobbingFilter(
# sys.path.insert(0, os.getcwd())

if not config.quiet:
print('Starting Python Call Graph trace')
print('Starting a trace with Python Call Graph')

pycg = PyCallGraph(config=config)
del config

pycallgraph.start_trace(
filter_func=filter_func,
time_filter_func=time_filter_func,
)
# pycallgraph.start_trace(
# filter_func=filter_func,
# time_filter_func=time_filter_func,
# )

# Execute the user script
try:
globals()['__file__'] = args[0]
with open(args[0]) as file_:
file_content = file_.read()
exec(file_content)
globals()['__file__'] = pycg.config.command
with open(pycg.config.command) as fp:
file_content = fp.read()
with pycg:
exec(file_content)
except SystemExit:
# Ignore it when the script calls os.exit() so we can still make the graph.
pass
Expand All @@ -69,4 +71,3 @@ pycallgraph.make_dot_graph(config.output_file, config.format, config.tool)

if not config.quiet:
print('Done!')

Loading

0 comments on commit ba37c48

Please sign in to comment.