Installing py-spy with buildout

Hello,
I have a problem installing py-spy within buildout. When adding py-spy to eggs the supposedly executable ./bin/py-py is generated. Unfortunately I had to notice, that this file is corrupted, as easy_install tends to prepend the shebang:

#!/path/to/my/python

The following content is just binary data as the file is a pre-built executable. The shebang makes sense for Python source, but easy_install has no need to add this statement in this case. I have inspected the sources and found out, that easy_install thinks it's an "old-style" distutils script (also see the code), which eventually leads to adding the shebang. I was unable to find a switch to change this.

As I know that some of the users here use py-spy to profile their Plone sites, I would like to know how you build it? Is there a specific recipe you use?

I created a new minimal example (where it crashes at a different place but for the same reasons):

python -m venv .
echo """
setuptools==42.0.2
zc.buildout==2.13.3
wheel""" > requirements.cfg
./bin/pip install -r requirements.txt
echo """
[buildout]
extends =
    http://dist.plone.org/release/5-latest/versions.cfg

eggs =
	Plone
	py-spy

parts =
    instance

# Circument infinite recursion
newest = false

[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
http-address = 8080
eggs =
    ${buildout:eggs}
""" > buildout.cfg
./bin/buildout

...
Generated interpreter '/home/paul/webcms/pyspy_demo/parts/instance/bin/interpreter'.
While:
  Installing instance.

An internal error occurred due to a bug in either zc.buildout or in a
recipe being used:
Traceback (most recent call last):
  File "/home/paul/webcms/pyspy_demo/lib/python3.8/site-packages/zc/buildout/buildout.py", line 2174, in main
    getattr(buildout, command)(args)
  File "/home/paul/webcms/pyspy_demo/lib/python3.8/site-packages/zc/buildout/buildout.py", line 817, in install
    installed_files = self[part]._call(recipe.install)
  File "/home/paul/webcms/pyspy_demo/lib/python3.8/site-packages/zc/buildout/buildout.py", line 1603, in _call
    return f()
  File "/home/paul/webcms/pyspy_demo/eggs/plone.recipe.zope2instance-6.5.1-py3.8.egg/plone/recipe/zope2instance/recipe.py", line 157, in install
    retval = Scripts.install(self)
  File "/home/paul/webcms/pyspy_demo/eggs/zc.recipe.egg-2.0.7-py3.8.egg/zc/recipe/egg/egg.py", line 256, in install
    return zc.buildout.easy_install.scripts(
  File "/home/paul/webcms/pyspy_demo/lib/python3.8/site-packages/zc/buildout/easy_install.py", line 1179, in scripts
    contents = dist.get_metadata('scripts/' + name)
  File "/home/paul/webcms/pyspy_demo/lib/python3.8/site-packages/pkg_resources/__init__.py", line 1424, in get_metadata
    return value.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x84 in position 24: invalid start byte in scripts/py-spy file at path: /home/paul/webcms/pyspy_demo/eggs/py_spy-0.3.3-py3.8-linux-x86_64.egg/EGG-INFO/scripts/py-spy

I'd recommend you add py-spy to your requirements.txt and run bin/pip install -r requirements.txt ... after that you can run bin/py-spy

1 Like

Thanks! That will do it! Although I'm still uncertain whose fault this is. Is buildout not prepared for this case of pre-compiled scripts or is something missing in the package itself? Like an entry for console_script in setup.py :thinking:

If you want to install precompiled eggs as script you can use a buildout part with the recipe zc.recipe.egg ... see https://pypi.org/project/zc.recipe.egg. And for compiling packages from source you can use a part with the recipe zc.recipe.cmmi https://pypi.org/project/zc.recipe.cmmi ... maybe this helps.

1 Like