Imported Upstream version 1.22.0
[platform/upstream/grpc.git] / src / python / grpcio / _spawn_patch.py
1 # Copyright 2016 gRPC authors.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 """Patches the spawn() command for windows compilers.
15
16 Windows has an 8191 character command line limit, but some compilers
17 support an @command_file directive where command_file is a file
18 containing the full command line.
19 """
20
21 from distutils import ccompiler
22 import os
23 import os.path
24 import shutil
25 import sys
26 import tempfile
27
28 MAX_COMMAND_LENGTH = 8191
29
30 _classic_spawn = ccompiler.CCompiler.spawn
31
32
33 def _commandfile_spawn(self, command):
34     command_length = sum([len(arg) for arg in command])
35     if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
36         # Even if this command doesn't support the @command_file, it will
37         # fail as is so we try blindly
38         print('Command line length exceeded, using command file')
39         print(' '.join(command))
40         temporary_directory = tempfile.mkdtemp()
41         command_filename = os.path.abspath(
42             os.path.join(temporary_directory, 'command'))
43         with open(command_filename, 'w') as command_file:
44             escaped_args = [
45                 '"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]
46             ]
47             command_file.write(' '.join(escaped_args))
48         modified_command = command[:1] + ['@{}'.format(command_filename)]
49         try:
50             _classic_spawn(self, modified_command)
51         finally:
52             shutil.rmtree(temporary_directory)
53     else:
54         _classic_spawn(self, command)
55
56
57 def monkeypatch_spawn():
58     """Monkeypatching is dumb, but it's either that or we become maintainers of
59      something much, much bigger."""
60     ccompiler.CCompiler.spawn = _commandfile_spawn