Commit d6792dc7 authored by Jérome Perrin's avatar Jérome Perrin

Support python provided by a part that does not need install

With shared builds, it's now possible that the [python2.7] part that is
providing executable for this buildout does not need to install any part and
makes the interpreter available since recipe initialisation.

This is causing an error during the overriden method computing part signature,
because parts are not installed yet:

    An internal error occurred due to a bug in either zc.buildout or in a
    recipe being used:
    Traceback (most recent call last):
      File "zc/buildout/buildout.py", line 2242, in main
        getattr(buildout, command)(args)
      File "zc/buildout/buildout.py", line 638, in install
        self._install_parts(install_args)
      File "zc/buildout/buildout.py", line 704, in _install_parts
        self._compute_part_signatures(install_parts)
      File "slapos/rebootstrap/__init__.py", line 37, in wrapper
        return getattr(self, attr)(*args, **kw)
      File "slapos/rebootstrap/__init__.py", line 95, in _compute_part_signatures
        installed_part_options[part]['__buildout_signature__']
    KeyError: 'already_installed_python'

To support that case, tolerate that parts are can be not installed yet at this
point.

/reviewed-on !1
parent 11705f88
...@@ -90,8 +90,9 @@ Buildout will be restarted automatically to have this change applied. ...@@ -90,8 +90,9 @@ Buildout will be restarted automatically to have this change applied.
buildout._compute_part_signatures(install_parts) buildout._compute_part_signatures(install_parts)
installed_part_options = buildout.installed_part_options installed_part_options = buildout.installed_part_options
for part in self._frozen.intersection(install_parts): for part in self._frozen.intersection(install_parts):
buildout[part]['__buildout_signature__'] = \ if part in installed_part_options:
installed_part_options[part]['__buildout_signature__'] buildout[part]['__buildout_signature__'] = \
installed_part_options[part]['__buildout_signature__']
class Cache(easy_install.Installer): class Cache(easy_install.Installer):
......
An edge case is when the python is provided by a part that does not need to install anything.
>>> import sys
>>> print system(buildout),
Develop: '/sample-buildout/recipes'
>>> write(sample_buildout, 'buildout.cfg',
... """
... [buildout]
... develop = recipes
... extensions = slapos.rebootstrap
... python = already_installed_python
...
... parts =
... realrun
...
... [already_installed_python]
... recipe = recipes:pyalreadyinstalled
...
... [realrun]
... recipe = recipes:pyshow
... """ % dict(syspython=sys.executable))
>>> print system(buildout),
Using already installed /system_python
Develop: '/sample-buildout/recipes'
Installing already_installed_python.
Installing realrun.
Running with: /system_python
...@@ -32,6 +32,7 @@ setup( ...@@ -32,6 +32,7 @@ setup(
name = "recipes", name = "recipes",
entry_points = {'zc.buildout':[ entry_points = {'zc.buildout':[
'pyinstall = pyinstall:Pyinstall', 'pyinstall = pyinstall:Pyinstall',
'pyalreadyinstalled = pyalreadyinstalled:PyAlreadyInstalled',
'pyshow = pyshow:Pyshow', 'pyshow = pyshow:Pyshow',
]}, ]},
) )
...@@ -55,6 +56,20 @@ class Pyinstall: ...@@ -55,6 +56,20 @@ class Pyinstall:
shutil.copy(sys.executable, python) shutil.copy(sys.executable, python)
return [] return []
update = install
""")
write(sample_buildout, 'recipes', 'pyalreadyinstalled.py', """
import os, zc.buildout, shutil, sys
class PyAlreadyInstalled:
def __init__(self, buildout, name, options):
print "Using already installed", sys.executable
options['executable'] = sys.executable
def install(self):
return []
update = install update = install
""") """)
write(sample_buildout, 'recipes', 'pyshow.py', """ write(sample_buildout, 'recipes', 'pyshow.py', """
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment