Python Shutil.copytree问题?

Python Shutil.copytree问题?

我目前正在做Chromium的开发,我想将下面这段代码里面的 distutils.dir_util.copy_tree(source, header_dir, preserve_times=False)改成shutil.copytree(source, header_dir, dirs_exist_ok=True),但是在测试的时候发现会导致出现其他问题,请问我应该如何修改这里的代码?

# Copyright 2015 The Chromium Authors

# Use of this source code is governed by a BSD-style license that can be

# found in the LICENSE file.

# Runs the Microsoft Message Compiler (mc.exe).

#

# Usage: message_compiler.py <environment_file> [<args to mc.exe>*]

from __future__ import print_function

import difflib

import distutils.dir_util

import filecmp

import os

import re

import shutil

import subprocess

import sys

import tempfile

def main():

env_file, rest = sys.argv[1], sys.argv[2:]

# Parse some argument flags.

header_dir = None

resource_dir = None

input_file = None

for i, arg in enumerate(rest):

if arg == '-h' and len(rest) > i + 1:

assert header_dir == None

header_dir = rest[i + 1]

elif arg == '-r' and len(rest) > i + 1:

assert resource_dir == None

resource_dir = rest[i + 1]

elif arg.endswith('.mc') or arg.endswith('.man'):

assert input_file == None

input_file = arg

# Copy checked-in outputs to final location.

THIS_DIR = os.path.abspath(os.path.dirname(__file__))

assert header_dir == resource_dir

source = os.path.join(THIS_DIR, "..", "..",

"third_party", "win_build_output",

re.sub(r'^(?:[^/]+/)?gen/', 'mc/', header_dir))

distutils.dir_util.copy_tree(source, header_dir, preserve_times=False)

# On non-Windows, that's all we can do.

if sys.platform != 'win32':

return

# On Windows, run mc.exe on the input and check that its outputs are

# identical to the checked-in outputs.

# Read the environment block from the file. This is stored in the format used

# by CreateProcess. Drop last 2 NULs, one for list terminator, one for

# trailing vs. separator.

env_pairs = open(env_file).read()[:-2].split('\0')

env_dict = dict([item.split('=', 1) for item in env_pairs])

extension = os.path.splitext(input_file)[1]

if extension in ['.man', '.mc']:

# For .man files, mc's output changed significantly from Version 10.0.15063

# to Version 10.0.16299. We should always have the output of the current

# default SDK checked in and compare to that. Early out if a different SDK

# is active. This also happens with .mc files.

# TODO(thakis): Check in new baselines and compare to 16299 instead once

# we use the 2017 Fall Creator's Update by default.

mc_help = subprocess.check_output(['mc.exe', '/?'], env=env_dict,

stderr=subprocess.STDOUT, shell=True)

version = re.search(br'Message Compiler\s+Version (\S+)', mc_help).group(1)

if version != '10.0.15063':

return

# mc writes to stderr, so this explicitly redirects to stdout and eats it.

try:

tmp_dir = tempfile.mkdtemp()

delete_tmp_dir = True

if header_dir:

rest[rest.index('-h') + 1] = tmp_dir

header_dir = tmp_dir

if resource_dir:

rest[rest.index('-r') + 1] = tmp_dir

resource_dir = tmp_dir

# This needs shell=True to search the path in env_dict for the mc

# executable.

subprocess.check_output(['mc.exe'] + rest,

env=env_dict,

stderr=subprocess.STDOUT,

shell=True)

# We require all source code (in particular, the header generated here) to

# be UTF-8. jinja can output the intermediate .mc file in UTF-8 or UTF-16LE.

# However, mc.exe only supports Unicode via the -u flag, and it assumes when

# that is specified that the input is UTF-16LE (and errors out on UTF-8

# files, assuming they're ANSI). Even with -u specified and UTF16-LE input,

# it generates an ANSI header, and includes broken versions of the message

# text in the comment before the value. To work around this, for any invalid

# // comment lines, we simply drop the line in the header after building it.

# Also, mc.exe apparently doesn't always write #define lines in

# deterministic order, so manually sort each block of #defines.

if header_dir:

header_file = os.path.join(

header_dir, os.path.splitext(os.path.basename(input_file))[0] + '.h')

header_contents = []

with open(header_file, 'rb') as f:

define_block = [] # The current contiguous block of #defines.

for line in f.readlines():

if line.startswith('//') and '?' in line:

continue

if line.startswith('#define '):

define_block.append(line)

continue

# On the first non-#define line, emit the sorted preceding #define

# block.

header_contents += sorted(define_block, key=lambda s: s.split()[-1])

define_block = []

header_contents.append(line)

# If the .h file ends with a #define block, flush the final block.

header_contents += sorted(define_block, key=lambda s: s.split()[-1])

with open(header_file, 'wb') as f:

f.write(''.join(header_contents))

# mc.exe invocation and post-processing are complete, now compare the output

# in tmp_dir to the checked-in outputs.

diff = filecmp.dircmp(tmp_dir, source)

if diff.diff_files or set(diff.left_list) != set(diff.right_list):

print('mc.exe output different from files in %s, see %s' % (source,

tmp_dir))

diff.report()

for f in diff.diff_files:

if f.endswith('.bin'): continue

fromfile = os.path.join(source, f)

tofile = os.path.join(tmp_dir, f)

print(''.join(

difflib.unified_diff(

open(fromfile, 'U').readlines(),

open(tofile, 'U').readlines(), fromfile, tofile)))

delete_tmp_dir = False

sys.exit(1)

except subprocess.CalledProcessError as e:

print(e.output)

sys.exit(e.returncode)

finally:

if os.path.exists(tmp_dir) and delete_tmp_dir:

shutil.rmtree(tmp_dir)

if __name__ == '__main__':

main()

上面是完整的代码

https://ci.chromium.org/ui/p/...

https://ci.chromium.org/ui/p/...

https://ci.chromium.org/ui/p/...

这三个链接是Trybots的测试结果

以上是 Python Shutil.copytree问题? 的全部内容, 来源链接: utcz.com/p/938678.html

回到顶部