diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 739e751c9..a57a84787 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -139,24 +139,34 @@ class Backend(): langlist = {} abs_files = [] result = [] - for src in unity_src: - comp = self.get_compiler_for_source(src, target.is_cross) - language = comp.get_language() - suffix = '.' + comp.get_default_suffix() - if language not in langlist: - outfilename = os.path.join(self.get_target_private_dir_abs(target), target.name + '-unity' + suffix) - outfileabs = os.path.join(self.environment.get_build_dir(), outfilename) - outfileabs_tmp = outfileabs + '.tmp' - abs_files.append(outfileabs) - outfileabs_tmp_dir = os.path.dirname(outfileabs_tmp) - if not os.path.exists(outfileabs_tmp_dir): - os.makedirs(outfileabs_tmp_dir) - outfile = open(outfileabs_tmp, 'w') - langlist[language] = outfile - result.append(outfilename) - ofile = langlist[language] - ofile.write('#include<%s>\n' % src) - [x.close() for x in langlist.values()] + + def init_language_file(language, suffix): + outfilename = os.path.join(self.get_target_private_dir_abs(target), + target.name + '-unity' + suffix) + outfileabs = os.path.join(self.environment.get_build_dir(), + outfilename) + outfileabs_tmp = outfileabs + '.tmp' + abs_files.append(outfileabs) + outfileabs_tmp_dir = os.path.dirname(outfileabs_tmp) + if not os.path.exists(outfileabs_tmp_dir): + os.makedirs(outfileabs_tmp_dir) + result.append(outfilename) + return open(outfileabs_tmp, 'w') + + try: + for src in unity_src: + comp = self.get_compiler_for_source(src, target.is_cross) + language = comp.get_language() + try: + ofile = langlist[language] + except KeyError: + suffix = '.' + comp.get_default_suffix() + ofile = langlist[language] = init_language_file(language, + suffix) + ofile.write('#include<%s>\n' % src) + finally: + for x in langlist.values(): + x.close() [mesonlib.replace_if_different(x, x + '.tmp') for x in abs_files] return result @@ -215,13 +225,11 @@ class Backend(): def serialise_tests(self): test_data = os.path.join(self.environment.get_scratch_dir(), 'meson_test_setup.dat') - datafile = open(test_data, 'wb') - self.write_test_file(datafile) - datafile.close() + with open(test_data, 'wb') as datafile: + self.write_test_file(datafile) benchmark_data = os.path.join(self.environment.get_scratch_dir(), 'meson_benchmark_setup.dat') - datafile = open(benchmark_data, 'wb') - self.write_benchmark_file(datafile) - datafile.close() + with open(benchmark_data, 'wb') as datafile: + self.write_benchmark_file(datafile) return (test_data, benchmark_data) def has_source_suffix(self, target, suffix): @@ -442,7 +450,8 @@ class Backend(): mfobj = {'type': 'dependency manifest', 'version': '1.0'} mfobj['projects'] = self.build.dep_manifest - open(ifilename, 'w').write(json.dumps(mfobj)) + with open(ifilename, 'w') as f: + f.write(json.dumps(mfobj)) d.data.append([ifilename, ofilename]) def get_regen_filelist(self): diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 595feddce..e81c407b6 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -133,17 +133,18 @@ class NinjaBackend(backends.Backend): self.all_outputs = {} self.valgrind = environment.find_valgrind() - def detect_vs_dep_prefix(self, outfile, tempfilename): + def detect_vs_dep_prefix(self, tempfilename): '''VS writes its dependency in a locale dependent format. Detect the search prefix to use.''' # Of course there is another program called 'cl' on # some platforms. Let's just require that on Windows # cl points to msvc. if not mesonlib.is_windows() or shutil.which('cl') is None: - return outfile - outfile.close() - open(os.path.join(self.environment.get_scratch_dir(), 'incdetect.c'), - 'w').write('''#include + return open(tempfilename, 'a') + filename = os.path.join(self.environment.get_scratch_dir(), + 'incdetect.c') + with open(filename, 'w') as f: + f.write('''#include int dummy; ''') @@ -157,9 +158,8 @@ int dummy; for line in stdo.split(b'\r\n'): if line.endswith(b'stdio.h'): matchstr = b':'.join(line.split(b':')[0:2]) + b':' - binfile = open(tempfilename, 'ab') - binfile.write(b'msvc_deps_prefix = ' + matchstr + b'\r\n') - binfile.close() + with open(tempfilename, 'ab') as binfile: + binfile.write(b'msvc_deps_prefix = ' + matchstr + b'\r\n') return open(tempfilename, 'a') raise MesonException('Could not determine vs dep dependency prefix string.') @@ -167,30 +167,31 @@ int dummy; self.interpreter = interp outfilename = os.path.join(self.environment.get_build_dir(), self.ninja_filename) tempfilename = outfilename + '~' - outfile = open(tempfilename, 'w') - outfile.write('# This is the build file for project "%s"\n' % self.build.get_project()) - outfile.write('# It is autogenerated by the Meson build system.\n') - outfile.write('# Do not edit by hand.\n\n') - outfile.write('ninja_required_version = 1.5.1\n\n') - outfile = self.detect_vs_dep_prefix(outfile, tempfilename) - self.generate_rules(outfile) - self.generate_phony(outfile) - outfile.write('# Build rules for targets\n\n') - [self.generate_target(t, outfile) for t in self.build.get_targets().values()] - outfile.write('# Test rules\n\n') - self.generate_tests(outfile) - outfile.write('# Install rules\n\n') - self.generate_install(outfile) - if 'b_coverage' in self.environment.coredata.base_options and \ - self.environment.coredata.base_options['b_coverage'].value: - outfile.write('# Coverage rules\n\n') - self.generate_coverage_rules(outfile) - outfile.write('# Suffix\n\n') - self.generate_utils(outfile) - self.generate_ending(outfile) + with open(tempfilename, 'w') as outfile: + outfile.write('# This is the build file for project "%s"\n' % + self.build.get_project()) + outfile.write('# It is autogenerated by the Meson build system.\n') + outfile.write('# Do not edit by hand.\n\n') + outfile.write('ninja_required_version = 1.5.1\n\n') + with self.detect_vs_dep_prefix(tempfilename) as outfile: + self.generate_rules(outfile) + self.generate_phony(outfile) + outfile.write('# Build rules for targets\n\n') + for t in self.build.get_targets().values(): + self.generate_target(t, outfile) + outfile.write('# Test rules\n\n') + self.generate_tests(outfile) + outfile.write('# Install rules\n\n') + self.generate_install(outfile) + if 'b_coverage' in self.environment.coredata.base_options and \ + self.environment.coredata.base_options['b_coverage'].value: + outfile.write('# Coverage rules\n\n') + self.generate_coverage_rules(outfile) + outfile.write('# Suffix\n\n') + self.generate_utils(outfile) + self.generate_ending(outfile) # Only ovewrite the old build file after the new one has been # fully created. - outfile.close() os.replace(tempfilename, outfilename) self.generate_compdb() @@ -202,7 +203,8 @@ int dummy; jsondb = subprocess.check_output([ninja_exe, '-t', 'compdb', 'c_COMPILER', 'cpp_COMPILER'], cwd=builddir) except Exception: raise MesonException('Could not create compilation database.') - open(os.path.join(builddir, 'compile_commands.json'), 'wb').write(jsondb) + with open(os.path.join(builddir, 'compile_commands.json'), 'wb') as f: + f.write(jsondb) # Get all generated headers. Any source file might need them so # we need to add an order dependency to them. @@ -505,8 +507,8 @@ int dummy; self.generate_subdir_install(d) elem.write(outfile) - ofile = open(install_data_file, 'wb') - pickle.dump(d, ofile) + with open(install_data_file, 'wb') as ofile: + pickle.dump(d, ofile) def generate_target_install(self, d): should_strip = self.environment.coredata.get_builtin_option('strip') @@ -1416,16 +1418,22 @@ rule FORTRAN_DEP_HACK # but those are really rare. I hope. if not compiler.can_compile(s): continue - for line in open(os.path.join(self.environment.get_source_dir(), s.subdir, s.fname)): - modmatch = modre.match(line) - if modmatch is not None: - modname = modmatch.group(1) - if modname.lower() == 'procedure': # MODULE PROCEDURE construct - continue - if modname in module_files: - raise InvalidArguments('Namespace collision: module %s defined in two files %s and %s.' % - (modname, module_files[modname], s)) - module_files[modname] = s + filename = os.path.join(self.environment.get_source_dir(), + s.subdir, s.fname) + with open(filename) as f: + for line in f: + modmatch = modre.match(line) + if modmatch is not None: + modname = modmatch.group(1) + if modname.lower() == 'procedure': + # MODULE PROCEDURE construct + continue + if modname in module_files: + raise InvalidArguments( + 'Namespace collision: module %s defined in ' + 'two files %s and %s.' % + (modname, module_files[modname], s)) + module_files[modname] = s self.fortran_deps[target.get_basename()] = module_files def get_fortran_deps(self, compiler, src, target): @@ -1433,27 +1441,32 @@ rule FORTRAN_DEP_HACK usere = re.compile(r"\s*use\s+(\w+)", re.IGNORECASE) dirname = self.get_target_private_dir(target) tdeps= self.fortran_deps[target.get_basename()] - for line in open(src): - usematch = usere.match(line) - if usematch is not None: - usename = usematch.group(1) - if usename not in tdeps: - # The module is not provided by any source file. This is due to - # a) missing file/typo/etc - # b) using a module provided by the compiler, such as OpenMP - # There's no easy way to tell which is which (that I know of) - # so just ignore this and go on. Ideally we would print a - # warning message to the user but this is a common occurrance, - # which would lead to lots of distracting noise. - continue - mod_source_file = tdeps[usename] - # Check if a source uses a module it exports itself. - # Potential bug if multiple targets have a file with - # the same name. - if mod_source_file.fname == os.path.split(src)[1]: - continue - mod_name = compiler.module_name_to_filename(usematch.group(1)) - mod_files.append(os.path.join(dirname, mod_name)) + with open(src) as f: + for line in f: + usematch = usere.match(line) + if usematch is not None: + usename = usematch.group(1) + if usename not in tdeps: + # The module is not provided by any source file. This + # is due to: + # a) missing file/typo/etc + # b) using a module provided by the compiler, such as + # OpenMP + # There's no easy way to tell which is which (that I + # know of) so just ignore this and go on. Ideally we + # would print a warning message to the user but this is + # a common occurrence, which would lead to lots of + # distracting noise. + continue + mod_source_file = tdeps[usename] + # Check if a source uses a module it exports itself. + # Potential bug if multiple targets have a file with + # the same name. + if mod_source_file.fname == os.path.split(src)[1]: + continue + mod_name = compiler.module_name_to_filename( + usematch.group(1)) + mod_files.append(os.path.join(dirname, mod_name)) return mod_files def get_cross_stdlib_args(self, target, compiler): diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 669bcf890..eca747360 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -175,14 +175,18 @@ class Vs2010Backend(backends.Backend): @staticmethod def touch_regen_timestamp(build_dir): - open(Vs2010Backend.get_regen_stampfile(build_dir), 'w').close() + with open(Vs2010Backend.get_regen_stampfile(build_dir), 'w'): + pass def generate_regen_info(self): deps = self.get_regen_filelist() regeninfo = RegenInfo(self.environment.get_source_dir(), self.environment.get_build_dir(), deps) - pickle.dump(regeninfo, open(os.path.join(self.environment.get_scratch_dir(), 'regeninfo.dump'), 'wb')) + filename = os.path.join(self.environment.get_scratch_dir(), + 'regeninfo.dump') + with open(filename, 'wb') as f: + pickle.dump(regeninfo, f) def get_obj_target_deps(self, obj_list): result = {} @@ -217,57 +221,66 @@ class Vs2010Backend(backends.Backend): return all_deps def generate_solution(self, sln_filename, projlist): - ofile = open(sln_filename, 'w') - ofile.write('Microsoft Visual Studio Solution File, Format Version 11.00\n') - ofile.write('# Visual Studio ' + self.vs_version + '\n') - prj_templ = prj_line = 'Project("{%s}") = "%s", "%s", "{%s}"\n' - for p in projlist: - prj_line = prj_templ % (self.environment.coredata.guid, p[0], p[1], p[2]) - ofile.write(prj_line) - all_deps = self.determine_deps(p) - ofile.write('\tProjectSection(ProjectDependencies) = postProject\n') - regen_guid = self.environment.coredata.regen_guid - ofile.write('\t\t{%s} = {%s}\n' % (regen_guid, regen_guid)) - for dep in all_deps.keys(): - guid = self.environment.coredata.target_guids[dep] - ofile.write('\t\t{%s} = {%s}\n' % (guid, guid)) - ofile.write('EndProjectSection\n') + with open(sln_filename, 'w') as ofile: + ofile.write('Microsoft Visual Studio Solution File, Format ' + 'Version 11.00\n') + ofile.write('# Visual Studio ' + self.vs_version + '\n') + prj_templ = prj_line = 'Project("{%s}") = "%s", "%s", "{%s}"\n' + for p in projlist: + prj_line = prj_templ % (self.environment.coredata.guid, + p[0], p[1], p[2]) + ofile.write(prj_line) + all_deps = self.determine_deps(p) + ofile.write('\tProjectSection(ProjectDependencies) = ' + 'postProject\n') + regen_guid = self.environment.coredata.regen_guid + ofile.write('\t\t{%s} = {%s}\n' % (regen_guid, regen_guid)) + for dep in all_deps.keys(): + guid = self.environment.coredata.target_guids[dep] + ofile.write('\t\t{%s} = {%s}\n' % (guid, guid)) + ofile.write('EndProjectSection\n') + ofile.write('EndProject\n') + test_line = prj_templ % (self.environment.coredata.guid, + 'RUN_TESTS', 'RUN_TESTS.vcxproj', + self.environment.coredata.test_guid) + ofile.write(test_line) ofile.write('EndProject\n') - test_line = prj_templ % (self.environment.coredata.guid, - 'RUN_TESTS', 'RUN_TESTS.vcxproj', self.environment.coredata.test_guid) - ofile.write(test_line) - ofile.write('EndProject\n') - regen_line = prj_templ % (self.environment.coredata.guid, - 'REGEN', 'REGEN.vcxproj', self.environment.coredata.regen_guid) - ofile.write(regen_line) - ofile.write('EndProject\n') - ofile.write('Global\n') - ofile.write('\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n') - ofile.write('\t\t%s|%s = %s|%s\n' % (self.buildtype, self.platform, self.buildtype, self.platform)) - ofile.write('\tEndGlobalSection\n') - ofile.write('\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n') - ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' % - (self.environment.coredata.regen_guid, self.buildtype, self.platform, - self.buildtype, self.platform)) - ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' % - (self.environment.coredata.regen_guid, self.buildtype, self.platform, - self.buildtype, self.platform)) - for p in projlist: + regen_line = prj_templ % (self.environment.coredata.guid, + 'REGEN', 'REGEN.vcxproj', + self.environment.coredata.regen_guid) + ofile.write(regen_line) + ofile.write('EndProject\n') + ofile.write('Global\n') + ofile.write('\tGlobalSection(SolutionConfigurationPlatforms) = ' + 'preSolution\n') + ofile.write('\t\t%s|%s = %s|%s\n' % + (self.buildtype, self.platform, self.buildtype, + self.platform)) + ofile.write('\tEndGlobalSection\n') + ofile.write('\tGlobalSection(ProjectConfigurationPlatforms) = ' + 'postSolution\n') ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' % - (p[2], self.buildtype, self.platform, - self.buildtype, self.platform)) - if not isinstance(self.build.targets[p[0]], build.RunTarget): - ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' % + (self.environment.coredata.regen_guid, self.buildtype, + self.platform, self.buildtype, self.platform)) + ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' % + (self.environment.coredata.regen_guid, self.buildtype, + self.platform, self.buildtype, self.platform)) + for p in projlist: + ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' % (p[2], self.buildtype, self.platform, self.buildtype, self.platform)) - ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' % - (self.environment.coredata.test_guid, self.buildtype, self.platform, - self.buildtype, self.platform)) - ofile.write('\tEndGlobalSection\n') - ofile.write('\tGlobalSection(SolutionProperties) = preSolution\n') - ofile.write('\t\tHideSolutionNode = FALSE\n') - ofile.write('\tEndGlobalSection\n') - ofile.write('EndGlobal\n') + if not isinstance(self.build.targets[p[0]], build.RunTarget): + ofile.write('\t\t{%s}.%s|%s.Build.0 = %s|%s\n' % + (p[2], self.buildtype, self.platform, + self.buildtype, self.platform)) + ofile.write('\t\t{%s}.%s|%s.ActiveCfg = %s|%s\n' % + (self.environment.coredata.test_guid, self.buildtype, + self.platform, self.buildtype, self.platform)) + ofile.write('\tEndGlobalSection\n') + ofile.write('\tGlobalSection(SolutionProperties) = preSolution\n') + ofile.write('\t\tHideSolutionNode = FALSE\n') + ofile.write('\tEndGlobalSection\n') + ofile.write('EndGlobal\n') def generate_projects(self): projlist = [] @@ -862,12 +875,15 @@ class Vs2010Backend(backends.Backend): tree.write(ofname, encoding='utf-8', xml_declaration=True) # ElementTree can not do prettyprinting so do it manually doc = xml.dom.minidom.parse(ofname) - open(ofname, 'w').write(doc.toprettyxml()) + with open(ofname, 'w') as of: + of.write(doc.toprettyxml()) # World of horror! Python insists on not quoting quotes and # fixing the escaped " into &quot; whereas MSVS # requires quoted but not fixed elements. Enter horrible hack. - txt = open(ofname, 'r').read() - open(ofname, 'w').write(txt.replace('&quot;', '"')) + with open(ofname, 'r') as of: + txt = of.read() + with open(ofname, 'w') as of: + of.write(txt.replace('&quot;', '"')) def gen_regenproj(self, project_name, ofname): root = ET.Element('Project', {'DefaultTargets': 'Build', diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index e64866d08..b15774180 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -82,26 +82,22 @@ class XCodeBackend(backends.Backend): self.proj_dir = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.xcodeproj') os.makedirs(self.proj_dir, exist_ok=True) self.proj_file = os.path.join(self.proj_dir, 'project.pbxproj') - self.ofile = open(self.proj_file, 'w') - self.generate_prefix() - self.generate_pbx_aggregate_target() - self.generate_pbx_build_file() - self.generate_pbx_build_style() - self.generate_pbx_container_item_proxy() - self.generate_pbx_file_reference() - self.generate_pbx_group() - self.generate_pbx_native_target() - self.generate_pbx_project() - self.generate_pbx_shell_build_phase(test_data) - self.generate_pbx_sources_build_phase() - self.generate_pbx_target_dependency() - self.generate_xc_build_configuration() - self.generate_xc_configurationList() - self.generate_suffix() - - # for some reason, the entire file was not being flushed to the disk. - # closing it explicitly forces a flush and fixes the issue - self.ofile.close() + with open(self.proj_file, 'w') as self.ofile: + self.generate_prefix() + self.generate_pbx_aggregate_target() + self.generate_pbx_build_file() + self.generate_pbx_build_style() + self.generate_pbx_container_item_proxy() + self.generate_pbx_file_reference() + self.generate_pbx_group() + self.generate_pbx_native_target() + self.generate_pbx_project() + self.generate_pbx_shell_build_phase(test_data) + self.generate_pbx_sources_build_phase() + self.generate_pbx_target_dependency() + self.generate_xc_build_configuration() + self.generate_xc_configurationList() + self.generate_suffix() def get_xcodetype(self, fname): return self.xcodetypemap[fname.split('.')[-1]] diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 1c6c1da7d..4088adc1c 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -538,9 +538,8 @@ class CCompiler(Compiler): binname += '.exe' # Write binary check source binary_name = os.path.join(work_dir, binname) - ofile = open(source_name, 'w') - ofile.write(code) - ofile.close() + with open(source_name, 'w') as ofile: + ofile.write(code) # Compile sanity check cmdlist = self.exelist + extra_flags + [source_name] + self.get_output_args(binary_name) pc = subprocess.Popen(cmdlist, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=work_dir) @@ -617,9 +616,8 @@ int main () {{ {1}; }}''' suflen = len(self.default_suffix) (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) os.close(fd) - ofile = open(srcname, 'w') - ofile.write(code) - ofile.close() + with open(srcname, 'w') as ofile: + ofile.write(code) # Convert flags to the native type of the selected compiler args = self.unix_link_flags_to_native(extra_args) # Read c_args/cpp_args/etc from the cross-info file (if needed) @@ -647,9 +645,8 @@ int main () {{ {1}; }}''' os.close(fd) (fd, dstname) = tempfile.mkstemp() os.close(fd) - ofile = open(srcname, 'w') - ofile.write(code) - ofile.close() + with open(srcname, 'w') as ofile: + ofile.write(code) # Convert flags to the native type of the selected compiler args = self.unix_link_flags_to_native(extra_args) # Select a CRT if needed since we're linking @@ -672,9 +669,8 @@ int main () {{ {1}; }}''' raise CrossNoRunException('Can not run test applications in this cross environment.') (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) os.close(fd) - ofile = open(srcname, 'w') - ofile.write(code) - ofile.close() + with open(srcname, 'w') as ofile: + ofile.write(code) # Convert flags to the native type of the selected compiler args = self.unix_link_flags_to_native(extra_args) # Select a CRT if needed since we're linking @@ -997,9 +993,9 @@ class ObjCCompiler(CCompiler): extra_flags = self.get_cross_extra_flags(environment, compile=True, link=False) if self.is_cross: extra_flags += self.get_compile_only_args() - ofile = open(source_name, 'w') - ofile.write('#import\nint main(int argc, char **argv) { return 0; }\n') - ofile.close() + with open(source_name, 'w') as ofile: + ofile.write('#import\n' + 'int main(int argc, char **argv) { return 0; }\n') pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name]) pc.wait() if pc.returncode != 0: @@ -1031,9 +1027,10 @@ class ObjCPPCompiler(CPPCompiler): extra_flags = self.get_cross_extra_flags(environment, compile=True, link=False) if self.is_cross: extra_flags += self.get_compile_only_args() - ofile = open(source_name, 'w') - ofile.write('#import\nclass MyClass;int main(int argc, char **argv) { return 0; }\n') - ofile.close() + with open(source_name, 'w') as ofile: + ofile.write('#import\n' + 'class MyClass;' + 'int main(int argc, char **argv) { return 0; }\n') pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name]) pc.wait() if pc.returncode != 0: @@ -1133,13 +1130,12 @@ class MonoCompiler(Compiler): src = 'sanity.cs' obj = 'sanity.exe' source_name = os.path.join(work_dir, src) - ofile = open(source_name, 'w') - ofile.write('''public class Sanity { + with open(source_name, 'w') as ofile: + ofile.write('''public class Sanity { static public void Main () { } } ''') - ofile.close() pc = subprocess.Popen(self.exelist + [src], cwd=work_dir) pc.wait() if pc.returncode != 0: @@ -1245,14 +1241,13 @@ class JavaCompiler(Compiler): src = 'SanityCheck.java' obj = 'SanityCheck' source_name = os.path.join(work_dir, src) - ofile = open(source_name, 'w') - ofile.write('''class SanityCheck { + with open(source_name, 'w') as ofile: + ofile.write('''class SanityCheck { public static void main(String[] args) { int i; } } ''') - ofile.close() pc = subprocess.Popen(self.exelist + [src], cwd=work_dir) pc.wait() if pc.returncode != 0: @@ -1292,11 +1287,10 @@ class ValaCompiler(Compiler): def sanity_check(self, work_dir, environment): src = 'valatest.vala' source_name = os.path.join(work_dir, src) - ofile = open(source_name, 'w') - ofile.write('''class SanityCheck : Object { + with open(source_name, 'w') as ofile: + ofile.write('''class SanityCheck : Object { } ''') - ofile.close() extra_flags = self.get_cross_extra_flags(environment, compile=True, link=False) pc = subprocess.Popen(self.exelist + extra_flags + ['-C', '-c', src], cwd=work_dir) pc.wait() @@ -1336,11 +1330,10 @@ class RustCompiler(Compiler): def sanity_check(self, work_dir, environment): source_name = os.path.join(work_dir, 'sanity.rs') output_name = os.path.join(work_dir, 'rusttest') - ofile = open(source_name, 'w') - ofile.write('''fn main() { + with open(source_name, 'w') as ofile: + ofile.write('''fn main() { } ''') - ofile.close() pc = subprocess.Popen(self.exelist + ['-o', output_name, source_name], cwd=work_dir) pc.wait() if pc.returncode != 0: @@ -1435,10 +1428,9 @@ class SwiftCompiler(Compiler): src = 'swifttest.swift' source_name = os.path.join(work_dir, src) output_name = os.path.join(work_dir, 'swifttest') - ofile = open(source_name, 'w') - ofile.write('''1 + 2 + with open(source_name, 'w') as ofile: + ofile.write('''1 + 2 ''') - ofile.close() extra_flags = self.get_cross_extra_flags(environment, compile=True, link=True) pc = subprocess.Popen(self.exelist + extra_flags + ['-emit-executable', '-o', output_name, src], cwd=work_dir) pc.wait() @@ -1461,11 +1453,10 @@ class DCompiler(Compiler): def sanity_check(self, work_dir, environment): source_name = os.path.join(work_dir, 'sanity.d') output_name = os.path.join(work_dir, 'dtest') - ofile = open(source_name, 'w') - ofile.write('''void main() { + with open(source_name, 'w') as ofile: + ofile.write('''void main() { } ''') - ofile.close() pc = subprocess.Popen(self.exelist + self.get_output_args(output_name) + [source_name], cwd=work_dir) pc.wait() if pc.returncode != 0: @@ -1872,9 +1863,8 @@ class VisualStudioCCompiler(CCompiler): code = 'int i;\n' (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) os.close(fd) - ofile = open(srcname, 'w') - ofile.write(code) - ofile.close() + with open(srcname, 'w') as ofile: + ofile.write(code) # Read c_args/cpp_args/etc from the cross-info file (if needed) extra_args = self.get_cross_extra_flags(env, compile=True, link=False) extra_args += self.get_compile_only_args() @@ -2286,12 +2276,11 @@ class FortranCompiler(Compiler): def sanity_check(self, work_dir, environment): source_name = os.path.join(work_dir, 'sanitycheckf.f90') binary_name = os.path.join(work_dir, 'sanitycheckf') - ofile = open(source_name, 'w') - ofile.write('''program prog + with open(source_name, 'w') as ofile: + ofile.write('''program prog print *, "Fortran compilation is working." end program prog ''') - ofile.close() extra_flags = self.get_cross_extra_flags(environment, compile=True, link=True) pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name]) pc.wait() diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 2f1875f14..9beb2949f 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -154,7 +154,8 @@ class CoreData(): raise RuntimeError('Tried to set unknown builtin option %s.' % optname) def load(filename): - obj = pickle.load(open(filename, 'rb')) + with open(filename, 'rb') as f: + obj = pickle.load(f) if not isinstance(obj, CoreData): raise RuntimeError('Core data file is corrupted.') if obj.version != version: @@ -165,7 +166,8 @@ def load(filename): def save(obj, filename): if obj.version != version: raise RuntimeError('Fatal version mismatch corruption.') - pickle.dump(obj, open(filename, 'wb')) + with open(filename, 'wb') as f: + pickle.dump(obj, f) def get_builtin_options(): return list(builtin_options.keys()) diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py index d123f77a6..679440df7 100644 --- a/mesonbuild/dependencies.py +++ b/mesonbuild/dependencies.py @@ -228,10 +228,11 @@ class PkgConfigDependency(Dependency): return self.is_found def extract_field(self, la_file, fieldname): - for line in open(la_file): - arr = line.strip().split('=') - if arr[0] == fieldname: - return arr[1][1:-1] + with open(la_file) as f: + for line in f: + arr = line.strip().split('=') + if arr[0] == fieldname: + return arr[1][1:-1] return None def extract_dlname_field(self, la_file): @@ -374,7 +375,8 @@ class ExternalProgram(): shebang and manually parse it to figure out the interpreter to use """ try: - first_line = open(script).readline().strip() + with open(script) as f: + first_line = f.readline().strip() if first_line.startswith('#!'): commands = first_line[2:].split('#')[0].strip().split() if mesonlib.is_windows(): @@ -552,12 +554,13 @@ class BoostDependency(Dependency): except FileNotFoundError: self.version = None return - for line in ifile: - if line.startswith("#define") and 'BOOST_LIB_VERSION' in line: - ver = line.split()[-1] - ver = ver[1:-1] - self.version = ver.replace('_', '.') - return + with ifile: + for line in ifile: + if line.startswith("#define") and 'BOOST_LIB_VERSION' in line: + ver = line.split()[-1] + ver = ver[1:-1] + self.version = ver.replace('_', '.') + return self.version = None def detect_src_modules(self): diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index c9a81fb87..6570f2b5e 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1032,7 +1032,8 @@ class Interpreter(): mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename) if not os.path.isfile(mesonfile): raise InvalidArguments('Missing Meson file in %s' % mesonfile) - code = open(mesonfile, encoding='utf8').read() + with open(mesonfile, encoding='utf8') as mf: + code = mf.read() if len(code.strip()) == 0: raise InvalidCode('Builder file is empty.') assert(isinstance(code, str)) @@ -1994,7 +1995,8 @@ class Interpreter(): if not os.path.isfile(absname): self.subdir = prev_subdir raise InterpreterException('Nonexistant build def file %s.' % buildfilename) - code = open(absname, encoding='utf8').read() + with open(absname, encoding='utf8') as f: + code = f.read() assert(isinstance(code, str)) try: codeblock = mparser.Parser(code).parse() diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py index 4b11c1096..afabc6283 100644 --- a/mesonbuild/mconf.py +++ b/mesonbuild/mconf.py @@ -36,15 +36,18 @@ class Conf: self.build_file = os.path.join(build_dir, 'meson-private/build.dat') if not os.path.isfile(self.coredata_file) or not os.path.isfile(self.build_file): raise ConfException('Directory %s does not seem to be a Meson build directory.' % build_dir) - self.coredata = pickle.load(open(self.coredata_file, 'rb')) - self.build = pickle.load(open(self.build_file, 'rb')) + with open(self.coredata_file, 'rb') as f: + self.coredata = pickle.load(f) + with open(self.build_file, 'rb') as f: + self.build = pickle.load(f) if self.coredata.version != coredata.version: raise ConfException('Version mismatch (%s vs %s)' % (coredata.version, self.coredata.version)) def save(self): # Only called if something has changed so overwrite unconditionally. - pickle.dump(self.coredata, open(self.coredata_file, 'wb')) + with open(self.coredata_file, 'wb') as f: + pickle.dump(self.coredata, f) # We don't write the build file because any changes to it # are erased when Meson is executed the nex time, i.e. the next # time Ninja is run. diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index b5b53397e..007aea833 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -96,7 +96,8 @@ def is_32bit(): def is_debianlike(): try: - open('/etc/debian_version', 'r') + with open('/etc/debian_version', 'r'): + pass return True except FileNotFoundError: return False @@ -262,7 +263,8 @@ def do_mesondefine(line, confdata): def do_conf_file(src, dst, confdata): try: - data = open(src).readlines() + with open(src) as f: + data = f.readlines() except Exception: raise MesonException('Could not read input file %s.' % src) # Only allow (a-z, A-Z, 0-9, _, -) as valid characters for a define @@ -276,7 +278,8 @@ def do_conf_file(src, dst, confdata): line = do_replacement(regex, line, confdata) result.append(line) dst_tmp = dst + '~' - open(dst_tmp, 'w').writelines(result) + with open(dst_tmp, 'w') as f: + f.writelines(result) shutil.copymode(src, dst_tmp) replace_if_different(dst, dst_tmp) @@ -306,9 +309,10 @@ def replace_if_different(dst, dst_tmp): # If contents are identical, don't touch the file to prevent # unnecessary rebuilds. try: - if open(dst, 'r').read() == open(dst_tmp, 'r').read(): - os.unlink(dst_tmp) - return + with open(dst, 'r') as f1, open(dst_tmp, 'r') as f2: + if f1.read() == f2.read(): + os.unlink(dst_tmp) + return except FileNotFoundError: pass os.replace(dst_tmp, dst) diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py index 65d979b35..617704a94 100644 --- a/mesonbuild/mesonmain.py +++ b/mesonbuild/mesonmain.py @@ -169,7 +169,8 @@ itself as required.''' g.generate(intr) g.run_postconf_scripts() dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat') - pickle.dump(b, open(dumpfile, 'wb')) + with open(dumpfile, 'wb') as f: + pickle.dump(b, f) # Write this last since we use the existence of this file to check if # we generated the build file successfully, so we don't want an error # that pops up during generation, post-conf scripts, etc to cause us to diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 629b0fcd3..2086c3788 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -177,10 +177,14 @@ def run(args): buildfile = os.path.join(bdir, 'meson-private/build.dat') testfile = os.path.join(bdir, 'meson-private/meson_test_setup.dat') benchmarkfile = os.path.join(bdir, 'meson-private/meson_benchmark_setup.dat') - coredata = pickle.load(open(corefile, 'rb')) - builddata = pickle.load(open(buildfile, 'rb')) - testdata = pickle.load(open(testfile, 'rb')) - benchmarkdata = pickle.load(open(benchmarkfile, 'rb')) + with open(corefile, 'rb') as f: + coredata = pickle.load(f) + with open(buildfile, 'rb') as f: + builddata = pickle.load(f) + with open(testfile, 'rb') as f: + testdata = pickle.load(f) + with open(benchmarkfile, 'rb') as f: + benchmarkdata = pickle.load(f) if options.list_targets: list_targets(coredata, builddata) elif options.target_files is not None: diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index b01b58795..29e2847e1 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -23,37 +23,41 @@ class PkgConfigModule: def generate_pkgconfig_file(self, state, libraries, subdirs, name, description, version, filebase, pub_reqs, priv_reqs, priv_libs): + coredata = state.environment.get_coredata() outdir = state.environment.scratch_dir fname = os.path.join(outdir, filebase + '.pc') - ofile = open(fname, 'w') - coredata = state.environment.get_coredata() - ofile.write('prefix=%s\n' % coredata.get_builtin_option('prefix')) - ofile.write('libdir=${prefix}/%s\n' % coredata.get_builtin_option('libdir')) - ofile.write('includedir=${prefix}/%s\n\n' % coredata.get_builtin_option('includedir')) - ofile.write('Name: %s\n' % name) - if len(description) > 0: - ofile.write('Description: %s\n' % description) - if len(version) > 0: - ofile.write('Version: %s\n' % version) - if len(pub_reqs) > 0: - ofile.write('Requires: {}\n'.format(' '.join(pub_reqs))) - if len(priv_reqs) > 0: - ofile.write('Requires.private: {}\n'.format(' '.join(priv_reqs))) - if len(priv_libs) > 0: - ofile.write('Libraries.private: {}\n'.format(' '.join(priv_libs))) - ofile.write('Libs: -L${libdir} ') - for l in libraries: - if l.custom_install_dir: - ofile.write('-L${prefix}/%s ' % l.custom_install_dir) - ofile.write('-l%s ' % l.name) - ofile.write('\n') - ofile.write('CFlags: ') - for h in subdirs: - if h == '.': - h = '' - ofile.write(os.path.join('-I${includedir}', h)) - ofile.write(' ') - ofile.write('\n') + with open(fname, 'w') as ofile: + ofile.write('prefix=%s\n' % coredata.get_builtin_option('prefix')) + ofile.write('libdir=${prefix}/%s\n' % + coredata.get_builtin_option('libdir')) + ofile.write('includedir=${prefix}/%s\n\n' % + coredata.get_builtin_option('includedir')) + ofile.write('Name: %s\n' % name) + if len(description) > 0: + ofile.write('Description: %s\n' % description) + if len(version) > 0: + ofile.write('Version: %s\n' % version) + if len(pub_reqs) > 0: + ofile.write('Requires: {}\n'.format(' '.join(pub_reqs))) + if len(priv_reqs) > 0: + ofile.write( + 'Requires.private: {}\n'.format(' '.join(priv_reqs))) + if len(priv_libs) > 0: + ofile.write( + 'Libraries.private: {}\n'.format(' '.join(priv_libs))) + ofile.write('Libs: -L${libdir} ') + for l in libraries: + if l.custom_install_dir: + ofile.write('-L${prefix}/%s ' % l.custom_install_dir) + ofile.write('-l%s ' % l.name) + ofile.write('\n') + ofile.write('CFlags: ') + for h in subdirs: + if h == '.': + h = '' + ofile.write(os.path.join('-I${includedir}', h)) + ofile.write(' ') + ofile.write('\n') def generate(self, state, args, kwargs): if len(args) > 0: diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py index acad204d2..89194e95f 100644 --- a/mesonbuild/modules/rpm.py +++ b/mesonbuild/modules/rpm.py @@ -80,82 +80,87 @@ class RPMModule: files.add('%%{_mandir}/man%u/%s.*' % (int(man_file.split('.')[-1]), man_file)) if len(files_devel) > 0: devel_subpkg = True - fn = open('%s.spec' % os.path.join(state.environment.get_build_dir(), proj), 'w+') - fn.write('Name: %s\n' % proj) - fn.write('Version: # FIXME\n') - fn.write('Release: 1%{?dist}\n') - fn.write('Summary: # FIXME\n') - fn.write('License: # FIXME\n') - fn.write('\n') - fn.write('Source0: %{name}-%{version}.tar.xz # FIXME\n') - fn.write('\n') - for compiler in compiler_deps: - fn.write('BuildRequires: %s\n' % compiler) - for dep in state.environment.coredata.deps: - fn.write('BuildRequires: pkgconfig(%s)\n' % dep) - for lib in state.environment.coredata.ext_libs.values(): - fn.write('BuildRequires: %s # FIXME\n' % lib.fullpath) - mlog.log('Warning, replace', mlog.bold(lib.fullpath), 'with real package.', - 'You can use following command to find package which contains this lib:', - mlog.bold('dnf provides %s' % lib.fullpath)) - for prog in state.environment.coredata.ext_progs.values(): - if not prog.found(): - fn.write('BuildRequires: /usr/bin/%s # FIXME\n' % prog.get_name()) - else: - fn.write('BuildRequires: %s\n' % ' '.join(prog.fullpath)) - fn.write('BuildRequires: meson\n') - fn.write('\n') - fn.write('%description\n') - fn.write('\n') - if devel_subpkg: - fn.write('%package devel\n') - fn.write('Summary: Development files for %{name}\n') - fn.write('Requires: %{name}%{?_isa} = %{version}-%{release}\n') + filename = os.path.join(state.environment.get_build_dir(), + '%s.spec' % proj) + with open(filename, 'w+') as fn: + fn.write('Name: %s\n' % proj) + fn.write('Version: # FIXME\n') + fn.write('Release: 1%{?dist}\n') + fn.write('Summary: # FIXME\n') + fn.write('License: # FIXME\n') + fn.write('\n') + fn.write('Source0: %{name}-%{version}.tar.xz # FIXME\n') + fn.write('\n') + for compiler in compiler_deps: + fn.write('BuildRequires: %s\n' % compiler) + for dep in state.environment.coredata.deps: + fn.write('BuildRequires: pkgconfig(%s)\n' % dep) + for lib in state.environment.coredata.ext_libs.values(): + fn.write('BuildRequires: %s # FIXME\n' % lib.fullpath) + mlog.log('Warning, replace', mlog.bold(lib.fullpath), + 'with real package.', + 'You can use following command to find package which ' + 'contains this lib:', + mlog.bold('dnf provides %s' % lib.fullpath)) + for prog in state.environment.coredata.ext_progs.values(): + if not prog.found(): + fn.write('BuildRequires: /usr/bin/%s # FIXME\n' % + prog.get_name()) + else: + fn.write('BuildRequires: %s\n' % ' '.join(prog.fullpath)) + fn.write('BuildRequires: meson\n') + fn.write('\n') + fn.write('%description\n') fn.write('\n') - fn.write('%description devel\n') - fn.write('Development files for %{name}.\n') + if devel_subpkg: + fn.write('%package devel\n') + fn.write('Summary: Development files for %{name}\n') + fn.write('Requires: %{name}%{?_isa} = %{version}-%{release}\n') + fn.write('\n') + fn.write('%description devel\n') + fn.write('Development files for %{name}.\n') + fn.write('\n') + fn.write('%prep\n') + fn.write('%autosetup\n') + fn.write('rm -rf rpmbuilddir && mkdir rpmbuilddir\n') fn.write('\n') - fn.write('%prep\n') - fn.write('%autosetup\n') - fn.write('rm -rf rpmbuilddir && mkdir rpmbuilddir\n') - fn.write('\n') - fn.write('%build\n') - fn.write('pushd rpmbuilddir\n') - fn.write(' %meson ..\n') - fn.write(' ninja-build -v\n') - fn.write('popd\n') - fn.write('\n') - fn.write('%install\n') - fn.write('pushd rpmbuilddir\n') - fn.write(' DESTDIR=%{buildroot} ninja-build -v install\n') - fn.write('popd\n') - if len(to_delete) > 0: - fn.write('rm -rf %s\n' % ' '.join(to_delete)) - fn.write('\n') - fn.write('%check\n') - fn.write('pushd rpmbuilddir\n') - fn.write(' ninja-build -v test\n') - fn.write('popd\n') - fn.write('\n') - fn.write('%files\n') - for f in files: - fn.write('%s\n' % f) - fn.write('\n') - if devel_subpkg: - fn.write('%files devel\n') - for f in files_devel: + fn.write('%build\n') + fn.write('pushd rpmbuilddir\n') + fn.write(' %meson ..\n') + fn.write(' ninja-build -v\n') + fn.write('popd\n') + fn.write('\n') + fn.write('%install\n') + fn.write('pushd rpmbuilddir\n') + fn.write(' DESTDIR=%{buildroot} ninja-build -v install\n') + fn.write('popd\n') + if len(to_delete) > 0: + fn.write('rm -rf %s\n' % ' '.join(to_delete)) + fn.write('\n') + fn.write('%check\n') + fn.write('pushd rpmbuilddir\n') + fn.write(' ninja-build -v test\n') + fn.write('popd\n') + fn.write('\n') + fn.write('%files\n') + for f in files: fn.write('%s\n' % f) fn.write('\n') - if so_installed: - fn.write('%post -p /sbin/ldconfig\n') + if devel_subpkg: + fn.write('%files devel\n') + for f in files_devel: + fn.write('%s\n' % f) + fn.write('\n') + if so_installed: + fn.write('%post -p /sbin/ldconfig\n') + fn.write('\n') + fn.write('%postun -p /sbin/ldconfig\n') + fn.write('\n') + fn.write('%changelog\n') + fn.write('* %s meson - \n' % + datetime.date.today().strftime('%a %b %d %Y')) + fn.write('- \n') fn.write('\n') - fn.write('%postun -p /sbin/ldconfig\n') - fn.write('\n') - fn.write('%changelog\n') - fn.write('* %s meson - \n' % datetime.date.today().strftime('%a %b %d %Y')) - fn.write('- \n') - fn.write('\n') - fn.close() mlog.log('RPM spec template written to %s.spec.\n' % proj) def initialize(): diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py index b35504747..9f57fd691 100644 --- a/mesonbuild/optinterpreter.py +++ b/mesonbuild/optinterpreter.py @@ -78,7 +78,8 @@ class OptionInterpreter: def process(self, option_file): try: - ast = mparser.Parser(open(option_file, 'r', encoding='utf8').read()).parse() + with open(option_file, 'r', encoding='utf8') as f: + ast = mparser.Parser(f.read()).parse() except mesonlib.MesonException as me: me.file = option_file raise me diff --git a/mesonbuild/scripts/meson_benchmark.py b/mesonbuild/scripts/meson_benchmark.py index d1107b609..6d138b0db 100644 --- a/mesonbuild/scripts/meson_benchmark.py +++ b/mesonbuild/scripts/meson_benchmark.py @@ -52,33 +52,34 @@ def run_benchmarks(options, datafile): failed_tests = 0 logfile_base = 'meson-logs/benchmarklog' jsonlogfilename = logfile_base+ '.json' - jsonlogfile = open(jsonlogfilename, 'w') - tests = pickle.load(open(datafile, 'rb')) + with open(datafile, 'rb') as f: + tests = pickle.load(f) num_tests = len(tests) if num_tests == 0: print('No benchmarks defined.') return 0 iteration_count = 5 wrap = [] # Benchmarks on cross builds are pointless so don't support them. - for i, test in enumerate(tests): - runs = [] - durations = [] - failed = False - for _ in range(iteration_count): - res = meson_test.run_single_test(wrap, test) - runs.append(res) - durations.append(res.duration) - if res.returncode != 0: - failed = True - mean = statistics.mean(durations) - stddev = statistics.stdev(durations) - if failed: - resultstr = 'FAIL' - failed_tests += 1 - else: - resultstr = 'OK' - print_stats(3, num_tests, test.name, resultstr, i, mean, stddev) - print_json_log(jsonlogfile, runs, test.name, i) + with open(jsonlogfilename, 'w') as jsonlogfile: + for i, test in enumerate(tests): + runs = [] + durations = [] + failed = False + for _ in range(iteration_count): + res = meson_test.run_single_test(wrap, test) + runs.append(res) + durations.append(res.duration) + if res.returncode != 0: + failed = True + mean = statistics.mean(durations) + stddev = statistics.stdev(durations) + if failed: + resultstr = 'FAIL' + failed_tests += 1 + else: + resultstr = 'OK' + print_stats(3, num_tests, test.name, resultstr, i, mean, stddev) + print_json_log(jsonlogfile, runs, test.name, i) print('\nFull log written to meson-logs/benchmarklog.json.') return failed_tests diff --git a/mesonbuild/scripts/meson_exe.py b/mesonbuild/scripts/meson_exe.py index 1a0fcdaa8..d2ae35737 100644 --- a/mesonbuild/scripts/meson_exe.py +++ b/mesonbuild/scripts/meson_exe.py @@ -74,7 +74,8 @@ def run(args): print('Test runner for Meson. Do not run on your own, mmm\'kay?') print(sys.argv[0] + ' [data file]') exe_data_file = options.args[0] - exe = pickle.load(open(exe_data_file, 'rb')) + with open(exe_data_file, 'rb') as f: + exe = pickle.load(f) return run_exe(exe) if __name__ == '__main__': diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py index 1924b9526..6e877cfc0 100644 --- a/mesonbuild/scripts/meson_install.py +++ b/mesonbuild/scripts/meson_install.py @@ -38,8 +38,8 @@ def do_copy(from_file, to_file): append_to_log(to_file) def do_install(datafilename): - ifile = open(datafilename, 'rb') - d = pickle.load(ifile) + with open(datafilename, 'rb') as ifile: + d = pickle.load(ifile) d.destdir = os.environ.get('DESTDIR', '') d.fullprefix = destdir_join(d.destdir, d.prefix) @@ -112,7 +112,9 @@ def install_man(d): os.makedirs(outdir, exist_ok=True) print('Installing %s to %s.' % (full_source_filename, outdir)) if outfilename.endswith('.gz') and not full_source_filename.endswith('.gz'): - open(outfilename, 'wb').write(gzip.compress(open(full_source_filename, 'rb').read())) + with open(outfilename, 'wb') as of: + with open(full_source_filename, 'rb') as sf: + of.write(gzip.compress(sf.read())) shutil.copystat(full_source_filename, outfilename) append_to_log(outfilename) else: @@ -142,7 +144,8 @@ def run_install_script(d): print('Running custom install script %s' % script) suffix = os.path.splitext(script)[1].lower() if platform.system().lower() == 'windows' and suffix != '.bat': - first_line = open(script, encoding='latin_1', errors='ignore').readline().strip() + with open(script, encoding='latin_1', errors='ignore') as f: + first_line = f.readline().strip() if first_line.startswith('#!'): if shutil.which(first_line[2:]): commands = [first_line[2:]] diff --git a/mesonbuild/scripts/meson_test.py b/mesonbuild/scripts/meson_test.py index 33b616526..951fb851f 100644 --- a/mesonbuild/scripts/meson_test.py +++ b/mesonbuild/scripts/meson_test.py @@ -202,10 +202,8 @@ def run_tests(datafilename): wrap = [options.wrapper] logfilename = logfile_base + '-' + options.wrapper.replace(' ', '_') + '.txt' jsonlogfilename = logfile_base + '-' + options.wrapper.replace(' ', '_') + '.json' - logfile = open(logfilename, 'w') - jsonlogfile = open(jsonlogfilename, 'w') - logfile.write('Log of Meson test suite run on %s.\n\n' % datetime.datetime.now().isoformat()) - tests = pickle.load(open(datafilename, 'rb')) + with open(datafilename, 'rb') as f: + tests = pickle.load(f) if len(tests) == 0: print('No tests defined.') return @@ -222,24 +220,31 @@ def run_tests(datafilename): executor = conc.ThreadPoolExecutor(max_workers=num_workers) futures = [] filtered_tests = filter_tests(options.suite, tests) - for i, test in enumerate(filtered_tests): - if test.suite[0] == '': - visible_name = test.name - else: - if options.suite is not None: - visible_name = options.suite + ' / ' + test.name + + with open(jsonlogfilename, 'w') as jsonlogfile, \ + open(logfilename, 'w') as logfile: + logfile.write('Log of Meson test suite run on %s.\n\n' % + datetime.datetime.now().isoformat()) + for i, test in enumerate(filtered_tests): + if test.suite[0] == '': + visible_name = test.name else: - visible_name = test.suite[0] + ' / ' + test.name + if options.suite is not None: + visible_name = options.suite + ' / ' + test.name + else: + visible_name = test.suite[0] + ' / ' + test.name - if not test.is_parallel: - drain_futures(futures) - futures = [] - res = run_single_test(wrap, test) - print_stats(numlen, filtered_tests, visible_name, res, i, logfile, jsonlogfile) - else: - f = executor.submit(run_single_test, wrap, test) - futures.append((f, numlen, filtered_tests, visible_name, i, logfile, jsonlogfile)) - drain_futures(futures) + if not test.is_parallel: + drain_futures(futures) + futures = [] + res = run_single_test(wrap, test) + print_stats(numlen, filtered_tests, visible_name, res, i, + logfile, jsonlogfile) + else: + f = executor.submit(run_single_test, wrap, test) + futures.append((f, numlen, filtered_tests, visible_name, i, + logfile, jsonlogfile)) + drain_futures(futures) return logfilename def run(args): diff --git a/mesonbuild/scripts/regen_checker.py b/mesonbuild/scripts/regen_checker.py index f65f3bdab..ddf494332 100644 --- a/mesonbuild/scripts/regen_checker.py +++ b/mesonbuild/scripts/regen_checker.py @@ -48,8 +48,10 @@ def run(args): private_dir = args[0] dumpfile = os.path.join(private_dir, 'regeninfo.dump') coredata = os.path.join(private_dir, 'coredata.dat') - regeninfo = pickle.load(open(dumpfile, 'rb')) - coredata = pickle.load(open(coredata, 'rb')) + with open(dumpfile, 'rb') as f: + regeninfo = pickle.load(f) + with open(coredata, 'rb') as f: + coredata = pickle.load(f) mesonscript = coredata.meson_script_file backend = coredata.get_builtin_option('backend') regen_timestamp = os.stat(dumpfile).st_mtime diff --git a/mesonbuild/scripts/symbolextractor.py b/mesonbuild/scripts/symbolextractor.py index 79c126420..c117301d4 100644 --- a/mesonbuild/scripts/symbolextractor.py +++ b/mesonbuild/scripts/symbolextractor.py @@ -34,16 +34,19 @@ parser.add_argument('args', nargs='+') def dummy_syms(outfilename): """Just touch it so relinking happens always.""" - open(outfilename, 'w').close() + with open(outfilename, 'w'): + pass def write_if_changed(text, outfilename): try: - oldtext = open(outfilename, 'r').read() + with open(outfilename, 'r') as f: + oldtext = f.read() if text == oldtext: return except FileNotFoundError: pass - open(outfilename, 'w').write(text) + with open(outfilename, 'w') as f: + f.write(text) def linux_syms(libfilename, outfilename): pe = subprocess.Popen(['readelf', '-d', libfilename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/mesonbuild/scripts/vcstagger.py b/mesonbuild/scripts/vcstagger.py index 390e37a8d..3f36e0af4 100644 --- a/mesonbuild/scripts/vcstagger.py +++ b/mesonbuild/scripts/vcstagger.py @@ -23,9 +23,16 @@ def config_vcs_tag(infile, outfile, fallback, source_dir, replace_string, regex_ except Exception: new_string = fallback - new_data = open(infile).read().replace(replace_string, new_string) - if (not os.path.exists(outfile)) or (open(outfile).read() != new_data): - open(outfile, 'w').write(new_data) + with open(infile) as f: + new_data = f.read().replace(replace_string, new_string) + if os.path.exists(outfile): + with open(outfile) as f: + needs_update = (f.read() != new_data) + else: + needs_update = True + if needs_update: + with open(outfile, 'w') as f: + f.write(new_data) def run(args): infile, outfile, fallback, source_dir, replace_string, regex_selector = args[0:6] diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index bfb7ed473..33f52f38d 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -58,23 +58,23 @@ def open_wrapdburl(urlstring): class PackageDefinition: def __init__(self, fname): self.values = {} - ifile = open(fname) - first = ifile.readline().strip() + with open(fname) as ifile: + first = ifile.readline().strip() - if first == '[wrap-file]': - self.type = 'file' - elif first == '[wrap-git]': - self.type = 'git' - else: - raise RuntimeError('Invalid format of package file') - for line in ifile: - line = line.strip() - if line == '': - continue - (k, v) = line.split('=', 1) - k = k.strip() - v = v.strip() - self.values[k] = v + if first == '[wrap-file]': + self.type = 'file' + elif first == '[wrap-git]': + self.type = 'git' + else: + raise RuntimeError('Invalid format of package file') + for line in ifile: + line = line.strip() + if line == '': + continue + (k, v) = line.split('=', 1) + k = k.strip() + v = v.strip() + self.values[k] = v def get(self, key): return self.values[key] @@ -177,7 +177,8 @@ class Resolver: expected = p.get('source_hash') if dhash != expected: raise RuntimeError('Incorrect hash for source %s:\n %s expected\n %s actual.' % (packagename, expected, dhash)) - open(ofname, 'wb').write(srcdata) + with open(ofname, 'wb') as f: + f.write(srcdata) if p.has_patch(): purl = p.get('patch_url') mlog.log('Downloading patch from', mlog.bold(purl)) @@ -186,7 +187,9 @@ class Resolver: expected = p.get('patch_hash') if phash != expected: raise RuntimeError('Incorrect hash for patch %s:\n %s expected\n %s actual' % (packagename, expected, phash)) - open(os.path.join(self.cachedir, p.get('patch_filename')), 'wb').write(pdata) + filename = os.path.join(self.cachedir, p.get('patch_filename')) + with open(filename, 'wb') as f: + f.write(pdata) else: mlog.log('Package does not require patch.') diff --git a/mesonbuild/wrap/wraptool.py b/mesonbuild/wrap/wraptool.py index c5f8eeffe..e94a2c5a6 100755 --- a/mesonbuild/wrap/wraptool.py +++ b/mesonbuild/wrap/wraptool.py @@ -92,7 +92,8 @@ def install(name): (branch, revision) = get_latest_version(name) u = open_wrapdburl(API_ROOT + 'projects/%s/%s/%s/get_wrap' % (name, branch, revision)) data = u.read() - open(wrapfile, 'wb').write(data) + with open(wrapfile, 'wb') as f: + f.write(data) print('Installed', name, 'branch', branch, 'revision', revision) def get_current_version(wrapfile): @@ -129,7 +130,8 @@ def update(name): os.unlink(os.path.join('subprojects/packagecache', patch_file)) except FileNotFoundError: pass - open(wrapfile, 'wb').write(data) + with open(wrapfile, 'wb') as f: + f.write(data) print('Updated', name, 'to branch', new_branch, 'revision', new_revision) def info(name):