gak / pycallgraph

pycallgraph is a Python module that creates call graphs for Python programs.
GNU General Public License v2.0
1.83k stars 335 forks source link

pycallgraph executable not created on install #119

Open roger-butler opened 11 years ago

roger-butler commented 11 years ago

I downloaded pycallgraph 1.0.1 and untarred it into a temporary directory. My Python environment is Enthought Canopy 1.1 on Windows 7. I ran easy_install pip to install pip, then pip install pycallgraph. Files were copied to my Python environment but not an executable. So I can run pycallgraph using the API but not the command line.

Any ideas?

gak commented 11 years ago

Hi @roger-butler

I have not tested pycallgraph on Windows so you'll have to excuse it not working first go :)

Can you print out the log out of of the pip install pycallgraph so we can see where the pycallgraph script was installed to?

From a quick Google, it seems that the script would have to be renamed to pycallgraph.py, and only then Windows will recognise it (due to file association). Obviously it would also need to be in your path, or executed with the correct path components.

I'll leave this ticket open to ensure the script is installed in Windows correctly.

roger-butler commented 10 years ago

Hello Gerald,

Thanks for helping with this.

My path contains C:\Users\rbutler\AppData\Local\Enthought\Canopy\User;C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\Scripts.

C:\Users\rbutler>pip install pycallgraph Requirement already satisfied (use --upgrade to upgrade): pycallgraph in c:\user s\rbutler\appdata\local\enthought\canopy\user\lib\site-packages\pycallgraph-1.0. 1-py2.7.egg Cleaning up...

The contents of pycallgraph-1.0.1-py2.7.egg are:

├───EGG-INFO
│   │   dependency_links.txt
│   │   not-zip-safe
│   │   PKG-INFO
│   │   SOURCES.txt
│   │   top_level.txt
│   │   
│   └───scripts
│           pycallgraph
│           
└───pycallgraph
    │   color.py
    │   color.pyc
    │   config.py
    │   config.pyc
    │   exceptions.py
    │   exceptions.pyc
    │   globbing_filter.py
    │   globbing_filter.pyc
    │   memory_profiler.py
    │   memory_profiler.pyc
    │   metadata.py
    │   metadata.pyc
    │   pycallgraph.py
    │   pycallgraph.pyc
    │   tracer.py
    │   tracer.pyc
    │   util.py
    │   util.pyc
    │   __init__.py
    │   __init__.pyc
    │   
    └───output
            gephi.py
            gephi.pyc
            graphviz.py
            graphviz.py.old
            graphviz.pyc
            output.py
            output.pyc
            pickle.py
            pickle.pyc
            ubigraph.py
            ubigraph.pyc
            __init__.py
            __init__.pyc

An EASY-INSTALL file pycallgraph was also installed into C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\Scripts. I have renamed this file to pycallgraph.py but still can't call it:

C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\Scripts>python pycallgraph
Traceback (most recent call last):
  File "pycallgraph", line 5, in <module>
    pkg_resources.run_script('pycallgraph==1.0.1', 'pycallgraph.py')
  File "C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\lib\site-packages\pkg_resources.py", line 499, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\lib\site-packages\pkg_resources.py", line 1239, in run_script
    execfile(script_filename, namespace, namespace)
  File "c:\users\rbutler\appdata\local\enthought\canopy\user\lib\site-packages\pycallgraph-1.0.1-py2.7.egg\EGG-INFO\scripts\pycallgraph.py", line 11, in <module>
    import pycallgraph as __pycallgraph
  File "C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\Scripts\pycallgraph.py", line 5, in <module>
    pkg_resources.run_script('pycallgraph==1.0.1', 'pycallgraph.py')
  File "C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\lib\site-packages\pkg_resources.py", line 499, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "C:\Users\rbutler\AppData\Local\Enthought\Canopy\User\lib\site-packages\pkg_resources.py", line 1239, in run_script
    execfile(script_filename, namespace, namespace)
  File "c:\users\rbutler\appdata\local\enthought\canopy\user\lib\site-packages\pycallgraph-1.0.1-py2.7.egg\EGG-INFO\scripts\pycallgraph.py", line 17, in <module>
    __config = __pycallgraph.Config()
AttributeError: 'module' object has no attribute 'Config'

Other modules such as pip tend to have Windows executables in the Scripts directory, e.g. pip.exe. Sorry, I don't know enough about Python installation to help much more.

Regards, Roger.

gak commented 10 years ago

@roger-butler Without having a computer to test on, it appears that the pycallgraph script it somehow importing itself instead of the main module. You can see the initial script finding and executing scripts\pycallgraph.py, but then when it tries to import the main pycallgraph module (which should be in pycallgraph not scripts), it imports the same scripts\pycallgraph.py file again.

Unfortunately not sure I can easily debug/fix this for you remotely, so I'll keep it open for fixing in the future.

I can only suggest to work out why it's calling itself instead of the correct module. I'm not sure what Enthought Canopy does different with Python, but it could be a possibility that it has something to do with it. Maybe try a standard Python install to see if it has the same problem.

Tibbar49 commented 10 years ago

Epydoc has a similar situation where their executable script epydoc needs to be renamed to epydoc.py inside of C:\Python27\Scripts. In addition, the script name has the same label as the Epydoc package, which would cause conflicts. But they dealt with this issue by removing the script from the Python path before importing the Epydoc package.

Following their example, I was able to get Python Call Graph to work on Windows by modifying this snippet in the executable pycallgraph.py script, just before it imports the pycallgraph package:

import sys
import os

# ----- INSERT -----
# Remove the directory containing pycallgraph.py from the Python search path
sys.path = [p for p in sys.path
            if not os.path.exists(os.path.join(p, 'pycallgraph.py'))]
# ------------------

import pycallgraph as __pycallgraph
eler90 commented 10 years ago

Hey Tibbar49, I'm also trying to use pycallgraph on Windows 7. I tried renaming the pycallgraph in the Scripts folder to pycallgraph.py and modifying the code of pycallgraph.h (in lib /sitepackeges directory). Somehow it still does not work. Could you maybe post the whole modiefied code of that file?

Tibbar49 commented 10 years ago

You shouldn't need to modify any header (*.h) files.

Since pycallgraph (renamed to pycallgraph.py and modified as noted above) in the C:\Python27\Scripts folder is not an application that Windows can see on the system path, you need to pass the script's full path to the Python executable:

python C:\Python27\Scripts\pycallgraph.py [arguments]

Alternatively, you can import the Python Call Graph package and use its API in your code.

Note: I tweaked the code in the previous comment to more thoroughly delete C:\Python27\Scripts from the Python search path.

jakubczaplicki commented 10 years ago

I've just installed pycallgraph on Win7 with easy_install pycallgraph and got hit by this issue.

What's missing, is a simple batch file in c:\Python27\Scripts\

Simply create c:\Python27\Scripts\pycallgraph.bat with the following content:

@echo off
rem Use python to execute the python script having the same name as this batch
rem file, but without any extension, located in the same directory as this
rem batch file
python "%~dpn0" %*
joris255 commented 9 years ago

Thank you Kuba !

Tibbar49 commented 9 years ago

Jakub's solution seems more elegant than mine. I would try his instead.

suurjaak commented 9 years ago

There is a better solution: pip supports automatic script creation. If setup.py used entry_points instead of scripts, it would create .exe files in Windows.

There would need to be a single entry method in pycallgraph, and this in setup.py:

entry_points={"console_scripts": ["pycallgraph = pycallgraph.pycallgraph:yourentrymethod"]},
avishapiro commented 8 years ago

Thanks @jakubczaplicki . That worked for me. I'm using Python 3.5 from the Anaconda distribution so I put the new pycallgraph.bat file in a different path (C:\Anaconda3\Scripts\), where pycallgraph (no extension) is located, exactly as you instructed.