def run(self): # make sure we're testing the latest self.run_command('build') # setup java classpath version = self.distribution.metadata.get_version() classpath = os.path.join(self.java_build, 'jep-' + version + '.jar') classpath += os.pathsep + os.path.join(self.java_build, 'jep-' + version + '-test.jar') classpath += os.pathsep + 'src/test/python/lib/sqlitejdbc-v056.jar' classpath += os.pathsep + 'src/test/python/lib/fakenetty.jar' # setup environment variables environment = {} if not is_osx() and not is_windows(): environment['LD_LIBRARY_PATH'] = sysconfig.get_config_var('LIBDIR') # http://bugs.python.org/issue20614 if is_windows(): environment['SYSTEMROOT'] = os.environ['SYSTEMROOT'] java_path = os.path.join(get_java_home(), 'bin') # if multiple versions of python are installed, this helps ensure the right # version is used executable = sys.executable if executable: py_path = os.path.dirname(executable) # java_path before python_path because py_path might point to a # default system path, like /usr/bin, which can contain other java # executables. Since all the subprocesses are Java running jep it # is very important to get the right java. environment['PATH'] = java_path + os.pathsep + py_path + os.pathsep + os.environ['PATH'] else: environment['PATH'] = java_path + os.pathsep + os.environ['PATH'] venv = hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) if not venv: # PYTHONHOME helps locate libraries but should not be set in a virtual env prefix = sysconfig.get_config_var('prefix') exec_prefix = sysconfig.get_config_var('exec_prefix') if prefix == exec_prefix: environment['PYTHONHOME'] = prefix else: environment['PYTHONHOME'] = prefix + ':' + exec_prefix # find the jep library and makes sure it's named correctly build_ext = self.get_finalized_command('build_ext') jep_lib = build_ext.get_outputs()[0] built_dir = os.path.dirname(jep_lib) link_native_lib(built_dir, jep_lib) environment['PYTHONPATH'] = self.get_finalized_command('build').build_lib # actually kick off the tests import subprocess args = [os.path.join(java_path, 'java'), '-classpath', '{0}'.format(classpath), 'jep.Run', 'src/test/python/runtests.py'] p = subprocess.Popen(args, env=environment) rc = p.wait() if rc != 0: raise DistutilsExecError("Unit tests failed with exit status %d" % (rc))
def run(self): # make sure we're testing the latest self.run_command('build') # setup java classpath version = self.distribution.metadata.get_version() classpath = os.path.join(self.java_build, 'jep-' + version + '.jar') classpath += os.pathsep + os.path.join(self.java_build, 'jep-' + version + '-test.jar') classpath += os.pathsep + 'tests/lib/sqlitejdbc-v056.jar' classpath += os.pathsep + 'tests/lib/fakenetty.jar' # setup environment variables environment = {} if not is_osx() and not is_windows(): environment['LD_LIBRARY_PATH'] = sysconfig.get_config_var('LIBDIR') # set the LD_PRELOAD environment variable if we can locate the # libpython<version>.so library. lib_python = get_libpython() if lib_python: environment['LD_PRELOAD'] = lib_python # http://bugs.python.org/issue20614 if is_windows(): environment['SYSTEMROOT'] = os.environ['SYSTEMROOT'] java_path = os.path.join(get_java_home(), 'bin') # if multiple versions of python are installed, this helps ensure the right # version is used executable = sys.executable if executable: py_path = os.path.dirname(executable) environment['PATH'] = py_path + os.pathsep + java_path + os.pathsep + os.environ['PATH'] else: environment['PATH'] = java_path + os.pathsep + os.environ['PATH'] # find the jep library and makes sure it's named correctly build_ext = self.get_finalized_command('build_ext') jep_lib = build_ext.get_outputs()[0] built_dir = os.path.dirname(jep_lib) link_native_lib(built_dir, jep_lib) # actually kick off the tests import subprocess args = [os.path.join(java_path, 'java'), '-classpath', '{0}'.format(classpath), '-Djava.library.path={0}'.format(built_dir), 'jep.Run', 'tests/runtests.py'] p = subprocess.Popen(args, env=environment) rc = p.wait() if rc != 0: raise DistutilsExecError("Unit tests failed with exit status %d" % (rc))
def link_native_lib(self, jep_dir, jep_lib): # we'll put the jep_dir as -Djava.library.path in the jep script if is_windows(): jep_dll = os.path.join(jep_dir, 'jep.dll') # Remove the old DLL if it exists to avoid a file move error. if os.path.exists(jep_dll): os.remove(jep_dll) # Do not use 'spawn' as that will run as a non-administrative user # that may no longer have access to the destination directory. self.move_file(os.path.join(jep_dir, jep_lib), jep_dll) elif is_osx(): # Apple says to put the file at /Library/Java/Extensions/libjep.jnilib, # which is good for a permanent install but not so good when using # virtualenv or testing spawn(['ln', '-sf', '{0}'.format(jep_lib), '{0}'.format(os.path.join(jep_dir, 'libjep.jnilib')),]) else: # otherwise, distutils outputs 'jep.so' which needs to be linked # to libjep.so. The JVM will not find the library without. spawn(['ln', '-sf', '{0}'.format(jep_lib), '{0}'.format(os.path.join(jep_dir, 'libjep.so')), ])
def link_native_lib(self, jep_dir, jep_lib): # we'll put the jep_dir as -Djava.library.path in the jep script if is_windows(): jep_dll = os.path.join(jep_dir, 'jep.dll') # Remove the old DLL if it exists to avoid a file move error. if os.path.exists(jep_dll): os.remove(jep_dll) # Do not use 'spawn' as that will run as a non-administrative user # that may no longer have access to the destination directory. self.move_file(os.path.join(jep_dir, jep_lib), jep_dll) elif is_osx(): # Apple says to put the file at /Library/Java/Extensions/libjep.jnilib, # which is good for a permanent install but not so good when using # virtualenv or testing spawn([ 'ln', '-sf', '{0}'.format(jep_lib), '{0}'.format(os.path.join(jep_dir, 'libjep.jnilib')), ]) else: # otherwise, distutils outputs 'jep.so' which needs to be linked # to libjep.so. The JVM will not find the library without. spawn([ 'ln', '-sf', '{0}'.format(jep_lib), '{0}'.format(os.path.join(jep_dir, 'libjep.so')), ])
def get_java_home(): global _java_home if _java_home is not None: return _java_home if is_osx(): # newer macs have an executable to help us try: result = shell("/usr/libexec/java_home") _java_home = result.stdout.decode("utf-8") return _java_home except CommandFailed: traceback.print_exc() if not os.path.exists(MAC_JAVA_HOME): configure_error("No JAVA_HOME") # Apple's JAVA_HOME is predictable, just use that if we can # though it doesn't work for Oracle's JDK if os.path.exists(MAC_JAVA_HOME): _java_home = MAC_JAVA_HOME return _java_home env_home = os.environ.get("JAVA_HOME") if env_home: if is_windows(): # remove quotes from each end if necessary env_home = env_home.strip('"') if os.path.exists(env_home): _java_home = env_home return env_home else: configure_error("Path " + env_home + " indicated by JAVA_HOME does not exist.") configure_error("Please set the environment variable JAVA_HOME to a path containing the JDK.")
def get_java_home(): global _java_home if _java_home is not None: return _java_home if is_osx(): # newer macs have an executable to help us try: result = shell('/usr/libexec/java_home') _java_home = result.stdout.decode("utf-8") return _java_home except CommandFailed: traceback.print_exc() if not os.path.exists(MAC_JAVA_HOME): configure_error('No JAVA_HOME') # Apple's JAVA_HOME is predictable, just use that if we can # though it doesn't work for Oracle's JDK if os.path.exists(MAC_JAVA_HOME): _java_home = MAC_JAVA_HOME return _java_home env_home = os.environ.get('JAVA_HOME') if env_home: if is_windows(): # remove quotes from each end if necessary env_home = env_home.strip('"') if os.path.exists(env_home): _java_home = env_home return env_home else: configure_error("Path " + env_home + " indicated by JAVA_HOME does not exist.") configure_error("Please set the environment variable JAVA_HOME to a path containing the JDK.")
def run(self): # make sure we're testing the latest self.run_command('build') # setup java classpath version = self.distribution.metadata.get_version() classpath = os.path.join(self.java_build, 'jep-' + version + '.jar') classpath += os.pathsep + os.path.join(self.java_build, 'jep.test-' + version + '.jar') classpath += os.pathsep + 'tests/lib/sqlitejdbc-v056.jar' classpath += os.pathsep + 'tests/lib/fakenetty.jar' # setup environment variables environment = {} if not is_osx() and not is_windows(): environment['LD_LIBRARY_PATH'] = sysconfig.get_config_var('LIBDIR') # set the LD_PRELOAD environment variable if we can locate the # libpython<version>.so library. lib_python = get_libpython() if lib_python: environment['LD_PRELOAD'] = lib_python # http://bugs.python.org/issue20614 if is_windows(): environment['SYSTEMROOT'] = os.environ['SYSTEMROOT'] # if multiple versions of python are installed, this helps ensure the right # version is used executable = sys.executable if executable: environment['PATH'] = os.path.dirname(executable) + os.pathsep + os.environ['PATH'] # find the jep library and makes sure it's named correctly build_ext = self.get_finalized_command('build_ext') jep_lib = build_ext.get_outputs()[0] built_dir = os.path.dirname(jep_lib) link_native_lib(built_dir, jep_lib) # actually kick off the tests import subprocess args = ['java', '-classpath', '{0}'.format(classpath), '-Djava.library.path={0}'.format(built_dir), 'jep.Run', 'tests/runtests.py'] p = subprocess.Popen(args, env=environment) p.wait()
def get_java_lib_folders(): if not is_osx(): if is_windows(): jre = os.path.join(get_java_home(), "lib") else: jre = os.path.join(get_java_home(), "jre", "lib") folders = [] for root, dirnames, filenames in os.walk(jre): if is_windows(): for filename in fnmatch.filter(filenames, "*jvm.lib"): folders.append(os.path.join(root, os.path.dirname(filename))) else: for filename in fnmatch.filter(filenames, "*jvm.so"): folders.append(os.path.join(root, os.path.dirname(filename))) return list(set(folders)) return []
def get_java_lib_folders(): if not is_osx(): if is_windows(): jre = os.path.join(get_java_home(), 'lib') else: jre = os.path.join(get_java_home(), 'jre', 'lib') folders = [] for root, dirnames, filenames in os.walk(jre): if is_windows(): for filename in fnmatch.filter(filenames, '*jvm.lib'): folders.append(os.path.join(root, os.path.dirname(filename))) else: for filename in fnmatch.filter(filenames, '*jvm.so'): folders.append(os.path.join(root, os.path.dirname(filename))) return list(set(folders)) return []
def get_python_libs(): """ Get the shared library names for embedding jep. See python-config """ if is_windows(): return ['python' + sysconfig.get_config_var('VERSION')] return ['python' + sysconfig.get_config_var('VERSION'), 'dl']
def run(self): from commands.util import is_windows if is_windows(): import sys import distutils import distutils.ccompiler from commands import msvc9compiler # See commands.msvc9compiler method comments for information on this override. distutils.ccompiler.compiler_class["msvc"] = ("jepmsvccompiler", "MSVCCompiler", "Microsoft Visual C++") sys.modules["distutils.jepmsvccompiler"] = msvc9compiler old_build_ext.run(self) # copy the jep.pyd to jep.dll early to avoid confusion if is_windows(): jep_lib = self.get_outputs()[0] dll = jep_lib.replace("pyd", "dll") self.copy_file(jep_lib, dll)
def run(self): from commands.util import is_windows if is_windows(): import sys import distutils import distutils.ccompiler from commands import msvc9compiler # See commands.msvc9compiler method comments for information on # this override. distutils.ccompiler.compiler_class['msvc'] = ( 'jepmsvccompiler', 'MSVCCompiler', "Microsoft Visual C++") sys.modules['distutils.jepmsvccompiler'] = msvc9compiler old_build_ext.run(self) # copy the jep.pyd to jep.dll early to avoid confusion if is_windows(): jep_lib = self.get_outputs()[0] dll = jep_lib.replace('pyd', 'dll') self.copy_file(jep_lib, dll)
def get_python_libs(): """ Get the shared library names for embedding jep. See python-config """ v = sysconfig.get_config_var("VERSION") ldv = sysconfig.get_config_var("LDVERSION") if ldv: v = ldv libs = ["python" + v] if not is_windows(): libs.append("dl") return libs
def get_python_libs(): """ Get the shared library names for embedding jep. See python-config """ v = sysconfig.get_config_var('VERSION') ldv = sysconfig.get_config_var('LDVERSION') if ldv: v = ldv libs = ['python' + v] if not is_windows(): libs.append('dl') return libs
def run(self): from commands.util import is_windows if is_windows(): import sys import distutils import distutils.ccompiler from commands import msvc9compiler # See commands.msvc9compiler method comments for information on this override. distutils.ccompiler.compiler_class['msvc']= ('jepmsvccompiler', 'MSVCCompiler', "Microsoft Visual C++") sys.modules['distutils.jepmsvccompiler'] = msvc9compiler old_build_ext.run(self) # class build_ext
def get_python_libs(): """ Get the shared library names for embedding jep. See python-config """ v = sysconfig.get_config_var('VERSION') ldv = sysconfig.get_config_var('LDVERSION') if ldv: v = ldv libs = ['python' + v] if not is_windows() and not is_bsd(): libs.append('dl') return libs
def run(self): from commands.util import is_windows if is_windows(): import sys import distutils import distutils.ccompiler from commands import msvc9compiler # See commands.msvc9compiler method comments for information on this override. distutils.ccompiler.compiler_class['msvc'] = ( 'jepmsvccompiler', 'MSVCCompiler', "Microsoft Visual C++") sys.modules['distutils.jepmsvccompiler'] = msvc9compiler old_build_ext.run(self) # class build_ext
def run(self): os.environ["CLASSPATH"] = "build/java/jep.test-{0}.jar{1}tests/lib/sqlitejdbc-v056.jar".format( self.distribution.metadata.get_version(), os.pathsep ) if is_windows(): # Use full path as spawn will only search the system PATH for *.exe on Windows if "VIRTUAL_ENV" in os.environ: py_loc = os.environ["VIRTUAL_ENV"] else: if "PYTHONHOME" in os.environ: py_loc = os.environ["PYTHONHOME"] else: configure_error( "Please set the environment variable PYTHONHOME for running the tests on Windows without a virtualenv." ) spawn(["{0}\Scripts\jep.bat".format(py_loc), "runtests.py"], search_path=0) else: spawn(["jep", "runtests.py"])
def run(self): os.environ[ 'CLASSPATH'] = 'build/java/jep.test-{0}.jar{1}tests/lib/sqlitejdbc-v056.jar'.format( self.distribution.metadata.get_version(), os.pathsep) if is_windows(): # Use full path as spawn will only search the system PATH for *.exe on Windows if 'VIRTUAL_ENV' in os.environ: py_loc = os.environ['VIRTUAL_ENV'] else: if 'PYTHONHOME' in os.environ: py_loc = os.environ['PYTHONHOME'] else: configure_error( 'Please set the environment variable PYTHONHOME for running the tests on Windows without a virtualenv.' ) spawn(['{0}\Scripts\jep.bat'.format(py_loc), 'runtests.py'], search_path=0) else: spawn(['jep', 'runtests.py'])
def get_java_home(): global _java_home if _java_home is not None: return _java_home # No need to use /usr/libexec/java_home. In seeq case, we always have java isolated in the toolchain # if is_osx(): # # newer macs have an executable to help us # try: # result = shell('/usr/libexec/java_home') # _java_home = result.stdout.decode('utf-8') # return _java_home # except CommandFailed: # traceback.print_exc() # if not os.path.exists(MAC_JAVA_HOME): # configure_error('No JAVA_HOME') # # # Apple's JAVA_HOME is predictable, just use that if we can # # though it doesn't work for Oracle's JDK # if os.path.exists(MAC_JAVA_HOME): # _java_home = MAC_JAVA_HOME # return _java_home env_home = os.environ.get('JAVA_HOME') if env_home: if is_windows(): # remove quotes from each end if necessary env_home = env_home.strip('"') if os.path.exists(env_home): _java_home = env_home return env_home else: configure_error('Path ' + env_home + ' indicated by JAVA_HOME does not exist.') configure_error( 'Please set the environment variable JAVA_HOME to a path containing the JDK.' )
def link_native_lib(output_dir, jep_lib_path): """ Links or moves the native jep library (jep.so, jep.dll) to where it can be found by Java. Args: output_dir: the directory the linked/moved file should be in should match the value passed as -Djava.library.path jep_lib_path: the path to the jep library e.g. build/lib.linux-x86_64-2.7/jep.so """ jep_lib = os.path.basename(jep_lib_path) if is_windows(): jep_dll = os.path.join(output_dir, 'jep.dll') # Remove the old DLL if it exists to avoid a file move error. if os.path.exists(jep_dll): os.remove(jep_dll) # Do not use 'spawn' as that will run as a non-administrative user # that may no longer have access to the destination directory. shutil.copy(os.path.join(output_dir, jep_lib), jep_dll) elif is_osx(): # Apple says to put the file at /Library/Java/Extensions/libjep.jnilib, # which is good for a permanent install but not so good when using # virtualenv or testing. spawn(['ln', '-sf', '{0}'.format(jep_lib), '{0}'.format(os.path.join(output_dir, 'libjep.jnilib')), ]) else: # Otherwise, distutils outputs 'jep.so' which needs to be linked # to 'libjep.so'. Otherwise the JVM will not find the library. spawn(['ln', '-sf', '{0}'.format(jep_lib), '{0}'.format(os.path.join(output_dir, 'libjep.so')), ])
def get_python_lib_dir(): if is_windows(): return os.path.join(os.environ.get('PYTHONHOME'), 'DLLs') return sysconfig.get_config_var('LIBDIR')
for root, dirs, files in os.walk("src"): for f in files: if f.endswith(pattern): ret.append(os.path.join(root, f)) return ret def read_file(name): return codecs.open(os.path.join(os.path.dirname(__file__), name), encoding="utf-8").read() if __name__ == "__main__": get_java_home() defines = [("PACKAGE", "jep"), ("USE_DEALLOC", 1), ("USE_NUMPY", numpy_found), ("VERSION", '"{0}"'.format(VERSION))] if is_windows(): defines.append(("WIN32", 1)) # Disable warnings about Secure CRT Functions in util.c and pyembed.c. defines.append(("_CRT_SECURE_NO_WARNINGS", 1)) setup( name="jep", version=VERSION, description="Jep embeds CPython in Java", long_description=read_file("README.rst"), author="Jep Developers", author_email="*****@*****.**", url="https://github.com/mrj0/jep", packages=["jep"], scripts=["src/scripts/jep"], keywords="java",
def get_python_linker_args(): if is_windows(): return [] return ["-L{0}".format(sysconfig.get_config_var("LIBDIR"))]
encoding='utf-8').read() if __name__ == '__main__': get_java_home() defines = [ ('PACKAGE', 'jep'), ('USE_DEALLOC', 1), ('JEP_NUMPY_ENABLED', numpy_found), ('VERSION', '"{0}"'.format(VERSION)), ] ldlib = sysconfig.get_config_var('LDLIBRARY') if ldlib: defines.append(('PYTHON_LDLIBRARY', '"' + ldlib + '"')) if is_windows(): defines.append(('WIN32', 1)) #Disable warnings about Secure CRT Functions in util.c and pyembed.c. defines.append(('_CRT_SECURE_NO_WARNINGS', 1)) setup( name='jep', version=VERSION, description='Jep embeds CPython in Java', long_description=read_file('README.rst'), author='Jep Developers', author_email='*****@*****.**', url='https://github.com/ninia/jep', packages=['jep'], package_dir={'': 'src/main/python'}, scripts=['src/main/scripts/jep'],
def get_python_lib_dir(): if is_windows(): return os.path.join(os.environ.get("PYTHONHOME"), "DLLs") return sysconfig.get_config_var("LIBDIR")
def get_python_linker_args(): if is_windows(): return [] return ['-L{0}'.format(sysconfig.get_config_var('LIBDIR'))]
def copy_scripts(self): """Copy each script listed in 'self.scripts'; if it's marked as a Python script in the Unix way (first line matches 'first_line_re', ie. starts with "\#!" and contains "python"), then adjust the first line to refer to the current Python interpreter as we copy. """ self.mkpath(self.build_dir) outfiles = [] install = self.get_finalized_command('install') context = dict( prefix=install.prefix, version=self.distribution.metadata.get_version(), install_base=install.install_base, install_platbase=install.install_platbase, install_lib=install.install_lib, virtual_env=os.environ.get('VIRTUAL_ENV') or '', ld_library_path='', ld_preload='', ) if not is_osx() and not is_windows(): context['ld_library_path'] = 'LD_LIBRARY_PATH="' + \ sysconfig.get_config_var('LIBDIR') + \ ':{0}"; export LD_LIBRARY_PATH'.format( install.install_lib) # set the LD_PRELOAD environment variable if we can locate the # libpython<version>.so library. lib_python = os.path.join(sysconfig.get_config_var('LIBDIR'), sysconfig.get_config_var('LDLIBRARY')) if os.path.exists(lib_python): context['ld_preload'] = 'LD_PRELOAD="{0}"; export LD_PRELOAD'.format(lib_python) else: # x64 systems will tend to also have a MULTIARCH folder lib_python = os.path.join(sysconfig.get_config_var('LIBDIR'), sysconfig.get_config_var('MULTIARCH'), sysconfig.get_config_var('LDLIBRARY')) if os.path.exists(lib_python): context['ld_preload'] = 'LD_PRELOAD="{0}"; export LD_PRELOAD'.format(lib_python) for script in self.scripts: if is_windows(): script='{0}.bat'.format(script) script = convert_path(script) outfile = os.path.join(self.build_dir, os.path.basename(script)) outfiles.append(outfile) if not self.force and not newer(script, outfile): log.debug("not copying %s (up-to-date)", script) continue # Always open the file, but ignore failures in dry-run mode -- # that way, we'll get accurate feedback if we can read the # script. try: f = open(script, "r") except IOError: if not self.dry_run: raise f = None log.info("copying and adjusting %s -> %s", script, self.build_dir) if not self.dry_run: outf = open(outfile, "w") outf.write(f.read().format(**context)) outf.close() if f: f.close() if os.name == 'posix': for file in outfiles: if self.dry_run: log.info("changing mode of %s", file) else: oldmode = os.stat(file)[ST_MODE] & 07777 newmode = (oldmode | 0555) & 07777 if newmode != oldmode: log.info("changing mode of %s from %o to %o", file, oldmode, newmode) os.chmod(file, newmode)
def copy_scripts(self): """Copy each script listed in 'self.scripts'; if it's marked as a Python script in the Unix way (first line matches 'first_line_re', ie. starts with "\#!" and contains "python"), then adjust the first line to refer to the current Python interpreter as we copy. """ self.mkpath(self.build_dir) outfiles = [] install = self.get_finalized_command('install') context = dict( version=self.distribution.metadata.get_version(), install_base=install.install_base, install_platbase=install.install_platbase, install_lib=install.install_lib, virtual_env=os.environ.get('VIRTUAL_ENV') or '', ld_library_path='', ld_preload='', ) if not is_osx() and not is_windows(): context['ld_library_path'] = 'LD_LIBRARY_PATH="' + \ sysconfig.get_config_var('LIBDIR') + \ ':{0}"; export LD_LIBRARY_PATH'.format( install.install_lib) # set the LD_PRELOAD environment variable if we can locate the # libpython<version>.so library. lib_python = os.path.join(sysconfig.get_config_var('LIBDIR'), sysconfig.get_config_var('LDLIBRARY')) if os.path.exists(lib_python): context['ld_preload'] = 'LD_PRELOAD="{0}"; export LD_PRELOAD'.format(lib_python) else: # x64 systems will tend to also have a MULTIARCH folder lib_python = os.path.join(sysconfig.get_config_var('LIBDIR'), sysconfig.get_config_var('MULTIARCH'), sysconfig.get_config_var('LDLIBRARY')) if os.path.exists(lib_python): context['ld_preload'] = 'LD_PRELOAD="{0}"; export LD_PRELOAD'.format(lib_python) for script in self.scripts: if is_windows(): script='{0}.bat'.format(script) script = convert_path(script) outfile = os.path.join(self.build_dir, os.path.basename(script)) outfiles.append(outfile) if not self.force and not newer(script, outfile): log.debug("not copying %s (up-to-date)", script) continue # Always open the file, but ignore failures in dry-run mode -- # that way, we'll get accurate feedback if we can read the # script. try: f = open(script, "r") except IOError: if not self.dry_run: raise f = None log.info("copying and adjusting %s -> %s", script, self.build_dir) if not self.dry_run: outf = open(outfile, "w") outf.write(f.read().format(**context)) outf.close() if f: f.close() if os.name == 'posix': for file in outfiles: if self.dry_run: log.info("changing mode of %s", file) else: oldmode = os.stat(file)[ST_MODE] & 0o7777 newmode = (oldmode | 0o555) & 0o7777 if newmode != oldmode: log.info("changing mode of %s from %o to %o", file, oldmode, newmode) os.chmod(file, newmode)