diff options
| author | robot-piglet <[email protected]> | 2025-08-29 14:19:24 +0300 |
|---|---|---|
| committer | robot-piglet <[email protected]> | 2025-08-29 14:40:38 +0300 |
| commit | 5715939b5b1a1812ed85171fb519f9c1c3c326e8 (patch) | |
| tree | 5d981253427e490749bbb50d3616507fa0d6d1bc /contrib/python/grpcio/py3/commands.py | |
| parent | c390a008ee5d15e1d8f49326671908f375e0851b (diff) | |
Intermediate changes
commit_hash:88dd3a7e237f5ebeb9b302a0e6866042635fda83
Diffstat (limited to 'contrib/python/grpcio/py3/commands.py')
| -rw-r--r-- | contrib/python/grpcio/py3/commands.py | 216 |
1 files changed, 124 insertions, 92 deletions
diff --git a/contrib/python/grpcio/py3/commands.py b/contrib/python/grpcio/py3/commands.py index 6d8228ffa05..0ceb0546a99 100644 --- a/contrib/python/grpcio/py3/commands.py +++ b/contrib/python/grpcio/py3/commands.py @@ -11,7 +11,7 @@ # 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. -"""Provides distutils command classes for the GRPC Python setup process.""" +"""Provides setuptools command classes for the GRPC Python setup process.""" # NOTE(https://github.com/grpc/grpc/issues/24028): allow setuptools to monkey # patch distutils @@ -31,10 +31,10 @@ from setuptools.command import build_py import support PYTHON_STEM = os.path.dirname(os.path.abspath(__file__)) -GRPC_STEM = os.path.abspath(PYTHON_STEM + '../../../../') -PROTO_STEM = os.path.join(GRPC_STEM, 'src', 'proto') -PROTO_GEN_STEM = os.path.join(GRPC_STEM, 'src', 'python', 'gens') -CYTHON_STEM = os.path.join(PYTHON_STEM, 'grpc', '_cython') +GRPC_STEM = os.path.abspath(PYTHON_STEM + "../../../../") +PROTO_STEM = os.path.join(GRPC_STEM, "src", "proto") +PROTO_GEN_STEM = os.path.join(GRPC_STEM, "src", "python", "gens") +CYTHON_STEM = os.path.join(PYTHON_STEM, "grpc", "_cython") class CommandError(Exception): @@ -46,9 +46,9 @@ class CommandError(Exception): def _get_grpc_custom_bdist(decorated_basename, target_bdist_basename): """Returns a string path to a bdist file for Linux to install. - If we can retrieve a pre-compiled bdist from online, uses it. Else, emits a - warning and builds from source. - """ + If we can retrieve a pre-compiled bdist from online, uses it. Else, emits a + warning and builds from source. + """ # TODO(atash): somehow the name that's returned from `wheel` is different # between different versions of 'wheel' (but from a compatibility standpoint, # the names are compatible); we should have some way of determining name @@ -58,28 +58,35 @@ def _get_grpc_custom_bdist(decorated_basename, target_bdist_basename): # Break import style to ensure that setup.py has had a chance to install the # relevant package. from urllib import request + decorated_path = decorated_basename + GRPC_CUSTOM_BDIST_EXT try: - url = BINARIES_REPOSITORY + '/{target}'.format(target=decorated_path) + url = BINARIES_REPOSITORY + "/{target}".format(target=decorated_path) bdist_data = request.urlopen(url).read() except IOError as error: - raise CommandError('{}\n\nCould not find the bdist {}: {}'.format( - traceback.format_exc(), decorated_path, error.message)) + raise CommandError( + "{}\n\nCould not find the bdist {}: {}".format( + traceback.format_exc(), decorated_path, error.message + ) + ) # Our chosen local bdist path. bdist_path = target_bdist_basename + GRPC_CUSTOM_BDIST_EXT try: - with open(bdist_path, 'w') as bdist_file: + with open(bdist_path, "w") as bdist_file: bdist_file.write(bdist_data) except IOError as error: - raise CommandError('{}\n\nCould not write grpcio bdist: {}'.format( - traceback.format_exc(), error.message)) + raise CommandError( + "{}\n\nCould not write grpcio bdist: {}".format( + traceback.format_exc(), error.message + ) + ) return bdist_path class SphinxDocumentation(setuptools.Command): """Command to generate documentation via sphinx.""" - description = 'generate sphinx documentation' + description = "generate sphinx documentation" user_options = [] def initialize_options(self): @@ -92,19 +99,22 @@ class SphinxDocumentation(setuptools.Command): # We import here to ensure that setup.py has had a chance to install the # relevant package eggs first. import sphinx.cmd.build - source_dir = os.path.join(GRPC_STEM, 'doc', 'python', 'sphinx') - target_dir = os.path.join(GRPC_STEM, 'doc', 'build') + + source_dir = os.path.join(GRPC_STEM, "doc", "python", "sphinx") + target_dir = os.path.join(GRPC_STEM, "doc", "build") exit_code = sphinx.cmd.build.build_main( - ['-b', 'html', '-W', '--keep-going', source_dir, target_dir]) + ["-b", "html", "-W", "--keep-going", source_dir, target_dir] + ) if exit_code != 0: raise CommandError( - "Documentation generation has warnings or errors") + "Documentation generation has warnings or errors" + ) class BuildProjectMetadata(setuptools.Command): """Command to generate project metadata in a module.""" - description = 'build grpcio project metadata files' + description = "build grpcio project metadata files" user_options = [] def initialize_options(self): @@ -114,95 +124,112 @@ class BuildProjectMetadata(setuptools.Command): pass def run(self): - with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'), - 'w') as module_file: - module_file.write('__version__ = """{}"""'.format( - self.distribution.get_version())) + with open( + os.path.join(PYTHON_STEM, "grpc/_grpcio_metadata.py"), "w" + ) as module_file: + module_file.write( + '__version__ = """{}"""'.format(self.distribution.get_version()) + ) class BuildPy(build_py.build_py): """Custom project build command.""" def run(self): - self.run_command('build_project_metadata') + self.run_command("build_project_metadata") build_py.build_py.run(self) def _poison_extensions(extensions, message): """Includes a file that will always fail to compile in all extensions.""" - poison_filename = os.path.join(PYTHON_STEM, 'poison.c') - with open(poison_filename, 'w') as poison: - poison.write('#error {}'.format(message)) + poison_filename = os.path.join(PYTHON_STEM, "poison.c") + with open(poison_filename, "w") as poison: + poison.write("#error {}".format(message)) for extension in extensions: extension.sources = [poison_filename] def check_and_update_cythonization(extensions): """Replace .pyx files with their generated counterparts and return whether or - not cythonization still needs to occur.""" + not cythonization still needs to occur.""" for extension in extensions: generated_pyx_sources = [] other_sources = [] for source in extension.sources: base, file_ext = os.path.splitext(source) - if file_ext == '.pyx': - generated_pyx_source = next((base + gen_ext for gen_ext in ( - '.c', - '.cpp', - ) if os.path.isfile(base + gen_ext)), None) + if file_ext == ".pyx": + generated_pyx_source = next( + ( + base + gen_ext + for gen_ext in ( + ".c", + ".cpp", + ) + if os.path.isfile(base + gen_ext) + ), + None, + ) if generated_pyx_source: generated_pyx_sources.append(generated_pyx_source) else: - sys.stderr.write('Cython-generated files are missing...\n') + sys.stderr.write("Cython-generated files are missing...\n") return False else: other_sources.append(source) extension.sources = generated_pyx_sources + other_sources - sys.stderr.write('Found cython-generated files...\n') + sys.stderr.write("Found cython-generated files...\n") return True def try_cythonize(extensions, linetracing=False, mandatory=True): """Attempt to cythonize the extensions. - Args: - extensions: A list of `distutils.extension.Extension`. - linetracing: A bool indicating whether or not to enable linetracing. - mandatory: Whether or not having Cython-generated files is mandatory. If it - is, extensions will be poisoned when they can't be fully generated. - """ + Args: + extensions: A list of `setuptools.Extension`. + linetracing: A bool indicating whether or not to enable linetracing. + mandatory: Whether or not having Cython-generated files is mandatory. If it + is, extensions will be poisoned when they can't be fully generated. + """ try: # Break import style to ensure we have access to Cython post-setup_requires import Cython.Build except ImportError: if mandatory: sys.stderr.write( - "This package needs to generate C files with Cython but it cannot. " - "Poisoning extension sources to disallow extension commands...") + "This package needs to generate C files with Cython but it" + " cannot. Poisoning extension sources to disallow extension" + " commands..." + ) _poison_extensions( extensions, - "Extensions have been poisoned due to missing Cython-generated code." + ( + "Extensions have been poisoned due to missing" + " Cython-generated code." + ), ) return extensions cython_compiler_directives = {} if linetracing: - additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')] - cython_compiler_directives['linetrace'] = True + additional_define_macros = [("CYTHON_TRACE_NOGIL", "1")] + cython_compiler_directives["linetrace"] = True return Cython.Build.cythonize( extensions, include_path=[ - include_dir for extension in extensions + include_dir + for extension in extensions for include_dir in extension.include_dirs - ] + [CYTHON_STEM], - compiler_directives=cython_compiler_directives) + ] + + [CYTHON_STEM], + compiler_directives=cython_compiler_directives, + ) class BuildExt(build_ext.build_ext): """Custom build_ext command to enable compiler-specific flags.""" C_OPTIONS = { - 'unix': ('-pthread',), - 'msvc': (), + "unix": ("-pthread",), + "msvc": (), } LINK_OPTIONS = {} @@ -214,30 +241,32 @@ class BuildExt(build_ext.build_ext): # so that the resulting file name matches the target architecture and we end up with a well-formed # wheel. filename = build_ext.build_ext.get_ext_filename(self, ext_name) - orig_ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') - new_ext_suffix = os.getenv('GRPC_PYTHON_OVERRIDE_EXT_SUFFIX') + orig_ext_suffix = sysconfig.get_config_var("EXT_SUFFIX") + new_ext_suffix = os.getenv("GRPC_PYTHON_OVERRIDE_EXT_SUFFIX") if new_ext_suffix and filename.endswith(orig_ext_suffix): - filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix + filename = filename[: -len(orig_ext_suffix)] + new_ext_suffix return filename def build_extensions(self): - def compiler_ok_with_extra_std(): """Test if default compiler is okay with specifying c++ version when invoked in C mode. GCC is okay with this, while clang is not. """ try: # TODO(lidiz) Remove the generated a.out for success tests. - cc = os.environ.get('CC', 'cc') - cc_test = subprocess.Popen([cc, '-x', 'c', '-std=c++14', '-'], - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - _, cc_err = cc_test.communicate(input=b'int main(){return 0;}') - return not 'invalid argument' in str(cc_err) + cc = os.environ.get("CC", "cc") + cc_test = subprocess.Popen( + [cc, "-x", "c", "-std=c++14", "-"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + _, cc_err = cc_test.communicate(input=b"int main(){return 0;}") + return not "invalid argument" in str(cc_err) except: - sys.stderr.write('Non-fatal exception:' + - traceback.format_exc() + '\n') + sys.stderr.write( + "Non-fatal exception:" + traceback.format_exc() + "\n" + ) return False # This special conditioning is here due to difference of compiler @@ -253,16 +282,17 @@ class BuildExt(build_ext.build_ext): old_compile = self.compiler._compile def new_compile(obj, src, ext, cc_args, extra_postargs, pp_opts): - if src.endswith('.c'): + if src.endswith(".c"): extra_postargs = [ - arg for arg in extra_postargs if not '-std=c++' in arg + arg for arg in extra_postargs if "-std=c++" not in arg ] - elif src.endswith('.cc') or src.endswith('.cpp'): + elif src.endswith(".cc") or src.endswith(".cpp"): extra_postargs = [ - arg for arg in extra_postargs if not '-std=gnu99' in arg + arg for arg in extra_postargs if "-std=gnu99" not in arg ] - return old_compile(obj, src, ext, cc_args, extra_postargs, - pp_opts) + return old_compile( + obj, src, ext, cc_args, extra_postargs, pp_opts + ) self.compiler._compile = new_compile @@ -270,11 +300,13 @@ class BuildExt(build_ext.build_ext): if compiler in BuildExt.C_OPTIONS: for extension in self.extensions: extension.extra_compile_args += list( - BuildExt.C_OPTIONS[compiler]) + BuildExt.C_OPTIONS[compiler] + ) if compiler in BuildExt.LINK_OPTIONS: for extension in self.extensions: extension.extra_link_args += list( - BuildExt.LINK_OPTIONS[compiler]) + BuildExt.LINK_OPTIONS[compiler] + ) if not check_and_update_cythonization(self.extensions): self.extensions = try_cythonize(self.extensions) try: @@ -283,16 +315,17 @@ class BuildExt(build_ext.build_ext): formatted_exception = traceback.format_exc() support.diagnose_build_ext_error(self, error, formatted_exception) raise CommandError( - "Failed `build_ext` step:\n{}".format(formatted_exception)) + "Failed `build_ext` step:\n{}".format(formatted_exception) + ) class Gather(setuptools.Command): """Command to gather project dependencies.""" - description = 'gather dependencies for grpcio' + description = "gather dependencies for grpcio" user_options = [ - ('test', 't', 'flag indicating to gather test dependencies'), - ('install', 'i', 'flag indicating to gather install dependencies') + ("test", "t", "flag indicating to gather test dependencies"), + ("install", "i", "flag indicating to gather install dependencies"), ] def initialize_options(self): @@ -304,30 +337,27 @@ class Gather(setuptools.Command): pass def run(self): - if self.install and self.distribution.install_requires: - self.distribution.fetch_build_eggs( - self.distribution.install_requires) - if self.test and self.distribution.tests_require: - self.distribution.fetch_build_eggs(self.distribution.tests_require) + pass class Clean(setuptools.Command): """Command to clean build artifacts.""" - description = 'Clean build artifacts.' + description = "Clean build artifacts." user_options = [ - ('all', 'a', 'a phony flag to allow our script to continue'), + ("all", "a", "a phony flag to allow our script to continue"), ] _FILE_PATTERNS = ( - 'python_build', - 'src/python/grpcio/__pycache__/', - 'src/python/grpcio/grpc/_cython/cygrpc.cpp', - 'src/python/grpcio/grpc/_cython/*.so', - 'src/python/grpcio/grpcio.egg-info/', + "pyb", + "src/python/grpcio/__pycache__/", + "src/python/grpcio/grpc/_cython/cygrpc.cpp", + "src/python/grpcio/grpc/_cython/*.so", + "src/python/grpcio/grpcio.egg-info/", ) _CURRENT_DIRECTORY = os.path.normpath( - os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../..")) + os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../..") + ) def initialize_options(self): self.all = False @@ -338,12 +368,14 @@ class Clean(setuptools.Command): def run(self): for path_spec in self._FILE_PATTERNS: this_glob = os.path.normpath( - os.path.join(Clean._CURRENT_DIRECTORY, path_spec)) + os.path.join(Clean._CURRENT_DIRECTORY, path_spec) + ) abs_paths = glob.glob(this_glob) for path in abs_paths: if not str(path).startswith(Clean._CURRENT_DIRECTORY): raise ValueError( - "Cowardly refusing to delete {}.".format(path)) + "Cowardly refusing to delete {}.".format(path) + ) print("Removing {}".format(os.path.relpath(path))) if os.path.isfile(path): os.remove(str(path)) |
