Enable binary linux distributions for Python

pull/4884/head
Masood Malekghassemi 9 years ago
parent 7c43f49092
commit 154b0eeaa9
  1. 5
      setup.py
  2. 130
      src/python/grpcio/commands.py

@ -119,6 +119,7 @@ PACKAGE_DIRECTORIES = {
}
INSTALL_REQUIRES = (
'six>=1.10',
'enum34>=1.0.4',
'futures>=2.2.0',
# TODO(atash): eventually split the grpcio package into a metapackage
@ -131,6 +132,7 @@ SETUP_REQUIRES = (
) + INSTALL_REQUIRES
COMMAND_CLASS = {
'install': commands.Install,
'doc': commands.SphinxDocumentation,
'build_proto_modules': commands.BuildProtoModules,
'build_project_metadata': commands.BuildProjectMetadata,
@ -138,6 +140,7 @@ COMMAND_CLASS = {
'build_ext': commands.BuildExt,
'gather': commands.Gather,
'run_interop': commands.RunInterop,
'bdist_egg_grpc_custom': commands.BdistEggCustomName,
}
# Ensure that package data is copied over before any commands have been run:
@ -187,7 +190,7 @@ else:
setuptools.setup(
name='grpcio',
version='0.12.0b5',
version='0.12.0b6',
license=LICENSE,
ext_modules=CYTHON_EXTENSION_MODULES,
packages=list(PACKAGES),

@ -30,15 +30,22 @@
"""Provides distutils command classes for the GRPC Python setup process."""
import distutils
import glob
import os
import os.path
import platform
import re
import shutil
import subprocess
import sys
import traceback
import setuptools
from setuptools.command import bdist_egg
from setuptools.command import build_ext
from setuptools.command import build_py
from setuptools.command import easy_install
from setuptools.command import install
from setuptools.command import test
import support
@ -58,6 +65,129 @@ class CommandError(Exception):
"""Simple exception class for GRPC custom commands."""
# TODO(atash): Remove this once PyPI has better Linux bdist support. See
# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
def _get_linux_bdist_egg(decorated_basename, target_egg_basename):
"""Returns a string path to a .egg file for Linux to install.
If we can retrieve a pre-compiled egg from online, uses it. Else, emits a
warning and builds from source.
"""
# Break import style to ensure that setup.py has had a chance to install the
# relevant package eggs.
from six.moves.urllib import request
decorated_path = decorated_basename + '.egg'
try:
url = (
'https://storage.googleapis.com/grpc-precompiled-binaries/'
'python/{target}'
.format(target=decorated_path))
egg_data = request.urlopen(url).read()
except IOError as error:
raise CommandError(
'{}\n\nCould not find the bdist egg {}: {}'
.format(traceback.format_exc(), decorated_path, error.message))
# Our chosen local egg path.
egg_path = target_egg_basename + '.egg'
try:
with open(egg_path, 'w') as egg_file:
egg_file.write(egg_data)
except IOError as error:
raise CommandError(
'{}\n\nCould not write grpcio egg: {}'
.format(traceback.format_exc(), error.message))
return egg_path
class EggNameMixin(object):
def egg_name(self, with_custom):
"""
Args:
with_custom: Boolean describing whether or not to decorate the egg name
with custom gRPC-specific target information.
"""
egg_command = self.get_finalized_command('bdist_egg')
base = os.path.splitext(os.path.basename(egg_command.egg_output))[0]
if with_custom:
flavor = 'ucs2' if sys.maxunicode == 65535 else 'ucs4'
return '{base}-{flavor}'.format(base=base, flavor=flavor)
else:
return base
class Install(install.install, EggNameMixin):
"""Custom Install command for gRPC Python.
This is for bdist shims and whatever else we might need a custom install
command for.
"""
user_options = install.install.user_options + [
# TODO(atash): remove this once manylinux gets on PyPI. See
# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
('use-linux-bdist', None,
'Whether to retrieve a binary for Linux instead of building from '
'source.'),
]
def initialize_options(self):
install.install.initialize_options(self)
self.use_linux_bdist = False
def finalize_options(self):
install.install.finalize_options(self)
def run(self):
if self.use_linux_bdist:
try:
egg_path = _get_linux_bdist_egg(self.egg_name(True),
self.egg_name(False))
except CommandError as error:
sys.stderr.write(
'\nWARNING: Failed to acquire grpcio prebuilt binary:\n'
'{}.\n\n'.format(error.message))
raise
try:
self._run_bdist_retrieval_install(egg_path)
except Exception as error:
# if anything else happens (and given how there's no way to really know
# what's happening in setuptools here, I mean *anything*), warn the user
# and fall back to building from source.
sys.stderr.write(
'{}\nWARNING: Failed to install grpcio prebuilt binary.\n\n'
.format(traceback.format_exc()))
install.install.run(self)
else:
install.install.run(self)
# TODO(atash): Remove this once PyPI has better Linux bdist support. See
# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
def _run_bdist_retrieval_install(self, bdist_egg):
easy_install = self.distribution.get_command_class('easy_install')
easy_install_command = easy_install(
self.distribution, args='x', root=self.root, record=self.record,
)
easy_install_command.ensure_finalized()
easy_install_command.always_copy_from = '.'
easy_install_command.package_index.scan(glob.glob('*.egg'))
arguments = [bdist_egg]
if setuptools.bootstrap_install_from:
args.insert(0, setuptools.bootstrap_install_from)
easy_install_command.args = arguments
easy_install_command.run()
setuptools.bootstrap_install_from = None
class BdistEggCustomName(bdist_egg.bdist_egg, EggNameMixin):
"""Thin wrapper around the bdist_egg command to build with our custom name."""
def run(self):
bdist_egg.bdist_egg.run(self)
target = os.path.join(self.dist_dir, '{}.egg'.format(self.egg_name(True)))
shutil.move(self.get_outputs()[0], target)
class SphinxDocumentation(setuptools.Command):
"""Command to generate documentation via sphinx."""

Loading…
Cancel
Save