Add Python3 support.
This commit is contained in:
parent
a12a5adb35
commit
d7f453cc34
|
@ -1,6 +1,7 @@
|
|||
0.18 "" (released xx.xx.xxxx)
|
||||
|
||||
* Fixed unadf archive listing.
|
||||
* Added support for Python 3.x and depend on Python >= 2.7.
|
||||
|
||||
|
||||
0.17 "I am Bruce Lee" (released 4.8.2012)
|
||||
|
|
|
@ -3,7 +3,7 @@ Installation
|
|||
|
||||
First, install the required software.
|
||||
|
||||
1. Python >= 2.5 from http://www.python.org/
|
||||
1. Python >= 2.7 from http://www.python.org/
|
||||
|
||||
Be sure to also have installed the included distutils module.
|
||||
On most distributions, the distutils module is included in
|
||||
|
|
7
patool
7
patool
|
@ -17,6 +17,7 @@
|
|||
"""
|
||||
patool [extract|list|create|formats] [sub-command-options] <command-args>
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import sys
|
||||
from patoolib import handle_archive, list_formats, baker
|
||||
|
@ -35,7 +36,7 @@ def handle_multi_archive(archives, cmd, **kwargs):
|
|||
if not os.path.isfile(archive):
|
||||
res = 1
|
||||
msg = "archive %r is not a file" % archive
|
||||
print >>sys.stderr, "patool error:", msg
|
||||
print("patool error:", msg, file=sys.stderr)
|
||||
else:
|
||||
newres = handle_archive(archive, cmd, **kwargs)
|
||||
# return error if one of the archives could not be extracted
|
||||
|
@ -94,7 +95,7 @@ def formats ():
|
|||
|
||||
try:
|
||||
sys.exit(baker.run())
|
||||
except baker.CommandError, msg:
|
||||
print >>sys.stderr, "patool error:", msg
|
||||
except baker.CommandError as msg:
|
||||
print("patool error:", msg, file=sys.stderr)
|
||||
baker.help(sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
|
|
@ -13,12 +13,14 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
if not hasattr(sys, "version_info") or sys.version_info < (2, 5, 0, "final", 0):
|
||||
raise SystemExit("This program requires Python 2.5 or later.")
|
||||
if not hasattr(sys, "version_info") or sys.version_info < (2, 7, 0, "final", 0):
|
||||
raise SystemExit("This program requires Python 2.7 or later.")
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import importlib
|
||||
from . import util
|
||||
|
||||
# Supported archive commands
|
||||
|
@ -310,29 +312,29 @@ def program_supports_compression (program, compression):
|
|||
def list_formats ():
|
||||
"""Print information about available archive formats to stdout."""
|
||||
for format in ArchiveFormats:
|
||||
print format, "files:"
|
||||
print(format, "files:")
|
||||
for command in ArchiveCommands:
|
||||
programs = ArchivePrograms[format]
|
||||
if command not in programs and None not in programs:
|
||||
print " %8s: - (not supported)" % command
|
||||
print(" %8s: - (not supported)" % command)
|
||||
continue
|
||||
try:
|
||||
program = find_archive_program(format, command)
|
||||
print " %8s: %s" % (command, program),
|
||||
print(" %8s: %s" % (command, program), end=' ')
|
||||
if format == 'tar':
|
||||
encs = [x for x in ArchiveCompressions if util.find_program(x)]
|
||||
if encs:
|
||||
print "(supported compressions: %s)" % ", ".join(encs),
|
||||
print("(supported compressions: %s)" % ", ".join(encs), end=' ')
|
||||
elif format == '7z':
|
||||
if util.p7zip_supports_rar():
|
||||
print "(rar archives supported)",
|
||||
print("(rar archives supported)", end=' ')
|
||||
else:
|
||||
print "(rar archives not supported)",
|
||||
print
|
||||
print("(rar archives not supported)", end=' ')
|
||||
print()
|
||||
except util.PatoolError:
|
||||
handlers = programs.get(None, programs.get(command))
|
||||
print " %8s: - (no program found; install %s)" % \
|
||||
(command, util.strlist_with_or(handlers))
|
||||
print(" %8s: - (no program found; install %s)" %
|
||||
(command, util.strlist_with_or(handlers)))
|
||||
return 0
|
||||
|
||||
|
||||
|
@ -521,15 +523,17 @@ def _handle_archive (archive, command, *args, **kwargs):
|
|||
def get_archive_cmdlist_func (program, command, format):
|
||||
# get python module for given archive program
|
||||
key = util.stripext(os.path.basename(program).lower())
|
||||
module = ProgramModules.get(key, key)
|
||||
# import archive handler function (eg. patoolib.programs.star.extract_tar)
|
||||
args = (module, command, format)
|
||||
import_cmd = "from .programs.%s import %s_%s as func" % args
|
||||
modulename = ".programs." + ProgramModules.get(key, key)
|
||||
# import the module
|
||||
try:
|
||||
exec import_cmd
|
||||
except ImportError:
|
||||
raise util.PatoolError('ImportError executing %r' % import_cmd)
|
||||
return locals()['func']
|
||||
module = importlib.import_module(modulename, __name__)
|
||||
except ImportError as msg:
|
||||
raise util.PatoolError(msg)
|
||||
# get archive handler function (eg. patoolib.programs.star.extract_tar)
|
||||
try:
|
||||
return getattr(module, '%s_%s' % (command, format))
|
||||
except AttributeError as msg:
|
||||
raise util.PatoolError(msg)
|
||||
|
||||
|
||||
def rmtree_log_error (func, path, exc):
|
||||
|
@ -542,7 +546,7 @@ def _diff_archives (archive1, archive2, **kwargs):
|
|||
"""Show differences between two archives."""
|
||||
if util.is_same_file(archive1, archive2):
|
||||
msg = "no differences found: archive `%s' and `%s' are the same files"
|
||||
print msg % (archive1, archive2)
|
||||
print(msg % (archive1, archive2))
|
||||
return 0
|
||||
diff = util.find_program("diff")
|
||||
if not diff:
|
||||
|
@ -588,10 +592,10 @@ def handle_archive (archive, command, *args, **kwargs):
|
|||
except KeyboardInterrupt:
|
||||
util.log_error("aborted")
|
||||
res = 1
|
||||
except util.PatoolError, msg:
|
||||
except util.PatoolError as msg:
|
||||
util.log_error(msg)
|
||||
res = 1
|
||||
except StandardError, msg:
|
||||
except Exception as msg:
|
||||
util.log_internal_error()
|
||||
res = 1
|
||||
return res
|
||||
|
|
|
@ -82,6 +82,11 @@ def format_paras(paras, width, indent=0):
|
|||
def totype(v, default):
|
||||
"""Tries to convert the value 'v' into the same type as 'default'.
|
||||
"""
|
||||
# Python3 does not have long, so fake it
|
||||
try:
|
||||
long
|
||||
except NameError:
|
||||
long = int
|
||||
|
||||
t = type(default)
|
||||
if t is int:
|
||||
|
@ -188,10 +193,10 @@ class Baker(object):
|
|||
|
||||
if defaults:
|
||||
# Zip up the keyword argument names with their defaults
|
||||
keywords = dict(zip(arglist[0-len(defaults):], defaults))
|
||||
keywords = dict(list(zip(arglist[0-len(defaults):], defaults)))
|
||||
elif has_kwargs:
|
||||
# Allow keyword arguments specified by params.
|
||||
keywords = dict(zip(params.keys(), [""]*len(params)))
|
||||
keywords = dict(list(zip(params.keys(), [""]*len(params))))
|
||||
# But set a flag to detect this
|
||||
self.param_keywords = True
|
||||
else:
|
||||
|
@ -409,7 +414,7 @@ class Baker(object):
|
|||
# Process short option(s)
|
||||
|
||||
# For each character after the '-'...
|
||||
for i in xrange(1, len(arg)):
|
||||
for i in range(1, len(arg)):
|
||||
char = arg[i]
|
||||
if char not in shortchars:
|
||||
continue
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""Archive commands echoing data, implemented by the Python print
|
||||
statement."""
|
||||
from __future__ import print_function
|
||||
from .. import util
|
||||
|
||||
|
||||
|
@ -60,5 +61,5 @@ def list_flac (archive, compression, cmd, **kwargs):
|
|||
|
||||
def stripext (cmd, archive, extension=""):
|
||||
"""Print the name without suffix."""
|
||||
print util.stripext(archive)+extension
|
||||
print(util.stripext(archive)+extension)
|
||||
return None
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""Utility functions."""
|
||||
from __future__ import print_function
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
@ -30,7 +31,7 @@ def init_mimedb():
|
|||
global mimedb
|
||||
try:
|
||||
mimedb = mimetypes.MimeTypes(strict=False)
|
||||
except StandardError, msg:
|
||||
except Exception as msg:
|
||||
log_error("could not initialize MIME database: %s" % msg)
|
||||
return
|
||||
add_mimedb_data(mimedb)
|
||||
|
@ -78,7 +79,7 @@ def add_mimetype(mimedb, mimetype, extension):
|
|||
mimedb.add_type(mimetype, extension, strict=strict)
|
||||
|
||||
|
||||
class PatoolError (StandardError):
|
||||
class PatoolError (Exception):
|
||||
"""Raised when errors occur."""
|
||||
pass
|
||||
|
||||
|
@ -324,7 +325,7 @@ def set_mode (filename, flags):
|
|||
if not (mode & flags):
|
||||
try:
|
||||
os.chmod(filename, flags | mode)
|
||||
except OSError, msg:
|
||||
except OSError as msg:
|
||||
log_error("could not set mode flags for `%s': %s" % (filename, msg))
|
||||
|
||||
|
||||
|
@ -375,20 +376,20 @@ def get_single_outfile (directory, archive, extension=""):
|
|||
|
||||
def log_error (msg, out=sys.stderr):
|
||||
"""Print error message to stderr (or any other given output)."""
|
||||
print >> out, "patool error:", msg
|
||||
print("patool error:", msg, file=out)
|
||||
|
||||
|
||||
def log_info (msg, out=sys.stdout):
|
||||
"""Print info message to stdout (or any other given output)."""
|
||||
print >> out, "patool:", msg
|
||||
print("patool:", msg, file=out)
|
||||
|
||||
|
||||
def log_internal_error (out=sys.stderr):
|
||||
"""Print internal error message to stderr."""
|
||||
print >> out, "patool: internal error"
|
||||
print("patool: internal error", file=out)
|
||||
traceback.print_exc()
|
||||
print >> out, "System info:"
|
||||
print >> out, "Python %s on %s" % (sys.version, sys.platform)
|
||||
print("System info:", file=out)
|
||||
print("Python %s on %s" % (sys.version, sys.platform), file=out)
|
||||
|
||||
|
||||
def p7zip_supports_rar ():
|
||||
|
@ -421,13 +422,17 @@ def append_to_path (path, directory):
|
|||
|
||||
def get_nt_7z_dir ():
|
||||
"""Return 7-Zip directory from registry, or an empty string."""
|
||||
# Python 3.x renamed the _winreg module to winreg
|
||||
try:
|
||||
import _winreg
|
||||
key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\7-Zip")
|
||||
import _winreg as winreg
|
||||
except ImportError:
|
||||
import winreg
|
||||
try:
|
||||
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\7-Zip")
|
||||
try:
|
||||
return _winreg.QueryValueEx(key, "Path")[0]
|
||||
return winreg.QueryValueEx(key, "Path")[0]
|
||||
finally:
|
||||
_winreg.CloseKey(key)
|
||||
winreg.CloseKey(key)
|
||||
except WindowsError:
|
||||
return ""
|
||||
|
||||
|
|
56
setup.py
56
setup.py
|
@ -17,10 +17,10 @@
|
|||
"""
|
||||
Setup file for the distuils module.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import sys
|
||||
if not hasattr(sys, "version_info") or sys.version_info < (2, 4, 0, "final", 0):
|
||||
raise SystemExit("This program requires Python 2.4 or later.")
|
||||
if not hasattr(sys, "version_info") or sys.version_info < (2, 7, 0, "final", 0):
|
||||
raise SystemExit("This program requires Python 2.7 or later.")
|
||||
import os
|
||||
import shutil
|
||||
import glob
|
||||
|
@ -164,37 +164,37 @@ class InnoScript:
|
|||
|
||||
def write_inno_script (self, fd):
|
||||
"""Write Inno script contents."""
|
||||
print >> fd, "; WARNING: This script has been created by py2exe. Changes to this script"
|
||||
print >> fd, "; will be overwritten the next time py2exe is run!"
|
||||
print >> fd, "[Setup]"
|
||||
print >> fd, "AppName=%s" % self.name
|
||||
print >> fd, "AppVerName=%s %s" % (self.name, self.version)
|
||||
print >> fd, r"DefaultDirName={pf}\%s" % self.name
|
||||
print >> fd, "DefaultGroupName=%s" % self.name
|
||||
print >> fd, "OutputBaseFilename=%s" % self.distfilebase
|
||||
print >> fd, "OutputDir=.."
|
||||
print >> fd, "SetupIconFile=%s" % self.icon
|
||||
print >> fd
|
||||
print("; WARNING: This script has been created by py2exe. Changes to this script", file=fd)
|
||||
print("; will be overwritten the next time py2exe is run!", file=fd)
|
||||
print("[Setup]", file=fd)
|
||||
print("AppName=%s" % self.name, file=fd)
|
||||
print("AppVerName=%s %s" % (self.name, self.version), file=fd)
|
||||
print(r"DefaultDirName={pf}\%s" % self.name, file=fd)
|
||||
print("DefaultGroupName=%s" % self.name, file=fd)
|
||||
print("OutputBaseFilename=%s" % self.distfilebase, file=fd)
|
||||
print("OutputDir=..", file=fd)
|
||||
print("SetupIconFile=%s" % self.icon, file=fd)
|
||||
print(file=fd)
|
||||
# List of source files
|
||||
files = self.windows_exe_files + \
|
||||
self.console_exe_files + \
|
||||
self.service_exe_files + \
|
||||
self.comserver_files + \
|
||||
self.lib_files
|
||||
print >> fd, '[Files]'
|
||||
print('[Files]', file=fd)
|
||||
for path in files:
|
||||
print >> fd, r'Source: "%s"; DestDir: "{app}\%s"; Flags: ignoreversion' % (path, os.path.dirname(path))
|
||||
print(r'Source: "%s"; DestDir: "{app}\%s"; Flags: ignoreversion' % (path, os.path.dirname(path)), file=fd)
|
||||
# Set icon filename
|
||||
print >> fd, '[Icons]'
|
||||
print('[Icons]', file=fd)
|
||||
for path in self.windows_exe_files:
|
||||
print >> fd, r'Name: "{group}\%s"; Filename: "{app}\%s"' % \
|
||||
(self.name, path)
|
||||
print >> fd, r'Name: "{group}\Uninstall %s"; Filename: "{uninstallexe}"' % self.name
|
||||
print >> fd
|
||||
print(r'Name: "{group}\%s"; Filename: "{app}\%s"' %
|
||||
(self.name, path), file=fd)
|
||||
print(r'Name: "{group}\Uninstall %s"; Filename: "{uninstallexe}"' % self.name, file=fd)
|
||||
print(file=fd)
|
||||
# Uninstall optional log files
|
||||
print >> fd, '[UninstallDelete]'
|
||||
print >> fd, r'Type: files; Name: "{pf}\%s\patool*.exe.log"' % self.name
|
||||
print >> fd
|
||||
print('[UninstallDelete]', file=fd)
|
||||
print(r'Type: files; Name: "{pf}\%s\patool*.exe.log"' % self.name, file=fd)
|
||||
print(file=fd)
|
||||
|
||||
def compile (self):
|
||||
"""Compile Inno script with iscc.exe."""
|
||||
|
@ -209,7 +209,7 @@ class InnoScript:
|
|||
cmd = ['signtool.exe', 'sign', '/f', pfxfile, self.distfile]
|
||||
subprocess.check_call(cmd)
|
||||
else:
|
||||
print "No signed installer: certificate %s not found." % pfxfile
|
||||
print("No signed installer: certificate %s not found." % pfxfile)
|
||||
|
||||
try:
|
||||
from py2exe.build_exe import py2exe as py2exe_build
|
||||
|
@ -222,16 +222,16 @@ try:
|
|||
"""Generate py2exe installer."""
|
||||
# First, let py2exe do it's work.
|
||||
py2exe_build.run(self)
|
||||
print "*** preparing the inno setup script ***"
|
||||
print("*** preparing the inno setup script ***")
|
||||
lib_dir = self.lib_dir
|
||||
dist_dir = self.dist_dir
|
||||
# create the Installer, using the files py2exe has created.
|
||||
script = InnoScript(lib_dir, dist_dir, self.windows_exe_files,
|
||||
self.console_exe_files, self.service_exe_files,
|
||||
self.comserver_files, self.lib_files)
|
||||
print "*** creating the inno setup script ***"
|
||||
print("*** creating the inno setup script ***")
|
||||
script.create()
|
||||
print "*** compiling the inno setup script ***"
|
||||
print("*** compiling the inno setup script ***")
|
||||
script.compile()
|
||||
script.sign()
|
||||
except ImportError:
|
||||
|
|
|
@ -14,12 +14,18 @@
|
|||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import sys
|
||||
import patoolib
|
||||
import pytest
|
||||
|
||||
basedir = os.path.dirname(__file__)
|
||||
datadir = os.path.join(basedir, 'data')
|
||||
|
||||
# Python 3.x renamed the function name attribute
|
||||
if sys.version_info[0] > 2:
|
||||
fnameattr = '__name__'
|
||||
else:
|
||||
fnameattr = 'func_name'
|
||||
|
||||
def needs_os (name):
|
||||
"""Decorator skipping test if given program is not available."""
|
||||
|
@ -28,7 +34,7 @@ def needs_os (name):
|
|||
if os.name != name:
|
||||
raise pytest.skip("operating system %s not found" % name)
|
||||
return f(*args, **kwargs)
|
||||
newfunc.func_name = f.func_name
|
||||
setattr(newfunc, fnameattr, getattr(f, fnameattr))
|
||||
return newfunc
|
||||
return check_prog
|
||||
|
||||
|
@ -40,7 +46,7 @@ def needs_program (program):
|
|||
if not patoolib.util.find_program(program):
|
||||
raise pytest.skip("program `%s' not available" % program)
|
||||
return f(*args, **kwargs)
|
||||
newfunc.func_name = f.func_name
|
||||
setattr(newfunc, fnameattr, getattr(f, fnameattr))
|
||||
return newfunc
|
||||
return check_prog
|
||||
|
||||
|
@ -55,7 +61,7 @@ def needs_one_program (programs):
|
|||
else:
|
||||
raise pytest.skip("None of programs %s available" % programs)
|
||||
return f(*args, **kwargs)
|
||||
newfunc.func_name = f.func_name
|
||||
setattr(newfunc, fnameattr, getattr(f, fnameattr))
|
||||
return newfunc
|
||||
return check_prog
|
||||
|
||||
|
@ -69,7 +75,7 @@ def needs_codec (program, codec):
|
|||
if not has_codec(program, codec):
|
||||
raise pytest.skip("codec `%s' for program `%s' not available" % (codec, program))
|
||||
return f(*args, **kwargs)
|
||||
newfunc.func_name = f.func_name
|
||||
setattr(newfunc, fnameattr, getattr(f, fnameattr))
|
||||
return newfunc
|
||||
return check_prog
|
||||
|
||||
|
@ -81,5 +87,3 @@ def has_codec (program, codec):
|
|||
if patoolib.program_supports_compression(program, codec):
|
||||
return True
|
||||
return patoolib.util.find_program(codec)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue