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

fix(build,#119,#155): fix Windows installation by using setuptools-entry-points #181

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
24 changes: 8 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
language:
- python
language: python

python:
- "2.7"
- "3.3"
- "3.4"
- "pypy"
# pytest does not support python 3.5
# https://bitbucket.org/pytest-dev/pytest/pull-request/296/astcall-signature-changed-on-35
# - "nightly"

matrix:
allow_failures:
- python:
- "pypy"
- python:
- "nigthly"
- 2.7
- 3.3
- 3.4
- 3.5
- 3.6
#- 3.7-dev
- pypy

env:
global:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ tests:

flake8 --exclude=__init__.py,memory_profiler.py pycallgraph
flake8 --ignore=F403 test
flake8 examples
flake8 examples --exclude=all.py

doc:
cd docs/examples && ./generate.py
Expand Down
2 changes: 1 addition & 1 deletion examples/gephi/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def main():

with PyCallGraph(output=gephi):
person = Person()
for a in xrange(10):
for a in range(10):
person.add_banana(Banana())
person.eat_bananas()

Expand Down
2 changes: 1 addition & 1 deletion examples/graphviz/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def main():

with PyCallGraph(output=graphviz):
person = Person()
for a in xrange(10):
for a in range(10):
person.add_banana(Banana())
person.eat_bananas()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ def main():
s2 = SubmoduleTwo()
s2.report()


if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion examples/graphviz/recursive.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ def main():
graphviz.output_file = 'recursive.png'

with PyCallGraph(output=graphviz):
for a in xrange(1, 10):
for a in range(1, 10):
factorial(a)


if __name__ == '__main__':
main()
5 changes: 3 additions & 2 deletions examples/graphviz/regexp.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ def main():
config = Config(include_stdlib=True)

with PyCallGraph(output=graphviz, config=config):
reo = compile()
reo = compile_regex()
match(reo)


def compile():
def compile_regex():
return re.compile('^[abetors]*$')


Expand All @@ -41,5 +41,6 @@ def words():
'abrasives',
]


if __name__ == '__main__':
main()
30 changes: 30 additions & 0 deletions pycallgraph/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python
"""
pycallgraph
This script is the command line interface to the pycallgraph Python library.

See http://pycallgraph.slowchop.com/ for more information.
"""


def main():
import pycallgraph

config = pycallgraph.Config()
config.parse_args()
config.strip_argv()

globals()['__file__'] = config.command

file_content = open(config.command).read()

with pycallgraph.PyCallGraph(config=config):
exec(file_content)


if __name__ == '__main__':
# Pep366 must always be the 1st thing to run.
if not globals().get('__package__'):
__package__ = "polyversion" # noqa: A001 F841 @ReservedAssignment

main()
8 changes: 7 additions & 1 deletion pycallgraph/config.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import argparse
import operator
import sys

from .output import outputters
from .globbing_filter import GlobbingFilter
from .grouper import Grouper


iteritems = operator.methodcaller('iteritems'
if sys.version_info < (3, ) else
'items')


class Config(object):
'''Handles configuration settings for pycallgraph, tracer, and each output
module. It also handles command line arguments.
Expand Down Expand Up @@ -38,7 +44,7 @@ def __init__(self, **kwargs):
self.did_init = True

# Update the defaults with anything from kwargs
[setattr(self, k, v) for k, v in kwargs.iteritems()]
[setattr(self, k, v) for k, v in iteritems(kwargs)]

self.create_parser()

Expand Down
11 changes: 9 additions & 2 deletions pycallgraph/output/graphviz.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from __future__ import division

import tempfile
import operator
import os
import sys
import textwrap
import subprocess as sub

Expand All @@ -11,6 +13,11 @@
from .output import Output


iteritems = operator.methodcaller('iteritems'
if sys.version_info < (3, ) else
'items')


class GraphvizOutput(Output):

def __init__(self, **kwargs):
Expand Down Expand Up @@ -151,7 +158,7 @@ def generate(self):

def attrs_from_dict(self, d):
output = []
for attr, val in d.iteritems():
for attr, val in iteritems(d):
output.append('%s = "%s"' % (attr, val))
return ', '.join(output)

Expand All @@ -167,7 +174,7 @@ def edge(self, edge, attr):

def generate_attributes(self):
output = []
for section, attrs in self.graph_attributes.iteritems():
for section, attrs in iteritems(self.graph_attributes):
output.append('{0} [ {1} ];'.format(
section, self.attrs_from_dict(attrs),
))
Expand Down
14 changes: 10 additions & 4 deletions pycallgraph/output/output.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import re
import operator
import os
import re
import sys
from distutils.spawn import find_executable

from ..exceptions import PyCallGraphException
from ..color import Color

iteritems = operator.methodcaller('iteritems'
if sys.version_info < (3, ) else
'items')


class Output(object):
'''Base class for all outputters.'''
Expand All @@ -16,14 +22,14 @@ def __init__(self, **kwargs):
self.edge_label_func = self.edge_label

# Update the defaults with anything from kwargs
[setattr(self, k, v) for k, v in kwargs.iteritems()]
[setattr(self, k, v) for k, v in iteritems(kwargs)]

def set_config(self, config):
'''
This is a quick hack to move the config variables set in Config into
the output module config variables.
'''
for k, v in config.__dict__.iteritems():
for k, v in iteritems(config.__dict__):
if hasattr(self, k) and \
callable(getattr(self, k)):
continue
Expand Down Expand Up @@ -116,7 +122,7 @@ def debug(self, text):
self.processor.config.log_debug(text)

@classmethod
def add_output_file(cls, subparser, defaults, help):
def add_output_file(cls, subparser, defaults, help): # noqa: A002
subparser.add_argument(
'-o', '--output-file', type=str, default=defaults.output_file,
help=help,
Expand Down
2 changes: 1 addition & 1 deletion pycallgraph/pycallgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(self, output=None, config=None):
def __enter__(self):
self.start()

def __exit__(self, type, value, traceback):
def __exit__(self, type, value, traceback): # noqa: A002
self.done()

def get_tracer_class(self):
Expand Down
17 changes: 12 additions & 5 deletions pycallgraph/tracer.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from __future__ import division

import inspect
import sys
import operator
import os
import sys
import time
from distutils import sysconfig
from collections import defaultdict
Expand All @@ -15,6 +16,11 @@
from .util import Util


iteritems = operator.methodcaller('iteritems'
if sys.version_info < (3, ) else
'items')


class SyncronousTracer(object):

def __init__(self, outputs, config):
Expand Down Expand Up @@ -294,7 +300,7 @@ def groups(self):
grp = defaultdict(list)
for node in self.nodes():
grp[node.group].append(node)
for g in grp.iteritems():
for g in iteritems(grp):
yield g

def stat_group_from_func(self, func, calls):
Expand All @@ -312,14 +318,14 @@ def stat_group_from_func(self, func, calls):
return stat_group

def nodes(self):
for func, calls in self.func_count.iteritems():
for func, calls in iteritems(self.func_count):
yield self.stat_group_from_func(func, calls)

def edges(self):
for src_func, dests in self.call_dict.iteritems():
for src_func, dests in iteritems(self.call_dict):
if not src_func:
continue
for dst_func, calls in dests.iteritems():
for dst_func, calls in iteritems(dests):
edge = self.stat_group_from_func(dst_func, calls)
edge.src_func = src_func
edge.dst_func = dst_func
Expand Down Expand Up @@ -372,4 +378,5 @@ def wrapper(*rest):

return wrapper


inspect.getmodule = simple_memoize(inspect.getmodule)
8 changes: 8 additions & 0 deletions scripts/pycallgraph
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ pycallgraph
This script is the command line interface to the pycallgraph Python library.
See http://pycallgraph.slowchop.com/ for more information.
.. deprecated:: > 1.0.1
Code here moved to :func:`pycallgraph.__main__.main()`
and now using setuptools console-script entry-points,
to properly install on Windows.
- See https://github.com/gak/pycallgraph/issues/119
- See https://github.com/gak/pycallgraph/issues/155
"""
import sys
import os
Expand Down
23 changes: 13 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
#!/usr/bin/env python

from os import path
from setuptools import setup
import sys

from setuptools import setup
from setuptools.command.test import test as TestCommand

## FIXME: importing my-package may fail if dependent projects
# from :mod:`./pycallgraph/__init__.py` are not installed yet at this stage!
import pycallgraph


# Only install the man page if the correct directory exists
# XXX: Commented because easy_install doesn't like it
#man_path = '/usr/share/man/man1/'
#if path.exists(man_path):
# data_files=[['/usr/share/man/man1/', ['man/pycallgraph.1']]]
#else:
# data_files=None
data_files = None

data_files=None

class PyTest(TestCommand):

Expand All @@ -30,6 +32,7 @@ def run_tests(self):
errno = pytest.main(self.test_args)
sys.exit(errno)


setup(
name='pycallgraph',
version=pycallgraph.__version__,
Expand All @@ -40,20 +43,21 @@ def run_tests(self):
license=open('LICENSE').read(),
url=pycallgraph.__url__,
packages=['pycallgraph', 'pycallgraph.output'],
scripts=['scripts/pycallgraph'],
entry_points={
'console_scripts': ['pycallgraph = pycallgraph.__main__:main']},
data_files=data_files,
use_2to3=True,

# TODO: Update download_url
download_url =
'http://pycallgraph.slowchop.com/files/download/pycallgraph-%s.tar.gz' % \
pycallgraph.__version__,
download_url=
'http://pycallgraph.slowchop.com/files/download/pycallgraph-%s.tar.gz' %
pycallgraph.__version__,

# Testing
tests_require=['pytest'],
cmdclass = {'test': PyTest},
cmdclass={'test': PyTest},

classifiers = [
classifiers=[
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU General Public License (GPL)',
Expand All @@ -68,4 +72,3 @@ def run_tests(self):
'Topic :: Software Development :: Debuggers',
],
)

3 changes: 2 additions & 1 deletion test/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from pycallgraph import PyCallGraph, Config
import tempfile

from helpers import *
import pytest


@pytest.fixture(scope='module')
Expand Down
Loading