aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/grpc/src/python/grpcio/support.py
blob: c6dc992db08cce68fe29ce2713575fef1f1a40fd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# Copyright 2016 gRPC authors.
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
 
import os 
import os.path 
import shutil 
import sys 
import tempfile 
 
from distutils import errors 
 
import commands 
 
C_PYTHON_DEV = """ 
#include <Python.h> 
int main(int argc, char **argv) { return 0; } 
""" 
C_PYTHON_DEV_ERROR_MESSAGE = """ 
Could not find <Python.h>. This could mean the following: 
  * You're on Ubuntu and haven't run `apt-get install <PY_REPR>-dev`.
  * You're on RHEL/Fedora and haven't run `yum install <PY_REPR>-devel` or
    `dnf install <PY_REPR>-devel` (make sure you also have redhat-rpm-config
    installed) 
  * You're on Mac OS X and the usual Python framework was somehow corrupted 
    (check your environment variables or try re-installing?) 
  * You're on Windows and your Python installation was somehow corrupted 
    (check your environment variables or try re-installing?) 
""" 
if sys.version_info[0] == 2:
    PYTHON_REPRESENTATION = 'python'
elif sys.version_info[0] == 3:
    PYTHON_REPRESENTATION = 'python3'
else:
    raise NotImplementedError('Unsupported Python version: %s' % sys.version)
 
C_CHECKS = { 
    C_PYTHON_DEV:
        C_PYTHON_DEV_ERROR_MESSAGE.replace('<PY_REPR>', PYTHON_REPRESENTATION),
} 
 
 
def _compile(compiler, source_string): 
    tempdir = tempfile.mkdtemp() 
    cpath = os.path.join(tempdir, 'a.c') 
    with open(cpath, 'w') as cfile: 
        cfile.write(source_string) 
    try: 
        compiler.compile([cpath]) 
    except errors.CompileError as error: 
        return error 
    finally: 
        shutil.rmtree(tempdir) 
 
 
def _expect_compile(compiler, source_string, error_message): 
    if _compile(compiler, source_string) is not None: 
        sys.stderr.write(error_message) 
        raise commands.CommandError( 
            "Diagnostics found a compilation environment issue:\n{}".format(
                error_message))
 
 
def diagnose_compile_error(build_ext, error): 
    """Attempt to diagnose an error during compilation.""" 
    for c_check, message in C_CHECKS.items(): 
        _expect_compile(build_ext.compiler, c_check, message) 
    python_sources = [ 
        source for source in build_ext.get_source_files() 
        if source.startswith('./src/python') and source.endswith('c') 
    ] 
    for source in python_sources: 
        if not os.path.isfile(source): 
            raise commands.CommandError(( 
                "Diagnostics found a missing Python extension source file:\n{}\n\n" 
                "This is usually because the Cython sources haven't been transpiled " 
                "into C yet and you're building from source.\n" 
                "Try setting the environment variable " 
                "`GRPC_PYTHON_BUILD_WITH_CYTHON=1` when invoking `setup.py` or " 
                "when using `pip`, e.g.:\n\n" 
                "pip install -rrequirements.txt\n" 
                "GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install .").format(source)) 
 
 
def diagnose_attribute_error(build_ext, error): 
    if any('_needs_stub' in arg for arg in error.args): 
        raise commands.CommandError( 
            "We expect a missing `_needs_stub` attribute from older versions of " 
            "setuptools. Consider upgrading setuptools.") 
 
 
_ERROR_DIAGNOSES = { 
    errors.CompileError: diagnose_compile_error, 
    AttributeError: diagnose_attribute_error,
} 
 
 
def diagnose_build_ext_error(build_ext, error, formatted): 
    diagnostic = _ERROR_DIAGNOSES.get(type(error)) 
    if diagnostic is None: 
        raise commands.CommandError( 
            "\n\nWe could not diagnose your build failure. If you are unable to "
            "proceed, please file an issue at http://www.github.com/grpc/grpc "
            "with `[Python install]` in the title; please attach the whole log "
            "(including everything that may have appeared above the Python "
            "backtrace).\n\n{}".format(formatted))
    else: 
        diagnostic(build_ext, error)