Commit edfa796c authored by Eric Coissac's avatar Eric Coissac

Resolve dependency with cython by making a temporary install if needed

parent 704dbd50
......@@ -4,10 +4,23 @@ Created on 13 fevr. 2014
@author: coissac
from distutils import log
import sys
from Cython.Distutils import build_ext as ori_build_ext # @UnresolvedImport
except ImportError:
from distutils.command.build_ext import build_ext as ori_build_ext
from obidistutils.serenity.cython import get_a_cython_module
import imp
import os.path"No cython installed, try to install a temporary cython")
cython = get_a_cython_module()
f, filename, description=imp.find_module('Distutils',[os.path.dirname(cython.__file__)])
submodule = imp.load_module('Cython.Distutils', f, filename, description)
ori_build_ext = submodule.build_ext
from distutils.errors import DistutilsSetupError
import os
......@@ -35,7 +35,13 @@ except ImportError:
description = __doc__
def initialize_options(self):
def finalize_options(self):
def run(self):"Sphinx not installed documentation will not be generated")
......@@ -11,16 +11,15 @@ import sys
from obidistutils.command.sdist import sdist
from setuptools import setup as ori_setup
has_setuptools = True
except ImportError:
from distutils.core import setup as ori_setup
has_setuptools = False
# try:
# from setuptools import setup as ori_setup
# has_setuptools = True
# except ImportError:
from distutils.core import setup as ori_setup
#has_setuptools = False
from distutils.extension import Extension
from import build
from obidistutils.command.littlebigman import littlebigman
from obidistutils.command.build_cexe import build_cexe
......@@ -137,19 +136,32 @@ FILES =[]
def setup(**attrs):
if has_setuptools:
requirements = open('requirements.txt').readlines()
requirements = [x.strip() for x in requirements]
requirements = [x for x in requirements if x[0]!='-']
# if has_setuptools:
# try:
# requirements = open('requirements.txt').readlines()
# requirements = [x.strip() for x in requirements]
# requirements = [x for x in requirements if x[0]!='-']
# if 'install_requires' not in attrs:
# attrs['install_requires']=requirements
# else:
# attrs['install_requires'].extend(requirements)
# except IOError:
# pass
if 'install_requires' not in attrs:
except IOError:
requirements = open('requirements.txt').readlines()
requirements = [x.strip() for x in requirements]
requirements = [x for x in requirements if x[0]!='-']
if 'install_requires' not in attrs:
except IOError:
if 'distclass' not in attrs:
Created on 2 oct. 2014
@author: coissac
import imp
import importlib
from distutils.errors import DistutilsError
from distutils.version import StrictVersion
from distutils import log
from obidistutils.serenity.globals import local_cython # @UnusedImport
from obidistutils.serenity.checkpip import get_a_pip_module
from obidistutils.serenity.checkpackage import get_package_requirement
from obidistutils.serenity.checkpackage import parse_package_requirement
from obidistutils.serenity.checkpackage import is_installed
from obidistutils.serenity.checkpackage import pip_install_package
from obidistutils.serenity.util import get_serenity_dir
def get_a_cython_module(pip=None):
global local_cython
if not local_cython:
if pip is None:
pip = get_a_pip_module()
cython_req = get_package_requirement('Cython',pip)
if cython_req is None:
requirement_project,requirement_relation,minversion = parse_package_requirement(cython_req) # @UnusedVariable
if cython_req is None or not is_installed(cython_req, pip):
tmpdir = get_serenity_dir()
ok = pip_install_package(cython_req,directory=tmpdir,pip=pip)
log.debug('temp install dir : %s' % tmpdir)
if ok!=0:
raise DistutilsError, "I cannot install a cython package"
f, filename, description = imp.find_module('Cython', [tmpdir])
cythonmodule = imp.load_module('Cython', f, filename, description)
if minversion is not None:
assert StrictVersion(cythonmodule.__version__) >= minversion, \
"Unable to find suitable version of cython get %s instead of %s" % (cythonmodule.__version__,
cythonmodule = importlib.import_module('Cython')
return local_cython[0]
......@@ -11,3 +11,4 @@ saved_args=[]
#!/usr/bin/env python
import os
import optparse
import sys
import re
from pip.exceptions import InstallationError, CommandError, PipError
from pip.log import logger
from pip.util import get_installed_distributions, get_prog
from pip.vcs import git, mercurial, subversion, bazaar # noqa
from pip.baseparser import ConfigOptionParser, UpdatingDefaultsHelpFormatter
from pip.commands import commands, get_summaries, get_similar_commands
# This fixes a peculiarity when importing via __import__ - as we are
# initialising the pip module, "from pip import cmdoptions" is recursive
# and appears not to work properly in that situation.
import pip.cmdoptions
cmdoptions = pip.cmdoptions
# The version as used in the and the docs
__version__ = "1.5.6"
def autocomplete():
"""Command and option completion for the main option parser (and options)
and its subcommands (and options).
Enable by sourcing one of the completion shell scripts (bash or zsh).
# Don't complete if user hasn't sourced bash_completion file.
if 'PIP_AUTO_COMPLETE' not in os.environ:
cwords = os.environ['COMP_WORDS'].split()[1:]
cword = int(os.environ['COMP_CWORD'])
current = cwords[cword - 1]
except IndexError:
current = ''
subcommands = [cmd for cmd, summary in get_summaries()]
options = []
# subcommand
subcommand_name = [w for w in cwords if w in subcommands][0]
except IndexError:
subcommand_name = None
parser = create_main_parser()
# subcommand options
if subcommand_name:
# special case: 'help' subcommand has no options
if subcommand_name == 'help':
# special case: list locally installed dists for uninstall command
if subcommand_name == 'uninstall' and not current.startswith('-'):
installed = []
lc = current.lower()
for dist in get_installed_distributions(local_only=True):
if dist.key.startswith(lc) and dist.key not in cwords[1:]:
# if there are no dists installed, fall back to option completion
if installed:
for dist in installed:
subcommand = commands[subcommand_name]()
options += [(opt.get_opt_string(), opt.nargs)
for opt in subcommand.parser.option_list_all
if != optparse.SUPPRESS_HELP]
# filter out previously specified options from available options
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
options = [(x, v) for (x, v) in options if x not in prev_opts]
# filter options by current input
options = [(k, v) for k, v in options if k.startswith(current)]
for option in options:
opt_label = option[0]
# append '=' to options which require args
if option[1]:
opt_label += '='
# show main parser options only when necessary
if current.startswith('-') or current.startswith('--'):
opts = [i.option_list for i in parser.option_groups]
opts = (o for it in opts for o in it)
subcommands += [i.get_opt_string() for i in opts
if != optparse.SUPPRESS_HELP]
print(' '.join([x for x in subcommands if x.startswith(current)]))
def create_main_parser():
parser_kw = {
'usage': '\n%prog <command> [options]',
'add_help_option': False,
'formatter': UpdatingDefaultsHelpFormatter(),
'name': 'global',
'prog': get_prog(),
parser = ConfigOptionParser(**parser_kw)
pip_pkg_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
parser.version = 'pip %s from %s (python %s)' % (
__version__, pip_pkg_dir, sys.version[:3])
# add the general options
gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser)
parser.main = True # so the help formatter knows
# create command listing for description
command_summaries = get_summaries()
description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries]
parser.description = '\n'.join(description)
return parser
def parseopts(args):
parser = create_main_parser()
# Note: parser calls disable_interspersed_args(), so the result of this call
# is to split the initial args into the general options before the
# subcommand and everything else.
# For example:
# args: ['--timeout=5', 'install', '--user', 'INITools']
# general_options: ['--timeout==5']
# args_else: ['install', '--user', 'INITools']
general_options, args_else = parser.parse_args(args)
# --version
if general_options.version:
# pip || pip help -> print_help()
if not args_else or (args_else[0] == 'help' and len(args_else) == 1):
# the subcommand name
cmd_name = args_else[0].lower()
#all the args without the subcommand
cmd_args = args[:]
if cmd_name not in commands:
guess = get_similar_commands(cmd_name)
msg = ['unknown command "%s"' % cmd_name]
if guess:
msg.append('maybe you meant "%s"' % guess)
raise CommandError(' - '.join(msg))
return cmd_name, cmd_args
def main(initial_args=None):
if initial_args is None:
initial_args = sys.argv[1:]
cmd_name, cmd_args = parseopts(initial_args)
except PipError:
e = sys.exc_info()[1]
sys.stderr.write("ERROR: %s" % e)
command = commands[cmd_name]()
return command.main(cmd_args)
def bootstrap():
Bootstrapping function to be called from script.
pkgs = ['pip']
import setuptools
except ImportError:
return main(['install', '--upgrade'] + pkgs + sys.argv[1:])
## Writing freeze files
class FrozenRequirement(object):
def __init__(self, name, req, editable, comments=()): = name
self.req = req
self.editable = editable
self.comments = comments
_rev_re = re.compile(r'-r(\d+)$')
_date_re = re.compile(r'-(20\d\d\d\d\d\d)$')
def from_dist(cls, dist, dependency_links, find_tags=False):
location = os.path.normcase(os.path.abspath(dist.location))
comments = []
from pip.vcs import vcs, get_src_requirement
if vcs.get_backend_name(location):
editable = True
req = get_src_requirement(dist, location, find_tags)
except InstallationError:
ex = sys.exc_info()[1]
logger.warn("Error when trying to get requirement for VCS system %s, falling back to uneditable format" % ex)
req = None
if req is None:
logger.warn('Could not determine repository location of %s' % location)
comments.append('## !! Could not determine repository location')
req = dist.as_requirement()
editable = False
editable = False
req = dist.as_requirement()
specs = req.specs
assert len(specs) == 1 and specs[0][0] == '=='
version = specs[0][1]
ver_match =
date_match =
if ver_match or date_match:
svn_backend = vcs.get_backend('svn')
if svn_backend:
svn_location = svn_backend(
).get_location(dist, dependency_links)
if not svn_location:
'Warning: cannot find svn location for %s' % req)
comments.append('## FIXME: could not find svn URL in dependency_links for this package:')
comments.append('# Installing as editable to satisfy requirement %s:' % req)
if ver_match:
rev =
rev = '{%s}' %
editable = True
req = '%s@%s#egg=%s' % (svn_location, rev, cls.egg_name(dist))
return cls(dist.project_name, req, editable, comments)
def egg_name(dist):
name = dist.egg_name()
match ='-py\d\.\d$', name)
if match:
name = name[:match.start()]
return name
def __str__(self):
req = self.req
if self.editable:
req = '-e %s' % req
return '\n'.join(list(self.comments) + [str(req)]) + '\n'
if __name__ == '__main__':
exit = main()
if exit:
import sys
from .runner import run
if __name__ == '__main__':
exit = run()
if exit:
pip._vendor is for vendoring dependencies of pip to prevent needing pip to
depend on something external.
Files inside of pip._vendor should be considered immutable and should only be
updated to versions from upstream.
from __future__ import absolute_import
import ast
from pip._vendor._markerlib.markers import default_environment, compile, interpret
except ImportError:
if 'ast' in globals():
def default_environment():
return {}
def compile(marker):
def marker_fn(environment=None, override=None):
# 'empty markers are True' heuristic won't install extra deps.
return not marker.strip()
marker_fn.__doc__ = marker
return marker_fn
def interpret(marker, environment=None, override=None):
return compile(marker)()
# -*- coding: utf-8 -*-
"""Interpret PEP 345 environment markers.
EXPR [in|==|!=|not in] EXPR [or|and] ...
where EXPR belongs to any of those: