summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author?ric Araujo <merwok@netwok.org>2011-10-19 03:08:54 +0200
committer?ric Araujo <merwok@netwok.org>2011-10-19 03:08:54 +0200
commit388b499a2b99bcd6e409bd0d593144faa0d52f40 (patch)
treed22aeff001ac3ee03d06bbafc31c740075b5bcb0
parent31f4c07c589c068242cada4bda617fa6bd51e5d5 (diff)
parent2fd0570dc0f3e5498fc26066a322168ea9d8d0db (diff)
downloaddisutils2-388b499a2b99bcd6e409bd0d593144faa0d52f40.tar.gz
Null merge default
-rw-r--r--DEVNOTES.txt18
-rw-r--r--PC/build_ssl.py282
-rw-r--r--distutils2/_backport/_hashopenssl.c524
-rw-r--r--distutils2/_backport/hashlib.py143
-rw-r--r--distutils2/_backport/md5.c381
-rw-r--r--distutils2/_backport/md5.h91
-rw-r--r--distutils2/_backport/md5module.c312
-rw-r--r--distutils2/_backport/sha256module.c701
-rw-r--r--distutils2/_backport/sha512module.c769
-rw-r--r--distutils2/_backport/shamodule.c593
-rw-r--r--distutils2/_backport/shutil.py39
-rw-r--r--distutils2/_backport/sysconfig.cfg4
-rw-r--r--distutils2/_backport/sysconfig.py46
-rw-r--r--distutils2/_backport/tarfile.py308
-rw-r--r--distutils2/_backport/tests/test_shutil.py17
-rw-r--r--distutils2/_backport/tests/test_sysconfig.py52
-rw-r--r--distutils2/command/bdist_msi.py10
-rw-r--r--distutils2/command/bdist_wininst.py36
-rw-r--r--distutils2/command/build_clib.py4
-rw-r--r--distutils2/command/build_ext.py35
-rw-r--r--distutils2/command/build_py.py4
-rw-r--r--distutils2/command/build_scripts.py18
-rw-r--r--distutils2/command/cmd.py12
-rw-r--r--distutils2/command/config.py23
-rw-r--r--distutils2/command/install_data.py2
-rw-r--r--distutils2/command/install_dist.py56
-rw-r--r--distutils2/command/install_distinfo.py26
-rw-r--r--distutils2/command/install_lib.py2
-rw-r--r--distutils2/command/install_scripts.py2
-rw-r--r--distutils2/command/register.py37
-rw-r--r--distutils2/command/sdist.py8
-rw-r--r--distutils2/command/upload.py29
-rw-r--r--distutils2/command/upload_docs.py18
-rw-r--r--distutils2/compat.py126
-rw-r--r--distutils2/compiler/__init__.py4
-rw-r--r--distutils2/compiler/bcppcompiler.py12
-rw-r--r--distutils2/compiler/ccompiler.py21
-rw-r--r--distutils2/compiler/cygwinccompiler.py11
-rw-r--r--distutils2/compiler/extension.py6
-rw-r--r--distutils2/compiler/msvc9compiler.py16
-rw-r--r--distutils2/compiler/msvccompiler.py12
-rw-r--r--distutils2/compiler/unixccompiler.py8
-rw-r--r--distutils2/config.py37
-rw-r--r--distutils2/create.py120
-rw-r--r--distutils2/database.py38
-rw-r--r--distutils2/depgraph.py49
-rw-r--r--distutils2/dist.py36
-rw-r--r--distutils2/fancy_getopt.py10
-rw-r--r--distutils2/install.py21
-rw-r--r--distutils2/manifest.py18
-rw-r--r--distutils2/markers.py18
-rw-r--r--distutils2/metadata.py25
-rw-r--r--distutils2/pypi/base.py2
-rw-r--r--distutils2/pypi/dist.py24
-rw-r--r--distutils2/pypi/simple.py73
-rw-r--r--distutils2/pypi/wrapper.py8
-rw-r--r--distutils2/pypi/xmlrpc.py6
-rw-r--r--distutils2/run.py67
-rw-r--r--distutils2/tests/__init__.py10
-rw-r--r--distutils2/tests/__main__.py2
-rw-r--r--distutils2/tests/pypi_server.py36
-rw-r--r--distutils2/tests/pypi_test_server.py2
-rw-r--r--distutils2/tests/support.py31
-rw-r--r--distutils2/tests/test_command_build_clib.py2
-rw-r--r--distutils2/tests/test_command_build_ext.py19
-rw-r--r--distutils2/tests/test_command_build_py.py19
-rw-r--r--distutils2/tests/test_command_build_scripts.py5
-rw-r--r--distutils2/tests/test_command_check.py12
-rw-r--r--distutils2/tests/test_command_config.py5
-rw-r--r--distutils2/tests/test_command_install_dist.py26
-rw-r--r--distutils2/tests/test_command_install_distinfo.py45
-rw-r--r--distutils2/tests/test_command_install_lib.py19
-rw-r--r--distutils2/tests/test_command_install_scripts.py5
-rw-r--r--distutils2/tests/test_command_register.py51
-rw-r--r--distutils2/tests/test_command_sdist.py30
-rw-r--r--distutils2/tests/test_command_test.py6
-rw-r--r--distutils2/tests/test_command_upload.py14
-rw-r--r--distutils2/tests/test_command_upload_docs.py32
-rw-r--r--distutils2/tests/test_compiler.py4
-rw-r--r--distutils2/tests/test_config.py14
-rw-r--r--distutils2/tests/test_create.py29
-rw-r--r--distutils2/tests/test_database.py63
-rw-r--r--distutils2/tests/test_depgraph.py2
-rw-r--r--distutils2/tests/test_dist.py16
-rw-r--r--distutils2/tests/test_install.py6
-rw-r--r--distutils2/tests/test_manifest.py12
-rw-r--r--distutils2/tests/test_markers.py3
-rw-r--r--distutils2/tests/test_metadata.py64
-rw-r--r--distutils2/tests/test_mixin2to3.py33
-rw-r--r--distutils2/tests/test_msvc9compiler.py10
-rw-r--r--distutils2/tests/test_pypi_server.py33
-rw-r--r--distutils2/tests/test_pypi_simple.py59
-rw-r--r--distutils2/tests/test_pypi_xmlrpc.py5
-rw-r--r--distutils2/tests/test_run.py11
-rw-r--r--distutils2/tests/test_util.py72
-rw-r--r--distutils2/tests/xxmodule.c521
-rw-r--r--distutils2/util.py145
-rw-r--r--distutils2/version.py8
-rw-r--r--runtests.py6
-rw-r--r--setup.py143
-rwxr-xr-xtests.sh29
101 files changed, 1281 insertions, 5748 deletions
diff --git a/DEVNOTES.txt b/DEVNOTES.txt
index ec97ba8..126418c 100644
--- a/DEVNOTES.txt
+++ b/DEVNOTES.txt
@@ -1,14 +1,16 @@
Notes for developers
====================
-- Distutils2 runs on Python from 2.4 to 2.7 so make sure you don't use code
- that doesn't work under one of these Python versions. There is also a
- version compatible with 3.1-3.3 in the "python3" branch.
+- Distutils2 runs on Python from 3.1 to 3.2 so make sure you don't use code
+ that doesn't work under one of these Python versions. The version compatible
+ with 2.4-2.7 in the "default" branch.
-- For 2.4, you need to run "python2.4 setup.py build" before you can try out
- pysetup or run tests (unless you use the runtests.py script which will call
- "setup.py build" automatically).
+- When merging default into python3, don't keep maximum compatibility with
+ Python 2 but use idiomatic 3.x code. For difficult conversions like encoding
+ handling with I/O, you can have a look or use a diff tool with the same file
+ in distutils or packaging from Python 3.3.
- Always run tests.sh before you commit a change. This implies that you have
- all Python versions installed from 2.4 to 2.7. Be sure to also have docutils
- installed on all Python versions to avoid skipping tests.
+ Python 3.1 and 3.2 installed as well as a checkout of Python 3.3 with its
+ executable available as "python3.3" in your $PATH. Be sure to also have
+ docutils installed on all Python versions to avoid skipping tests.
diff --git a/PC/build_ssl.py b/PC/build_ssl.py
deleted file mode 100644
index eff2938..0000000
--- a/PC/build_ssl.py
+++ /dev/null
@@ -1,282 +0,0 @@
-# Script for building the _ssl and _hashlib modules for Windows.
-# Uses Perl to setup the OpenSSL environment correctly
-# and build OpenSSL, then invokes a simple nmake session
-# for the actual _ssl.pyd and _hashlib.pyd DLLs.
-
-# THEORETICALLY, you can:
-# * Unpack the latest SSL release one level above your main Python source
-# directory. It is likely you will already find the zlib library and
-# any other external packages there.
-# * Install ActivePerl and ensure it is somewhere on your path.
-# * Run this script from the PCBuild directory.
-#
-# it should configure and build SSL, then build the _ssl and _hashlib
-# Python extensions without intervention.
-
-# Modified by Christian Heimes
-# Now this script supports pre-generated makefiles and assembly files.
-# Developers don't need an installation of Perl anymore to build Python. A svn
-# checkout from our svn repository is enough.
-#
-# In Order to create the files in the case of an update you still need Perl.
-# Run build_ssl in this order:
-# python.exe build_ssl.py Release x64
-# python.exe build_ssl.py Release Win32
-
-import os, sys, re, shutil
-
-# Find all "foo.exe" files on the PATH.
-def find_all_on_path(filename, extras = None):
- entries = os.environ["PATH"].split(os.pathsep)
- ret = []
- for p in entries:
- fname = os.path.abspath(os.path.join(p, filename))
- if os.path.isfile(fname) and fname not in ret:
- ret.append(fname)
- if extras:
- for p in extras:
- fname = os.path.abspath(os.path.join(p, filename))
- if os.path.isfile(fname) and fname not in ret:
- ret.append(fname)
- return ret
-
-# Find a suitable Perl installation for OpenSSL.
-# cygwin perl does *not* work. ActivePerl does.
-# Being a Perl dummy, the simplest way I can check is if the "Win32" package
-# is available.
-def find_working_perl(perls):
- for perl in perls:
- fh = os.popen('"%s" -e "use Win32;"' % perl)
- fh.read()
- rc = fh.close()
- if rc:
- continue
- return perl
- print("Can not find a suitable PERL:")
- if perls:
- print(" the following perl interpreters were found:")
- for p in perls:
- print(" ", p)
- print(" None of these versions appear suitable for building OpenSSL")
- else:
- print(" NO perl interpreters were found on this machine at all!")
- print(" Please install ActivePerl and ensure it appears on your path")
- return None
-
-# Locate the best SSL directory given a few roots to look into.
-def find_best_ssl_dir(sources):
- candidates = []
- for s in sources:
- try:
- # note: do not abspath s; the build will fail if any
- # higher up directory name has spaces in it.
- fnames = os.listdir(s)
- except os.error:
- fnames = []
- for fname in fnames:
- fqn = os.path.join(s, fname)
- if os.path.isdir(fqn) and fname.startswith("openssl-"):
- candidates.append(fqn)
- # Now we have all the candidates, locate the best.
- best_parts = []
- best_name = None
- for c in candidates:
- parts = re.split("[.-]", os.path.basename(c))[1:]
- # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers
- if len(parts) >= 4:
- continue
- if parts > best_parts:
- best_parts = parts
- best_name = c
- if best_name is not None:
- print("Found an SSL directory at '%s'" % (best_name,))
- else:
- print("Could not find an SSL directory in '%s'" % (sources,))
- sys.stdout.flush()
- return best_name
-
-def create_makefile64(makefile, m32):
- """Create and fix makefile for 64bit
-
- Replace 32 with 64bit directories
- """
- if not os.path.isfile(m32):
- return
- with open(m32) as fin:
- with open(makefile, 'w') as fout:
- for line in fin:
- line = line.replace("=tmp32", "=tmp64")
- line = line.replace("=out32", "=out64")
- line = line.replace("=inc32", "=inc64")
- # force 64 bit machine
- line = line.replace("MKLIB=lib", "MKLIB=lib /MACHINE:X64")
- line = line.replace("LFLAGS=", "LFLAGS=/MACHINE:X64 ")
- # don't link against the lib on 64bit systems
- line = line.replace("bufferoverflowu.lib", "")
- fout.write(line)
- os.unlink(m32)
-
-def fix_makefile(makefile):
- """Fix some stuff in all makefiles
- """
- if not os.path.isfile(makefile):
- return
- with open(makefile) as fin:
- lines = fin.readlines()
- with open(makefile, 'w') as fout:
- for line in lines:
- if line.startswith("PERL="):
- continue
- if line.startswith("CP="):
- line = "CP=copy\n"
- if line.startswith("MKDIR="):
- line = "MKDIR=mkdir\n"
- if line.startswith("CFLAG="):
- line = line.strip()
- for algo in ("RC5", "MDC2", "IDEA"):
- noalgo = " -DOPENSSL_NO_%s" % algo
- if noalgo not in line:
- line = line + noalgo
- line = line + '\n'
- fout.write(line)
-
-def run_configure(configure, do_script):
- print("perl Configure "+configure+" no-idea no-mdc2")
- os.system("perl Configure "+configure+" no-idea no-mdc2")
- print(do_script)
- os.system(do_script)
-
-def cmp(f1, f2):
- bufsize = 1024 * 8
- with open(f1, 'rb') as fp1, open(f2, 'rb') as fp2:
- while True:
- b1 = fp1.read(bufsize)
- b2 = fp2.read(bufsize)
- if b1 != b2:
- return False
- if not b1:
- return True
-
-def copy(src, dst):
- if os.path.isfile(dst) and cmp(src, dst):
- return
- shutil.copy(src, dst)
-
-def main():
- build_all = "-a" in sys.argv
- # Default to 'Release' configuration on for the 'Win32' platform
- try:
- configuration, platform = sys.argv[1:3]
- except ValueError:
- configuration, platform = 'Release', 'Win32'
- if configuration == "Release":
- debug = False
- elif configuration == "Debug":
- debug = True
- else:
- raise ValueError(str(sys.argv))
-
- if platform == "Win32":
- arch = "x86"
- configure = "VC-WIN32"
- do_script = "ms\\do_nasm"
- makefile="ms\\nt.mak"
- m32 = makefile
- dirsuffix = "32"
- elif platform == "x64":
- arch="amd64"
- configure = "VC-WIN64A"
- do_script = "ms\\do_win64a"
- makefile = "ms\\nt64.mak"
- m32 = makefile.replace('64', '')
- dirsuffix = "64"
- #os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON"
- else:
- raise ValueError(str(sys.argv))
-
- make_flags = ""
- if build_all:
- make_flags = "-a"
- # perl should be on the path, but we also look in "\perl" and "c:\\perl"
- # as "well known" locations
- perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
- perl = find_working_perl(perls)
- if perl:
- print("Found a working perl at '%s'" % (perl,))
- else:
- print("No Perl installation was found. Existing Makefiles are used.")
- sys.stdout.flush()
- # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
- ssl_dir = find_best_ssl_dir(("..\\..",))
- if ssl_dir is None:
- sys.exit(1)
-
- old_cd = os.getcwd()
- try:
- os.chdir(ssl_dir)
- # rebuild makefile when we do the role over from 32 to 64 build
- if arch == "amd64" and os.path.isfile(m32) and not os.path.isfile(makefile):
- os.unlink(m32)
-
- # If the ssl makefiles do not exist, we invoke Perl to generate them.
- # Due to a bug in this script, the makefile sometimes ended up empty
- # Force a regeneration if it is.
- if not os.path.isfile(makefile) or os.path.getsize(makefile)==0:
- if perl is None:
- print("Perl is required to build the makefiles!")
- sys.exit(1)
-
- print("Creating the makefiles...")
- sys.stdout.flush()
- # Put our working Perl at the front of our path
- os.environ["PATH"] = os.path.dirname(perl) + \
- os.pathsep + \
- os.environ["PATH"]
- run_configure(configure, do_script)
- if debug:
- print("OpenSSL debug builds aren't supported.")
- #if arch=="x86" and debug:
- # # the do_masm script in openssl doesn't generate a debug
- # # build makefile so we generate it here:
- # os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)
-
- if arch == "amd64":
- create_makefile64(makefile, m32)
- fix_makefile(makefile)
- copy(r"crypto\buildinf.h", r"crypto\buildinf_%s.h" % arch)
- copy(r"crypto\opensslconf.h", r"crypto\opensslconf_%s.h" % arch)
-
- # If the assembler files don't exist in tmpXX, copy them there
- if perl is None and os.path.exists("asm"+dirsuffix):
- if not os.path.exists("tmp"+dirsuffix):
- os.mkdir("tmp"+dirsuffix)
- for f in os.listdir("asm"+dirsuffix):
- if not f.endswith(".asm"): continue
- if os.path.isfile(r"tmp%s\%s" % (dirsuffix, f)): continue
- shutil.copy(r"asm%s\%s" % (dirsuffix, f), "tmp"+dirsuffix)
-
- # Now run make.
- if arch == "amd64":
- rc = os.system("ml64 -c -Foms\\uptable.obj ms\\uptable.asm")
- if rc:
- print("ml64 assembler has failed.")
- sys.exit(rc)
-
- copy(r"crypto\buildinf_%s.h" % arch, r"crypto\buildinf.h")
- copy(r"crypto\opensslconf_%s.h" % arch, r"crypto\opensslconf.h")
-
- #makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)
- makeCommand = "nmake /nologo -f \"%s\"" % makefile
- print("Executing ssl makefiles: " + makeCommand)
- sys.stdout.flush()
- rc = os.system(makeCommand)
- if rc:
- print("Executing "+makefile+" failed")
- print(rc)
- sys.exit(rc)
- finally:
- os.chdir(old_cd)
- sys.exit(rc)
-
-if __name__=='__main__':
- main()
diff --git a/distutils2/_backport/_hashopenssl.c b/distutils2/_backport/_hashopenssl.c
deleted file mode 100644
index fdcae5d..0000000
--- a/distutils2/_backport/_hashopenssl.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* Module that wraps all OpenSSL hash algorithms */
-
-/*
- * Copyright (C) 2005 Gregory P. Smith (greg@krypto.org)
- * Licensed to PSF under a Contributor Agreement.
- *
- * Derived from a skeleton of shamodule.c containing work performed by:
- *
- * Andrew Kuchling (amk@amk.ca)
- * Greg Stein (gstein@lyra.org)
- *
- */
-
-#define PY_SSIZE_T_CLEAN
-
-#include "Python.h"
-#include "structmember.h"
-
-#if (PY_VERSION_HEX < 0x02050000)
-#define Py_ssize_t int
-#endif
-
-/* EVP is the preferred interface to hashing in OpenSSL */
-#include <openssl/evp.h>
-
-#define MUNCH_SIZE INT_MAX
-
-
-#ifndef HASH_OBJ_CONSTRUCTOR
-#define HASH_OBJ_CONSTRUCTOR 0
-#endif
-
-typedef struct {
- PyObject_HEAD
- PyObject *name; /* name of this hash algorithm */
- EVP_MD_CTX ctx; /* OpenSSL message digest context */
-} EVPobject;
-
-
-static PyTypeObject EVPtype;
-
-
-#define DEFINE_CONSTS_FOR_NEW(Name) \
- static PyObject *CONST_ ## Name ## _name_obj; \
- static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \
- static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL;
-
-DEFINE_CONSTS_FOR_NEW(md5)
-DEFINE_CONSTS_FOR_NEW(sha1)
-DEFINE_CONSTS_FOR_NEW(sha224)
-DEFINE_CONSTS_FOR_NEW(sha256)
-DEFINE_CONSTS_FOR_NEW(sha384)
-DEFINE_CONSTS_FOR_NEW(sha512)
-
-
-static EVPobject *
-newEVPobject(PyObject *name)
-{
- EVPobject *retval = (EVPobject *)PyObject_New(EVPobject, &EVPtype);
-
- /* save the name for .name to return */
- if (retval != NULL) {
- Py_INCREF(name);
- retval->name = name;
- }
-
- return retval;
-}
-
-/* Internal methods for a hash object */
-
-static void
-EVP_dealloc(PyObject *ptr)
-{
- EVP_MD_CTX_cleanup(&((EVPobject *)ptr)->ctx);
- Py_XDECREF(((EVPobject *)ptr)->name);
- PyObject_Del(ptr);
-}
-
-
-/* External methods for a hash object */
-
-PyDoc_STRVAR(EVP_copy__doc__, "Return a copy of the hash object.");
-
-static PyObject *
-EVP_copy(EVPobject *self, PyObject *unused)
-{
- EVPobject *newobj;
-
- if ( (newobj = newEVPobject(self->name))==NULL)
- return NULL;
-
- EVP_MD_CTX_copy(&newobj->ctx, &self->ctx);
- return (PyObject *)newobj;
-}
-
-PyDoc_STRVAR(EVP_digest__doc__,
-"Return the digest value as a string of binary data.");
-
-static PyObject *
-EVP_digest(EVPobject *self, PyObject *unused)
-{
- unsigned char digest[EVP_MAX_MD_SIZE];
- EVP_MD_CTX temp_ctx;
- PyObject *retval;
- unsigned int digest_size;
-
- EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
- digest_size = EVP_MD_CTX_size(&temp_ctx);
- EVP_DigestFinal(&temp_ctx, digest, NULL);
-
- retval = PyString_FromStringAndSize((const char *)digest, digest_size);
- EVP_MD_CTX_cleanup(&temp_ctx);
- return retval;
-}
-
-PyDoc_STRVAR(EVP_hexdigest__doc__,
-"Return the digest value as a string of hexadecimal digits.");
-
-static PyObject *
-EVP_hexdigest(EVPobject *self, PyObject *unused)
-{
- unsigned char digest[EVP_MAX_MD_SIZE];
- EVP_MD_CTX temp_ctx;
- PyObject *retval;
- char *hex_digest;
- unsigned int i, j, digest_size;
-
- /* Get the raw (binary) digest value */
- EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
- digest_size = EVP_MD_CTX_size(&temp_ctx);
- EVP_DigestFinal(&temp_ctx, digest, NULL);
-
- EVP_MD_CTX_cleanup(&temp_ctx);
-
- /* Create a new string */
- /* NOTE: not thread safe! modifying an already created string object */
- /* (not a problem because we hold the GIL by default) */
- retval = PyString_FromStringAndSize(NULL, digest_size * 2);
- if (!retval)
- return NULL;
- hex_digest = PyString_AsString(retval);
- if (!hex_digest) {
- Py_DECREF(retval);
- return NULL;
- }
-
- /* Make hex version of the digest */
- for(i=j=0; i<digest_size; i++) {
- char c;
- c = (digest[i] >> 4) & 0xf;
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- c = (digest[i] & 0xf);
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- }
- return retval;
-}
-
-PyDoc_STRVAR(EVP_update__doc__,
-"Update this hash object's state with the provided string.");
-
-static PyObject *
-EVP_update(EVPobject *self, PyObject *args)
-{
- unsigned char *cp;
- Py_ssize_t len;
-
- if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
- return NULL;
-
- if (len > 0 && len <= MUNCH_SIZE) {
- EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
- unsigned int));
- } else {
- Py_ssize_t offset = 0;
- while (len) {
- unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
- EVP_DigestUpdate(&self->ctx, cp + offset, process);
- len -= process;
- offset += process;
- }
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef EVP_methods[] = {
- {"update", (PyCFunction)EVP_update, METH_VARARGS, EVP_update__doc__},
- {"digest", (PyCFunction)EVP_digest, METH_NOARGS, EVP_digest__doc__},
- {"hexdigest", (PyCFunction)EVP_hexdigest, METH_NOARGS, EVP_hexdigest__doc__},
- {"copy", (PyCFunction)EVP_copy, METH_NOARGS, EVP_copy__doc__},
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-EVP_get_block_size(EVPobject *self, void *closure)
-{
- return PyInt_FromLong(EVP_MD_CTX_block_size(&((EVPobject *)self)->ctx));
-}
-
-static PyObject *
-EVP_get_digest_size(EVPobject *self, void *closure)
-{
- return PyInt_FromLong(EVP_MD_CTX_size(&((EVPobject *)self)->ctx));
-}
-
-static PyMemberDef EVP_members[] = {
- {"name", T_OBJECT, offsetof(EVPobject, name), READONLY, PyDoc_STR("algorithm name.")},
- {NULL} /* Sentinel */
-};
-
-static PyGetSetDef EVP_getseters[] = {
- {"digest_size",
- (getter)EVP_get_digest_size, NULL,
- NULL,
- NULL},
- {"block_size",
- (getter)EVP_get_block_size, NULL,
- NULL,
- NULL},
- /* the old md5 and sha modules support 'digest_size' as in PEP 247.
- * the old sha module also supported 'digestsize'. ugh. */
- {"digestsize",
- (getter)EVP_get_digest_size, NULL,
- NULL,
- NULL},
- {NULL} /* Sentinel */
-};
-
-
-static PyObject *
-EVP_repr(PyObject *self)
-{
- char buf[100];
- PyOS_snprintf(buf, sizeof(buf), "<%s HASH object @ %p>",
- PyString_AsString(((EVPobject *)self)->name), self);
- return PyString_FromString(buf);
-}
-
-#if HASH_OBJ_CONSTRUCTOR
-static int
-EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds)
-{
- static char *kwlist[] = {"name", "string", NULL};
- PyObject *name_obj = NULL;
- char *nameStr;
- unsigned char *cp = NULL;
- Py_ssize_t len = 0;
- const EVP_MD *digest;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s#:HASH", kwlist,
- &name_obj, &cp, &len)) {
- return -1;
- }
-
- if (!PyArg_Parse(name_obj, "s", &nameStr)) {
- PyErr_SetString(PyExc_TypeError, "name must be a string");
- return -1;
- }
-
- digest = EVP_get_digestbyname(nameStr);
- if (!digest) {
- PyErr_SetString(PyExc_ValueError, "unknown hash function");
- return -1;
- }
- EVP_DigestInit(&self->ctx, digest);
-
- self->name = name_obj;
- Py_INCREF(self->name);
-
- if (cp && len) {
- if (len > 0 && len <= MUNCH_SIZE) {
- EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
- unsigned int));
- } else {
- Py_ssize_t offset = 0;
- while (len) {
- unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
- EVP_DigestUpdate(&self->ctx, cp + offset, process);
- len -= process;
- offset += process;
- }
- }
- }
-
- return 0;
-}
-#endif
-
-
-PyDoc_STRVAR(hashtype_doc,
-"A hash represents the object used to calculate a checksum of a\n\
-string of information.\n\
-\n\
-Methods:\n\
-\n\
-update() -- updates the current digest with an additional string\n\
-digest() -- return the current digest value\n\
-hexdigest() -- return the current digest as a string of hexadecimal digits\n\
-copy() -- return a copy of the current hash object\n\
-\n\
-Attributes:\n\
-\n\
-name -- the hash algorithm being used by this object\n\
-digest_size -- number of bytes in this hashes output\n");
-
-static PyTypeObject EVPtype = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "_hashlib.HASH", /*tp_name*/
- sizeof(EVPobject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- EVP_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- EVP_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- hashtype_doc, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- EVP_methods, /* tp_methods */
- EVP_members, /* tp_members */
- EVP_getseters, /* tp_getset */
-#if 1
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
-#endif
-#if HASH_OBJ_CONSTRUCTOR
- (initproc)EVP_tp_init, /* tp_init */
-#endif
-};
-
-static PyObject *
-EVPnew(PyObject *name_obj,
- const EVP_MD *digest, const EVP_MD_CTX *initial_ctx,
- const unsigned char *cp, Py_ssize_t len)
-{
- EVPobject *self;
-
- if (!digest && !initial_ctx) {
- PyErr_SetString(PyExc_ValueError, "unsupported hash type");
- return NULL;
- }
-
- if ((self = newEVPobject(name_obj)) == NULL)
- return NULL;
-
- if (initial_ctx) {
- EVP_MD_CTX_copy(&self->ctx, initial_ctx);
- } else {
- EVP_DigestInit(&self->ctx, digest);
- }
-
- if (cp && len) {
- if (len > 0 && len <= MUNCH_SIZE) {
- EVP_DigestUpdate(&self->ctx, cp, Py_SAFE_DOWNCAST(len, Py_ssize_t,
- unsigned int));
- } else {
- Py_ssize_t offset = 0;
- while (len) {
- unsigned int process = len > MUNCH_SIZE ? MUNCH_SIZE : len;
- EVP_DigestUpdate(&self->ctx, cp + offset, process);
- len -= process;
- offset += process;
- }
- }
- }
-
- return (PyObject *)self;
-}
-
-
-/* The module-level function: new() */
-
-PyDoc_STRVAR(EVP_new__doc__,
-"Return a new hash object using the named algorithm.\n\
-An optional string argument may be provided and will be\n\
-automatically hashed.\n\
-\n\
-The MD5 and SHA1 algorithms are always supported.\n");
-
-static PyObject *
-EVP_new(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- static char *kwlist[] = {"name", "string", NULL};
- PyObject *name_obj = NULL;
- char *name;
- const EVP_MD *digest;
- unsigned char *cp = NULL;
- Py_ssize_t len = 0;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s#:new", kwlist,
- &name_obj, &cp, &len)) {
- return NULL;
- }
-
- if (!PyArg_Parse(name_obj, "s", &name)) {
- PyErr_SetString(PyExc_TypeError, "name must be a string");
- return NULL;
- }
-
- digest = EVP_get_digestbyname(name);
-
- return EVPnew(name_obj, digest, NULL, cp, len);
-}
-
-/*
- * This macro generates constructor function definitions for specific
- * hash algorithms. These constructors are much faster than calling
- * the generic one passing it a python string and are noticably
- * faster than calling a python new() wrapper. Thats important for
- * code that wants to make hashes of a bunch of small strings.
- */
-#define GEN_CONSTRUCTOR(NAME) \
- static PyObject * \
- EVP_new_ ## NAME (PyObject *self, PyObject *args) \
- { \
- unsigned char *cp = NULL; \
- Py_ssize_t len = 0; \
- \
- if (!PyArg_ParseTuple(args, "|s#:" #NAME , &cp, &len)) { \
- return NULL; \
- } \
- \
- return EVPnew( \
- CONST_ ## NAME ## _name_obj, \
- NULL, \
- CONST_new_ ## NAME ## _ctx_p, \
- cp, len); \
- }
-
-/* a PyMethodDef structure for the constructor */
-#define CONSTRUCTOR_METH_DEF(NAME) \
- {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \
- PyDoc_STR("Returns a " #NAME \
- " hash object; optionally initialized with a string") \
- }
-
-/* used in the init function to setup a constructor */
-#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \
- CONST_ ## NAME ## _name_obj = PyString_FromString(#NAME); \
- if (EVP_get_digestbyname(#NAME)) { \
- CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \
- EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \
- } \
-} while (0);
-
-GEN_CONSTRUCTOR(md5)
-GEN_CONSTRUCTOR(sha1)
-GEN_CONSTRUCTOR(sha224)
-GEN_CONSTRUCTOR(sha256)
-GEN_CONSTRUCTOR(sha384)
-GEN_CONSTRUCTOR(sha512)
-
-/* List of functions exported by this module */
-
-static struct PyMethodDef EVP_functions[] = {
- {"new", (PyCFunction)EVP_new, METH_VARARGS|METH_KEYWORDS, EVP_new__doc__},
- CONSTRUCTOR_METH_DEF(md5),
- CONSTRUCTOR_METH_DEF(sha1),
- CONSTRUCTOR_METH_DEF(sha224),
- CONSTRUCTOR_METH_DEF(sha256),
- CONSTRUCTOR_METH_DEF(sha384),
- CONSTRUCTOR_METH_DEF(sha512),
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-
-PyMODINIT_FUNC
-init_hashlib(void)
-{
- PyObject *m;
-
- OpenSSL_add_all_digests();
-
- /* TODO build EVP_functions openssl_* entries dynamically based
- * on what hashes are supported rather than listing many
- * but having some be unsupported. Only init appropriate
- * constants. */
-
- EVPtype.ob_type = &PyType_Type;
- if (PyType_Ready(&EVPtype) < 0)
- return;
-
- m = Py_InitModule("_hashlib", EVP_functions);
- if (m == NULL)
- return;
-
-#if HASH_OBJ_CONSTRUCTOR
- Py_INCREF(&EVPtype);
- PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
-#endif
-
- /* these constants are used by the convenience constructors */
- INIT_CONSTRUCTOR_CONSTANTS(md5);
- INIT_CONSTRUCTOR_CONSTANTS(sha1);
- INIT_CONSTRUCTOR_CONSTANTS(sha224);
- INIT_CONSTRUCTOR_CONSTANTS(sha256);
- INIT_CONSTRUCTOR_CONSTANTS(sha384);
- INIT_CONSTRUCTOR_CONSTANTS(sha512);
-}
diff --git a/distutils2/_backport/hashlib.py b/distutils2/_backport/hashlib.py
deleted file mode 100644
index dd2b02a..0000000
--- a/distutils2/_backport/hashlib.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# $Id$
-#
-# Copyright (C) 2005 Gregory P. Smith (greg@krypto.org)
-# Licensed to PSF under a Contributor Agreement.
-#
-
-__doc__ = """hashlib module - A common interface to many hash functions.
-
-new(name, string='') - returns a new hash object implementing the
- given hash function; initializing the hash
- using the given string data.
-
-Named constructor functions are also available, these are much faster
-than using new():
-
-md5(), sha1(), sha224(), sha256(), sha384(), and sha512()
-
-More algorithms may be available on your platform but the above are
-guaranteed to exist.
-
-NOTE: If you want the adler32 or crc32 hash functions they are available in
-the zlib module.
-
-Choose your hash function wisely. Some have known collision weaknesses.
-sha384 and sha512 will be slow on 32 bit platforms.
-
-Hash objects have these methods:
- - update(arg): Update the hash object with the string arg. Repeated calls
- are equivalent to a single call with the concatenation of all
- the arguments.
- - digest(): Return the digest of the strings passed to the update() method
- so far. This may contain non-ASCII characters, including
- NUL bytes.
- - hexdigest(): Like digest() except the digest is returned as a string of
- double length, containing only hexadecimal digits.
- - copy(): Return a copy (clone) of the hash object. This can be used to
- efficiently compute the digests of strings that share a common
- initial substring.
-
-For example, to obtain the digest of the string 'Nobody inspects the
-spammish repetition':
-
- >>> import hashlib
- >>> m = hashlib.md5()
- >>> m.update("Nobody inspects")
- >>> m.update(" the spammish repetition")
- >>> m.digest()
- '\\xbbd\\x9c\\x83\\xdd\\x1e\\xa5\\xc9\\xd9\\xde\\xc9\\xa1\\x8d\\xf0\\xff\\xe9'
-
-More condensed:
-
- >>> hashlib.sha224("Nobody inspects the spammish repetition").hexdigest()
- 'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
-
-"""
-
-# This tuple and __get_builtin_constructor() must be modified if a new
-# always available algorithm is added.
-__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
-
-algorithms = __always_supported
-
-__all__ = __always_supported + ('new', 'algorithms')
-
-
-def __get_builtin_constructor(name):
- if name in ('SHA1', 'sha1'):
- from distutils2._backport import _sha
- return _sha.new
- elif name in ('MD5', 'md5'):
- from distutils2._backport import _md5
- return _md5.new
- elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'):
- from distutils2._backport import _sha256
- bs = name[3:]
- if bs == '256':
- return _sha256.sha256
- elif bs == '224':
- return _sha256.sha224
- elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'):
- from distutils2._backport import _sha512
- bs = name[3:]
- if bs == '512':
- return _sha512.sha512
- elif bs == '384':
- return _sha512.sha384
-
- raise ValueError('unsupported hash type %s' % name)
-
-
-def __get_openssl_constructor(name):
- try:
- f = getattr(_hashlib, 'openssl_' + name)
- # Allow the C module to raise ValueError. The function will be
- # defined but the hash not actually available thanks to OpenSSL.
- f()
- # Use the C function directly (very fast)
- return f
- except (AttributeError, ValueError):
- return __get_builtin_constructor(name)
-
-
-def __py_new(name, string=''):
- """new(name, string='') - Return a new hashing object using the named algorithm;
- optionally initialized with a string.
- """
- return __get_builtin_constructor(name)(string)
-
-
-def __hash_new(name, string=''):
- """new(name, string='') - Return a new hashing object using the named algorithm;
- optionally initialized with a string.
- """
- try:
- return _hashlib.new(name, string)
- except ValueError:
- # If the _hashlib module (OpenSSL) doesn't support the named
- # hash, try using our builtin implementations.
- # This allows for SHA224/256 and SHA384/512 support even though
- # the OpenSSL library prior to 0.9.8 doesn't provide them.
- return __get_builtin_constructor(name)(string)
-
-
-try:
- from distutils2._backport import _hashlib
- new = __hash_new
- __get_hash = __get_openssl_constructor
-except ImportError:
- new = __py_new
- __get_hash = __get_builtin_constructor
-
-for __func_name in __always_supported:
- # try them all, some may not work due to the OpenSSL
- # version not supporting that algorithm.
- try:
- globals()[__func_name] = __get_hash(__func_name)
- except ValueError:
- import logging
- logging.exception('code for hash %s was not found.', __func_name)
-
-# Cleanup locals()
-del __always_supported, __func_name, __get_hash
-del __py_new, __hash_new, __get_openssl_constructor
diff --git a/distutils2/_backport/md5.c b/distutils2/_backport/md5.c
deleted file mode 100644
index c35d96c..0000000
--- a/distutils2/_backport/md5.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.c is L. Peter Deutsch
- <ghost@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
- either statically or dynamically; added missing #include <string.h>
- in library.
- 2002-03-11 lpd Corrected argument list for main(), and added int return
- type, in test program and T value program.
- 2002-02-21 lpd Added missing #include <stdio.h> in test program.
- 2000-07-03 lpd Patched to eliminate warnings about "constant is
- unsigned in ANSI C, signed in traditional"; made test program
- self-checking.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
- 1999-05-03 lpd Original version.
- */
-
-#include "md5.h"
-#include <string.h>
-
-#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
-#ifdef ARCH_IS_BIG_ENDIAN
-# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
-#else
-# define BYTE_ORDER 0
-#endif
-
-#define T_MASK ((md5_word_t)~0)
-#define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87)
-#define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9)
-#define T3 0x242070db
-#define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111)
-#define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050)
-#define T6 0x4787c62a
-#define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec)
-#define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe)
-#define T9 0x698098d8
-#define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850)
-#define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e)
-#define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841)
-#define T13 0x6b901122
-#define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c)
-#define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71)
-#define T16 0x49b40821
-#define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d)
-#define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf)
-#define T19 0x265e5a51
-#define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855)
-#define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2)
-#define T22 0x02441453
-#define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e)
-#define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437)
-#define T25 0x21e1cde6
-#define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829)
-#define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278)
-#define T28 0x455a14ed
-#define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa)
-#define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07)
-#define T31 0x676f02d9
-#define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375)
-#define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd)
-#define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e)
-#define T35 0x6d9d6122
-#define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3)
-#define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb)
-#define T38 0x4bdecfa9
-#define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f)
-#define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f)
-#define T41 0x289b7ec6
-#define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805)
-#define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a)
-#define T44 0x04881d05
-#define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6)
-#define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a)
-#define T47 0x1fa27cf8
-#define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a)
-#define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb)
-#define T50 0x432aff97
-#define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58)
-#define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6)
-#define T53 0x655b59c3
-#define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d)
-#define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82)
-#define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e)
-#define T57 0x6fa87e4f
-#define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f)
-#define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb)
-#define T60 0x4e0811a1
-#define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d)
-#define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca)
-#define T63 0x2ad7d2bb
-#define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e)
-
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
- md5_word_t
- a = pms->abcd[0], b = pms->abcd[1],
- c = pms->abcd[2], d = pms->abcd[3];
- md5_word_t t;
-#if BYTE_ORDER > 0
- /* Define storage only for big-endian CPUs. */
- md5_word_t X[16];
-#else
- /* Define storage for little-endian or both types of CPUs. */
- md5_word_t xbuf[16];
- const md5_word_t *X;
-#endif
-
- {
-#if BYTE_ORDER == 0
- /*
- * Determine dynamically whether this is a big-endian or
- * little-endian machine, since we can use a more efficient
- * algorithm on the latter.
- */
- static const int w = 1;
-
- if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
-#endif
-#if BYTE_ORDER <= 0 /* little-endian */
- {
- /*
- * On little-endian machines, we can process properly aligned
- * data without copying it.
- */
- if (!((data - (const md5_byte_t *)0) & 3)) {
- /* data are properly aligned */
- X = (const md5_word_t *)data;
- } else {
- /* not aligned */
- memcpy(xbuf, data, 64);
- X = xbuf;
- }
- }
-#endif
-#if BYTE_ORDER == 0
- else /* dynamic big-endian */
-#endif
-#if BYTE_ORDER >= 0 /* big-endian */
- {
- /*
- * On big-endian machines, we must arrange the bytes in the
- * right order.
- */
- const md5_byte_t *xp = data;
- int i;
-
-# if BYTE_ORDER == 0
- X = xbuf; /* (dynamic only) */
-# else
-# define xbuf X /* (static only) */
-# endif
- for (i = 0; i < 16; ++i, xp += 4)
- xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
- }
-#endif
- }
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
- /* Round 1. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + F(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 7, T1);
- SET(d, a, b, c, 1, 12, T2);
- SET(c, d, a, b, 2, 17, T3);
- SET(b, c, d, a, 3, 22, T4);
- SET(a, b, c, d, 4, 7, T5);
- SET(d, a, b, c, 5, 12, T6);
- SET(c, d, a, b, 6, 17, T7);
- SET(b, c, d, a, 7, 22, T8);
- SET(a, b, c, d, 8, 7, T9);
- SET(d, a, b, c, 9, 12, T10);
- SET(c, d, a, b, 10, 17, T11);
- SET(b, c, d, a, 11, 22, T12);
- SET(a, b, c, d, 12, 7, T13);
- SET(d, a, b, c, 13, 12, T14);
- SET(c, d, a, b, 14, 17, T15);
- SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
- /* Round 2. */
- /* Let [abcd k s i] denote the operation
- a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + G(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 1, 5, T17);
- SET(d, a, b, c, 6, 9, T18);
- SET(c, d, a, b, 11, 14, T19);
- SET(b, c, d, a, 0, 20, T20);
- SET(a, b, c, d, 5, 5, T21);
- SET(d, a, b, c, 10, 9, T22);
- SET(c, d, a, b, 15, 14, T23);
- SET(b, c, d, a, 4, 20, T24);
- SET(a, b, c, d, 9, 5, T25);
- SET(d, a, b, c, 14, 9, T26);
- SET(c, d, a, b, 3, 14, T27);
- SET(b, c, d, a, 8, 20, T28);
- SET(a, b, c, d, 13, 5, T29);
- SET(d, a, b, c, 2, 9, T30);
- SET(c, d, a, b, 7, 14, T31);
- SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
- /* Round 3. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + H(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 5, 4, T33);
- SET(d, a, b, c, 8, 11, T34);
- SET(c, d, a, b, 11, 16, T35);
- SET(b, c, d, a, 14, 23, T36);
- SET(a, b, c, d, 1, 4, T37);
- SET(d, a, b, c, 4, 11, T38);
- SET(c, d, a, b, 7, 16, T39);
- SET(b, c, d, a, 10, 23, T40);
- SET(a, b, c, d, 13, 4, T41);
- SET(d, a, b, c, 0, 11, T42);
- SET(c, d, a, b, 3, 16, T43);
- SET(b, c, d, a, 6, 23, T44);
- SET(a, b, c, d, 9, 4, T45);
- SET(d, a, b, c, 12, 11, T46);
- SET(c, d, a, b, 15, 16, T47);
- SET(b, c, d, a, 2, 23, T48);
-#undef SET
-
- /* Round 4. */
- /* Let [abcd k s t] denote the operation
- a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
- t = a + I(b,c,d) + X[k] + Ti;\
- a = ROTATE_LEFT(t, s) + b
- /* Do the following 16 operations. */
- SET(a, b, c, d, 0, 6, T49);
- SET(d, a, b, c, 7, 10, T50);
- SET(c, d, a, b, 14, 15, T51);
- SET(b, c, d, a, 5, 21, T52);
- SET(a, b, c, d, 12, 6, T53);
- SET(d, a, b, c, 3, 10, T54);
- SET(c, d, a, b, 10, 15, T55);
- SET(b, c, d, a, 1, 21, T56);
- SET(a, b, c, d, 8, 6, T57);
- SET(d, a, b, c, 15, 10, T58);
- SET(c, d, a, b, 6, 15, T59);
- SET(b, c, d, a, 13, 21, T60);
- SET(a, b, c, d, 4, 6, T61);
- SET(d, a, b, c, 11, 10, T62);
- SET(c, d, a, b, 2, 15, T63);
- SET(b, c, d, a, 9, 21, T64);
-#undef SET
-
- /* Then perform the following additions. (That is increment each
- of the four registers by the value it had before this block
- was started.) */
- pms->abcd[0] += a;
- pms->abcd[1] += b;
- pms->abcd[2] += c;
- pms->abcd[3] += d;
-}
-
-void
-md5_init(md5_state_t *pms)
-{
- pms->count[0] = pms->count[1] = 0;
- pms->abcd[0] = 0x67452301;
- pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476;
- pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301;
- pms->abcd[3] = 0x10325476;
-}
-
-void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
- const md5_byte_t *p = data;
- int left = nbytes;
- int offset = (pms->count[0] >> 3) & 63;
- md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
- if (nbytes <= 0)
- return;
-
- /* Update the message length. */
- pms->count[1] += nbytes >> 29;
- pms->count[0] += nbits;
- if (pms->count[0] < nbits)
- pms->count[1]++;
-
- /* Process an initial partial block. */
- if (offset) {
- int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
- memcpy(pms->buf + offset, p, copy);
- if (offset + copy < 64)
- return;
- p += copy;
- left -= copy;
- md5_process(pms, pms->buf);
- }
-
- /* Process full blocks. */
- for (; left >= 64; p += 64, left -= 64)
- md5_process(pms, p);
-
- /* Process a final partial block. */
- if (left)
- memcpy(pms->buf, p, left);
-}
-
-void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
- static const md5_byte_t pad[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- md5_byte_t data[8];
- int i;
-
- /* Save the length before padding. */
- for (i = 0; i < 8; ++i)
- data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
- /* Pad to 56 bytes mod 64. */
- md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
- /* Append the length. */
- md5_append(pms, data, 8);
- for (i = 0; i < 16; ++i)
- digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
diff --git a/distutils2/_backport/md5.h b/distutils2/_backport/md5.h
deleted file mode 100644
index 1718401..0000000
--- a/distutils2/_backport/md5.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved.
-
- This software is provided 'as-is', without any express or implied
- warranty. In no event will the authors be held liable for any damages
- arising from the use of this software.
-
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it
- freely, subject to the following restrictions:
-
- 1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
-
- L. Peter Deutsch
- ghost@aladdin.com
-
- */
-/* $Id: md5.h 43594 2006-04-03 16:27:50Z matthias.klose $ */
-/*
- Independent implementation of MD5 (RFC 1321).
-
- This code implements the MD5 Algorithm defined in RFC 1321, whose
- text is available at
- http://www.ietf.org/rfc/rfc1321.txt
- The code is derived from the text of the RFC, including the test suite
- (section A.5) but excluding the rest of Appendix A. It does not include
- any code or documentation that is identified in the RFC as being
- copyrighted.
-
- The original and principal author of md5.h is L. Peter Deutsch
- <ghost@aladdin.com>. Other authors are noted in the change history
- that follows (in reverse chronological order):
-
- 2002-04-13 lpd Removed support for non-ANSI compilers; removed
- references to Ghostscript; clarified derivation from RFC 1321;
- now handles byte order either statically or dynamically.
- 1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
- 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
- added conditionalization for C++ compilation from Martin
- Purschke <purschke@bnl.gov>.
- 1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-# define md5_INCLUDED
-
-/*
- * This package supports both compile-time and run-time determination of CPU
- * byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
- * compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
- * defined as non-zero, the code will be compiled to run only on big-endian
- * CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
- * run on either big- or little-endian CPUs, but will run slightly less
- * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
- md5_word_t count[2]; /* message length in bits, lsw first */
- md5_word_t abcd[4]; /* digest buffer */
- md5_byte_t buf[64]; /* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/* Initialize the algorithm. */
-void md5_init(md5_state_t *pms);
-
-/* Append a string to the message. */
-void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-
-/* Finish the message and return the digest. */
-void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-
-#ifdef __cplusplus
-} /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
diff --git a/distutils2/_backport/md5module.c b/distutils2/_backport/md5module.c
deleted file mode 100644
index 5e4f116..0000000
--- a/distutils2/_backport/md5module.c
+++ /dev/null
@@ -1,312 +0,0 @@
-
-/* MD5 module */
-
-/* This module provides an interface to the RSA Data Security,
- Inc. MD5 Message-Digest Algorithm, described in RFC 1321.
- It requires the files md5c.c and md5.h (which are slightly changed
- from the versions in the RFC to avoid the "global.h" file.) */
-
-
-/* MD5 objects */
-
-#include "Python.h"
-#include "structmember.h"
-#include "md5.h"
-
-typedef struct {
- PyObject_HEAD
- md5_state_t md5; /* the context holder */
-} md5object;
-
-static PyTypeObject MD5type;
-
-#define is_md5object(v) ((v)->ob_type == &MD5type)
-
-static md5object *
-newmd5object(void)
-{
- md5object *md5p;
-
- md5p = PyObject_New(md5object, &MD5type);
- if (md5p == NULL)
- return NULL;
-
- md5_init(&md5p->md5); /* actual initialisation */
- return md5p;
-}
-
-
-/* MD5 methods */
-
-static void
-md5_dealloc(md5object *md5p)
-{
- PyObject_Del(md5p);
-}
-
-
-/* MD5 methods-as-attributes */
-
-static PyObject *
-md5_update(md5object *self, PyObject *args)
-{
- unsigned char *cp;
- int len;
-
- if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
- return NULL;
-
- md5_append(&self->md5, cp, len);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(update_doc,
-"update (arg)\n\
-\n\
-Update the md5 object with the string arg. Repeated calls are\n\
-equivalent to a single call with the concatenation of all the\n\
-arguments.");
-
-
-static PyObject *
-md5_digest(md5object *self)
-{
- md5_state_t mdContext;
- unsigned char aDigest[16];
-
- /* make a temporary copy, and perform the final */
- mdContext = self->md5;
- md5_finish(&mdContext, aDigest);
-
- return PyString_FromStringAndSize((char *)aDigest, 16);
-}
-
-PyDoc_STRVAR(digest_doc,
-"digest() -> string\n\
-\n\
-Return the digest of the strings passed to the update() method so\n\
-far. This is a 16-byte string which may contain non-ASCII characters,\n\
-including null bytes.");
-
-
-static PyObject *
-md5_hexdigest(md5object *self)
-{
- md5_state_t mdContext;
- unsigned char digest[16];
- unsigned char hexdigest[32];
- int i, j;
-
- /* make a temporary copy, and perform the final */
- mdContext = self->md5;
- md5_finish(&mdContext, digest);
-
- /* Make hex version of the digest */
- for(i=j=0; i<16; i++) {
- char c;
- c = (digest[i] >> 4) & 0xf;
- c = (c>9) ? c+'a'-10 : c + '0';
- hexdigest[j++] = c;
- c = (digest[i] & 0xf);
- c = (c>9) ? c+'a'-10 : c + '0';
- hexdigest[j++] = c;
- }
- return PyString_FromStringAndSize((char*)hexdigest, 32);
-}
-
-
-PyDoc_STRVAR(hexdigest_doc,
-"hexdigest() -> string\n\
-\n\
-Like digest(), but returns the digest as a string of hexadecimal digits.");
-
-
-static PyObject *
-md5_copy(md5object *self)
-{
- md5object *md5p;
-
- if ((md5p = newmd5object()) == NULL)
- return NULL;
-
- md5p->md5 = self->md5;
-
- return (PyObject *)md5p;
-}
-
-PyDoc_STRVAR(copy_doc,
-"copy() -> md5 object\n\
-\n\
-Return a copy (``clone'') of the md5 object.");
-
-
-static PyMethodDef md5_methods[] = {
- {"update", (PyCFunction)md5_update, METH_VARARGS, update_doc},
- {"digest", (PyCFunction)md5_digest, METH_NOARGS, digest_doc},
- {"hexdigest", (PyCFunction)md5_hexdigest, METH_NOARGS, hexdigest_doc},
- {"copy", (PyCFunction)md5_copy, METH_NOARGS, copy_doc},
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-md5_get_block_size(PyObject *self, void *closure)
-{
- return PyInt_FromLong(64);
-}
-
-static PyObject *
-md5_get_digest_size(PyObject *self, void *closure)
-{
- return PyInt_FromLong(16);
-}
-
-static PyObject *
-md5_get_name(PyObject *self, void *closure)
-{
- return PyString_FromStringAndSize("MD5", 3);
-}
-
-static PyGetSetDef md5_getseters[] = {
- {"digest_size",
- (getter)md5_get_digest_size, NULL,
- NULL,
- NULL},
- {"block_size",
- (getter)md5_get_block_size, NULL,
- NULL,
- NULL},
- {"name",
- (getter)md5_get_name, NULL,
- NULL,
- NULL},
- /* the old md5 and sha modules support 'digest_size' as in PEP 247.
- * the old sha module also supported 'digestsize'. ugh. */
- {"digestsize",
- (getter)md5_get_digest_size, NULL,
- NULL,
- NULL},
- {NULL} /* Sentinel */
-};
-
-
-PyDoc_STRVAR(module_doc,
-"This module implements the interface to RSA's MD5 message digest\n\
-algorithm (see also Internet RFC 1321). Its use is quite\n\
-straightforward: use the new() to create an md5 object. You can now\n\
-feed this object with arbitrary strings using the update() method, and\n\
-at any point you can ask it for the digest (a strong kind of 128-bit\n\
-checksum, a.k.a. ``fingerprint'') of the concatenation of the strings\n\
-fed to it so far using the digest() method.\n\
-\n\
-Functions:\n\
-\n\
-new([arg]) -- return a new md5 object, initialized with arg if provided\n\
-md5([arg]) -- DEPRECATED, same as new, but for compatibility\n\
-\n\
-Special Objects:\n\
-\n\
-MD5Type -- type object for md5 objects");
-
-PyDoc_STRVAR(md5type_doc,
-"An md5 represents the object used to calculate the MD5 checksum of a\n\
-string of information.\n\
-\n\
-Methods:\n\
-\n\
-update() -- updates the current digest with an additional string\n\
-digest() -- return the current digest value\n\
-hexdigest() -- return the current digest as a string of hexadecimal digits\n\
-copy() -- return a copy of the current md5 object");
-
-static PyTypeObject MD5type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "_md5.md5", /*tp_name*/
- sizeof(md5object), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)md5_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- md5type_doc, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- md5_methods, /*tp_methods*/
- 0, /*tp_members*/
- md5_getseters, /*tp_getset*/
-};
-
-
-/* MD5 functions */
-
-static PyObject *
-MD5_new(PyObject *self, PyObject *args)
-{
- md5object *md5p;
- unsigned char *cp = NULL;
- int len = 0;
-
- if (!PyArg_ParseTuple(args, "|s#:new", &cp, &len))
- return NULL;
-
- if ((md5p = newmd5object()) == NULL)
- return NULL;
-
- if (cp)
- md5_append(&md5p->md5, cp, len);
-
- return (PyObject *)md5p;
-}
-
-PyDoc_STRVAR(new_doc,
-"new([arg]) -> md5 object\n\
-\n\
-Return a new md5 object. If arg is present, the method call update(arg)\n\
-is made.");
-
-
-/* List of functions exported by this module */
-
-static PyMethodDef md5_functions[] = {
- {"new", (PyCFunction)MD5_new, METH_VARARGS, new_doc},
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-
-PyMODINIT_FUNC
-init_md5(void)
-{
- PyObject *m, *d;
-
- MD5type.ob_type = &PyType_Type;
- if (PyType_Ready(&MD5type) < 0)
- return;
- m = Py_InitModule3("_md5", md5_functions, module_doc);
- if (m == NULL)
- return;
- d = PyModule_GetDict(m);
- PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
- PyModule_AddIntConstant(m, "digest_size", 16);
- /* No need to check the error here, the caller will do that */
-}
diff --git a/distutils2/_backport/sha256module.c b/distutils2/_backport/sha256module.c
deleted file mode 100644
index 96cbd10..0000000
--- a/distutils2/_backport/sha256module.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/* SHA256 module */
-
-/* This module provides an interface to NIST's SHA-256 and SHA-224 Algorithms */
-
-/* See below for information about the original code this module was
- based upon. Additional work performed by:
-
- Andrew Kuchling (amk@amk.ca)
- Greg Stein (gstein@lyra.org)
- Trevor Perrin (trevp@trevp.net)
-
- Copyright (C) 2005 Gregory P. Smith (greg@krypto.org)
- Licensed to PSF under a Contributor Agreement.
-
-*/
-
-/* SHA objects */
-
-#include "Python.h"
-#include "structmember.h"
-
-
-/* Endianness testing and definitions */
-#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
- if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
-
-#define PCT_LITTLE_ENDIAN 1
-#define PCT_BIG_ENDIAN 0
-
-/* Some useful types */
-
-typedef unsigned char SHA_BYTE;
-
-#if SIZEOF_INT == 4
-typedef unsigned int SHA_INT32; /* 32-bit integer */
-#else
-/* not defined. compilation will die. */
-#endif
-
-/* The SHA block size and message digest sizes, in bytes */
-
-#define SHA_BLOCKSIZE 64
-#define SHA_DIGESTSIZE 32
-
-/* The structure for storing SHA info */
-
-typedef struct {
- PyObject_HEAD
- SHA_INT32 digest[8]; /* Message digest */
- SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
- SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
- int Endianness;
- int local; /* unprocessed amount in data */
- int digestsize;
-} SHAobject;
-
-/* When run on a little-endian CPU we need to perform byte reversal on an
- array of longwords. */
-
-static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
-{
- SHA_INT32 value;
-
- if ( Endianness == PCT_BIG_ENDIAN )
- return;
-
- byteCount /= sizeof(*buffer);
- while (byteCount--) {
- value = *buffer;
- value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
- ( ( value & 0x00FF00FFL ) << 8 );
- *buffer++ = ( value << 16 ) | ( value >> 16 );
- }
-}
-
-static void SHAcopy(SHAobject *src, SHAobject *dest)
-{
- dest->Endianness = src->Endianness;
- dest->local = src->local;
- dest->digestsize = src->digestsize;
- dest->count_lo = src->count_lo;
- dest->count_hi = src->count_hi;
- memcpy(dest->digest, src->digest, sizeof(src->digest));
- memcpy(dest->data, src->data, sizeof(src->data));
-}
-
-
-/* ------------------------------------------------------------------------
- *
- * This code for the SHA-256 algorithm was noted as public domain. The
- * original headers are pasted below.
- *
- * Several changes have been made to make it more compatible with the
- * Python environment and desired interface.
- *
- */
-
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * gurantee it works.
- *
- * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
- */
-
-
-/* SHA256 by Tom St Denis */
-
-/* Various logical functions */
-#define ROR(x, y)\
-( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \
-((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
-#define Ch(x,y,z) (z ^ (x & (y ^ z)))
-#define Maj(x,y,z) (((x | y) & z) | (x & y))
-#define S(x, n) ROR((x),(n))
-#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
-#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
-#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
-#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
-#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
-
-
-static void
-sha_transform(SHAobject *sha_info)
-{
- int i;
- SHA_INT32 S[8], W[64], t0, t1;
-
- memcpy(W, sha_info->data, sizeof(sha_info->data));
- longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
-
- for (i = 16; i < 64; ++i) {
- W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
- }
- for (i = 0; i < 8; ++i) {
- S[i] = sha_info->digest[i];
- }
-
- /* Compress */
-#define RND(a,b,c,d,e,f,g,h,i,ki) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c); \
- d += t0; \
- h = t0 + t1;
-
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
-
-#undef RND
-
- /* feedback */
- for (i = 0; i < 8; i++) {
- sha_info->digest[i] = sha_info->digest[i] + S[i];
- }
-
-}
-
-
-
-/* initialize the SHA digest */
-
-static void
-sha_init(SHAobject *sha_info)
-{
- TestEndianness(sha_info->Endianness)
- sha_info->digest[0] = 0x6A09E667L;
- sha_info->digest[1] = 0xBB67AE85L;
- sha_info->digest[2] = 0x3C6EF372L;
- sha_info->digest[3] = 0xA54FF53AL;
- sha_info->digest[4] = 0x510E527FL;
- sha_info->digest[5] = 0x9B05688CL;
- sha_info->digest[6] = 0x1F83D9ABL;
- sha_info->digest[7] = 0x5BE0CD19L;
- sha_info->count_lo = 0L;
- sha_info->count_hi = 0L;
- sha_info->local = 0;
- sha_info->digestsize = 32;
-}
-
-static void
-sha224_init(SHAobject *sha_info)
-{
- TestEndianness(sha_info->Endianness)
- sha_info->digest[0] = 0xc1059ed8L;
- sha_info->digest[1] = 0x367cd507L;
- sha_info->digest[2] = 0x3070dd17L;
- sha_info->digest[3] = 0xf70e5939L;
- sha_info->digest[4] = 0xffc00b31L;
- sha_info->digest[5] = 0x68581511L;
- sha_info->digest[6] = 0x64f98fa7L;
- sha_info->digest[7] = 0xbefa4fa4L;
- sha_info->count_lo = 0L;
- sha_info->count_hi = 0L;
- sha_info->local = 0;
- sha_info->digestsize = 28;
-}
-
-
-/* update the SHA digest */
-
-static void
-sha_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
-{
- int i;
- SHA_INT32 clo;
-
- clo = sha_info->count_lo + ((SHA_INT32) count << 3);
- if (clo < sha_info->count_lo) {
- ++sha_info->count_hi;
- }
- sha_info->count_lo = clo;
- sha_info->count_hi += (SHA_INT32) count >> 29;
- if (sha_info->local) {
- i = SHA_BLOCKSIZE - sha_info->local;
- if (i > count) {
- i = count;
- }
- memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
- count -= i;
- buffer += i;
- sha_info->local += i;
- if (sha_info->local == SHA_BLOCKSIZE) {
- sha_transform(sha_info);
- }
- else {
- return;
- }
- }
- while (count >= SHA_BLOCKSIZE) {
- memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
- buffer += SHA_BLOCKSIZE;
- count -= SHA_BLOCKSIZE;
- sha_transform(sha_info);
- }
- memcpy(sha_info->data, buffer, count);
- sha_info->local = count;
-}
-
-/* finish computing the SHA digest */
-
-static void
-sha_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
-{
- int count;
- SHA_INT32 lo_bit_count, hi_bit_count;
-
- lo_bit_count = sha_info->count_lo;
- hi_bit_count = sha_info->count_hi;
- count = (int) ((lo_bit_count >> 3) & 0x3f);
- ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
- if (count > SHA_BLOCKSIZE - 8) {
- memset(((SHA_BYTE *) sha_info->data) + count, 0,
- SHA_BLOCKSIZE - count);
- sha_transform(sha_info);
- memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
- }
- else {
- memset(((SHA_BYTE *) sha_info->data) + count, 0,
- SHA_BLOCKSIZE - 8 - count);
- }
-
- /* GJS: note that we add the hi/lo in big-endian. sha_transform will
- swap these values into host-order. */
- sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
- sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
- sha_info->data[58] = (hi_bit_count >> 8) & 0xff;
- sha_info->data[59] = (hi_bit_count >> 0) & 0xff;
- sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
- sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
- sha_info->data[62] = (lo_bit_count >> 8) & 0xff;
- sha_info->data[63] = (lo_bit_count >> 0) & 0xff;
- sha_transform(sha_info);
- digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
- digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
- digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
- digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
- digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
- digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
- digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
- digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
- digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
- digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
- digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
- digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
- digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
- digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
- digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
- digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
- digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
- digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
- digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
- digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
- digest[20] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
- digest[21] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
- digest[22] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff);
- digest[23] = (unsigned char) ((sha_info->digest[5] ) & 0xff);
- digest[24] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
- digest[25] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
- digest[26] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff);
- digest[27] = (unsigned char) ((sha_info->digest[6] ) & 0xff);
- digest[28] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
- digest[29] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
- digest[30] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff);
- digest[31] = (unsigned char) ((sha_info->digest[7] ) & 0xff);
-}
-
-/*
- * End of copied SHA code.
- *
- * ------------------------------------------------------------------------
- */
-
-static PyTypeObject SHA224type;
-static PyTypeObject SHA256type;
-
-
-static SHAobject *
-newSHA224object(void)
-{
- return (SHAobject *)PyObject_New(SHAobject, &SHA224type);
-}
-
-static SHAobject *
-newSHA256object(void)
-{
- return (SHAobject *)PyObject_New(SHAobject, &SHA256type);
-}
-
-/* Internal methods for a hash object */
-
-static void
-SHA_dealloc(PyObject *ptr)
-{
- PyObject_Del(ptr);
-}
-
-
-/* External methods for a hash object */
-
-PyDoc_STRVAR(SHA256_copy__doc__, "Return a copy of the hash object.");
-
-static PyObject *
-SHA256_copy(SHAobject *self, PyObject *unused)
-{
- SHAobject *newobj;
-
- if (((PyObject*)self)->ob_type == &SHA256type) {
- if ( (newobj = newSHA256object())==NULL)
- return NULL;
- } else {
- if ( (newobj = newSHA224object())==NULL)
- return NULL;
- }
-
- SHAcopy(self, newobj);
- return (PyObject *)newobj;
-}
-
-PyDoc_STRVAR(SHA256_digest__doc__,
-"Return the digest value as a string of binary data.");
-
-static PyObject *
-SHA256_digest(SHAobject *self, PyObject *unused)
-{
- unsigned char digest[SHA_DIGESTSIZE];
- SHAobject temp;
-
- SHAcopy(self, &temp);
- sha_final(digest, &temp);
- return PyString_FromStringAndSize((const char *)digest, self->digestsize);
-}
-
-PyDoc_STRVAR(SHA256_hexdigest__doc__,
-"Return the digest value as a string of hexadecimal digits.");
-
-static PyObject *
-SHA256_hexdigest(SHAobject *self, PyObject *unused)
-{
- unsigned char digest[SHA_DIGESTSIZE];
- SHAobject temp;
- PyObject *retval;
- char *hex_digest;
- int i, j;
-
- /* Get the raw (binary) digest value */
- SHAcopy(self, &temp);
- sha_final(digest, &temp);
-
- /* Create a new string */
- retval = PyString_FromStringAndSize(NULL, self->digestsize * 2);
- if (!retval)
- return NULL;
- hex_digest = PyString_AsString(retval);
- if (!hex_digest) {
- Py_DECREF(retval);
- return NULL;
- }
-
- /* Make hex version of the digest */
- for(i=j=0; i<self->digestsize; i++) {
- char c;
- c = (digest[i] >> 4) & 0xf;
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- c = (digest[i] & 0xf);
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- }
- return retval;
-}
-
-PyDoc_STRVAR(SHA256_update__doc__,
-"Update this hash object's state with the provided string.");
-
-static PyObject *
-SHA256_update(SHAobject *self, PyObject *args)
-{
- unsigned char *cp;
- int len;
-
- if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
- return NULL;
-
- sha_update(self, cp, len);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef SHA_methods[] = {
- {"copy", (PyCFunction)SHA256_copy, METH_NOARGS, SHA256_copy__doc__},
- {"digest", (PyCFunction)SHA256_digest, METH_NOARGS, SHA256_digest__doc__},
- {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_NOARGS, SHA256_hexdigest__doc__},
- {"update", (PyCFunction)SHA256_update, METH_VARARGS, SHA256_update__doc__},
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-SHA256_get_block_size(PyObject *self, void *closure)
-{
- return PyInt_FromLong(SHA_BLOCKSIZE);
-}
-
-static PyObject *
-SHA256_get_name(PyObject *self, void *closure)
-{
- if (((SHAobject *)self)->digestsize == 32)
- return PyString_FromStringAndSize("SHA256", 6);
- else
- return PyString_FromStringAndSize("SHA224", 6);
-}
-
-static PyGetSetDef SHA_getseters[] = {
- {"block_size",
- (getter)SHA256_get_block_size, NULL,
- NULL,
- NULL},
- {"name",
- (getter)SHA256_get_name, NULL,
- NULL,
- NULL},
- {NULL} /* Sentinel */
-};
-
-static PyMemberDef SHA_members[] = {
- {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
- /* the old md5 and sha modules support 'digest_size' as in PEP 247.
- * the old sha module also supported 'digestsize'. ugh. */
- {"digestsize", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject SHA224type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "_sha256.sha224", /*tp_name*/
- sizeof(SHAobject), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- SHA_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- SHA_methods, /* tp_methods */
- SHA_members, /* tp_members */
- SHA_getseters, /* tp_getset */
-};
-
-static PyTypeObject SHA256type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "_sha256.sha256", /*tp_name*/
- sizeof(SHAobject), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- SHA_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- SHA_methods, /* tp_methods */
- SHA_members, /* tp_members */
- SHA_getseters, /* tp_getset */
-};
-
-
-/* The single module-level function: new() */
-
-PyDoc_STRVAR(SHA256_new__doc__,
-"Return a new SHA-256 hash object; optionally initialized with a string.");
-
-static PyObject *
-SHA256_new(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- static char *kwlist[] = {"string", NULL};
- SHAobject *new;
- unsigned char *cp = NULL;
- int len;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
- &cp, &len)) {
- return NULL;
- }
-
- if ((new = newSHA256object()) == NULL)
- return NULL;
-
- sha_init(new);
-
- if (PyErr_Occurred()) {
- Py_DECREF(new);
- return NULL;
- }
- if (cp)
- sha_update(new, cp, len);
-
- return (PyObject *)new;
-}
-
-PyDoc_STRVAR(SHA224_new__doc__,
-"Return a new SHA-224 hash object; optionally initialized with a string.");
-
-static PyObject *
-SHA224_new(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- static char *kwlist[] = {"string", NULL};
- SHAobject *new;
- unsigned char *cp = NULL;
- int len;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
- &cp, &len)) {
- return NULL;
- }
-
- if ((new = newSHA224object()) == NULL)
- return NULL;
-
- sha224_init(new);
-
- if (PyErr_Occurred()) {
- Py_DECREF(new);
- return NULL;
- }
- if (cp)
- sha_update(new, cp, len);
-
- return (PyObject *)new;
-}
-
-
-/* List of functions exported by this module */
-
-static struct PyMethodDef SHA_functions[] = {
- {"sha256", (PyCFunction)SHA256_new, METH_VARARGS|METH_KEYWORDS, SHA256_new__doc__},
- {"sha224", (PyCFunction)SHA224_new, METH_VARARGS|METH_KEYWORDS, SHA224_new__doc__},
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-
-#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
-
-PyMODINIT_FUNC
-init_sha256(void)
-{
- PyObject *m;
-
- SHA224type.ob_type = &PyType_Type;
- if (PyType_Ready(&SHA224type) < 0)
- return;
- SHA256type.ob_type = &PyType_Type;
- if (PyType_Ready(&SHA256type) < 0)
- return;
- m = Py_InitModule("_sha256", SHA_functions);
- if (m == NULL)
- return;
-}
diff --git a/distutils2/_backport/sha512module.c b/distutils2/_backport/sha512module.c
deleted file mode 100644
index dbaec17..0000000
--- a/distutils2/_backport/sha512module.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/* SHA512 module */
-
-/* This module provides an interface to NIST's SHA-512 and SHA-384 Algorithms */
-
-/* See below for information about the original code this module was
- based upon. Additional work performed by:
-
- Andrew Kuchling (amk@amk.ca)
- Greg Stein (gstein@lyra.org)
- Trevor Perrin (trevp@trevp.net)
-
- Copyright (C) 2005 Gregory P. Smith (greg@krypto.org)
- Licensed to PSF under a Contributor Agreement.
-
-*/
-
-/* SHA objects */
-
-#include "Python.h"
-#include "structmember.h"
-
-#ifdef PY_LONG_LONG /* If no PY_LONG_LONG, don't compile anything! */
-
-/* Endianness testing and definitions */
-#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
- if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
-
-#define PCT_LITTLE_ENDIAN 1
-#define PCT_BIG_ENDIAN 0
-
-/* Some useful types */
-
-typedef unsigned char SHA_BYTE;
-
-#if SIZEOF_INT == 4
-typedef unsigned int SHA_INT32; /* 32-bit integer */
-typedef unsigned PY_LONG_LONG SHA_INT64; /* 64-bit integer */
-#else
-/* not defined. compilation will die. */
-#endif
-
-/* The SHA block size and message digest sizes, in bytes */
-
-#define SHA_BLOCKSIZE 128
-#define SHA_DIGESTSIZE 64
-
-/* The structure for storing SHA info */
-
-typedef struct {
- PyObject_HEAD
- SHA_INT64 digest[8]; /* Message digest */
- SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
- SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
- int Endianness;
- int local; /* unprocessed amount in data */
- int digestsize;
-} SHAobject;
-
-/* When run on a little-endian CPU we need to perform byte reversal on an
- array of longwords. */
-
-static void longReverse(SHA_INT64 *buffer, int byteCount, int Endianness)
-{
- SHA_INT64 value;
-
- if ( Endianness == PCT_BIG_ENDIAN )
- return;
-
- byteCount /= sizeof(*buffer);
- while (byteCount--) {
- value = *buffer;
-
- ((unsigned char*)buffer)[0] = (unsigned char)(value >> 56) & 0xff;
- ((unsigned char*)buffer)[1] = (unsigned char)(value >> 48) & 0xff;
- ((unsigned char*)buffer)[2] = (unsigned char)(value >> 40) & 0xff;
- ((unsigned char*)buffer)[3] = (unsigned char)(value >> 32) & 0xff;
- ((unsigned char*)buffer)[4] = (unsigned char)(value >> 24) & 0xff;
- ((unsigned char*)buffer)[5] = (unsigned char)(value >> 16) & 0xff;
- ((unsigned char*)buffer)[6] = (unsigned char)(value >> 8) & 0xff;
- ((unsigned char*)buffer)[7] = (unsigned char)(value ) & 0xff;
-
- buffer++;
- }
-}
-
-static void SHAcopy(SHAobject *src, SHAobject *dest)
-{
- dest->Endianness = src->Endianness;
- dest->local = src->local;
- dest->digestsize = src->digestsize;
- dest->count_lo = src->count_lo;
- dest->count_hi = src->count_hi;
- memcpy(dest->digest, src->digest, sizeof(src->digest));
- memcpy(dest->data, src->data, sizeof(src->data));
-}
-
-
-/* ------------------------------------------------------------------------
- *
- * This code for the SHA-512 algorithm was noted as public domain. The
- * original headers are pasted below.
- *
- * Several changes have been made to make it more compatible with the
- * Python environment and desired interface.
- *
- */
-
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * gurantee it works.
- *
- * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
- */
-
-
-/* SHA512 by Tom St Denis */
-
-/* Various logical functions */
-#define ROR64(x, y) \
- ( ((((x) & 0xFFFFFFFFFFFFFFFFULL)>>((unsigned PY_LONG_LONG)(y) & 63)) | \
- ((x)<<((unsigned PY_LONG_LONG)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFFULL)
-#define Ch(x,y,z) (z ^ (x & (y ^ z)))
-#define Maj(x,y,z) (((x | y) & z) | (x & y))
-#define S(x, n) ROR64((x),(n))
-#define R(x, n) (((x) & 0xFFFFFFFFFFFFFFFFULL) >> ((unsigned PY_LONG_LONG)n))
-#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
-#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
-#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
-#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
-
-
-static void
-sha512_transform(SHAobject *sha_info)
-{
- int i;
- SHA_INT64 S[8], W[80], t0, t1;
-
- memcpy(W, sha_info->data, sizeof(sha_info->data));
- longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
-
- for (i = 16; i < 80; ++i) {
- W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
- }
- for (i = 0; i < 8; ++i) {
- S[i] = sha_info->digest[i];
- }
-
- /* Compress */
-#define RND(a,b,c,d,e,f,g,h,i,ki) \
- t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
- t1 = Sigma0(a) + Maj(a, b, c); \
- d += t0; \
- h = t0 + t1;
-
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98d728ae22ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cdULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2fULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbcULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9bULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbeULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28cULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896fULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfabULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213fULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826fULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffcULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aedULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3dfULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63deULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353bULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202aULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acbULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3ULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fcULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72ULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ecULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915ULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532bULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619cULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1eULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178ULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fbaULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6ULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90daeULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471bULL);
- RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84ULL);
- RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493ULL);
- RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebcULL);
- RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4cULL);
- RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6ULL);
- RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2aULL);
- RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faecULL);
- RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817ULL);
-
-#undef RND
-
- /* feedback */
- for (i = 0; i < 8; i++) {
- sha_info->digest[i] = sha_info->digest[i] + S[i];
- }
-
-}
-
-
-
-/* initialize the SHA digest */
-
-static void
-sha512_init(SHAobject *sha_info)
-{
- TestEndianness(sha_info->Endianness)
- sha_info->digest[0] = 0x6a09e667f3bcc908ULL;
- sha_info->digest[1] = 0xbb67ae8584caa73bULL;
- sha_info->digest[2] = 0x3c6ef372fe94f82bULL;
- sha_info->digest[3] = 0xa54ff53a5f1d36f1ULL;
- sha_info->digest[4] = 0x510e527fade682d1ULL;
- sha_info->digest[5] = 0x9b05688c2b3e6c1fULL;
- sha_info->digest[6] = 0x1f83d9abfb41bd6bULL;
- sha_info->digest[7] = 0x5be0cd19137e2179ULL;
- sha_info->count_lo = 0L;
- sha_info->count_hi = 0L;
- sha_info->local = 0;
- sha_info->digestsize = 64;
-}
-
-static void
-sha384_init(SHAobject *sha_info)
-{
- TestEndianness(sha_info->Endianness)
- sha_info->digest[0] = 0xcbbb9d5dc1059ed8ULL;
- sha_info->digest[1] = 0x629a292a367cd507ULL;
- sha_info->digest[2] = 0x9159015a3070dd17ULL;
- sha_info->digest[3] = 0x152fecd8f70e5939ULL;
- sha_info->digest[4] = 0x67332667ffc00b31ULL;
- sha_info->digest[5] = 0x8eb44a8768581511ULL;
- sha_info->digest[6] = 0xdb0c2e0d64f98fa7ULL;
- sha_info->digest[7] = 0x47b5481dbefa4fa4ULL;
- sha_info->count_lo = 0L;
- sha_info->count_hi = 0L;
- sha_info->local = 0;
- sha_info->digestsize = 48;
-}
-
-
-/* update the SHA digest */
-
-static void
-sha512_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
-{
- int i;
- SHA_INT32 clo;
-
- clo = sha_info->count_lo + ((SHA_INT32) count << 3);
- if (clo < sha_info->count_lo) {
- ++sha_info->count_hi;
- }
- sha_info->count_lo = clo;
- sha_info->count_hi += (SHA_INT32) count >> 29;
- if (sha_info->local) {
- i = SHA_BLOCKSIZE - sha_info->local;
- if (i > count) {
- i = count;
- }
- memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
- count -= i;
- buffer += i;
- sha_info->local += i;
- if (sha_info->local == SHA_BLOCKSIZE) {
- sha512_transform(sha_info);
- }
- else {
- return;
- }
- }
- while (count >= SHA_BLOCKSIZE) {
- memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
- buffer += SHA_BLOCKSIZE;
- count -= SHA_BLOCKSIZE;
- sha512_transform(sha_info);
- }
- memcpy(sha_info->data, buffer, count);
- sha_info->local = count;
-}
-
-/* finish computing the SHA digest */
-
-static void
-sha512_final(unsigned char digest[SHA_DIGESTSIZE], SHAobject *sha_info)
-{
- int count;
- SHA_INT32 lo_bit_count, hi_bit_count;
-
- lo_bit_count = sha_info->count_lo;
- hi_bit_count = sha_info->count_hi;
- count = (int) ((lo_bit_count >> 3) & 0x7f);
- ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
- if (count > SHA_BLOCKSIZE - 16) {
- memset(((SHA_BYTE *) sha_info->data) + count, 0,
- SHA_BLOCKSIZE - count);
- sha512_transform(sha_info);
- memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 16);
- }
- else {
- memset(((SHA_BYTE *) sha_info->data) + count, 0,
- SHA_BLOCKSIZE - 16 - count);
- }
-
- /* GJS: note that we add the hi/lo in big-endian. sha512_transform will
- swap these values into host-order. */
- sha_info->data[112] = 0;
- sha_info->data[113] = 0;
- sha_info->data[114] = 0;
- sha_info->data[115] = 0;
- sha_info->data[116] = 0;
- sha_info->data[117] = 0;
- sha_info->data[118] = 0;
- sha_info->data[119] = 0;
- sha_info->data[120] = (hi_bit_count >> 24) & 0xff;
- sha_info->data[121] = (hi_bit_count >> 16) & 0xff;
- sha_info->data[122] = (hi_bit_count >> 8) & 0xff;
- sha_info->data[123] = (hi_bit_count >> 0) & 0xff;
- sha_info->data[124] = (lo_bit_count >> 24) & 0xff;
- sha_info->data[125] = (lo_bit_count >> 16) & 0xff;
- sha_info->data[126] = (lo_bit_count >> 8) & 0xff;
- sha_info->data[127] = (lo_bit_count >> 0) & 0xff;
- sha512_transform(sha_info);
- digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 56) & 0xff);
- digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 48) & 0xff);
- digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 40) & 0xff);
- digest[ 3] = (unsigned char) ((sha_info->digest[0] >> 32) & 0xff);
- digest[ 4] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
- digest[ 5] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
- digest[ 6] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
- digest[ 7] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
- digest[ 8] = (unsigned char) ((sha_info->digest[1] >> 56) & 0xff);
- digest[ 9] = (unsigned char) ((sha_info->digest[1] >> 48) & 0xff);
- digest[10] = (unsigned char) ((sha_info->digest[1] >> 40) & 0xff);
- digest[11] = (unsigned char) ((sha_info->digest[1] >> 32) & 0xff);
- digest[12] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
- digest[13] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
- digest[14] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
- digest[15] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
- digest[16] = (unsigned char) ((sha_info->digest[2] >> 56) & 0xff);
- digest[17] = (unsigned char) ((sha_info->digest[2] >> 48) & 0xff);
- digest[18] = (unsigned char) ((sha_info->digest[2] >> 40) & 0xff);
- digest[19] = (unsigned char) ((sha_info->digest[2] >> 32) & 0xff);
- digest[20] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
- digest[21] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
- digest[22] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
- digest[23] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
- digest[24] = (unsigned char) ((sha_info->digest[3] >> 56) & 0xff);
- digest[25] = (unsigned char) ((sha_info->digest[3] >> 48) & 0xff);
- digest[26] = (unsigned char) ((sha_info->digest[3] >> 40) & 0xff);
- digest[27] = (unsigned char) ((sha_info->digest[3] >> 32) & 0xff);
- digest[28] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
- digest[29] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
- digest[30] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
- digest[31] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
- digest[32] = (unsigned char) ((sha_info->digest[4] >> 56) & 0xff);
- digest[33] = (unsigned char) ((sha_info->digest[4] >> 48) & 0xff);
- digest[34] = (unsigned char) ((sha_info->digest[4] >> 40) & 0xff);
- digest[35] = (unsigned char) ((sha_info->digest[4] >> 32) & 0xff);
- digest[36] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
- digest[37] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
- digest[38] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
- digest[39] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
- digest[40] = (unsigned char) ((sha_info->digest[5] >> 56) & 0xff);
- digest[41] = (unsigned char) ((sha_info->digest[5] >> 48) & 0xff);
- digest[42] = (unsigned char) ((sha_info->digest[5] >> 40) & 0xff);
- digest[43] = (unsigned char) ((sha_info->digest[5] >> 32) & 0xff);
- digest[44] = (unsigned char) ((sha_info->digest[5] >> 24) & 0xff);
- digest[45] = (unsigned char) ((sha_info->digest[5] >> 16) & 0xff);
- digest[46] = (unsigned char) ((sha_info->digest[5] >> 8) & 0xff);
- digest[47] = (unsigned char) ((sha_info->digest[5] ) & 0xff);
- digest[48] = (unsigned char) ((sha_info->digest[6] >> 56) & 0xff);
- digest[49] = (unsigned char) ((sha_info->digest[6] >> 48) & 0xff);
- digest[50] = (unsigned char) ((sha_info->digest[6] >> 40) & 0xff);
- digest[51] = (unsigned char) ((sha_info->digest[6] >> 32) & 0xff);
- digest[52] = (unsigned char) ((sha_info->digest[6] >> 24) & 0xff);
- digest[53] = (unsigned char) ((sha_info->digest[6] >> 16) & 0xff);
- digest[54] = (unsigned char) ((sha_info->digest[6] >> 8) & 0xff);
- digest[55] = (unsigned char) ((sha_info->digest[6] ) & 0xff);
- digest[56] = (unsigned char) ((sha_info->digest[7] >> 56) & 0xff);
- digest[57] = (unsigned char) ((sha_info->digest[7] >> 48) & 0xff);
- digest[58] = (unsigned char) ((sha_info->digest[7] >> 40) & 0xff);
- digest[59] = (unsigned char) ((sha_info->digest[7] >> 32) & 0xff);
- digest[60] = (unsigned char) ((sha_info->digest[7] >> 24) & 0xff);
- digest[61] = (unsigned char) ((sha_info->digest[7] >> 16) & 0xff);
- digest[62] = (unsigned char) ((sha_info->digest[7] >> 8) & 0xff);
- digest[63] = (unsigned char) ((sha_info->digest[7] ) & 0xff);
-}
-
-/*
- * End of copied SHA code.
- *
- * ------------------------------------------------------------------------
- */
-
-static PyTypeObject SHA384type;
-static PyTypeObject SHA512type;
-
-
-static SHAobject *
-newSHA384object(void)
-{
- return (SHAobject *)PyObject_New(SHAobject, &SHA384type);
-}
-
-static SHAobject *
-newSHA512object(void)
-{
- return (SHAobject *)PyObject_New(SHAobject, &SHA512type);
-}
-
-/* Internal methods for a hash object */
-
-static void
-SHA512_dealloc(PyObject *ptr)
-{
- PyObject_Del(ptr);
-}
-
-
-/* External methods for a hash object */
-
-PyDoc_STRVAR(SHA512_copy__doc__, "Return a copy of the hash object.");
-
-static PyObject *
-SHA512_copy(SHAobject *self, PyObject *unused)
-{
- SHAobject *newobj;
-
- if (((PyObject*)self)->ob_type == &SHA512type) {
- if ( (newobj = newSHA512object())==NULL)
- return NULL;
- } else {
- if ( (newobj = newSHA384object())==NULL)
- return NULL;
- }
-
- SHAcopy(self, newobj);
- return (PyObject *)newobj;
-}
-
-PyDoc_STRVAR(SHA512_digest__doc__,
-"Return the digest value as a string of binary data.");
-
-static PyObject *
-SHA512_digest(SHAobject *self, PyObject *unused)
-{
- unsigned char digest[SHA_DIGESTSIZE];
- SHAobject temp;
-
- SHAcopy(self, &temp);
- sha512_final(digest, &temp);
- return PyString_FromStringAndSize((const char *)digest, self->digestsize);
-}
-
-PyDoc_STRVAR(SHA512_hexdigest__doc__,
-"Return the digest value as a string of hexadecimal digits.");
-
-static PyObject *
-SHA512_hexdigest(SHAobject *self, PyObject *unused)
-{
- unsigned char digest[SHA_DIGESTSIZE];
- SHAobject temp;
- PyObject *retval;
- char *hex_digest;
- int i, j;
-
- /* Get the raw (binary) digest value */
- SHAcopy(self, &temp);
- sha512_final(digest, &temp);
-
- /* Create a new string */
- retval = PyString_FromStringAndSize(NULL, self->digestsize * 2);
- if (!retval)
- return NULL;
- hex_digest = PyString_AsString(retval);
- if (!hex_digest) {
- Py_DECREF(retval);
- return NULL;
- }
-
- /* Make hex version of the digest */
- for (i=j=0; i<self->digestsize; i++) {
- char c;
- c = (digest[i] >> 4) & 0xf;
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- c = (digest[i] & 0xf);
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- }
- return retval;
-}
-
-PyDoc_STRVAR(SHA512_update__doc__,
-"Update this hash object's state with the provided string.");
-
-static PyObject *
-SHA512_update(SHAobject *self, PyObject *args)
-{
- unsigned char *cp;
- int len;
-
- if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
- return NULL;
-
- sha512_update(self, cp, len);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef SHA_methods[] = {
- {"copy", (PyCFunction)SHA512_copy, METH_NOARGS, SHA512_copy__doc__},
- {"digest", (PyCFunction)SHA512_digest, METH_NOARGS, SHA512_digest__doc__},
- {"hexdigest", (PyCFunction)SHA512_hexdigest, METH_NOARGS, SHA512_hexdigest__doc__},
- {"update", (PyCFunction)SHA512_update, METH_VARARGS, SHA512_update__doc__},
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-SHA512_get_block_size(PyObject *self, void *closure)
-{
- return PyInt_FromLong(SHA_BLOCKSIZE);
-}
-
-static PyObject *
-SHA512_get_name(PyObject *self, void *closure)
-{
- if (((SHAobject *)self)->digestsize == 64)
- return PyString_FromStringAndSize("SHA512", 6);
- else
- return PyString_FromStringAndSize("SHA384", 6);
-}
-
-static PyGetSetDef SHA_getseters[] = {
- {"block_size",
- (getter)SHA512_get_block_size, NULL,
- NULL,
- NULL},
- {"name",
- (getter)SHA512_get_name, NULL,
- NULL,
- NULL},
- {NULL} /* Sentinel */
-};
-
-static PyMemberDef SHA_members[] = {
- {"digest_size", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
- /* the old md5 and sha modules support 'digest_size' as in PEP 247.
- * the old sha module also supported 'digestsize'. ugh. */
- {"digestsize", T_INT, offsetof(SHAobject, digestsize), READONLY, NULL},
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject SHA384type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "_sha512.sha384", /*tp_name*/
- sizeof(SHAobject), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- SHA512_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- SHA_methods, /* tp_methods */
- SHA_members, /* tp_members */
- SHA_getseters, /* tp_getset */
-};
-
-static PyTypeObject SHA512type = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "_sha512.sha512", /*tp_name*/
- sizeof(SHAobject), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- SHA512_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- SHA_methods, /* tp_methods */
- SHA_members, /* tp_members */
- SHA_getseters, /* tp_getset */
-};
-
-
-/* The single module-level function: new() */
-
-PyDoc_STRVAR(SHA512_new__doc__,
-"Return a new SHA-512 hash object; optionally initialized with a string.");
-
-static PyObject *
-SHA512_new(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- static char *kwlist[] = {"string", NULL};
- SHAobject *new;
- unsigned char *cp = NULL;
- int len;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
- &cp, &len)) {
- return NULL;
- }
-
- if ((new = newSHA512object()) == NULL)
- return NULL;
-
- sha512_init(new);
-
- if (PyErr_Occurred()) {
- Py_DECREF(new);
- return NULL;
- }
- if (cp)
- sha512_update(new, cp, len);
-
- return (PyObject *)new;
-}
-
-PyDoc_STRVAR(SHA384_new__doc__,
-"Return a new SHA-384 hash object; optionally initialized with a string.");
-
-static PyObject *
-SHA384_new(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- static char *kwlist[] = {"string", NULL};
- SHAobject *new;
- unsigned char *cp = NULL;
- int len;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
- &cp, &len)) {
- return NULL;
- }
-
- if ((new = newSHA384object()) == NULL)
- return NULL;
-
- sha384_init(new);
-
- if (PyErr_Occurred()) {
- Py_DECREF(new);
- return NULL;
- }
- if (cp)
- sha512_update(new, cp, len);
-
- return (PyObject *)new;
-}
-
-
-/* List of functions exported by this module */
-
-static struct PyMethodDef SHA_functions[] = {
- {"sha512", (PyCFunction)SHA512_new, METH_VARARGS|METH_KEYWORDS, SHA512_new__doc__},
- {"sha384", (PyCFunction)SHA384_new, METH_VARARGS|METH_KEYWORDS, SHA384_new__doc__},
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-
-#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
-
-PyMODINIT_FUNC
-init_sha512(void)
-{
- PyObject *m;
-
- SHA384type.ob_type = &PyType_Type;
- if (PyType_Ready(&SHA384type) < 0)
- return;
- SHA512type.ob_type = &PyType_Type;
- if (PyType_Ready(&SHA512type) < 0)
- return;
- m = Py_InitModule("_sha512", SHA_functions);
- if (m == NULL)
- return;
-}
-
-#endif
diff --git a/distutils2/_backport/shamodule.c b/distutils2/_backport/shamodule.c
deleted file mode 100644
index 171dfa1..0000000
--- a/distutils2/_backport/shamodule.c
+++ /dev/null
@@ -1,593 +0,0 @@
-/* SHA module */
-
-/* This module provides an interface to NIST's Secure Hash Algorithm */
-
-/* See below for information about the original code this module was
- based upon. Additional work performed by:
-
- Andrew Kuchling (amk@amk.ca)
- Greg Stein (gstein@lyra.org)
-
- Copyright (C) 2005 Gregory P. Smith (greg@krypto.org)
- Licensed to PSF under a Contributor Agreement.
-
-*/
-
-/* SHA objects */
-
-#include "Python.h"
-#include "structmember.h"
-
-
-/* Endianness testing and definitions */
-#define TestEndianness(variable) {int i=1; variable=PCT_BIG_ENDIAN;\
- if (*((char*)&i)==1) variable=PCT_LITTLE_ENDIAN;}
-
-#define PCT_LITTLE_ENDIAN 1
-#define PCT_BIG_ENDIAN 0
-
-/* Some useful types */
-
-typedef unsigned char SHA_BYTE;
-
-#if SIZEOF_INT == 4
-typedef unsigned int SHA_INT32; /* 32-bit integer */
-#else
-/* not defined. compilation will die. */
-#endif
-
-/* The SHA block size and message digest sizes, in bytes */
-
-#define SHA_BLOCKSIZE 64
-#define SHA_DIGESTSIZE 20
-
-/* The structure for storing SHS info */
-
-typedef struct {
- PyObject_HEAD
- SHA_INT32 digest[5]; /* Message digest */
- SHA_INT32 count_lo, count_hi; /* 64-bit bit count */
- SHA_BYTE data[SHA_BLOCKSIZE]; /* SHA data buffer */
- int Endianness;
- int local; /* unprocessed amount in data */
-} SHAobject;
-
-/* When run on a little-endian CPU we need to perform byte reversal on an
- array of longwords. */
-
-static void longReverse(SHA_INT32 *buffer, int byteCount, int Endianness)
-{
- SHA_INT32 value;
-
- if ( Endianness == PCT_BIG_ENDIAN )
- return;
-
- byteCount /= sizeof(*buffer);
- while (byteCount--) {
- value = *buffer;
- value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
- ( ( value & 0x00FF00FFL ) << 8 );
- *buffer++ = ( value << 16 ) | ( value >> 16 );
- }
-}
-
-static void SHAcopy(SHAobject *src, SHAobject *dest)
-{
- dest->Endianness = src->Endianness;
- dest->local = src->local;
- dest->count_lo = src->count_lo;
- dest->count_hi = src->count_hi;
- memcpy(dest->digest, src->digest, sizeof(src->digest));
- memcpy(dest->data, src->data, sizeof(src->data));
-}
-
-
-/* ------------------------------------------------------------------------
- *
- * This code for the SHA algorithm was noted as public domain. The original
- * headers are pasted below.
- *
- * Several changes have been made to make it more compatible with the
- * Python environment and desired interface.
- *
- */
-
-/* NIST Secure Hash Algorithm */
-/* heavily modified by Uwe Hollerbach <uh@alumni.caltech edu> */
-/* from Peter C. Gutmann's implementation as found in */
-/* Applied Cryptography by Bruce Schneier */
-/* Further modifications to include the "UNRAVEL" stuff, below */
-
-/* This code is in the public domain */
-
-/* UNRAVEL should be fastest & biggest */
-/* UNROLL_LOOPS should be just as big, but slightly slower */
-/* both undefined should be smallest and slowest */
-
-#define UNRAVEL
-/* #define UNROLL_LOOPS */
-
-/* The SHA f()-functions. The f1 and f3 functions can be optimized to
- save one boolean operation each - thanks to Rich Schroeppel,
- rcs@cs.arizona.edu for discovering this */
-
-/*#define f1(x,y,z) ((x & y) | (~x & z)) // Rounds 0-19 */
-#define f1(x,y,z) (z ^ (x & (y ^ z))) /* Rounds 0-19 */
-#define f2(x,y,z) (x ^ y ^ z) /* Rounds 20-39 */
-/*#define f3(x,y,z) ((x & y) | (x & z) | (y & z)) // Rounds 40-59 */
-#define f3(x,y,z) ((x & y) | (z & (x | y))) /* Rounds 40-59 */
-#define f4(x,y,z) (x ^ y ^ z) /* Rounds 60-79 */
-
-/* SHA constants */
-
-#define CONST1 0x5a827999L /* Rounds 0-19 */
-#define CONST2 0x6ed9eba1L /* Rounds 20-39 */
-#define CONST3 0x8f1bbcdcL /* Rounds 40-59 */
-#define CONST4 0xca62c1d6L /* Rounds 60-79 */
-
-/* 32-bit rotate */
-
-#define R32(x,n) ((x << n) | (x >> (32 - n)))
-
-/* the generic case, for when the overall rotation is not unraveled */
-
-#define FG(n) \
- T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n; \
- E = D; D = C; C = R32(B,30); B = A; A = T
-
-/* specific cases, for when the overall rotation is unraveled */
-
-#define FA(n) \
- T = R32(A,5) + f##n(B,C,D) + E + *WP++ + CONST##n; B = R32(B,30)
-
-#define FB(n) \
- E = R32(T,5) + f##n(A,B,C) + D + *WP++ + CONST##n; A = R32(A,30)
-
-#define FC(n) \
- D = R32(E,5) + f##n(T,A,B) + C + *WP++ + CONST##n; T = R32(T,30)
-
-#define FD(n) \
- C = R32(D,5) + f##n(E,T,A) + B + *WP++ + CONST##n; E = R32(E,30)
-
-#define FE(n) \
- B = R32(C,5) + f##n(D,E,T) + A + *WP++ + CONST##n; D = R32(D,30)
-
-#define FT(n) \
- A = R32(B,5) + f##n(C,D,E) + T + *WP++ + CONST##n; C = R32(C,30)
-
-/* do SHA transformation */
-
-static void
-sha_transform(SHAobject *sha_info)
-{
- int i;
- SHA_INT32 T, A, B, C, D, E, W[80], *WP;
-
- memcpy(W, sha_info->data, sizeof(sha_info->data));
- longReverse(W, (int)sizeof(sha_info->data), sha_info->Endianness);
-
- for (i = 16; i < 80; ++i) {
- W[i] = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
-
- /* extra rotation fix */
- W[i] = R32(W[i], 1);
- }
- A = sha_info->digest[0];
- B = sha_info->digest[1];
- C = sha_info->digest[2];
- D = sha_info->digest[3];
- E = sha_info->digest[4];
- WP = W;
-#ifdef UNRAVEL
- FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1); FC(1); FD(1);
- FE(1); FT(1); FA(1); FB(1); FC(1); FD(1); FE(1); FT(1); FA(1); FB(1);
- FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2); FE(2); FT(2);
- FA(2); FB(2); FC(2); FD(2); FE(2); FT(2); FA(2); FB(2); FC(2); FD(2);
- FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3); FA(3); FB(3);
- FC(3); FD(3); FE(3); FT(3); FA(3); FB(3); FC(3); FD(3); FE(3); FT(3);
- FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4); FC(4); FD(4);
- FE(4); FT(4); FA(4); FB(4); FC(4); FD(4); FE(4); FT(4); FA(4); FB(4);
- sha_info->digest[0] += E;
- sha_info->digest[1] += T;
- sha_info->digest[2] += A;
- sha_info->digest[3] += B;
- sha_info->digest[4] += C;
-#else /* !UNRAVEL */
-#ifdef UNROLL_LOOPS
- FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
- FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1); FG(1);
- FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
- FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2); FG(2);
- FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
- FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3); FG(3);
- FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
- FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4); FG(4);
-#else /* !UNROLL_LOOPS */
- for (i = 0; i < 20; ++i) { FG(1); }
- for (i = 20; i < 40; ++i) { FG(2); }
- for (i = 40; i < 60; ++i) { FG(3); }
- for (i = 60; i < 80; ++i) { FG(4); }
-#endif /* !UNROLL_LOOPS */
- sha_info->digest[0] += A;
- sha_info->digest[1] += B;
- sha_info->digest[2] += C;
- sha_info->digest[3] += D;
- sha_info->digest[4] += E;
-#endif /* !UNRAVEL */
-}
-
-/* initialize the SHA digest */
-
-static void
-sha_init(SHAobject *sha_info)
-{
- TestEndianness(sha_info->Endianness)
-
- sha_info->digest[0] = 0x67452301L;
- sha_info->digest[1] = 0xefcdab89L;
- sha_info->digest[2] = 0x98badcfeL;
- sha_info->digest[3] = 0x10325476L;
- sha_info->digest[4] = 0xc3d2e1f0L;
- sha_info->count_lo = 0L;
- sha_info->count_hi = 0L;
- sha_info->local = 0;
-}
-
-/* update the SHA digest */
-
-static void
-sha_update(SHAobject *sha_info, SHA_BYTE *buffer, int count)
-{
- int i;
- SHA_INT32 clo;
-
- clo = sha_info->count_lo + ((SHA_INT32) count << 3);
- if (clo < sha_info->count_lo) {
- ++sha_info->count_hi;
- }
- sha_info->count_lo = clo;
- sha_info->count_hi += (SHA_INT32) count >> 29;
- if (sha_info->local) {
- i = SHA_BLOCKSIZE - sha_info->local;
- if (i > count) {
- i = count;
- }
- memcpy(((SHA_BYTE *) sha_info->data) + sha_info->local, buffer, i);
- count -= i;
- buffer += i;
- sha_info->local += i;
- if (sha_info->local == SHA_BLOCKSIZE) {
- sha_transform(sha_info);
- }
- else {
- return;
- }
- }
- while (count >= SHA_BLOCKSIZE) {
- memcpy(sha_info->data, buffer, SHA_BLOCKSIZE);
- buffer += SHA_BLOCKSIZE;
- count -= SHA_BLOCKSIZE;
- sha_transform(sha_info);
- }
- memcpy(sha_info->data, buffer, count);
- sha_info->local = count;
-}
-
-/* finish computing the SHA digest */
-
-static void
-sha_final(unsigned char digest[20], SHAobject *sha_info)
-{
- int count;
- SHA_INT32 lo_bit_count, hi_bit_count;
-
- lo_bit_count = sha_info->count_lo;
- hi_bit_count = sha_info->count_hi;
- count = (int) ((lo_bit_count >> 3) & 0x3f);
- ((SHA_BYTE *) sha_info->data)[count++] = 0x80;
- if (count > SHA_BLOCKSIZE - 8) {
- memset(((SHA_BYTE *) sha_info->data) + count, 0,
- SHA_BLOCKSIZE - count);
- sha_transform(sha_info);
- memset((SHA_BYTE *) sha_info->data, 0, SHA_BLOCKSIZE - 8);
- }
- else {
- memset(((SHA_BYTE *) sha_info->data) + count, 0,
- SHA_BLOCKSIZE - 8 - count);
- }
-
- /* GJS: note that we add the hi/lo in big-endian. sha_transform will
- swap these values into host-order. */
- sha_info->data[56] = (hi_bit_count >> 24) & 0xff;
- sha_info->data[57] = (hi_bit_count >> 16) & 0xff;
- sha_info->data[58] = (hi_bit_count >> 8) & 0xff;
- sha_info->data[59] = (hi_bit_count >> 0) & 0xff;
- sha_info->data[60] = (lo_bit_count >> 24) & 0xff;
- sha_info->data[61] = (lo_bit_count >> 16) & 0xff;
- sha_info->data[62] = (lo_bit_count >> 8) & 0xff;
- sha_info->data[63] = (lo_bit_count >> 0) & 0xff;
- sha_transform(sha_info);
- digest[ 0] = (unsigned char) ((sha_info->digest[0] >> 24) & 0xff);
- digest[ 1] = (unsigned char) ((sha_info->digest[0] >> 16) & 0xff);
- digest[ 2] = (unsigned char) ((sha_info->digest[0] >> 8) & 0xff);
- digest[ 3] = (unsigned char) ((sha_info->digest[0] ) & 0xff);
- digest[ 4] = (unsigned char) ((sha_info->digest[1] >> 24) & 0xff);
- digest[ 5] = (unsigned char) ((sha_info->digest[1] >> 16) & 0xff);
- digest[ 6] = (unsigned char) ((sha_info->digest[1] >> 8) & 0xff);
- digest[ 7] = (unsigned char) ((sha_info->digest[1] ) & 0xff);
- digest[ 8] = (unsigned char) ((sha_info->digest[2] >> 24) & 0xff);
- digest[ 9] = (unsigned char) ((sha_info->digest[2] >> 16) & 0xff);
- digest[10] = (unsigned char) ((sha_info->digest[2] >> 8) & 0xff);
- digest[11] = (unsigned char) ((sha_info->digest[2] ) & 0xff);
- digest[12] = (unsigned char) ((sha_info->digest[3] >> 24) & 0xff);
- digest[13] = (unsigned char) ((sha_info->digest[3] >> 16) & 0xff);
- digest[14] = (unsigned char) ((sha_info->digest[3] >> 8) & 0xff);
- digest[15] = (unsigned char) ((sha_info->digest[3] ) & 0xff);
- digest[16] = (unsigned char) ((sha_info->digest[4] >> 24) & 0xff);
- digest[17] = (unsigned char) ((sha_info->digest[4] >> 16) & 0xff);
- digest[18] = (unsigned char) ((sha_info->digest[4] >> 8) & 0xff);
- digest[19] = (unsigned char) ((sha_info->digest[4] ) & 0xff);
-}
-
-/*
- * End of copied SHA code.
- *
- * ------------------------------------------------------------------------
- */
-
-static PyTypeObject SHAtype;
-
-
-static SHAobject *
-newSHAobject(void)
-{
- return (SHAobject *)PyObject_New(SHAobject, &SHAtype);
-}
-
-/* Internal methods for a hashing object */
-
-static void
-SHA_dealloc(PyObject *ptr)
-{
- PyObject_Del(ptr);
-}
-
-
-/* External methods for a hashing object */
-
-PyDoc_STRVAR(SHA_copy__doc__, "Return a copy of the hashing object.");
-
-static PyObject *
-SHA_copy(SHAobject *self, PyObject *unused)
-{
- SHAobject *newobj;
-
- if ( (newobj = newSHAobject())==NULL)
- return NULL;
-
- SHAcopy(self, newobj);
- return (PyObject *)newobj;
-}
-
-PyDoc_STRVAR(SHA_digest__doc__,
-"Return the digest value as a string of binary data.");
-
-static PyObject *
-SHA_digest(SHAobject *self, PyObject *unused)
-{
- unsigned char digest[SHA_DIGESTSIZE];
- SHAobject temp;
-
- SHAcopy(self, &temp);
- sha_final(digest, &temp);
- return PyString_FromStringAndSize((const char *)digest, sizeof(digest));
-}
-
-PyDoc_STRVAR(SHA_hexdigest__doc__,
-"Return the digest value as a string of hexadecimal digits.");
-
-static PyObject *
-SHA_hexdigest(SHAobject *self, PyObject *unused)
-{
- unsigned char digest[SHA_DIGESTSIZE];
- SHAobject temp;
- PyObject *retval;
- char *hex_digest;
- int i, j;
-
- /* Get the raw (binary) digest value */
- SHAcopy(self, &temp);
- sha_final(digest, &temp);
-
- /* Create a new string */
- retval = PyString_FromStringAndSize(NULL, sizeof(digest) * 2);
- if (!retval)
- return NULL;
- hex_digest = PyString_AsString(retval);
- if (!hex_digest) {
- Py_DECREF(retval);
- return NULL;
- }
-
- /* Make hex version of the digest */
- for(i=j=0; i<sizeof(digest); i++) {
- char c;
- c = (digest[i] >> 4) & 0xf;
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- c = (digest[i] & 0xf);
- c = (c>9) ? c+'a'-10 : c + '0';
- hex_digest[j++] = c;
- }
- return retval;
-}
-
-PyDoc_STRVAR(SHA_update__doc__,
-"Update this hashing object's state with the provided string.");
-
-static PyObject *
-SHA_update(SHAobject *self, PyObject *args)
-{
- unsigned char *cp;
- int len;
-
- if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
- return NULL;
-
- sha_update(self, cp, len);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef SHA_methods[] = {
- {"copy", (PyCFunction)SHA_copy, METH_NOARGS, SHA_copy__doc__},
- {"digest", (PyCFunction)SHA_digest, METH_NOARGS, SHA_digest__doc__},
- {"hexdigest", (PyCFunction)SHA_hexdigest, METH_NOARGS, SHA_hexdigest__doc__},
- {"update", (PyCFunction)SHA_update, METH_VARARGS, SHA_update__doc__},
- {NULL, NULL} /* sentinel */
-};
-
-static PyObject *
-SHA_get_block_size(PyObject *self, void *closure)
-{
- return PyInt_FromLong(SHA_BLOCKSIZE);
-}
-
-static PyObject *
-SHA_get_digest_size(PyObject *self, void *closure)
-{
- return PyInt_FromLong(SHA_DIGESTSIZE);
-}
-
-static PyObject *
-SHA_get_name(PyObject *self, void *closure)
-{
- return PyString_FromStringAndSize("SHA1", 4);
-}
-
-static PyGetSetDef SHA_getseters[] = {
- {"digest_size",
- (getter)SHA_get_digest_size, NULL,
- NULL,
- NULL},
- {"block_size",
- (getter)SHA_get_block_size, NULL,
- NULL,
- NULL},
- {"name",
- (getter)SHA_get_name, NULL,
- NULL,
- NULL},
- /* the old md5 and sha modules support 'digest_size' as in PEP 247.
- * the old sha module also supported 'digestsize'. ugh. */
- {"digestsize",
- (getter)SHA_get_digest_size, NULL,
- NULL,
- NULL},
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject SHAtype = {
- PyObject_HEAD_INIT(NULL)
- 0, /*ob_size*/
- "_sha.sha", /*tp_name*/
- sizeof(SHAobject), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- SHA_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- SHA_methods, /* tp_methods */
- 0, /* tp_members */
- SHA_getseters, /* tp_getset */
-};
-
-
-/* The single module-level function: new() */
-
-PyDoc_STRVAR(SHA_new__doc__,
-"Return a new SHA hashing object. An optional string argument\n\
-may be provided; if present, this string will be automatically\n\
-hashed.");
-
-static PyObject *
-SHA_new(PyObject *self, PyObject *args, PyObject *kwdict)
-{
- static char *kwlist[] = {"string", NULL};
- SHAobject *new;
- unsigned char *cp = NULL;
- int len;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "|s#:new", kwlist,
- &cp, &len)) {
- return NULL;
- }
-
- if ((new = newSHAobject()) == NULL)
- return NULL;
-
- sha_init(new);
-
- if (PyErr_Occurred()) {
- Py_DECREF(new);
- return NULL;
- }
- if (cp)
- sha_update(new, cp, len);
-
- return (PyObject *)new;
-}
-
-
-/* List of functions exported by this module */
-
-static struct PyMethodDef SHA_functions[] = {
- {"new", (PyCFunction)SHA_new, METH_VARARGS|METH_KEYWORDS, SHA_new__doc__},
- {NULL, NULL} /* Sentinel */
-};
-
-
-/* Initialize this module. */
-
-#define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
-
-PyMODINIT_FUNC
-init_sha(void)
-{
- PyObject *m;
-
- SHAtype.ob_type = &PyType_Type;
- if (PyType_Ready(&SHAtype) < 0)
- return;
- m = Py_InitModule("_sha", SHA_functions);
- if (m == NULL)
- return;
-
- /* Add some symbolic constants to the module */
- insint("blocksize", 1); /* For future use, in case some hash
- functions require an integral number of
- blocks */
- insint("digestsize", 20);
- insint("digest_size", 20);
-}
diff --git a/distutils2/_backport/shutil.py b/distutils2/_backport/shutil.py
index f440a31..0b5d2e5 100644
--- a/distutils2/_backport/shutil.py
+++ b/distutils2/_backport/shutil.py
@@ -9,6 +9,7 @@ import sys
import stat
from os.path import abspath
import fnmatch
+import collections
import errno
try:
@@ -93,15 +94,9 @@ def copyfile(src, dst):
if stat.S_ISFIFO(st.st_mode):
raise SpecialFileError("`%s` is a named pipe" % fn)
- fsrc = open(src, 'rb')
- try:
- fdst = open(dst, 'wb')
- try:
+ with open(src, 'rb') as fsrc:
+ with open(dst, 'wb') as fdst:
copyfileobj(fsrc, fdst)
- finally:
- fdst.close()
- finally:
- fsrc.close()
def copymode(src, dst):
"""Copy mode bits from src to dst"""
@@ -121,7 +116,7 @@ def copystat(src, dst):
if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
try:
os.chflags(dst, st.st_flags)
- except OSError, why:
+ except OSError as why:
if (not hasattr(errno, 'EOPNOTSUPP') or
why.errno != errno.EOPNOTSUPP):
raise
@@ -204,7 +199,7 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
try:
os.makedirs(dst)
- except OSError, e:
+ except OSError as e:
if e.errno != errno.EEXIST:
raise
@@ -232,13 +227,13 @@ def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2,
copy_function(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
- except Error, err:
+ except Error as err:
errors.extend(err.args[0])
- except EnvironmentError, why:
+ except EnvironmentError as why:
errors.append((srcname, dstname, str(why)))
try:
copystat(src, dst)
- except OSError, why:
+ except OSError as why:
if WindowsError is not None and isinstance(why, WindowsError):
# Copying file access times may fail on Windows
pass
@@ -400,7 +395,7 @@ def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0,
# flags for compression program, each element of list will be an argument
if compress is not None and compress not in compress_ext:
raise ValueError("bad value for 'compress', or compression format not "
- "supported: %s" % compress)
+ "supported : {0}".format(compress))
archive_name = base_name + '.tar' + compress_ext.get(compress, '')
archive_dir = os.path.dirname(archive_name)
@@ -521,7 +516,7 @@ def get_archive_formats():
Each element of the returned sequence is a tuple (name, description)
"""
formats = [(name, registry[2]) for name, registry in
- _ARCHIVE_FORMATS.iteritems()]
+ _ARCHIVE_FORMATS.items()]
formats.sort()
return formats
@@ -536,7 +531,7 @@ def register_archive_format(name, function, extra_args=None, description=''):
"""
if extra_args is None:
extra_args = []
- if not callable(function):
+ if not isinstance(function, collections.Callable):
raise TypeError('The %s object is not callable' % function)
if not isinstance(extra_args, (tuple, list)):
raise TypeError('extra_args needs to be a sequence')
@@ -611,7 +606,7 @@ def get_unpack_formats():
(name, extensions, description)
"""
formats = [(name, info[0], info[3]) for name, info in
- _UNPACK_FORMATS.iteritems()]
+ _UNPACK_FORMATS.items()]
formats.sort()
return formats
@@ -619,7 +614,7 @@ def _check_unpack_options(extensions, function, extra_args):
"""Checks what gets registered as an unpacker."""
# first make sure no other unpacker is registered for this extension
existing_extensions = {}
- for name, info in _UNPACK_FORMATS.iteritems():
+ for name, info in _UNPACK_FORMATS.items():
for ext in info[0]:
existing_extensions[ext] = name
@@ -629,7 +624,7 @@ def _check_unpack_options(extensions, function, extra_args):
raise RegistryError(msg % (extension,
existing_extensions[extension]))
- if not callable(function):
+ if not isinstance(function, collections.Callable):
raise TypeError('The registered function must be a callable')
@@ -728,7 +723,7 @@ if _BZ2_SUPPORTED:
"bzip2'ed tar-file")
def _find_unpack_format(filename):
- for name, info in _UNPACK_FORMATS.iteritems():
+ for name, info in _UNPACK_FORMATS.items():
for extension in info[0]:
if filename.endswith(extension):
return name
@@ -756,7 +751,7 @@ def unpack_archive(filename, extract_dir=None, format=None):
try:
format_info = _UNPACK_FORMATS[format]
except KeyError:
- raise ValueError("Unknown unpack format '%s'" % format)
+ raise ValueError("Unknown unpack format '{0}'".format(format))
func = format_info[1]
func(filename, extract_dir, **dict(format_info[2]))
@@ -764,7 +759,7 @@ def unpack_archive(filename, extract_dir=None, format=None):
# we need to look at the registered unpackers supported extensions
format = _find_unpack_format(filename)
if format is None:
- raise ReadError("Unknown archive format '%s'" % filename)
+ raise ReadError("Unknown archive format '{0}'".format(filename))
func = _UNPACK_FORMATS[format][1]
kwargs = dict(_UNPACK_FORMATS[format][2])
diff --git a/distutils2/_backport/sysconfig.cfg b/distutils2/_backport/sysconfig.cfg
index 4f081ba..565c0eb 100644
--- a/distutils2/_backport/sysconfig.cfg
+++ b/distutils2/_backport/sysconfig.cfg
@@ -40,8 +40,8 @@ stdlib = {base}/lib/python{py_version_short}
platstdlib = {platbase}/lib/python{py_version_short}
purelib = {base}/lib/python{py_version_short}/site-packages
platlib = {platbase}/lib/python{py_version_short}/site-packages
-include = {base}/include/python{py_version_short}
-platinclude = {platbase}/include/python{py_version_short}
+include = {base}/include/python{py_version_short}{abiflags}
+platinclude = {platbase}/include/python{py_version_short}{abiflags}
data = {base}
[posix_home]
diff --git a/distutils2/_backport/sysconfig.py b/distutils2/_backport/sysconfig.py
index 63ff0d7..784d0a6 100644
--- a/distutils2/_backport/sysconfig.py
+++ b/distutils2/_backport/sysconfig.py
@@ -4,7 +4,7 @@ import os
import re
import sys
from os.path import pardir, realpath
-from ConfigParser import RawConfigParser
+from configparser import RawConfigParser
__all__ = [
'get_config_h_filename',
@@ -209,11 +209,8 @@ def _parse_makefile(filename, vars=None):
done = {}
notdone = {}
- f = open(filename)
- try:
+ with open(filename, errors="surrogateescape") as f:
lines = f.readlines()
- finally:
- f.close()
for line in lines:
if line.startswith('#') or line.strip() == '':
@@ -237,7 +234,7 @@ def _parse_makefile(filename, vars=None):
done[n] = v
# do variable interpolation here
- variables = notdone.keys()
+ variables = list(notdone.keys())
# Variables with a 'PY_' prefix in the makefile. These need to
# be made available without that prefix through sysconfig.
@@ -316,7 +313,10 @@ def get_makefile_filename():
"""Return the path of the Makefile."""
if _PYTHON_BUILD:
return os.path.join(_PROJECT_BASE, "Makefile")
- config_dir_name = 'config'
+ if hasattr(sys, 'abiflags'):
+ config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags)
+ else:
+ config_dir_name = 'config'
return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile')
@@ -326,7 +326,7 @@ def _init_posix(vars):
makefile = get_makefile_filename()
try:
_parse_makefile(makefile, vars)
- except IOError, e:
+ except IOError as e:
msg = "invalid Python installation: unable to open %s" % makefile
if hasattr(e, "strerror"):
msg = msg + " (%s)" % e.strerror
@@ -334,12 +334,9 @@ def _init_posix(vars):
# load the installed pyconfig.h:
config_h = get_config_h_filename()
try:
- f = open(config_h)
- try:
+ with open(config_h) as f:
parse_config_h(f, vars)
- finally:
- f.close()
- except IOError, e:
+ except IOError as e:
msg = "invalid Python installation: unable to open %s" % config_h
if hasattr(e, "strerror"):
msg = msg + " (%s)" % e.strerror
@@ -465,6 +462,11 @@ def get_config_vars(*args):
_CONFIG_VARS['base'] = _PREFIX
_CONFIG_VARS['platbase'] = _EXEC_PREFIX
_CONFIG_VARS['projectbase'] = _PROJECT_BASE
+ try:
+ _CONFIG_VARS['abiflags'] = sys.abiflags
+ except AttributeError:
+ # sys.abiflags may not be defined on all platforms.
+ _CONFIG_VARS['abiflags'] = ''
if os.name in ('nt', 'os2'):
_init_non_posix(_CONFIG_VARS)
@@ -724,13 +726,13 @@ def get_platform():
# On OSX the machine type returned by uname is always the
# 32-bit variant, even if the executable architecture is
# the 64-bit variant
- if sys.maxint >= 2**32:
+ if sys.maxsize >= 2**32:
machine = 'x86_64'
elif machine in ('PowerPC', 'Power_Macintosh'):
# Pick a sane name for the PPC architecture.
# See 'i386' case
- if sys.maxint >= 2**32:
+ if sys.maxsize >= 2**32:
machine = 'ppc64'
else:
machine = 'ppc'
@@ -745,18 +747,18 @@ def get_python_version():
def _print_dict(title, data):
for index, (key, value) in enumerate(sorted(data.items())):
if index == 0:
- print '%s: ' % (title)
- print '\t%s = "%s"' % (key, value)
+ print('%s: ' % (title))
+ print('\t%s = "%s"' % (key, value))
def _main():
"""Display all information sysconfig detains."""
- print 'Platform: "%s"' % get_platform()
- print 'Python version: "%s"' % get_python_version()
- print 'Current installation scheme: "%s"' % _get_default_scheme()
- print
+ print('Platform: "%s"' % get_platform())
+ print('Python version: "%s"' % get_python_version())
+ print('Current installation scheme: "%s"' % _get_default_scheme())
+ print()
_print_dict('Paths', get_paths())
- print
+ print()
_print_dict('Variables', get_config_vars())
diff --git a/distutils2/_backport/tarfile.py b/distutils2/_backport/tarfile.py
index 3e5d61b..4d7ad74 100644
--- a/distutils2/_backport/tarfile.py
+++ b/distutils2/_backport/tarfile.py
@@ -1,9 +1,8 @@
-#!/usr/bin/env python
-# encoding: utf-8
+#!/usr/bin/env python3
#-------------------------------------------------------------------
# tarfile.py
#-------------------------------------------------------------------
-# Copyright (C) 2002 Lars Gustäbel <lars@gustaebel.de>
+# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de>
# All rights reserved.
#
# Permission is hereby granted, free of charge, to any person
@@ -33,10 +32,10 @@
__version__ = "$Revision$"
version = "0.9.0"
-__author__ = u"Lars Gust\u00e4bel (lars@gustaebel.de)"
+__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)"
__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $"
__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $"
-__credits__ = u"Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend."
+__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend."
#---------
# Imports
@@ -68,38 +67,38 @@ except NameError:
# from tarfile import *
__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"]
-from __builtin__ import open as _open # Since 'open' is TarFile.open
+from builtins import open as _open # Since 'open' is TarFile.open
#---------------------------------------------------------
# tar constants
#---------------------------------------------------------
-NUL = "\0" # the null character
+NUL = b"\0" # the null character
BLOCKSIZE = 512 # length of processing blocks
RECORDSIZE = BLOCKSIZE * 20 # length of records
-GNU_MAGIC = "ustar \0" # magic gnu tar string
-POSIX_MAGIC = "ustar\x0000" # magic posix tar string
+GNU_MAGIC = b"ustar \0" # magic gnu tar string
+POSIX_MAGIC = b"ustar\x0000" # magic posix tar string
LENGTH_NAME = 100 # maximum length of a filename
LENGTH_LINK = 100 # maximum length of a linkname
LENGTH_PREFIX = 155 # maximum length of the prefix field
-REGTYPE = "0" # regular file
-AREGTYPE = "\0" # regular file
-LNKTYPE = "1" # link (inside tarfile)
-SYMTYPE = "2" # symbolic link
-CHRTYPE = "3" # character special device
-BLKTYPE = "4" # block special device
-DIRTYPE = "5" # directory
-FIFOTYPE = "6" # fifo special device
-CONTTYPE = "7" # contiguous file
+REGTYPE = b"0" # regular file
+AREGTYPE = b"\0" # regular file
+LNKTYPE = b"1" # link (inside tarfile)
+SYMTYPE = b"2" # symbolic link
+CHRTYPE = b"3" # character special device
+BLKTYPE = b"4" # block special device
+DIRTYPE = b"5" # directory
+FIFOTYPE = b"6" # fifo special device
+CONTTYPE = b"7" # contiguous file
-GNUTYPE_LONGNAME = "L" # GNU tar longname
-GNUTYPE_LONGLINK = "K" # GNU tar longlink
-GNUTYPE_SPARSE = "S" # GNU tar sparse file
+GNUTYPE_LONGNAME = b"L" # GNU tar longname
+GNUTYPE_LONGLINK = b"K" # GNU tar longlink
+GNUTYPE_SPARSE = b"S" # GNU tar sparse file
-XHDTYPE = "x" # POSIX.1-2001 extended header
-XGLTYPE = "g" # POSIX.1-2001 global header
-SOLARIS_XHDTYPE = "X" # Solaris extended header
+XHDTYPE = b"x" # POSIX.1-2001 extended header
+XGLTYPE = b"g" # POSIX.1-2001 global header
+SOLARIS_XHDTYPE = b"X" # Solaris extended header
USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format
GNU_FORMAT = 1 # GNU tar format
@@ -129,7 +128,7 @@ PAX_FIELDS = ("path", "linkpath", "size", "mtime",
"uid", "gid", "uname", "gname")
# Fields from a pax header that are affected by hdrcharset.
-PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname"))
+PAX_NAME_FIELDS = {"path", "linkpath", "uname", "gname"}
# Fields in a pax header that are numbers, all other fields
# are treated as strings.
@@ -145,26 +144,26 @@ PAX_NUMBER_FIELDS = {
#---------------------------------------------------------
# Bits used in the mode field, values in octal.
#---------------------------------------------------------
-S_IFLNK = 0120000 # symbolic link
-S_IFREG = 0100000 # regular file
-S_IFBLK = 0060000 # block device
-S_IFDIR = 0040000 # directory
-S_IFCHR = 0020000 # character device
-S_IFIFO = 0010000 # fifo
-
-TSUID = 04000 # set UID on execution
-TSGID = 02000 # set GID on execution
-TSVTX = 01000 # reserved
-
-TUREAD = 0400 # read by owner
-TUWRITE = 0200 # write by owner
-TUEXEC = 0100 # execute/search by owner
-TGREAD = 0040 # read by group
-TGWRITE = 0020 # write by group
-TGEXEC = 0010 # execute/search by group
-TOREAD = 0004 # read by other
-TOWRITE = 0002 # write by other
-TOEXEC = 0001 # execute/search by other
+S_IFLNK = 0o120000 # symbolic link
+S_IFREG = 0o100000 # regular file
+S_IFBLK = 0o060000 # block device
+S_IFDIR = 0o040000 # directory
+S_IFCHR = 0o020000 # character device
+S_IFIFO = 0o010000 # fifo
+
+TSUID = 0o4000 # set UID on execution
+TSGID = 0o2000 # set GID on execution
+TSVTX = 0o1000 # reserved
+
+TUREAD = 0o400 # read by owner
+TUWRITE = 0o200 # write by owner
+TUEXEC = 0o100 # execute/search by owner
+TGREAD = 0o040 # read by group
+TGWRITE = 0o020 # write by group
+TGEXEC = 0o010 # execute/search by group
+TOREAD = 0o004 # read by other
+TOWRITE = 0o002 # write by other
+TOEXEC = 0o001 # execute/search by other
#---------------------------------------------------------
# initialization
@@ -187,7 +186,7 @@ def stn(s, length, encoding, errors):
def nts(s, encoding, errors):
"""Convert a null-terminated bytes object to a string.
"""
- p = s.find("\0")
+ p = s.find(b"\0")
if p != -1:
s = s[:p]
return s.decode(encoding, errors)
@@ -197,14 +196,14 @@ def nti(s):
"""
# There are two possible encodings for a number field, see
# itn() below.
- if s[0] != chr(0200):
+ if s[0] != chr(0o200):
try:
n = int(nts(s, "ascii", "strict") or "0", 8)
except ValueError:
raise InvalidHeaderError("invalid header")
else:
- n = 0L
- for i in xrange(len(s) - 1):
+ n = 0
+ for i in range(len(s) - 1):
n <<= 8
n += ord(s[i + 1])
return n
@@ -215,11 +214,11 @@ def itn(n, digits=8, format=DEFAULT_FORMAT):
# POSIX 1003.1-1988 requires numbers to be encoded as a string of
# octal digits followed by a null-byte, this allows values up to
# (8**(digits-1))-1. GNU tar allows storing numbers greater than
- # that if necessary. A leading 0200 byte indicates this particular
+ # that if necessary. A leading 0o200 byte indicates this particular
# encoding, the following digits-1 bytes are a big-endian
# representation. This allows values up to (256**(digits-1))-1.
if 0 <= n < 8 ** (digits - 1):
- s = "%0*o" % (digits - 1, n) + NUL
+ s = bytes("%0*o" % (digits - 1, n), "ascii") + NUL
else:
if format != GNU_FORMAT or n >= 256 ** (digits - 1):
raise ValueError("overflow in number field")
@@ -229,11 +228,11 @@ def itn(n, digits=8, format=DEFAULT_FORMAT):
# this could raise OverflowError.
n = struct.unpack("L", struct.pack("l", n))[0]
- s = ""
- for i in xrange(digits - 1):
- s = chr(n & 0377) + s
+ s = bytearray()
+ for i in range(digits - 1):
+ s.insert(0, n & 0o377)
n >>= 8
- s = chr(0200) + s
+ s.insert(0, 0o200)
return s
def calc_chksums(buf):
@@ -261,7 +260,7 @@ def copyfileobj(src, dst, length=None):
BUFSIZE = 16 * 1024
blocks, remainder = divmod(length, BUFSIZE)
- for b in xrange(blocks):
+ for b in range(blocks):
buf = src.read(BUFSIZE)
if len(buf) < BUFSIZE:
raise IOError("end of file reached")
@@ -353,7 +352,7 @@ class SubsequentHeaderError(HeaderError):
#---------------------------
# internal stream interface
#---------------------------
-class _LowLevelFile(object):
+class _LowLevelFile:
"""Low-level file object. Supports reading and writing.
It is used instead of a regular file object for streaming
access.
@@ -366,7 +365,7 @@ class _LowLevelFile(object):
}[mode]
if hasattr(os, "O_BINARY"):
mode |= os.O_BINARY
- self.fd = os.open(name, mode, 0666)
+ self.fd = os.open(name, mode, 0o666)
def close(self):
os.close(self.fd)
@@ -377,7 +376,7 @@ class _LowLevelFile(object):
def write(self, s):
os.write(self.fd, s)
-class _Stream(object):
+class _Stream:
"""Class that serves as an adapter between TarFile and
a stream-like object. The stream-like object only
needs to have a read() or write() method and is accessed
@@ -407,8 +406,8 @@ class _Stream(object):
self.comptype = comptype
self.fileobj = fileobj
self.bufsize = bufsize
- self.buf = ""
- self.pos = 0L
+ self.buf = b""
+ self.pos = 0
self.closed = False
try:
@@ -418,7 +417,7 @@ class _Stream(object):
except ImportError:
raise CompressionError("zlib module is not available")
self.zlib = zlib
- self.crc = zlib.crc32("")
+ self.crc = zlib.crc32(b"")
if mode == "r":
self._init_read_gz()
else:
@@ -430,7 +429,7 @@ class _Stream(object):
except ImportError:
raise CompressionError("bz2 module is not available")
if mode == "r":
- self.dbuf = ""
+ self.dbuf = b""
self.cmp = bz2.BZ2Decompressor()
else:
self.cmp = bz2.BZ2Compressor()
@@ -451,8 +450,8 @@ class _Stream(object):
-self.zlib.MAX_WBITS,
self.zlib.DEF_MEM_LEVEL,
0)
- timestamp = struct.pack("<L", long(time.time()))
- self.__write("\037\213\010\010%s\002\377" % timestamp)
+ timestamp = struct.pack("<L", int(time.time()))
+ self.__write(b"\037\213\010\010" + timestamp + b"\002\377")
if self.name.endswith(".gz"):
self.name = self.name[:-3]
# RFC1952 says we must use ISO-8859-1 for the FNAME field.
@@ -462,7 +461,7 @@ class _Stream(object):
"""Write string s to the stream.
"""
if self.comptype == "gz":
- self.crc = self.zlib.crc32(s, self.crc) & 0xffffffffL
+ self.crc = self.zlib.crc32(s, self.crc)
self.pos += len(s)
if self.comptype != "tar":
s = self.cmp.compress(s)
@@ -489,7 +488,7 @@ class _Stream(object):
if self.mode == "w" and self.buf:
self.fileobj.write(self.buf)
- self.buf = ""
+ self.buf = b""
if self.comptype == "gz":
# The native zlib crc is an unsigned 32-bit integer, but
# the Python wrapper implicitly casts that to a signed C
@@ -497,8 +496,8 @@ class _Stream(object):
# while the same crc on a 64-bit box may "look positive".
# To avoid irksome warnings from the `struct` module, force
# it to look positive on all boxes.
- self.fileobj.write(struct.pack("<L", self.crc & 0xffffffffL))
- self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFFL))
+ self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff))
+ self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF))
if not self._extfileobj:
self.fileobj.close()
@@ -509,12 +508,12 @@ class _Stream(object):
"""Initialize for reading a gzip compressed fileobj.
"""
self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS)
- self.dbuf = ""
+ self.dbuf = b""
# taken from gzip.GzipFile with some alterations
- if self.__read(2) != "\037\213":
+ if self.__read(2) != b"\037\213":
raise ReadError("not a gzip file")
- if self.__read(1) != "\010":
+ if self.__read(1) != b"\010":
raise CompressionError("unsupported compression method")
flag = ord(self.__read(1))
@@ -547,7 +546,7 @@ class _Stream(object):
"""
if pos - self.pos >= 0:
blocks, remainder = divmod(pos - self.pos, self.bufsize)
- for i in xrange(blocks):
+ for i in range(blocks):
self.read(self.bufsize)
self.read(remainder)
else:
@@ -609,7 +608,7 @@ class _Stream(object):
return buf
# class _Stream
-class _StreamProxy(object):
+class _StreamProxy:
"""Small proxy class that enables transparent compression
detection for the Stream interface (mode 'r|*').
"""
@@ -623,9 +622,9 @@ class _StreamProxy(object):
return self.buf
def getcomptype(self):
- if self.buf.startswith("\037\213\010"):
+ if self.buf.startswith(b"\037\213\010"):
return "gz"
- if self.buf.startswith("BZh91"):
+ if self.buf.startswith(b"BZh91"):
return "bz2"
return "tar"
@@ -633,7 +632,7 @@ class _StreamProxy(object):
self.fileobj.close()
# class StreamProxy
-class _BZ2Proxy(object):
+class _BZ2Proxy:
"""Small proxy class that enables external file object
support for "r:bz2" and "w:bz2" modes. This is actually
a workaround for a limitation in bz2 module's BZ2File
@@ -655,7 +654,7 @@ class _BZ2Proxy(object):
if self.mode == "r":
self.bz2obj = bz2.BZ2Decompressor()
self.fileobj.seek(0)
- self.buf = ""
+ self.buf = b""
else:
self.bz2obj = bz2.BZ2Compressor()
@@ -696,7 +695,7 @@ class _BZ2Proxy(object):
#------------------------
# Extraction file object
#------------------------
-class _FileInFile(object):
+class _FileInFile:
"""A thin wrapper around an existing file object that
provides a part of its data as an individual file
object.
@@ -749,7 +748,7 @@ class _FileInFile(object):
else:
size = min(size, self.size - self.position)
- buf = ""
+ buf = b""
while size > 0:
while True:
data, start, stop, offset = self.map[self.map_index]
@@ -771,7 +770,7 @@ class _FileInFile(object):
#class _FileInFile
-class ExFileObject(object):
+class ExFileObject:
"""File-like object for reading an archive member.
Is returned by TarFile.extractfile().
"""
@@ -788,7 +787,7 @@ class ExFileObject(object):
self.size = tarinfo.size
self.position = 0
- self.buffer = ""
+ self.buffer = b""
def readable(self):
return True
@@ -806,11 +805,11 @@ class ExFileObject(object):
if self.closed:
raise ValueError("I/O operation on closed file")
- buf = ""
+ buf = b""
if self.buffer:
if size is None:
buf = self.buffer
- self.buffer = ""
+ self.buffer = b""
else:
buf = self.buffer[:size]
self.buffer = self.buffer[size:]
@@ -834,14 +833,14 @@ class ExFileObject(object):
if self.closed:
raise ValueError("I/O operation on closed file")
- pos = self.buffer.find("\n") + 1
+ pos = self.buffer.find(b"\n") + 1
if pos == 0:
# no newline found.
while True:
buf = self.fileobj.read(self.blocksize)
self.buffer += buf
- if not buf or "\n" in buf:
- pos = self.buffer.find("\n") + 1
+ if not buf or b"\n" in buf:
+ pos = self.buffer.find(b"\n") + 1
if pos == 0:
# no newline found.
pos = len(self.buffer)
@@ -873,25 +872,25 @@ class ExFileObject(object):
return self.position
- def seek(self, pos, whence=0):
+ def seek(self, pos, whence=os.SEEK_SET):
"""Seek to a position in the file.
"""
if self.closed:
raise ValueError("I/O operation on closed file")
- if whence == 0: # os.SEEK_SET
+ if whence == os.SEEK_SET:
self.position = min(max(pos, 0), self.size)
- elif whence == 1: # os.SEEK_CUR
+ elif whence == os.SEEK_CUR:
if pos < 0:
self.position = max(self.position + pos, 0)
else:
self.position = min(self.position + pos, self.size)
- elif whence == 2: # os.SEEK_END
+ elif whence == os.SEEK_END:
self.position = max(min(self.size + pos, self.size), 0)
else:
raise ValueError("Invalid argument")
- self.buffer = ""
+ self.buffer = b""
self.fileobj.seek(self.position)
def close(self):
@@ -912,7 +911,7 @@ class ExFileObject(object):
#------------------
# Exported Classes
#------------------
-class TarInfo(object):
+class TarInfo:
"""Informational class which holds the details about an
archive member given by a tar header block.
TarInfo objects are returned by TarFile.getmember(),
@@ -931,7 +930,7 @@ class TarInfo(object):
of the member.
"""
self.name = name # member name
- self.mode = 0644 # file permissions
+ self.mode = 0o644 # file permissions
self.uid = 0 # user id
self.gid = 0 # group id
self.size = 0 # file size
@@ -972,7 +971,7 @@ class TarInfo(object):
"""
info = {
"name": self.name,
- "mode": self.mode & 07777,
+ "mode": self.mode & 0o7777,
"uid": self.uid,
"gid": self.gid,
"size": self.size,
@@ -991,7 +990,7 @@ class TarInfo(object):
return info
- def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="strict"):
+ def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"):
"""Return a tar header as a string of 512 byte blocks.
"""
info = self.get_info()
@@ -1023,7 +1022,7 @@ class TarInfo(object):
"""
info["magic"] = GNU_MAGIC
- buf = ""
+ buf = b""
if len(info["linkname"]) > LENGTH_LINK:
buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors)
@@ -1070,14 +1069,14 @@ class TarInfo(object):
val = info[name]
if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float):
- pax_headers[name] = unicode(val)
+ pax_headers[name] = str(val)
info[name] = 0
# Create a pax extended header if necessary.
if pax_headers:
buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding)
else:
- buf = ""
+ buf = b""
return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace")
@@ -1109,12 +1108,12 @@ class TarInfo(object):
"""
parts = [
stn(info.get("name", ""), 100, encoding, errors),
- itn(info.get("mode", 0) & 07777, 8, format),
+ itn(info.get("mode", 0) & 0o7777, 8, format),
itn(info.get("uid", 0), 8, format),
itn(info.get("gid", 0), 8, format),
itn(info.get("size", 0), 12, format),
itn(info.get("mtime", 0), 12, format),
- " ", # checksum field
+ b" ", # checksum field
info.get("type", REGTYPE),
stn(info.get("linkname", ""), 100, encoding, errors),
info.get("magic", POSIX_MAGIC),
@@ -1125,9 +1124,9 @@ class TarInfo(object):
stn(info.get("prefix", ""), 155, encoding, errors)
]
- buf = struct.pack("%ds" % BLOCKSIZE, "".join(parts))
+ buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts))
chksum = calc_chksums(buf[-BLOCKSIZE:])[0]
- buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
+ buf = buf[:-364] + bytes("%06o\0" % chksum, "ascii") + buf[-357:]
return buf
@staticmethod
@@ -1161,7 +1160,7 @@ class TarInfo(object):
def _create_pax_generic_header(cls, pax_headers, type, encoding):
"""Return a POSIX.1-2008 extended or global header sequence
that contains a list of keyword, value pairs. The values
- must be unicode objects.
+ must be strings.
"""
# Check if one of the fields contains surrogate characters and thereby
# forces hdrcharset=BINARY, see _proc_pax() for more information.
@@ -1173,10 +1172,10 @@ class TarInfo(object):
binary = True
break
- records = ""
+ records = b""
if binary:
# Put the hdrcharset field at the beginning of the header.
- records += "21 hdrcharset=BINARY\n"
+ records += b"21 hdrcharset=BINARY\n"
for keyword, value in pax_headers.items():
keyword = keyword.encode("utf8")
@@ -1194,7 +1193,7 @@ class TarInfo(object):
if n == p:
break
p = n
- records += bytes(str(p), "ascii") + " " + keyword + "=" + value + "\n"
+ records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n"
# We use a hardcoded "././@PaxHeader" name like star does
# instead of the one that POSIX recommends.
@@ -1355,7 +1354,7 @@ class TarInfo(object):
while isextended:
buf = tarfile.fileobj.read(BLOCKSIZE)
pos = 0
- for i in xrange(21):
+ for i in range(21):
try:
offset = nti(buf[pos:pos + 12])
numbytes = nti(buf[pos + 12:pos + 24])
@@ -1392,7 +1391,7 @@ class TarInfo(object):
# these fields are UTF-8 encoded but since POSIX.1-2008 tar
# implementations are allowed to store them as raw binary strings if
# the translation to UTF-8 fails.
- match = re.search(r"\d+ hdrcharset=([^\n]+)\n", buf)
+ match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf)
if match is not None:
pax_headers["hdrcharset"] = match.group(1).decode("utf8")
@@ -1409,7 +1408,7 @@ class TarInfo(object):
# "%d %s=%s\n" % (length, keyword, value). length is the size
# of the complete record including the length field itself and
# the newline. keyword and value are both UTF-8 encoded strings.
- regex = re.compile(r"(\d+) ([^=]+)=")
+ regex = re.compile(br"(\d+) ([^=]+)=")
pos = 0
while True:
match = regex.match(buf, pos)
@@ -1478,10 +1477,10 @@ class TarInfo(object):
"""Process a GNU tar extended sparse header, version 0.0.
"""
offsets = []
- for match in re.finditer(r"\d+ GNU.sparse.offset=(\d+)\n", buf):
+ for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf):
offsets.append(int(match.group(1)))
numbytes = []
- for match in re.finditer(r"\d+ GNU.sparse.numbytes=(\d+)\n", buf):
+ for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf):
numbytes.append(int(match.group(1)))
next.sparse = list(zip(offsets, numbytes))
@@ -1497,12 +1496,12 @@ class TarInfo(object):
fields = None
sparse = []
buf = tarfile.fileobj.read(BLOCKSIZE)
- fields, buf = buf.split("\n", 1)
+ fields, buf = buf.split(b"\n", 1)
fields = int(fields)
while len(sparse) < fields * 2:
- if "\n" not in buf:
+ if b"\n" not in buf:
buf += tarfile.fileobj.read(BLOCKSIZE)
- number, buf = buf.split("\n", 1)
+ number, buf = buf.split(b"\n", 1)
sparse.append(int(number))
next.offset_data = tarfile.fileobj.tell()
next.sparse = list(zip(sparse[::2], sparse[1::2]))
@@ -1569,7 +1568,7 @@ class TarInfo(object):
return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE)
# class TarInfo
-class TarFile(object):
+class TarFile:
"""The TarFile Class provides an interface to tar archives.
"""
@@ -1597,7 +1596,7 @@ class TarFile(object):
def __init__(self, name=None, mode="r", fileobj=None, format=None,
tarinfo=None, dereference=None, ignore_zeros=None, encoding=None,
- errors="strict", pax_headers=None, debug=None, errorlevel=None):
+ errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None):
"""Open an (uncompressed) tar archive `name'. `mode' is either 'r' to
read from an existing archive, 'a' to append data to an existing
file or 'w' to create a new file overwriting an existing one. `mode'
@@ -1624,10 +1623,7 @@ class TarFile(object):
if hasattr(fileobj, "mode"):
self._mode = fileobj.mode
self._extfileobj = True
- if name:
- self.name = os.path.abspath(name)
- else:
- self.name = None
+ self.name = os.path.abspath(name) if name else None
self.fileobj = fileobj
# Init attributes.
@@ -1678,7 +1674,7 @@ class TarFile(object):
except EOFHeaderError:
self.fileobj.seek(self.offset)
break
- except HeaderError, e:
+ except HeaderError as e:
raise ReadError(str(e))
if self.mode in "aw":
@@ -1740,7 +1736,7 @@ class TarFile(object):
saved_pos = fileobj.tell()
try:
return func(name, "r", fileobj, **kwargs)
- except (ReadError, CompressionError), e:
+ except (ReadError, CompressionError) as e:
if fileobj is not None:
fileobj.seek(saved_pos)
continue
@@ -2010,31 +2006,27 @@ class TarFile(object):
for tarinfo in self:
if verbose:
- print filemode(tarinfo.mode),
- print "%s/%s" % (tarinfo.uname or tarinfo.uid,
- tarinfo.gname or tarinfo.gid),
+ print(filemode(tarinfo.mode), end=' ')
+ print("%s/%s" % (tarinfo.uname or tarinfo.uid,
+ tarinfo.gname or tarinfo.gid), end=' ')
if tarinfo.ischr() or tarinfo.isblk():
- print "%10s" % ("%d,%d" \
- % (tarinfo.devmajor, tarinfo.devminor)),
+ print("%10s" % ("%d,%d" \
+ % (tarinfo.devmajor, tarinfo.devminor)), end=' ')
else:
- print "%10d" % tarinfo.size,
- print "%d-%02d-%02d %02d:%02d:%02d" \
- % time.localtime(tarinfo.mtime)[:6],
+ print("%10d" % tarinfo.size, end=' ')
+ print("%d-%02d-%02d %02d:%02d:%02d" \
+ % time.localtime(tarinfo.mtime)[:6], end=' ')
- if tarinfo.isdir():
- sep = "/"
- else:
- sep = ""
- print tarinfo.name + sep,
+ print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ')
if verbose:
if tarinfo.issym():
- print "->", tarinfo.linkname,
+ print("->", tarinfo.linkname, end=' ')
if tarinfo.islnk():
- print "link to", tarinfo.linkname,
- print
+ print("link to", tarinfo.linkname, end=' ')
+ print()
- def add(self, name, arcname=None, recursive=True, exclude=None, filter=None):
+ def add(self, name, arcname=None, recursive=True, exclude=None, *, filter=None):
"""Add the file `name' to the archive. `name' may be any type of file
(directory, fifo, symbolic link, etc.). If given, `arcname'
specifies an alternative name for the file in the archive.
@@ -2139,7 +2131,7 @@ class TarFile(object):
# Extract directories with a safe mode.
directories.append(tarinfo)
tarinfo = copy.copy(tarinfo)
- tarinfo.mode = 0700
+ tarinfo.mode = 0o700
# Do not set_attrs directories, as we will do that further down
self.extract(tarinfo, path, set_attrs=not tarinfo.isdir())
@@ -2154,7 +2146,7 @@ class TarFile(object):
self.chown(tarinfo, dirpath)
self.utime(tarinfo, dirpath)
self.chmod(tarinfo, dirpath)
- except ExtractError, e:
+ except ExtractError as e:
if self.errorlevel > 1:
raise
else:
@@ -2169,7 +2161,7 @@ class TarFile(object):
"""
self._check("r")
- if isinstance(member, basestring):
+ if isinstance(member, str):
tarinfo = self.getmember(member)
else:
tarinfo = member
@@ -2181,7 +2173,7 @@ class TarFile(object):
try:
self._extract_member(tarinfo, os.path.join(path, tarinfo.name),
set_attrs=set_attrs)
- except EnvironmentError, e:
+ except EnvironmentError as e:
if self.errorlevel > 0:
raise
else:
@@ -2189,7 +2181,7 @@ class TarFile(object):
self._dbg(1, "tarfile: %s" % e.strerror)
else:
self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename))
- except ExtractError, e:
+ except ExtractError as e:
if self.errorlevel > 1:
raise
else:
@@ -2206,7 +2198,7 @@ class TarFile(object):
"""
self._check("r")
- if isinstance(member, basestring):
+ if isinstance(member, str):
tarinfo = self.getmember(member)
else:
tarinfo = member
@@ -2287,8 +2279,8 @@ class TarFile(object):
try:
# Use a safe mode for the directory, the real mode is set
# later in _extract_member().
- os.mkdir(targetpath, 0700)
- except EnvironmentError, e:
+ os.mkdir(targetpath, 0o700)
+ except EnvironmentError as e:
if e.errno != errno.EEXIST:
raise
@@ -2387,7 +2379,7 @@ class TarFile(object):
else:
if sys.platform != "os2emx":
os.chown(targetpath, u, g)
- except EnvironmentError, e:
+ except EnvironmentError as e:
raise ExtractError("could not change owner")
def chmod(self, tarinfo, targetpath):
@@ -2396,7 +2388,7 @@ class TarFile(object):
if hasattr(os, 'chmod'):
try:
os.chmod(targetpath, tarinfo.mode)
- except EnvironmentError, e:
+ except EnvironmentError as e:
raise ExtractError("could not change mode")
def utime(self, tarinfo, targetpath):
@@ -2406,7 +2398,7 @@ class TarFile(object):
return
try:
os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime))
- except EnvironmentError, e:
+ except EnvironmentError as e:
raise ExtractError("could not change modification time")
#--------------------------------------------------------------------------
@@ -2427,12 +2419,12 @@ class TarFile(object):
while True:
try:
tarinfo = self.tarinfo.fromtarfile(self)
- except EOFHeaderError, e:
+ except EOFHeaderError as e:
if self.ignore_zeros:
self._dbg(2, "0x%X: %s" % (self.offset, e))
self.offset += BLOCKSIZE
continue
- except InvalidHeaderError, e:
+ except InvalidHeaderError as e:
if self.ignore_zeros:
self._dbg(2, "0x%X: %s" % (self.offset, e))
self.offset += BLOCKSIZE
@@ -2442,10 +2434,10 @@ class TarFile(object):
except EmptyHeaderError:
if self.offset == 0:
raise ReadError("empty file")
- except TruncatedHeaderError, e:
+ except TruncatedHeaderError as e:
if self.offset == 0:
raise ReadError(str(e))
- except SubsequentHeaderError, e:
+ except SubsequentHeaderError as e:
raise ReadError(str(e))
break
@@ -2532,7 +2524,7 @@ class TarFile(object):
"""Write debugging output to sys.stderr.
"""
if level <= self.debug:
- print >> sys.stderr, msg
+ print(msg, file=sys.stderr)
def __enter__(self):
self._check()
@@ -2549,7 +2541,7 @@ class TarFile(object):
self.closed = True
# class TarFile
-class TarIter(object):
+class TarIter:
"""Iterator Class.
for tarinfo in TarFile(...):
@@ -2565,7 +2557,7 @@ class TarIter(object):
"""Return iterator object.
"""
return self
- def next(self):
+ def __next__(self):
"""Return the next item using TarFile's next() method.
When all members have been read, set TarFile as _loaded.
"""
diff --git a/distutils2/_backport/tests/test_shutil.py b/distutils2/_backport/tests/test_shutil.py
index fc883ad..67f3de8 100644
--- a/distutils2/_backport/tests/test_shutil.py
+++ b/distutils2/_backport/tests/test_shutil.py
@@ -2,11 +2,11 @@ import os
import sys
import stat
import tempfile
+from io import StringIO
from os.path import splitdrive
-from StringIO import StringIO
-
+from functools import wraps
from distutils.spawn import find_executable, spawn
-from distutils2.compat import wraps
+
from distutils2._backport import shutil, tarfile
from distutils2._backport.shutil import (
_make_tarball, _make_zipfile, make_archive, unpack_archive,
@@ -15,7 +15,7 @@ from distutils2._backport.shutil import (
Error, RegistryError)
from distutils2.tests import unittest, support
-from test.test_support import TESTFN
+from test.support import TESTFN
try:
@@ -370,7 +370,7 @@ class TestShutil(unittest.TestCase):
os.mkfifo(pipe)
try:
shutil.copytree(TESTFN, TESTFN2)
- except shutil.Error, e:
+ except shutil.Error as e:
errors = e.args[0]
self.assertEqual(len(errors), 1)
src, dst, error_msg = errors[0]
@@ -756,7 +756,7 @@ class TestMove(unittest.TestCase):
self.dst_file = os.path.join(self.dst_dir, filename)
f = open(self.src_file, "wb")
try:
- f.write("spam")
+ f.write(b"spam")
finally:
f.close()
@@ -877,7 +877,7 @@ class TestCopyFile(unittest.TestCase):
_delete = False
- class Faux(object):
+ class Faux:
_entered = False
_exited_with = None
_raised = False
@@ -917,7 +917,6 @@ class TestCopyFile(unittest.TestCase):
self.assertRaises(IOError, shutil.copyfile, 'srcfile', 'destfile')
- @unittest.skip("can't use the with statement and support 2.4")
def test_w_dest_open_fails(self):
srcfile = self.Faux()
@@ -937,7 +936,6 @@ class TestCopyFile(unittest.TestCase):
self.assertEqual(srcfile._exited_with[1].args,
('Cannot open "destfile"',))
- @unittest.skip("can't use the with statement and support 2.4")
def test_w_dest_close_fails(self):
srcfile = self.Faux()
@@ -960,7 +958,6 @@ class TestCopyFile(unittest.TestCase):
self.assertEqual(srcfile._exited_with[1].args,
('Cannot close',))
- @unittest.skip("can't use the with statement and support 2.4")
def test_w_source_close_fails(self):
srcfile = self.Faux(True)
diff --git a/distutils2/_backport/tests/test_sysconfig.py b/distutils2/_backport/tests/test_sysconfig.py
index 9c77f66..937396c 100644
--- a/distutils2/_backport/tests/test_sysconfig.py
+++ b/distutils2/_backport/tests/test_sysconfig.py
@@ -3,7 +3,7 @@ import sys
import subprocess
import shutil
from copy import copy
-from StringIO import StringIO
+from io import StringIO
from distutils2._backport import sysconfig
from distutils2._backport.sysconfig import (
@@ -14,7 +14,7 @@ from distutils2._backport.sysconfig import (
from distutils2.tests import unittest
from distutils2.tests.support import skip_unless_symlink
-from test.test_support import TESTFN, unlink
+from test.support import TESTFN, unlink
class TestSysConfig(unittest.TestCase):
@@ -140,14 +140,14 @@ class TestSysConfig(unittest.TestCase):
get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
'-fwrapv -O3 -Wall -Wstrict-prototypes')
- maxint = sys.maxint
+ maxint = sys.maxsize
try:
- sys.maxint = 2147483647
+ sys.maxsize = 2147483647
self.assertEqual(get_platform(), 'macosx-10.3-ppc')
- sys.maxint = 9223372036854775807
+ sys.maxsize = 9223372036854775807
self.assertEqual(get_platform(), 'macosx-10.3-ppc64')
finally:
- sys.maxint = maxint
+ sys.maxsize = maxint
self._set_uname(('Darwin', 'macziade', '8.11.1',
('Darwin Kernel Version 8.11.1: '
@@ -158,14 +158,14 @@ class TestSysConfig(unittest.TestCase):
get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
'-fwrapv -O3 -Wall -Wstrict-prototypes')
- maxint = sys.maxint
+ maxint = sys.maxsize
try:
- sys.maxint = 2147483647
+ sys.maxsize = 2147483647
self.assertEqual(get_platform(), 'macosx-10.3-i386')
- sys.maxint = 9223372036854775807
+ sys.maxsize = 9223372036854775807
self.assertEqual(get_platform(), 'macosx-10.3-x86_64')
finally:
- sys.maxint = maxint
+ sys.maxsize = maxint
# macbook with fat binaries (fat, universal or fat64)
get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.4'
@@ -243,7 +243,7 @@ class TestSysConfig(unittest.TestCase):
def get(python):
cmd = [python, '-c',
'from distutils2._backport import sysconfig; '
- 'print sysconfig.get_platform()']
+ 'print(sysconfig.get_platform())']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=os.environ)
return p.communicate()
real = os.path.realpath(sys.executable)
@@ -254,7 +254,6 @@ class TestSysConfig(unittest.TestCase):
finally:
unlink(link)
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_user_similar(self):
# Issue #8759: make sure the posix scheme for the users
# is similar to the global posix_prefix one
@@ -296,18 +295,15 @@ class TestSysConfig(unittest.TestCase):
if 'MACOSX_DEPLOYMENT_TARGET' in env:
del env['MACOSX_DEPLOYMENT_TARGET']
- devnull_fp = open('/dev/null', 'w')
- try:
+ with open('/dev/null', 'w') as devnull_fp:
p = subprocess.Popen([
sys.executable, '-c',
'from distutils2._backport import sysconfig; '
- 'print sysconfig.get_platform()',
+ 'print(sysconfig.get_platform())',
],
stdout=subprocess.PIPE,
stderr=devnull_fp,
env=env)
- finally:
- devnull_fp.close()
test_platform = p.communicate()[0].strip()
test_platform = test_platform.decode('utf-8')
status = p.wait()
@@ -320,12 +316,11 @@ class TestSysConfig(unittest.TestCase):
env = os.environ.copy()
env['MACOSX_DEPLOYMENT_TARGET'] = '10.1'
- dev_null = open('/dev/null')
- try:
+ with open('/dev/null') as dev_null:
p = subprocess.Popen([
sys.executable, '-c',
'from distutils2._backport import sysconfig; '
- 'print sysconfig.get_platform()',
+ 'print(sysconfig.get_platform())',
],
stdout=subprocess.PIPE,
stderr=dev_null,
@@ -336,8 +331,6 @@ class TestSysConfig(unittest.TestCase):
self.assertEqual(status, 0)
self.assertEqual(my_platform, test_platform)
- finally:
- dev_null.close()
class MakefileTests(unittest.TestCase):
@@ -350,15 +343,12 @@ class MakefileTests(unittest.TestCase):
def test_parse_makefile(self):
self.addCleanup(unlink, TESTFN)
- makefile = open(TESTFN, "w")
- try:
- print >> makefile, "var1=a$(VAR2)"
- print >> makefile, "VAR2=b$(var3)"
- print >> makefile, "var3=42"
- print >> makefile, "var4=$/invalid"
- print >> makefile, "var5=dollar$$5"
- finally:
- makefile.close()
+ with open(TESTFN, "w") as makefile:
+ print("var1=a$(VAR2)", file=makefile)
+ print("VAR2=b$(var3)", file=makefile)
+ print("var3=42", file=makefile)
+ print("var4=$/invalid", file=makefile)
+ print("var5=dollar$$5", file=makefile)
vars = sysconfig._parse_makefile(TESTFN)
self.assertEqual(vars, {
'var1': 'ab42',
diff --git a/distutils2/command/bdist_msi.py b/distutils2/command/bdist_msi.py
index 1d967bd..40e733f 100644
--- a/distutils2/command/bdist_msi.py
+++ b/distutils2/command/bdist_msi.py
@@ -394,8 +394,7 @@ class bdist_msi(Command):
# entries for each version as the above code does
if self.pre_install_script:
scriptfn = os.path.join(self.bdist_dir, "preinstall.bat")
- f = open(scriptfn, "w")
- try:
+ with open(scriptfn, "w") as f:
# The batch file will be executed with [PYTHON], so that %1
# is the path to the Python interpreter; %0 will be the path
# of the batch file.
@@ -405,13 +404,8 @@ class bdist_msi(Command):
# """
# <actual script>
f.write('rem ="""\n%1 %0\nexit\n"""\n')
- fp = open(self.pre_install_script)
- try:
+ with open(self.pre_install_script) as fp:
f.write(fp.read())
- finally:
- fp.close()
- finally:
- f.close()
add_data(self.db, "Binary",
[("PreInstall", msilib.Binary(scriptfn)),
])
diff --git a/distutils2/command/bdist_wininst.py b/distutils2/command/bdist_wininst.py
index 3df272b..e4cde7a 100644
--- a/distutils2/command/bdist_wininst.py
+++ b/distutils2/command/bdist_wininst.py
@@ -248,40 +248,33 @@ class bdist_wininst(Command):
logger.info("creating %s", installer_name)
if bitmap:
- fp = open(bitmap, "rb")
- try:
+ with open(bitmap, "rb") as fp:
bitmapdata = fp.read()
- finally:
- fp.close()
bitmaplen = len(bitmapdata)
else:
bitmaplen = 0
- file = open(installer_name, "wb")
- try:
+ with open(installer_name, "wb") as file:
file.write(self.get_exe_bytes())
if bitmap:
file.write(bitmapdata)
# Convert cfgdata from unicode to ascii, mbcs encoded
- if isinstance(cfgdata, unicode):
+ if isinstance(cfgdata, str):
cfgdata = cfgdata.encode("mbcs")
# Append the pre-install script
- cfgdata = cfgdata + "\0"
+ cfgdata = cfgdata + b"\0"
if self.pre_install_script:
# We need to normalize newlines, so we open in text mode and
# convert back to bytes. "latin-1" simply avoids any possible
# failures.
- fp = codecs.open(self.pre_install_script, encoding="latin-1")
- try:
+ with open(self.pre_install_script, encoding="latin-1") as fp:
script_data = fp.read().encode("latin-1")
- finally:
- fp.close()
- cfgdata = cfgdata + script_data + "\n\0"
+ cfgdata = cfgdata + script_data + b"\n\0"
else:
# empty pre-install script
- cfgdata = cfgdata + "\0"
+ cfgdata = cfgdata + b"\0"
file.write(cfgdata)
# The 'magic number' 0x1234567B is used to make sure that the
@@ -295,13 +288,8 @@ class bdist_wininst(Command):
bitmaplen, # number of bytes in bitmap
)
file.write(header)
- fp = open(arcname, "rb")
- try:
+ with open(arcname, "rb") as fp:
file.write(fp.read())
- finally:
- fp.close()
- finally:
- file.close()
def get_installer_filename(self, fullname):
# Factored out to allow overriding in subclasses
@@ -356,9 +344,5 @@ class bdist_wininst(Command):
sfix = ''
filename = os.path.join(directory, "wininst-%.1f%s.exe" % (bv, sfix))
- fp = open(filename, "rb")
- try:
- content = fp.read()
- finally:
- fp.close()
- return content
+ with open(filename, "rb") as fp:
+ return fp.read()
diff --git a/distutils2/command/build_clib.py b/distutils2/command/build_clib.py
index 0a8807f..7d819d3 100644
--- a/distutils2/command/build_clib.py
+++ b/distutils2/command/build_clib.py
@@ -82,7 +82,7 @@ class build_clib(Command):
if self.include_dirs is None:
self.include_dirs = self.distribution.include_dirs or []
- if isinstance(self.include_dirs, basestring):
+ if isinstance(self.include_dirs, str):
self.include_dirs = self.include_dirs.split(os.pathsep)
# XXX same as for build_ext -- what about 'self.define' and
@@ -130,7 +130,7 @@ class build_clib(Command):
name, build_info = lib
- if not isinstance(name, basestring):
+ if not isinstance(name, str):
raise PackagingSetupError("first element of each tuple in 'libraries' " + \
"must be a string (the library name)")
if '/' in name or (os.sep != '/' and os.sep in name):
diff --git a/distutils2/command/build_ext.py b/distutils2/command/build_ext.py
index b73149a..81d82e9 100644
--- a/distutils2/command/build_ext.py
+++ b/distutils2/command/build_ext.py
@@ -3,6 +3,7 @@
import os
import re
import sys
+import site
import logging
from distutils2._backport import sysconfig
@@ -15,12 +16,6 @@ from distutils2.util import newer_group
from distutils2.compiler.extension import Extension
from distutils2 import logger
-import site
-if sys.version_info[:2] >= (2, 6):
- HAS_USER_SITE = True
-else:
- HAS_USER_SITE = False
-
if os.name == 'nt':
from distutils2.compiler.msvccompiler import get_build_version
MSVC_VERSION = int(get_build_version())
@@ -65,6 +60,8 @@ class build_ext(Command):
('inplace', 'i',
"ignore build-lib and put compiled extensions into the source " +
"directory alongside your pure Python modules"),
+ ('user', None,
+ "add user include, library and rpath"),
('include-dirs=', 'I',
"list of directories to search for header files" + sep_by),
('define=', 'D',
@@ -91,12 +88,8 @@ class build_ext(Command):
"path to the SWIG executable"),
]
- boolean_options = ['inplace', 'debug', 'force']
+ boolean_options = ['inplace', 'debug', 'force', 'user']
- if HAS_USER_SITE:
- user_options.append(('user', None,
- "add user include, library and rpath"))
- boolean_options.append('user')
help_options = [
('help-compiler', None,
@@ -123,8 +116,7 @@ class build_ext(Command):
self.compiler = None
self.swig = None
self.swig_opts = None
- if HAS_USER_SITE:
- self.user = None
+ self.user = None
def finalize_options(self):
self.set_undefined_options('build',
@@ -159,7 +151,7 @@ class build_ext(Command):
plat_py_include = sysconfig.get_path('platinclude')
if self.include_dirs is None:
self.include_dirs = self.distribution.include_dirs or []
- if isinstance(self.include_dirs, basestring):
+ if isinstance(self.include_dirs, str):
self.include_dirs = self.include_dirs.split(os.pathsep)
# Put the Python "system" include dir at the end, so that
@@ -168,7 +160,7 @@ class build_ext(Command):
if plat_py_include != py_include:
self.include_dirs.append(plat_py_include)
- if isinstance(self.libraries, basestring):
+ if isinstance(self.libraries, str):
self.libraries = [self.libraries]
# Life is easier if we're not forever checking for None, so
@@ -177,12 +169,12 @@ class build_ext(Command):
self.libraries = []
if self.library_dirs is None:
self.library_dirs = []
- elif isinstance(self.library_dirs, basestring):
+ elif isinstance(self.library_dirs, str):
self.library_dirs = self.library_dirs.split(os.pathsep)
if self.rpath is None:
self.rpath = []
- elif isinstance(self.rpath, basestring):
+ elif isinstance(self.rpath, str):
self.rpath = self.rpath.split(os.pathsep)
# for extensions under windows use different directories
@@ -243,8 +235,7 @@ class build_ext(Command):
# for extensions under Linux or Solaris with a shared Python library,
# Python's library directory must be appended to library_dirs
sysconfig.get_config_var('Py_ENABLE_SHARED')
- if ((sys.platform.startswith('linux') or sys.platform.startswith('gnu')
- or sys.platform.startswith('sunos'))
+ if (sys.platform.startswith(('linux', 'gnu', 'sunos'))
and sysconfig.get_config_var('Py_ENABLE_SHARED')):
if sys.executable.startswith(os.path.join(sys.exec_prefix, "bin")):
# building third party extensions
@@ -274,7 +265,7 @@ class build_ext(Command):
self.swig_opts = self.swig_opts.split(' ')
# Finally add the user include and library directories if requested
- if HAS_USER_SITE and self.user:
+ if self.user:
user_include = os.path.join(site.USER_BASE, "include")
user_lib = os.path.join(site.USER_BASE, "lib")
if os.path.isdir(user_include):
@@ -362,7 +353,7 @@ class build_ext(Command):
for ext in self.extensions:
try:
self.build_extension(ext)
- except (CCompilerError, PackagingError, CompileError), e:
+ except (CCompilerError, PackagingError, CompileError) as e:
if not ext.optional:
raise
logger.warning('%s: building extension %r failed: %s',
@@ -650,7 +641,7 @@ class build_ext(Command):
else:
if sysconfig.get_config_var('Py_ENABLE_SHARED'):
- template = 'python%d.%d'
+ template = 'python%d.%d' + getattr(sys, 'abiflags', '')
pythonlib = template % sys.version_info[:2]
return ext.libraries + [pythonlib]
else:
diff --git a/distutils2/command/build_py.py b/distutils2/command/build_py.py
index fec81a9..e27e271 100644
--- a/distutils2/command/build_py.py
+++ b/distutils2/command/build_py.py
@@ -342,7 +342,7 @@ class build_py(Command, Mixin2to3):
return outputs
def build_module(self, module, module_file, package):
- if isinstance(package, basestring):
+ if isinstance(package, str):
package = package.split('.')
elif not isinstance(package, (list, tuple)):
raise TypeError(
@@ -388,7 +388,7 @@ class build_py(Command, Mixin2to3):
self.build_module(module, module_file, package)
def byte_compile(self, files):
- if getattr(sys, 'dont_write_bytecode', False):
+ if sys.dont_write_bytecode:
logger.warning('%s: byte-compiling is disabled, skipping.',
self.get_command_name())
return
diff --git a/distutils2/command/build_scripts.py b/distutils2/command/build_scripts.py
index 300f692..e752ff1 100644
--- a/distutils2/command/build_scripts.py
+++ b/distutils2/command/build_scripts.py
@@ -2,17 +2,18 @@
import os
import re
+from tokenize import detect_encoding
from distutils2.command.cmd import Command
from distutils2.util import convert_path, newer
from distutils2 import logger
from distutils2.compat import Mixin2to3
-from distutils2.compat import detect_encoding, fsencode
+from distutils2.compat import fsencode
from distutils2._backport import sysconfig
# check if Python is called on the first line with this expression
-first_line_re = re.compile('^#!.*python[0-9.]*([ \t].*)?$')
+first_line_re = re.compile(b'^#!.*python[0-9.]*([ \t].*)?$')
class build_scripts(Command, Mixin2to3):
@@ -94,7 +95,7 @@ class build_scripts(Command, Mixin2to3):
match = first_line_re.match(first_line)
if match:
adjust = True
- post_interp = match.group(1) or ''
+ post_interp = match.group(1) or b''
if adjust:
logger.info("copying and adjusting %s -> %s", script,
@@ -108,7 +109,7 @@ class build_scripts(Command, Mixin2to3):
"python%s%s" % (sysconfig.get_config_var("VERSION"),
sysconfig.get_config_var("EXE")))
executable = fsencode(executable)
- shebang = "#!" + executable + post_interp + "\n"
+ shebang = b"#!" + executable + post_interp + b"\n"
# Python parser starts to read a script using UTF-8 until
# it gets a #coding:xxx cookie. The shebang has to be the
# first line of a file, the #coding:xxx cookie cannot be
@@ -130,12 +131,9 @@ class build_scripts(Command, Mixin2to3):
"The shebang (%r) is not decodable "
"from the script encoding (%s)" % (
shebang, encoding))
- outf = open(outfile, "wb")
- try:
+ with open(outfile, "wb") as outf:
outf.write(shebang)
outf.writelines(f.readlines())
- finally:
- outf.close()
if f:
f.close()
else:
@@ -148,8 +146,8 @@ class build_scripts(Command, Mixin2to3):
if self.dry_run:
logger.info("changing mode of %s", file)
else:
- oldmode = os.stat(file).st_mode & 07777
- newmode = (oldmode | 0555) & 07777
+ oldmode = os.stat(file).st_mode & 0o7777
+ newmode = (oldmode | 0o555) & 0o7777
if newmode != oldmode:
logger.info("changing mode of %s from %o to %o",
file, oldmode, newmode)
diff --git a/distutils2/command/cmd.py b/distutils2/command/cmd.py
index 88c1784..6d76e7f 100644
--- a/distutils2/command/cmd.py
+++ b/distutils2/command/cmd.py
@@ -8,7 +8,7 @@ from distutils2.errors import PackagingOptionError
from distutils2._backport.shutil import copyfile, move, make_archive
-class Command(object):
+class Command:
"""Abstract base class for defining command classes, the "worker bees"
of the Packaging. A useful analogy for command classes is to think of
them as subroutines with local variables called "options". The options
@@ -216,7 +216,7 @@ class Command(object):
if val is None:
setattr(self, option, default)
return default
- elif not isinstance(val, basestring):
+ elif not isinstance(val, str):
raise PackagingOptionError("'%s' must be a %s (got `%s`)" %
(option, what, val))
return val
@@ -236,14 +236,14 @@ class Command(object):
val = getattr(self, option)
if val is None:
return
- elif isinstance(val, basestring):
+ elif isinstance(val, str):
setattr(self, option, re.split(r',\s*|\s+', val))
else:
if isinstance(val, list):
# checks if all elements are str
ok = True
for element in val:
- if not isinstance(element, basestring):
+ if not isinstance(element, str):
ok = False
break
else:
@@ -351,7 +351,7 @@ class Command(object):
def execute(self, func, args, msg=None, level=1):
util.execute(func, args, msg, dry_run=self.dry_run)
- def mkpath(self, name, mode=00777, dry_run=None, verbose=0):
+ def mkpath(self, name, mode=0o777, dry_run=None, verbose=0):
if dry_run is None:
dry_run = self.dry_run
name = os.path.normpath(name)
@@ -421,7 +421,7 @@ class Command(object):
skip_msg = "skipping %s (inputs unchanged)" % outfile
# Allow 'infiles' to be a single string
- if isinstance(infiles, basestring):
+ if isinstance(infiles, str):
infiles = (infiles,)
elif not isinstance(infiles, (list, tuple)):
raise TypeError(
diff --git a/distutils2/command/config.py b/distutils2/command/config.py
index e3af2e5..437cde9 100644
--- a/distutils2/command/config.py
+++ b/distutils2/command/config.py
@@ -67,17 +67,17 @@ class config(Command):
def finalize_options(self):
if self.include_dirs is None:
self.include_dirs = self.distribution.include_dirs or []
- elif isinstance(self.include_dirs, basestring):
+ elif isinstance(self.include_dirs, str):
self.include_dirs = self.include_dirs.split(os.pathsep)
if self.libraries is None:
self.libraries = []
- elif isinstance(self.libraries, basestring):
+ elif isinstance(self.libraries, str):
self.libraries = [self.libraries]
if self.library_dirs is None:
self.library_dirs = []
- elif isinstance(self.library_dirs, basestring):
+ elif isinstance(self.library_dirs, str):
self.library_dirs = self.library_dirs.split(os.pathsep)
def run(self):
@@ -110,8 +110,7 @@ class config(Command):
def _gen_temp_sourcefile(self, body, headers, lang):
filename = "_configtest" + LANG_EXT[lang]
- file = open(filename, "w")
- try:
+ with open(filename, "w") as file:
if headers:
for header in headers:
file.write("#include <%s>\n" % header)
@@ -119,8 +118,6 @@ class config(Command):
file.write(body)
if body[-1] != "\n":
file.write("\n")
- finally:
- file.close()
return filename
def _preprocess(self, body, headers, include_dirs, lang):
@@ -206,11 +203,10 @@ class config(Command):
self._check_compiler()
src, out = self._preprocess(body, headers, include_dirs, lang)
- if isinstance(pattern, basestring):
+ if isinstance(pattern, str):
pattern = re.compile(pattern)
- file = open(out)
- try:
+ with open(out) as file:
match = False
while True:
line = file.readline()
@@ -219,8 +215,6 @@ class config(Command):
if pattern.search(line):
match = True
break
- finally:
- file.close()
self._clean()
return match
@@ -351,8 +345,5 @@ def dump_file(filename, head=None):
logger.info(filename)
else:
logger.info(head)
- file = open(filename)
- try:
+ with open(filename) as file:
logger.info(file.read())
- finally:
- file.close()
diff --git a/distutils2/command/install_data.py b/distutils2/command/install_data.py
index c1fd462..d3c67a7 100644
--- a/distutils2/command/install_data.py
+++ b/distutils2/command/install_data.py
@@ -48,7 +48,7 @@ class install_data(Command):
self.mkpath(dir_dest)
try:
out = self.copy_file(_file[0], dir_dest)[0]
- except Error, e:
+ except Error as e:
logger.warning('%s: %s', self.get_command_name(), e)
out = destination
diff --git a/distutils2/command/install_dist.py b/distutils2/command/install_dist.py
index 884699b..159ccc2 100644
--- a/distutils2/command/install_dist.py
+++ b/distutils2/command/install_dist.py
@@ -13,12 +13,6 @@ from distutils2.util import write_file
from distutils2.util import convert_path, change_root, get_platform
from distutils2.errors import PackagingOptionError
-import site
-if sys.version_info[:2] >= (2, 6):
- HAS_USER_SITE = True
-else:
- HAS_USER_SITE = False
-
class install_dist(Command):
@@ -30,6 +24,9 @@ class install_dist(Command):
"installation prefix"),
('exec-prefix=', None,
"(Unix only) prefix for platform-specific files"),
+ ('user', None,
+ "install in user site-packages directory [%s]" %
+ get_path('purelib', '%s_user' % os.name)),
('home=', None,
"(Unix only) home directory to install under"),
@@ -100,15 +97,7 @@ class install_dist(Command):
]
boolean_options = ['compile', 'force', 'skip-build', 'no-distinfo',
- 'requested', 'no-record']
-
- if HAS_USER_SITE:
- user_options.append(
- ('user', None,
- "install in user site-packages directory [%s]" %
- get_path('purelib', '%s_user' % os.name)))
-
- boolean_options.append('user')
+ 'requested', 'no-record', 'user']
negative_opt = {'no-compile': 'compile', 'no-requested': 'requested'}
@@ -118,8 +107,7 @@ class install_dist(Command):
self.prefix = None
self.exec_prefix = None
self.home = None
- if HAS_USER_SITE:
- self.user = False
+ self.user = False
# These select only the installation base; it's up to the user to
# specify the installation scheme (currently, that means supplying
@@ -138,9 +126,8 @@ class install_dist(Command):
self.install_lib = None # set to either purelib or platlib
self.install_scripts = None
self.install_data = None
- if HAS_USER_SITE:
- self.install_userbase = get_config_var('userbase')
- self.install_usersite = get_path('purelib', '%s_user' % os.name)
+ self.install_userbase = get_config_var('userbase')
+ self.install_usersite = get_path('purelib', '%s_user' % os.name)
self.compile = None
self.optimize = None
@@ -221,9 +208,8 @@ class install_dist(Command):
raise PackagingOptionError(
"must supply either home or prefix/exec-prefix -- not both")
- if HAS_USER_SITE and self.user and (
- self.prefix or self.exec_prefix or self.home or
- self.install_base or self.install_platbase):
+ if self.user and (self.prefix or self.exec_prefix or self.home or
+ self.install_base or self.install_platbase):
raise PackagingOptionError(
"can't combine user with prefix/exec_prefix/home or "
"install_base/install_platbase")
@@ -276,11 +262,9 @@ class install_dist(Command):
'exec_prefix': exec_prefix,
'srcdir': srcdir,
'projectbase': projectbase,
- }
-
- if HAS_USER_SITE:
- self.config_vars['userbase'] = self.install_userbase
- self.config_vars['usersite'] = self.install_usersite
+ 'userbase': self.install_userbase,
+ 'usersite': self.install_usersite,
+ }
self.expand_basedirs()
@@ -298,7 +282,7 @@ class install_dist(Command):
self.dump_dirs("post-expand_dirs()")
# Create directories under USERBASE
- if HAS_USER_SITE and self.user:
+ if self.user:
self.create_user_dirs()
# Pick the actual directory to install all modules to: either
@@ -313,10 +297,8 @@ class install_dist(Command):
# Convert directories from Unix /-separated syntax to the local
# convention.
- self.convert_paths('lib', 'purelib', 'platlib',
- 'scripts', 'data', 'headers')
- if HAS_USER_SITE:
- self.convert_paths('userbase', 'usersite')
+ self.convert_paths('lib', 'purelib', 'platlib', 'scripts',
+ 'data', 'headers', 'userbase', 'usersite')
# Well, we're not actually fully completely finalized yet: we still
# have to deal with 'extra_path', which is the hack for allowing
@@ -357,7 +339,7 @@ class install_dist(Command):
"installation scheme is incomplete")
return
- if HAS_USER_SITE and self.user:
+ if self.user:
if self.install_userbase is None:
raise PackagingPlatformError(
"user base directory is not specified")
@@ -385,7 +367,7 @@ class install_dist(Command):
def finalize_other(self):
"""Finalize options for non-posix platforms"""
- if HAS_USER_SITE and self.user:
+ if self.user:
if self.install_userbase is None:
raise PackagingPlatformError(
"user base directory is not specified")
@@ -466,7 +448,7 @@ class install_dist(Command):
self.extra_path = self.distribution.extra_path
if self.extra_path is not None:
- if isinstance(self.extra_path, basestring):
+ if isinstance(self.extra_path, str):
self.extra_path = self.extra_path.split(',')
if len(self.extra_path) == 1:
@@ -501,7 +483,7 @@ class install_dist(Command):
home = convert_path(os.path.expanduser("~"))
for name, path in self.config_vars.items():
if path.startswith(home) and not os.path.isdir(path):
- os.makedirs(path, 0700)
+ os.makedirs(path, 0o700)
# -- Command execution methods -------------------------------------
diff --git a/distutils2/command/install_distinfo.py b/distutils2/command/install_distinfo.py
index 82e099d..1220551 100644
--- a/distutils2/command/install_distinfo.py
+++ b/distutils2/command/install_distinfo.py
@@ -4,12 +4,8 @@
import os
import csv
-import codecs
+import hashlib
from shutil import rmtree
-try:
- import hashlib
-except ImportError:
- from distutils2._backport import hashlib
from distutils2 import logger
from distutils2.command.cmd import Command
@@ -90,11 +86,8 @@ class install_distinfo(Command):
installer_path = os.path.join(self.distinfo_dir, 'INSTALLER')
logger.info('creating %s', installer_path)
if not self.dry_run:
- f = open(installer_path, 'w')
- try:
+ with open(installer_path, 'w') as f:
f.write(self.installer)
- finally:
- f.close()
self.outfiles.append(installer_path)
if self.requested:
@@ -111,15 +104,12 @@ class install_distinfo(Command):
'RESOURCES')
logger.info('creating %s', resources_path)
if not self.dry_run:
- f = open(resources_path, 'wb')
- try:
+ with open(resources_path, 'wb') as f:
writer = csv.writer(f, delimiter=',',
lineterminator='\n',
quotechar='"')
for row in install_data.get_resources_out():
writer.writerow(row)
- finally:
- f.close()
self.outfiles.append(resources_path)
@@ -127,8 +117,7 @@ class install_distinfo(Command):
record_path = os.path.join(self.distinfo_dir, 'RECORD')
logger.info('creating %s', record_path)
if not self.dry_run:
- f = codecs.open(record_path, 'w', encoding='utf-8')
- try:
+ with open(record_path, 'w', encoding='utf-8') as f:
writer = csv.writer(f, delimiter=',',
lineterminator='\n',
quotechar='"')
@@ -141,19 +130,14 @@ class install_distinfo(Command):
writer.writerow((fpath, '', ''))
else:
size = os.path.getsize(fpath)
- fp = open(fpath, 'rb')
- try:
+ with open(fpath, 'rb') as fp:
hash = hashlib.md5()
hash.update(fp.read())
- finally:
- fp.close()
md5sum = hash.hexdigest()
writer.writerow((fpath, md5sum, size))
# add the RECORD file itself
writer.writerow((record_path, '', ''))
- finally:
- f.close()
self.outfiles.append(record_path)
def get_outputs(self):
diff --git a/distutils2/command/install_lib.py b/distutils2/command/install_lib.py
index 028e1aa..ea53eab 100644
--- a/distutils2/command/install_lib.py
+++ b/distutils2/command/install_lib.py
@@ -114,7 +114,7 @@ class install_lib(Command):
return outfiles
def byte_compile(self, files):
- if getattr(sys, 'dont_write_bytecode', False):
+ if sys.dont_write_bytecode:
# XXX do we want this? because a Python runs without bytecode
# doesn't mean that the *dists should not contain bytecode
#--or does it?
diff --git a/distutils2/command/install_scripts.py b/distutils2/command/install_scripts.py
index 3bed33c..6366be2 100644
--- a/distutils2/command/install_scripts.py
+++ b/distutils2/command/install_scripts.py
@@ -48,7 +48,7 @@ class install_scripts(Command):
if self.dry_run:
logger.info("changing mode of %s", file)
else:
- mode = (os.stat(file).st_mode | 0555) & 07777
+ mode = (os.stat(file).st_mode | 0o555) & 0o7777
logger.info("changing mode of %s to %o", file, mode)
os.chmod(file, mode)
diff --git a/distutils2/command/register.py b/distutils2/command/register.py
index de69a2f..79ec7b3 100644
--- a/distutils2/command/register.py
+++ b/distutils2/command/register.py
@@ -3,8 +3,9 @@
# Contributed by Richard Jones
import getpass
-import urllib2
-import urlparse
+import urllib.error
+import urllib.parse
+import urllib.request
from distutils2 import logger
from distutils2.util import (read_pypirc, generate_pypirc, DEFAULT_REPOSITORY,
@@ -80,7 +81,7 @@ class register(Command):
def classifiers(self):
''' Fetch the list of classifiers from the server.
'''
- response = urllib2.urlopen(self.repository+'?:action=list_classifiers')
+ response = urllib.request.urlopen(self.repository+'?:action=list_classifiers')
logger.info(response.read())
def verify_metadata(self):
@@ -143,22 +144,22 @@ We need to know who you are, so please choose either:
4. quit
Your selection [default 1]: ''')
- choice = raw_input()
+ choice = input()
if not choice:
choice = '1'
elif choice not in choices:
- print 'Please choose one of the four options!'
+ print('Please choose one of the four options!')
if choice == '1':
# get the username and password
while not username:
- username = raw_input('Username: ')
+ username = input('Username: ')
while not password:
password = getpass.getpass('Password: ')
# set up the authentication
- auth = urllib2.HTTPPasswordMgr()
- host = urlparse.urlparse(self.repository)[1]
+ auth = urllib.request.HTTPPasswordMgr()
+ host = urllib.parse.urlparse(self.repository)[1]
auth.add_password(self.realm, host, username, password)
# send the info to the server and report the result
code, result = self.post_to_server(self.build_post_data('submit'),
@@ -178,7 +179,7 @@ Your selection [default 1]: ''')
get_pypirc_path())
choice = 'X'
while choice.lower() not in 'yn':
- choice = raw_input('Save your login (y/N)?')
+ choice = input('Save your login (y/N)?')
if not choice:
choice = 'n'
if choice.lower() == 'y':
@@ -189,7 +190,7 @@ Your selection [default 1]: ''')
data['name'] = data['password'] = data['email'] = ''
data['confirm'] = None
while not data['name']:
- data['name'] = raw_input('Username: ')
+ data['name'] = input('Username: ')
while data['password'] != data['confirm']:
while not data['password']:
data['password'] = getpass.getpass('Password: ')
@@ -198,9 +199,9 @@ Your selection [default 1]: ''')
if data['password'] != data['confirm']:
data['password'] = ''
data['confirm'] = None
- print "Password and confirm don't match!"
+ print("Password and confirm don't match!")
while not data['email']:
- data['email'] = raw_input(' EMail: ')
+ data['email'] = input(' EMail: ')
code, result = self.post_to_server(data)
if code != 200:
logger.info('server response (%s): %s', code, result)
@@ -211,7 +212,7 @@ Your selection [default 1]: ''')
data = {':action': 'password_reset'}
data['email'] = ''
while not data['email']:
- data['email'] = raw_input('Your email address: ')
+ data['email'] = input('Your email address: ')
code, result = self.post_to_server(data)
logger.info('server response (%s): %s', code, result)
@@ -236,20 +237,20 @@ Your selection [default 1]: ''')
'Content-type': content_type,
'Content-length': str(len(body))
}
- req = urllib2.Request(self.repository, body, headers)
+ req = urllib.request.Request(self.repository, body, headers)
# handle HTTP and include the Basic Auth handler
- opener = urllib2.build_opener(
- urllib2.HTTPBasicAuthHandler(password_mgr=auth)
+ opener = urllib.request.build_opener(
+ urllib.request.HTTPBasicAuthHandler(password_mgr=auth)
)
data = ''
try:
result = opener.open(req)
- except urllib2.HTTPError, e:
+ except urllib.error.HTTPError as e:
if self.show_response:
data = e.fp.read()
result = e.code, e.msg
- except urllib2.URLError, e:
+ except urllib.error.URLError as e:
result = 500, str(e)
else:
if self.show_response:
diff --git a/distutils2/command/sdist.py b/distutils2/command/sdist.py
index 978b009..20f3616 100644
--- a/distutils2/command/sdist.py
+++ b/distutils2/command/sdist.py
@@ -3,7 +3,7 @@
import os
import re
import sys
-from StringIO import StringIO
+from io import StringIO
from distutils2 import logger
from distutils2.util import resolve_name
@@ -134,7 +134,7 @@ class sdist(Command):
if self.manifest_builders is None:
self.manifest_builders = []
else:
- if isinstance(self.manifest_builders, basestring):
+ if isinstance(self.manifest_builders, str):
self.manifest_builders = self.manifest_builders.split(',')
builders = []
for builder in self.manifest_builders:
@@ -143,7 +143,7 @@ class sdist(Command):
continue
try:
builder = resolve_name(builder)
- except ImportError, e:
+ except ImportError as e:
raise PackagingModuleError(e)
builders.append(builder)
@@ -337,7 +337,7 @@ class sdist(Command):
"""
return self.archive_files
- def create_tree(self, base_dir, files, mode=0777, verbose=1,
+ def create_tree(self, base_dir, files, mode=0o777, verbose=1,
dry_run=False):
need_dir = set()
for file in files:
diff --git a/distutils2/command/upload.py b/distutils2/command/upload.py
index 0bdac4a..20f2be0 100644
--- a/distutils2/command/upload.py
+++ b/distutils2/command/upload.py
@@ -4,14 +4,11 @@ import os
import socket
import logging
import platform
-import urlparse
+import urllib.parse
from base64 import standard_b64encode
-try:
- from hashlib import md5
-except ImportError:
- from distutils2._backport.hashlib import md5
-from urllib2 import HTTPError
-from urllib2 import urlopen, Request
+from hashlib import md5
+from urllib.error import HTTPError
+from urllib.request import urlopen, Request
from distutils2 import logger
from distutils2.errors import PackagingOptionError
@@ -87,7 +84,7 @@ class upload(Command):
def upload_file(self, command, pyversion, filename):
# Makes sure the repository URL is compliant
scheme, netloc, url, params, query, fragments = \
- urlparse.urlparse(self.repository)
+ urllib.parse.urlparse(self.repository)
if params or query or fragments:
raise AssertionError("Incompatible url %s" % self.repository)
@@ -104,11 +101,8 @@ class upload(Command):
# Fill in the data - send all the metadata in case we need to
# register a new release
- f = open(filename, 'rb')
- try:
+ with open(filename, 'rb') as f:
content = f.read()
- finally:
- f.close()
data = self.distribution.metadata.todict()
@@ -124,11 +118,8 @@ class upload(Command):
data['comment'] = 'built for %s' % platform.platform(terse=True)
if self.sign:
- fp = open(filename + '.asc')
- try:
+ with open(filename + '.asc') as fp:
sig = fp.read()
- finally:
- fp.close()
data['gpg_signature'] = [
(os.path.basename(filename) + ".asc", sig)]
@@ -136,7 +127,7 @@ class upload(Command):
# The exact encoding of the authentication string is debated.
# Anyway PyPI only accepts ascii for both username or password.
user_pass = (self.username + ":" + self.password).encode('ascii')
- auth = "Basic " + standard_b64encode(user_pass)
+ auth = b"Basic " + standard_b64encode(user_pass)
# Build up the MIME payload for the POST data
files = []
@@ -160,10 +151,10 @@ class upload(Command):
result = urlopen(request)
status = result.code
reason = result.msg
- except socket.error, e:
+ except socket.error as e:
logger.error(e)
return
- except HTTPError, e:
+ except HTTPError as e:
status = e.code
reason = e.msg
diff --git a/distutils2/command/upload_docs.py b/distutils2/command/upload_docs.py
index 2f813d3..9e93fb5 100644
--- a/distutils2/command/upload_docs.py
+++ b/distutils2/command/upload_docs.py
@@ -5,9 +5,9 @@ import base64
import socket
import zipfile
import logging
-import httplib
-import urlparse
-from StringIO import StringIO
+import http.client
+import urllib.parse
+from io import BytesIO
from distutils2 import logger
from distutils2.util import (read_pypirc, DEFAULT_REPOSITORY, DEFAULT_REALM,
@@ -18,7 +18,7 @@ from distutils2.command.cmd import Command
def zip_dir(directory):
"""Compresses recursively contents of directory into a BytesIO object"""
- destination = StringIO()
+ destination = BytesIO()
zip_file = zipfile.ZipFile(destination, "w")
try:
for root, dirs, files in os.walk(directory):
@@ -91,16 +91,16 @@ class upload_docs(Command):
credentials = self.username + ':' + self.password
# FIXME should use explicit encoding
- auth = "Basic " + base64.encodestring(credentials.encode()).strip()
+ auth = b"Basic " + base64.encodebytes(credentials.encode()).strip()
logger.info("Submitting documentation to %s", self.repository)
- scheme, netloc, url, params, query, fragments = urlparse.urlparse(
+ scheme, netloc, url, params, query, fragments = urllib.parse.urlparse(
self.repository)
if scheme == "http":
- conn = httplib.HTTPConnection(netloc)
+ conn = http.client.HTTPConnection(netloc)
elif scheme == "https":
- conn = httplib.HTTPSConnection(netloc)
+ conn = http.client.HTTPSConnection(netloc)
else:
raise AssertionError("unsupported scheme %r" % scheme)
@@ -113,7 +113,7 @@ class upload_docs(Command):
conn.endheaders()
conn.send(body)
- except socket.error, e:
+ except socket.error as e:
logger.error(e)
return
diff --git a/distutils2/compat.py b/distutils2/compat.py
index 7c82142..f7ac7a7 100644
--- a/distutils2/compat.py
+++ b/distutils2/compat.py
@@ -4,10 +4,7 @@ This module provides individual classes or objects backported from
Python 3.2, for internal use only. Whole modules are in _backport.
"""
-import os
-import re
import sys
-import codecs
from distutils2 import logger
@@ -62,131 +59,12 @@ class Mixin2to3(_KLASS):
# The rest of this file does not exist in packaging
# functions are sorted alphabetically and are not included in __all__
-try:
- any
-except NameError:
- def any(seq):
- for elem in seq:
- if elem:
- return True
- return False
-
-
-_cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
-
-
-def _get_normal_name(orig_enc):
- """Imitates get_normal_name in tokenizer.c."""
- # Only care about the first 12 characters.
- enc = orig_enc[:12].lower().replace("_", "-")
- if enc == "utf-8" or enc.startswith("utf-8-"):
- return "utf-8"
- if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \
- enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")):
- return "iso-8859-1"
- return orig_enc
-
-
-def detect_encoding(readline):
- """
- The detect_encoding() function is used to detect the encoding that should
- be used to decode a Python source file. It requires one argment, readline,
- in the same way as the tokenize() generator.
-
- It will call readline a maximum of twice, and return the encoding used
- (as a string) and a list of any lines (left as bytes) it has read in.
-
- It detects the encoding from the presence of a utf-8 bom or an encoding
- cookie as specified in pep-0263. If both a bom and a cookie are present,
- but disagree, a SyntaxError will be raised. If the encoding cookie is an
- invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
- 'utf-8-sig' is returned.
-
- If no encoding is specified, then the default of 'utf-8' will be returned.
- """
- bom_found = False
- encoding = None
- default = 'utf-8'
-
- def read_or_stop():
- try:
- return readline()
- except StopIteration:
- return ''
-
- def find_cookie(line):
- try:
- line_string = line.decode('ascii')
- except UnicodeDecodeError:
- return None
-
- matches = _cookie_re.findall(line_string)
- if not matches:
- return None
- encoding = _get_normal_name(matches[0])
- try:
- codec = codecs.lookup(encoding)
- except LookupError:
- # This behaviour mimics the Python interpreter
- raise SyntaxError("unknown encoding: " + encoding)
-
- if bom_found:
- if codec.name != 'utf-8':
- # This behaviour mimics the Python interpreter
- raise SyntaxError('encoding problem: utf-8')
- encoding += '-sig'
- return encoding
-
- first = read_or_stop()
- if first.startswith(codecs.BOM_UTF8):
- bom_found = True
- first = first[3:]
- default = 'utf-8-sig'
- if not first:
- return default, []
-
- encoding = find_cookie(first)
- if encoding:
- return encoding, [first]
-
- second = read_or_stop()
- if not second:
- return default, [first]
-
- encoding = find_cookie(second)
- if encoding:
- return encoding, [first, second]
-
- return default, [first, second]
-
def fsencode(filename):
- if isinstance(filename, str):
+ if isinstance(filename, bytes):
return filename
- elif isinstance(filename, unicode):
+ elif isinstance(filename, str):
return filename.encode(sys.getfilesystemencoding())
else:
raise TypeError("expect bytes or str, not %s" %
type(filename).__name__)
-
-
-try:
- from functools import wraps
-except ImportError:
- def wraps(func=None):
- """No-op replacement for functools.wraps"""
- def wrapped(func):
- return func
- return wrapped
-
-try:
- from platform import python_implementation
-except ImportError:
- def python_implementation():
- if 'PyPy' in sys.version:
- return 'PyPy'
- if os.name == 'java':
- return 'Jython'
- if sys.version.startswith('IronPython'):
- return 'IronPython'
- return 'CPython'
diff --git a/distutils2/compiler/__init__.py b/distutils2/compiler/__init__.py
index 2f95319..c69a57b 100644
--- a/distutils2/compiler/__init__.py
+++ b/distutils2/compiler/__init__.py
@@ -142,7 +142,7 @@ def show_compilers():
compilers = []
for name, cls in _COMPILERS.items():
- if isinstance(cls, basestring):
+ if isinstance(cls, str):
cls = resolve_name(cls)
_COMPILERS[name] = cls
@@ -179,7 +179,7 @@ def new_compiler(plat=None, compiler=None, verbose=0, dry_run=False,
msg = msg + " with '%s' compiler" % compiler
raise PackagingPlatformError(msg)
- if isinstance(cls, basestring):
+ if isinstance(cls, str):
cls = resolve_name(cls)
_COMPILERS[compiler] = cls
diff --git a/distutils2/compiler/bcppcompiler.py b/distutils2/compiler/bcppcompiler.py
index b7d5bb3..972c0f4 100644
--- a/distutils2/compiler/bcppcompiler.py
+++ b/distutils2/compiler/bcppcompiler.py
@@ -104,7 +104,7 @@ class BCPPCompiler(CCompiler) :
# This needs to be compiled to a .res file -- do it now.
try:
self.spawn(["brcc32", "-fo", obj, src])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
continue # the 'for' loop
@@ -128,7 +128,7 @@ class BCPPCompiler(CCompiler) :
self.spawn([self.cc] + compile_opts + pp_opts +
[input_opt, output_opt] +
extra_postargs + [src])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
return objects
@@ -146,7 +146,7 @@ class BCPPCompiler(CCompiler) :
pass # XXX what goes here?
try:
self.spawn([self.lib] + lib_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LibError(msg)
else:
logger.debug("skipping %s (up-to-date)", output_filename)
@@ -268,7 +268,7 @@ class BCPPCompiler(CCompiler) :
self.mkpath(os.path.dirname(output_filename))
try:
self.spawn([self.linker] + ld_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LinkError(msg)
else:
@@ -351,5 +351,5 @@ class BCPPCompiler(CCompiler) :
self.mkpath(os.path.dirname(output_file))
try:
self.spawn(pp_args)
- except PackagingExecError, exc:
- raise CompileError(exc)
+ except PackagingExecError as msg:
+ raise CompileError(msg)
diff --git a/distutils2/compiler/ccompiler.py b/distutils2/compiler/ccompiler.py
index 8ea2e50..009ba46 100644
--- a/distutils2/compiler/ccompiler.py
+++ b/distutils2/compiler/ccompiler.py
@@ -12,7 +12,7 @@ from distutils2.errors import CompileError, LinkError, UnknownFileError
from distutils2.compiler import gen_preprocess_options
-class CCompiler(object):
+class CCompiler:
"""Abstract base class to define the interface that must be implemented
by real compiler classes. Also has some utility methods used by
several compiler classes.
@@ -148,7 +148,7 @@ class CCompiler(object):
self.set_executable(key, value)
def set_executable(self, key, value):
- if isinstance(value, basestring):
+ if isinstance(value, str):
setattr(self, key, split_quoted(value))
else:
setattr(self, key, value)
@@ -170,8 +170,8 @@ class CCompiler(object):
if not (isinstance(defn, tuple) and
(len(defn) == 1 or
(len(defn) == 2 and
- (isinstance(defn[1], basestring) or defn[1] is None))) and
- isinstance(defn[0], basestring)):
+ (isinstance(defn[1], str) or defn[1] is None))) and
+ isinstance(defn[0], str)):
raise TypeError(("invalid macro definition '%s': " % defn) + \
"must be tuple (string,), (string, string), or " + \
"(string, None)")
@@ -311,7 +311,7 @@ class CCompiler(object):
"""Process arguments and decide which source files to compile."""
if outdir is None:
outdir = self.output_dir
- elif not isinstance(outdir, basestring):
+ elif not isinstance(outdir, str):
raise TypeError("'output_dir' must be a string or None")
if macros is None:
@@ -371,7 +371,7 @@ class CCompiler(object):
"""
if output_dir is None:
output_dir = self.output_dir
- elif not isinstance(output_dir, basestring):
+ elif not isinstance(output_dir, str):
raise TypeError("'output_dir' must be a string or None")
if macros is None:
@@ -403,7 +403,7 @@ class CCompiler(object):
if output_dir is None:
output_dir = self.output_dir
- elif not isinstance(output_dir, basestring):
+ elif not isinstance(output_dir, str):
raise TypeError("'output_dir' must be a string or None")
return objects, output_dir
@@ -727,8 +727,7 @@ class CCompiler(object):
if library_dirs is None:
library_dirs = []
fd, fname = tempfile.mkstemp(".c", funcname, text=True)
- f = os.fdopen(fd, "w")
- try:
+ with os.fdopen(fd, "w") as f:
for incl in includes:
f.write("""#include "%s"\n""" % incl)
f.write("""\
@@ -736,8 +735,6 @@ main (int argc, char **argv) {
%s();
}
""" % funcname)
- finally:
- f.close()
try:
objects = self.compile([fname], include_dirs=include_dirs)
except CompileError:
@@ -854,7 +851,7 @@ main (int argc, char **argv) {
return
return move(src, dst)
- def mkpath(self, name, mode=0777):
+ def mkpath(self, name, mode=0o777):
name = os.path.normpath(name)
if os.path.isdir(name) or name == '':
return
diff --git a/distutils2/compiler/cygwinccompiler.py b/distutils2/compiler/cygwinccompiler.py
index 2b1c59a..4b0b786 100644
--- a/distutils2/compiler/cygwinccompiler.py
+++ b/distutils2/compiler/cygwinccompiler.py
@@ -156,13 +156,13 @@ class CygwinCCompiler(UnixCCompiler):
# gcc needs '.res' and '.rc' compiled to object files !!!
try:
self.spawn(["windres", "-i", src, "-o", obj])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
else: # for other files use the C-compiler
try:
self.spawn(self.compiler_so + cc_args + [src, '-o', obj] +
extra_postargs)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
def link(self, target_desc, objects, output_filename, output_dir=None,
@@ -344,14 +344,11 @@ def check_config_h():
# let's see if __GNUC__ is mentioned in python.h
fn = sysconfig.get_config_h_filename()
try:
- config_h = open(fn)
- try:
+ with open(fn) as config_h:
if "__GNUC__" in config_h.read():
return CONFIG_H_OK, "'%s' mentions '__GNUC__'" % fn
else:
return CONFIG_H_NOTOK, "'%s' does not mention '__GNUC__'" % fn
- finally:
- config_h.close()
- except IOError, exc:
+ except IOError as exc:
return (CONFIG_H_UNCERTAIN,
"couldn't read '%s': %s" % (fn, exc.strerror))
diff --git a/distutils2/compiler/extension.py b/distutils2/compiler/extension.py
index 1ccf30c..f5fc0c0 100644
--- a/distutils2/compiler/extension.py
+++ b/distutils2/compiler/extension.py
@@ -13,7 +13,7 @@ from distutils2 import logger
# order to do anything.
-class Extension(object):
+class Extension:
"""Just a collection of attributes that describes an extension
module and everything needed to build it (hopefully in a portable
way, but there are hooks that let you be as unportable as you need).
@@ -86,14 +86,14 @@ class Extension(object):
extra_compile_args=None, extra_link_args=None,
export_symbols=None, swig_opts=None, depends=None,
language=None, optional=None, **kw):
- if not isinstance(name, basestring):
+ if not isinstance(name, str):
raise AssertionError("'name' must be a string")
if not isinstance(sources, list):
raise AssertionError("'sources' must be a list of strings")
for v in sources:
- if not isinstance(v, basestring):
+ if not isinstance(v, str):
raise AssertionError("'sources' must be a list of strings")
self.name = name
diff --git a/distutils2/compiler/msvc9compiler.py b/distutils2/compiler/msvc9compiler.py
index a7a524e..fb53d7d 100644
--- a/distutils2/compiler/msvc9compiler.py
+++ b/distutils2/compiler/msvc9compiler.py
@@ -46,7 +46,7 @@ PLAT_TO_VCVARS = {
}
-class Reg(object):
+class Reg:
"""Helper class to read values from the registry
"""
@@ -108,7 +108,7 @@ class Reg(object):
return s
convert_mbcs = staticmethod(convert_mbcs)
-class MacroExpander(object):
+class MacroExpander:
def __init__(self, version):
self.macros = {}
@@ -477,7 +477,7 @@ class MSVCCompiler(CCompiler) :
try:
self.spawn([self.rc] + pp_opts +
[output_opt] + [input_opt])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
continue
elif ext in self._mc_extensions:
@@ -504,7 +504,7 @@ class MSVCCompiler(CCompiler) :
self.spawn([self.rc] +
["/fo" + obj] + [rc_file])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
continue
else:
@@ -517,7 +517,7 @@ class MSVCCompiler(CCompiler) :
self.spawn([self.cc] + compile_opts + pp_opts +
[input_opt, output_opt] +
extra_postargs)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
return objects
@@ -542,7 +542,7 @@ class MSVCCompiler(CCompiler) :
pass # XXX what goes here?
try:
self.spawn([self.lib] + lib_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LibError(msg)
else:
logger.debug("skipping %s (up-to-date)", output_filename)
@@ -620,7 +620,7 @@ class MSVCCompiler(CCompiler) :
self.mkpath(os.path.dirname(output_filename))
try:
self.spawn([self.linker] + ld_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LinkError(msg)
# embed the manifest
@@ -637,7 +637,7 @@ class MSVCCompiler(CCompiler) :
try:
self.spawn(['mt.exe', '-nologo', '-manifest',
temp_manifest, out_arg])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LinkError(msg)
else:
logger.debug("skipping %s (up-to-date)", output_filename)
diff --git a/distutils2/compiler/msvccompiler.py b/distutils2/compiler/msvccompiler.py
index fb4d521..7a0d313 100644
--- a/distutils2/compiler/msvccompiler.py
+++ b/distutils2/compiler/msvccompiler.py
@@ -105,7 +105,7 @@ def convert_mbcs(s):
return s
-class MacroExpander(object):
+class MacroExpander:
def __init__(self, version):
self.macros = {}
@@ -386,7 +386,7 @@ class MSVCCompiler(CCompiler):
try:
self.spawn([self.rc] + pp_opts +
[output_opt] + [input_opt])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
continue
elif ext in self._mc_extensions:
@@ -415,7 +415,7 @@ class MSVCCompiler(CCompiler):
self.spawn([self.rc] +
["/fo" + obj] + [rc_file])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
continue
else:
@@ -429,7 +429,7 @@ class MSVCCompiler(CCompiler):
self.spawn([self.cc] + compile_opts + pp_opts +
[input_opt, output_opt] +
extra_postargs)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
return objects
@@ -448,7 +448,7 @@ class MSVCCompiler(CCompiler):
pass # XXX what goes here?
try:
self.spawn([self.lib] + lib_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LibError(msg)
else:
@@ -515,7 +515,7 @@ class MSVCCompiler(CCompiler):
self.mkpath(os.path.dirname(output_filename))
try:
self.spawn([self.linker] + ld_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LinkError(msg)
else:
diff --git a/distutils2/compiler/unixccompiler.py b/distutils2/compiler/unixccompiler.py
index 02af746..95bcd79 100644
--- a/distutils2/compiler/unixccompiler.py
+++ b/distutils2/compiler/unixccompiler.py
@@ -165,7 +165,7 @@ class UnixCCompiler(CCompiler):
self.mkpath(os.path.dirname(output_file))
try:
self.spawn(pp_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
@@ -175,7 +175,7 @@ class UnixCCompiler(CCompiler):
try:
self.spawn(compiler_so + cc_args + [src, '-o', obj] +
extra_postargs)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise CompileError(msg)
def create_static_lib(self, objects, output_libname,
@@ -199,7 +199,7 @@ class UnixCCompiler(CCompiler):
if self.ranlib:
try:
self.spawn(self.ranlib + [output_filename])
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LibError(msg)
else:
logger.debug("skipping %s (up-to-date)", output_filename)
@@ -253,7 +253,7 @@ class UnixCCompiler(CCompiler):
linker = _darwin_compiler_fixup(linker, ld_args)
self.spawn(linker + ld_args)
- except PackagingExecError, msg:
+ except PackagingExecError as msg:
raise LinkError(msg)
else:
logger.debug("skipping %s (up-to-date)", output_filename)
diff --git a/distutils2/config.py b/distutils2/config.py
index e6a52fc..10ab865 100644
--- a/distutils2/config.py
+++ b/distutils2/config.py
@@ -2,11 +2,10 @@
import os
import sys
-import codecs
import logging
from shlex import split
-from ConfigParser import RawConfigParser
+from configparser import RawConfigParser
from distutils2 import logger
from distutils2.errors import PackagingOptionError
from distutils2.compiler.extension import Extension
@@ -43,11 +42,9 @@ def _pop_values(values_dct, key):
continue
fields.append(tmp_vals[0])
# Get bash options like `gcc -print-file-name=libgcc.a` XXX bash options?
- # kludge around shlex not supporting unicode
- vals = u' '.join(fields).encode('utf-8')
- vals = split(vals)
+ vals = split(' '.join(fields))
if vals:
- return [val.decode('utf-8') for val in vals]
+ return vals
def _rel_path(base, path):
@@ -76,7 +73,7 @@ def get_resources_dests(resources_root, rules):
return destinations
-class Config(object):
+class Config:
"""Class used to work with configuration files"""
def __init__(self, dist):
self.dist = dist
@@ -157,7 +154,7 @@ class Config(object):
for line in setup_hooks:
try:
hook = resolve_name(line)
- except ImportError, e:
+ except ImportError as e:
logger.warning('cannot find setup hook: %s',
e.args[0])
else:
@@ -192,11 +189,8 @@ class Config(object):
value = []
for filename in filenames:
# will raise if file not found
- description_file = open(filename)
- try:
+ with open(filename) as description_file:
value.append(description_file.read().strip())
- finally:
- description_file.close()
# add filename as a required file
if filename not in metadata.requires_files:
metadata.requires_files.append(filename)
@@ -216,7 +210,7 @@ class Config(object):
self.dist.packages = []
packages = files.get('packages', [])
- if isinstance(packages, basestring):
+ if isinstance(packages, str):
packages = [packages]
for package in packages:
@@ -226,10 +220,10 @@ class Config(object):
self.dist.packages.append(package)
self.dist.py_modules = files.get('modules', [])
- if isinstance(self.dist.py_modules, basestring):
+ if isinstance(self.dist.py_modules, str):
self.dist.py_modules = [self.dist.py_modules]
self.dist.scripts = files.get('scripts', [])
- if isinstance(self.dist.scripts, basestring):
+ if isinstance(self.dist.scripts, str):
self.dist.scripts = [self.dist.scripts]
self.dist.package_data = {}
@@ -311,11 +305,8 @@ class Config(object):
for filename in filenames:
logger.debug(" reading %s", filename)
- f = codecs.open(filename, 'r', encoding='utf-8')
- try:
+ with open(filename, 'r', encoding='utf-8') as f:
parser.readfp(f)
- finally:
- f.close()
if os.path.split(filename)[-1] == 'setup.cfg':
self._read_setup_cfg(parser, filename)
@@ -339,7 +330,7 @@ class Config(object):
if opt == 'sub_commands':
val = split_multiline(val)
- if isinstance(val, basestring):
+ if isinstance(val, str):
val = [val]
# Hooks use a suffix system to prevent being overriden
@@ -372,19 +363,19 @@ class Config(object):
setattr(self.dist, opt, strtobool(val))
else:
setattr(self.dist, opt, val)
- except ValueError, msg:
+ except ValueError as msg:
raise PackagingOptionError(msg)
def _load_compilers(self, compilers):
compilers = split_multiline(compilers)
- if isinstance(compilers, basestring):
+ if isinstance(compilers, str):
compilers = [compilers]
for compiler in compilers:
set_compiler(compiler.strip())
def _load_commands(self, commands):
commands = split_multiline(commands)
- if isinstance(commands, basestring):
+ if isinstance(commands, str):
commands = [commands]
for command in commands:
set_command(command.strip())
diff --git a/distutils2/create.py b/distutils2/create.py
index 78c291c..139cf6a 100644
--- a/distutils2/create.py
+++ b/distutils2/create.py
@@ -23,25 +23,17 @@ import re
import imp
import sys
import glob
-import codecs
import shutil
+from hashlib import md5
from textwrap import dedent
-from ConfigParser import RawConfigParser
+from tokenize import detect_encoding
+from configparser import RawConfigParser
# importing this with an underscore as it should be replaced by the
# dict form or another structures for all purposes
from distutils2._trove import all_classifiers as _CLASSIFIERS_LIST
-from distutils2.compat import detect_encoding
from distutils2.version import is_valid_version
from distutils2._backport import sysconfig
-try:
- any
-except NameError:
- from distutils2.compat import any
-try:
- from hashlib import md5
-except ImportError:
- from distutils2._backport.hashlib import md5
_FILENAME = 'setup.cfg'
@@ -120,26 +112,20 @@ def load_setup():
This function load the setup file in all cases (even if it have already
been loaded before, because we are monkey patching its setup function with
a particular one"""
- f = open("setup.py", "rb")
- try:
+ with open("setup.py", "rb") as f:
encoding, lines = detect_encoding(f.readline)
- finally:
- f.close()
- f = open("setup.py")
- try:
+ with open("setup.py", encoding=encoding) as f:
imp.load_module("setup", f, "setup.py", (".py", "r", imp.PY_SOURCE))
- finally:
- f.close()
def ask_yn(question, default=None, helptext=None):
question += ' (y/n)'
while True:
answer = ask(question, default, helptext, required=True)
- if answer and answer[0].lower() in 'yn':
+ if answer and answer[0].lower() in ('y', 'n'):
return answer[0].lower()
- print '\nERROR: You must select "Y" or "N".\n'
+ print('\nERROR: You must select "Y" or "N".\n')
# XXX use util.ask
@@ -148,11 +134,11 @@ def ask_yn(question, default=None, helptext=None):
def ask(question, default=None, helptext=None, required=True,
lengthy=False, multiline=False):
- prompt = u'%s: ' % (question,)
+ prompt = '%s: ' % (question,)
if default:
- prompt = u'%s [%s]: ' % (question, default)
+ prompt = '%s [%s]: ' % (question, default)
if default and len(question) + len(default) > 70:
- prompt = u'%s\n [%s]: ' % (question, default)
+ prompt = '%s\n [%s]: ' % (question, default)
if lengthy or multiline:
prompt += '\n > '
@@ -167,19 +153,19 @@ def ask(question, default=None, helptext=None, required=True,
line = sys.stdin.readline().strip()
if line == '?':
- print '=' * 70
- print helptext
- print '=' * 70
+ print('=' * 70)
+ print(helptext)
+ print('=' * 70)
continue
if default and not line:
return default
if not line and required:
- print '*' * 70
- print 'This value cannot be empty.'
- print '==========================='
+ print('*' * 70)
+ print('This value cannot be empty.')
+ print('===========================')
if helptext:
- print helptext
- print '*' * 70
+ print(helptext)
+ print('*' * 70)
continue
return line
@@ -216,7 +202,7 @@ def _build_licences(classifiers):
LICENCES = _build_licences(_CLASSIFIERS_LIST)
-class MainProgram(object):
+class MainProgram:
"""Make a project setup configuration file (setup.cfg)."""
def __init__(self):
@@ -286,34 +272,32 @@ class MainProgram(object):
def _write_cfg(self):
if os.path.exists(_FILENAME):
if os.path.exists('%s.old' % _FILENAME):
- print ('ERROR: %(name)s.old backup exists, please check that '
- 'current %(name)s is correct and remove %(name)s.old' %
- {'name': _FILENAME})
+ print("ERROR: %(name)s.old backup exists, please check that "
+ "current %(name)s is correct and remove %(name)s.old" %
+ {'name': _FILENAME})
return
shutil.move(_FILENAME, '%s.old' % _FILENAME)
- fp = codecs.open(_FILENAME, 'w', encoding='utf-8')
- try:
- fp.write(u'[metadata]\n')
+ with open(_FILENAME, 'w', encoding='utf-8') as fp:
+ fp.write('[metadata]\n')
# TODO use metadata module instead of hard-coding field-specific
# behavior here
# simple string entries
for name in ('name', 'version', 'summary', 'download_url'):
- fp.write(u'%s = %s\n' % (name, self.data.get(name, 'UNKNOWN')))
+ fp.write('%s = %s\n' % (name, self.data.get(name, 'UNKNOWN')))
# optional string entries
if 'keywords' in self.data and self.data['keywords']:
- fp.write(u'keywords = %s\n' % ' '.join(self.data['keywords']))
+ fp.write('keywords = %s\n' % ' '.join(self.data['keywords']))
for name in ('home_page', 'author', 'author_email',
'maintainer', 'maintainer_email', 'description-file'):
if name in self.data and self.data[name]:
- fp.write(u'%s = %s\n' % (name.decode('utf-8'),
- self.data[name].decode('utf-8')))
+ fp.write('%s = %s\n' % (name, self.data[name]))
if 'description' in self.data:
fp.write(
- u'description = %s\n'
- % u'\n |'.join(self.data['description'].split('\n')))
+ 'description = %s\n'
+ % '\n |'.join(self.data['description'].split('\n')))
# multiple use string entries
for name in ('platform', 'supported-platform', 'classifier',
@@ -321,25 +305,23 @@ class MainProgram(object):
'requires-external'):
if not(name in self.data and self.data[name]):
continue
- fp.write(u'%s = ' % name)
- fp.write(u''.join(' %s\n' % val
+ fp.write('%s = ' % name)
+ fp.write(''.join(' %s\n' % val
for val in self.data[name]).lstrip())
- fp.write(u'\n[files]\n')
+ fp.write('\n[files]\n')
for name in ('packages', 'modules', 'scripts',
'package_data', 'extra_files'):
if not(name in self.data and self.data[name]):
continue
- fp.write(u'%s = %s\n'
- % (name, u'\n '.join(self.data[name]).strip()))
- fp.write(u'\nresources =\n')
+ fp.write('%s = %s\n'
+ % (name, '\n '.join(self.data[name]).strip()))
+ fp.write('\nresources =\n')
for src, dest in self.data['resources']:
- fp.write(u' %s = %s\n' % (src, dest))
- fp.write(u'\n')
- finally:
- fp.close()
+ fp.write(' %s = %s\n' % (src, dest))
+ fp.write('\n')
- os.chmod(_FILENAME, 0644)
- print 'Wrote %r.' % _FILENAME
+ os.chmod(_FILENAME, 0o644)
+ print('Wrote "%s".' % _FILENAME)
def convert_py_to_cfg(self):
"""Generate a setup.cfg from an existing setup.py.
@@ -368,9 +350,8 @@ class MainProgram(object):
('description', 'summary'),
('long_description', 'description'),
('url', 'home_page'),
- ('platforms', 'platform'))
- if sys.version >= '2.5':
- labels += (
+ ('platforms', 'platform'),
+ # backport only for 2.5+
('provides', 'provides-dist'),
('obsoletes', 'obsoletes-dist'),
('requires', 'requires-dist'))
@@ -386,7 +367,7 @@ class MainProgram(object):
# 2.1 data_files -> resources
if dist.data_files:
if (len(dist.data_files) < 2 or
- isinstance(dist.data_files[1], basestring)):
+ isinstance(dist.data_files[1], str)):
dist.data_files = [('', dist.data_files)]
# add tokens in the destination paths
vars = {'distribution.name': data['name']}
@@ -421,11 +402,8 @@ class MainProgram(object):
self.data['description']).lower().encode())
ref = ref.digest()
for readme in glob.glob('README*'):
- fp = codecs.open(readme, encoding='utf-8')
- try:
+ with open(readme, encoding='utf-8') as fp:
contents = fp.read()
- finally:
- fp.close()
contents = re.sub('\s', '', contents.lower()).encode()
val = md5(contents).digest()
if val == ref:
@@ -637,8 +615,8 @@ class MainProgram(object):
break
if len(found_list) == 0:
- print ('ERROR: Could not find a matching license for "%s"' %
- license)
+ print('ERROR: Could not find a matching license for "%s"' %
+ license)
continue
question = 'Matching licenses:\n\n'
@@ -659,8 +637,8 @@ class MainProgram(object):
try:
index = found_list[int(choice) - 1]
except ValueError:
- print ('ERROR: Invalid selection, type a number from the list '
- 'above.')
+ print("ERROR: Invalid selection, type a number from the list "
+ "above.")
classifiers.add(_CLASSIFIERS_LIST[index])
@@ -683,8 +661,8 @@ class MainProgram(object):
classifiers.add(key)
return
except (IndexError, ValueError):
- print ('ERROR: Invalid selection, type a single digit '
- 'number.')
+ print("ERROR: Invalid selection, type a single digit "
+ "number.")
def main():
diff --git a/distutils2/database.py b/distutils2/database.py
index 55fe71f..63918b5 100644
--- a/distutils2/database.py
+++ b/distutils2/database.py
@@ -5,11 +5,8 @@ import re
import csv
import sys
import zipimport
-from StringIO import StringIO
-try:
- from hashlib import md5
-except ImportError:
- from distutils2._backport.hashlib import md5
+from io import StringIO
+from hashlib import md5
from distutils2 import logger
from distutils2.errors import PackagingError
@@ -122,7 +119,7 @@ def _generate_cache(use_egg_info, paths):
_cache_generated_egg = True
-class Distribution(object):
+class Distribution:
"""Created with the *path* of the ``.dist-info`` directory provided to the
constructor. It reads the metadata contained in ``METADATA`` when it is
instantiated."""
@@ -162,8 +159,7 @@ class Distribution(object):
def _get_records(self, local=False):
results = []
- record = self.get_distinfo_file('RECORD')
- try:
+ with self.get_distinfo_file('RECORD') as record:
record_reader = csv.reader(record, delimiter=',',
lineterminator='\n')
for row in record_reader:
@@ -173,20 +169,15 @@ class Distribution(object):
path = path.replace('/', os.sep)
path = os.path.join(sys.prefix, path)
results.append((path, checksum, size))
- finally:
- record.close()
return results
def get_resource_path(self, relative_path):
- resources_file = self.get_distinfo_file('RESOURCES')
- try:
+ with self.get_distinfo_file('RESOURCES') as resources_file:
resources_reader = csv.reader(resources_file, delimiter=',',
lineterminator='\n')
for relative, destination in resources_reader:
if relative == relative_path:
return destination
- finally:
- resources_file.close()
raise KeyError(
'no resource file with relative path %r is installed' %
relative_path)
@@ -284,7 +275,7 @@ class Distribution(object):
__hash__ = object.__hash__
-class EggInfoDistribution(object):
+class EggInfoDistribution:
"""Created with the *path* of the ``.egg-info`` directory or file provided
to the constructor. It reads the metadata contained in the file itself, or
if the given path happens to be a directory, the metadata is read from the
@@ -318,7 +309,7 @@ class EggInfoDistribution(object):
def yield_lines(strs):
"""Yield non-empty/non-comment lines of a ``basestring``
or sequence"""
- if isinstance(strs, basestring):
+ if isinstance(strs, str):
for s in strs.splitlines():
s = s.strip()
# skip blank lines/comments
@@ -337,11 +328,8 @@ class EggInfoDistribution(object):
self.metadata = Metadata(path=meta_path)
try:
req_path = os.path.join(path, 'EGG-INFO', 'requires.txt')
- fp = open(req_path, 'r')
- try:
+ with open(req_path, 'r') as fp:
requires = fp.read()
- finally:
- fp.close()
except IOError:
requires = None
else:
@@ -361,11 +349,8 @@ class EggInfoDistribution(object):
if os.path.isdir(path):
path = os.path.join(path, 'PKG-INFO')
try:
- fp = open(os.path.join(path, 'requires.txt'), 'r')
- try:
+ with open(os.path.join(path, 'requires.txt'), 'r') as fp:
requires = fp.read()
- finally:
- fp.close()
except IOError:
requires = None
self.metadata = Metadata(path=path)
@@ -427,11 +412,8 @@ class EggInfoDistribution(object):
def list_installed_files(self, local=False):
def _md5(path):
- f = open(path, 'rb')
- try:
+ with open(path, 'rb') as f:
content = f.read()
- finally:
- f.close()
return md5(content).hexdigest()
def _size(path):
diff --git a/distutils2/depgraph.py b/distutils2/depgraph.py
index af8157c..5fc9bc2 100644
--- a/distutils2/depgraph.py
+++ b/distutils2/depgraph.py
@@ -7,7 +7,7 @@ graph, find reverse dependencies, and print a graph in DOT format.
import sys
-from StringIO import StringIO
+from io import StringIO
from distutils2.errors import PackagingError
from distutils2.version import VersionPredicate, IrrationalVersionError
@@ -107,26 +107,26 @@ def graph_to_dot(graph, f, skip_disconnected=True):
"""
disconnected = []
- f.write(u"digraph dependencies {\n")
+ f.write("digraph dependencies {\n")
for dist, adjs in graph.adjacency_list.items():
if len(adjs) == 0 and not skip_disconnected:
disconnected.append(dist)
for other, label in adjs:
if not label is None:
- f.write(u'"%s" -> "%s" [label="%s"]\n' %
+ f.write('"%s" -> "%s" [label="%s"]\n' %
(dist.name, other.name, label))
else:
- f.write(u'"%s" -> "%s"\n' % (dist.name, other.name))
+ f.write('"%s" -> "%s"\n' % (dist.name, other.name))
if not skip_disconnected and len(disconnected) > 0:
- f.write(u'subgraph disconnected {\n')
- f.write(u'label = "Disconnected"\n')
- f.write(u'bgcolor = red\n')
+ f.write('subgraph disconnected {\n')
+ f.write('label = "Disconnected"\n')
+ f.write('bgcolor = red\n')
for dist in disconnected:
- f.write(u'"%s"' % dist.name)
- f.write(u'\n')
- f.write(u'}\n')
- f.write(u'}\n')
+ f.write('"%s"' % dist.name)
+ f.write('\n')
+ f.write('}\n')
+ f.write('}\n')
def generate_graph(dists):
@@ -234,22 +234,22 @@ def main():
graph = generate_graph(dists)
finally:
sys.stderr = old
- except Exception, e:
+ except Exception as e:
tempout.seek(0)
tempout = tempout.read()
- print 'Could not generate the graph'
- print tempout
- print e
+ print('Could not generate the graph')
+ print(tempout)
+ print(e)
sys.exit(1)
for dist, reqs in graph.missing.items():
if len(reqs) > 0:
- print 'Warning: Missing dependencies for %r:' % dist.name, \
- ', '.join(reqs)
+ print("Warning: Missing dependencies for %r:" % dist.name,
+ ", ".join(reqs))
# XXX replace with argparse
if len(sys.argv) == 1:
- print 'Dependency graph:'
- print ' ', repr(graph).replace('\n', '\n ')
+ print('Dependency graph:')
+ print(' ', repr(graph).replace('\n', '\n '))
sys.exit(0)
elif len(sys.argv) > 1 and sys.argv[1] in ('-d', '--dot'):
if len(sys.argv) > 2:
@@ -257,18 +257,15 @@ def main():
else:
filename = 'depgraph.dot'
- f = open(filename, 'w')
- try:
+ with open(filename, 'w') as f:
graph_to_dot(graph, f, True)
- finally:
- f.close()
tempout.seek(0)
tempout = tempout.read()
- print tempout
- print 'Dot file written at %r' % filename
+ print(tempout)
+ print('Dot file written at %r' % filename)
sys.exit(0)
else:
- print 'Supported option: -d [filename]'
+ print('Supported option: -d [filename]')
sys.exit(1)
diff --git a/distutils2/dist.py b/distutils2/dist.py
index 25d7c2b..e2a4266 100644
--- a/distutils2/dist.py
+++ b/distutils2/dist.py
@@ -32,7 +32,7 @@ def gen_usage(script_name):
return USAGE % {'script': script}
-class Distribution(object):
+class Distribution:
"""Class used to represent a project and work with it.
Most of the work hiding behind 'pysetup run' is really done within a
@@ -355,7 +355,7 @@ Common commands: (see '--help-commands' for more)
# it takes.
try:
cmd_class = get_command_class(command)
- except PackagingModuleError, msg:
+ except PackagingModuleError as msg:
raise PackagingArgError(msg)
# XXX We want to push this in distutils2.command
@@ -460,14 +460,14 @@ Common commands: (see '--help-commands' for more)
options = self.global_options
parser.set_option_table(options)
parser.print_help(self.common_usage + "\nGlobal options:")
- print
+ print()
if display_options:
parser.set_option_table(self.display_options)
parser.print_help(
"Information display options (just display " +
"information, ignore any commands)")
- print
+ print()
for command in self.commands:
if isinstance(command, type) and issubclass(command, Command):
@@ -480,9 +480,9 @@ Common commands: (see '--help-commands' for more)
else:
parser.set_option_table(cls.user_options)
parser.print_help("Options for %r command:" % cls.__name__)
- print
+ print()
- print gen_usage(self.script_name)
+ print(gen_usage(self.script_name))
def handle_display_options(self, option_order):
"""If there were any non-global "display-only" options
@@ -494,8 +494,8 @@ Common commands: (see '--help-commands' for more)
# we ignore "foo bar").
if self.help_commands:
self.print_commands()
- print
- print gen_usage(self.script_name)
+ print()
+ print(gen_usage(self.script_name))
return True
# If user supplied any of the "display metadata" options, then
@@ -511,12 +511,12 @@ Common commands: (see '--help-commands' for more)
opt = opt.replace('-', '_')
value = self.metadata[opt]
if opt in ('keywords', 'platform'):
- print ','.join(value)
+ print(','.join(value))
elif opt in ('classifier', 'provides', 'requires',
'obsoletes'):
- print '\n'.join(value)
+ print('\n'.join(value))
else:
- print value
+ print(value)
any_display_options = True
return any_display_options
@@ -525,14 +525,14 @@ Common commands: (see '--help-commands' for more)
"""Print a subset of the list of all commands -- used by
'print_commands()'.
"""
- print header + ":"
+ print(header + ":")
for cmd in commands:
cls = self.cmdclass.get(cmd) or get_command_class(cmd)
description = getattr(cls, 'description',
'(no description available)')
- print " %-*s %s" % (max_length, cmd, description)
+ print(" %-*s %s" % (max_length, cmd, description))
def _get_command_groups(self):
"""Helper function to retrieve all the command class names divided
@@ -562,7 +562,7 @@ Common commands: (see '--help-commands' for more)
"Standard commands",
max_length)
if extra_commands:
- print
+ print()
self.print_command_list(extra_commands,
"Extra commands",
max_length)
@@ -622,7 +622,7 @@ Common commands: (see '--help-commands' for more)
neg_opt = {}
try:
- is_string = isinstance(value, basestring)
+ is_string = isinstance(value, str)
if option in neg_opt and is_string:
setattr(command_obj, neg_opt[option], not strtobool(value))
elif option in bool_opts and is_string:
@@ -633,7 +633,7 @@ Common commands: (see '--help-commands' for more)
raise PackagingOptionError(
"error in %s: command %r has no such option %r" %
(source, command_name, option))
- except ValueError, msg:
+ except ValueError as msg:
raise PackagingOptionError(msg)
def get_reinitialized_command(self, command, reinit_subcommands=False):
@@ -725,10 +725,10 @@ Common commands: (see '--help-commands' for more)
return
for hook in hooks.values():
- if isinstance(hook, basestring):
+ if isinstance(hook, str):
try:
hook_obj = resolve_name(hook)
- except ImportError, e:
+ except ImportError as e:
raise PackagingModuleError(e)
else:
hook_obj = hook
diff --git a/distutils2/fancy_getopt.py b/distutils2/fancy_getopt.py
index 966f843..09a663a 100644
--- a/distutils2/fancy_getopt.py
+++ b/distutils2/fancy_getopt.py
@@ -28,7 +28,7 @@ longopt_re = re.compile(r'^%s$' % longopt_pat)
neg_alias_re = re.compile("^(%s)=!(%s)$" % (longopt_pat, longopt_pat))
-class FancyGetopt(object):
+class FancyGetopt:
"""Wrapper around the standard 'getopt()' module that provides some
handy extra functionality:
* short and long options are tied together
@@ -151,13 +151,13 @@ class FancyGetopt(object):
raise ValueError("invalid option tuple: %r" % option)
# Type- and value-check the option names
- if not isinstance(longopt, basestring) or len(longopt) < 2:
+ if not isinstance(longopt, str) or len(longopt) < 2:
raise PackagingGetoptError(
("invalid long option '%s': "
"must be a string of length >= 2") % longopt)
if (not ((short is None) or
- (isinstance(short, basestring) and len(short) == 1))):
+ (isinstance(short, str) and len(short) == 1))):
raise PackagingGetoptError(
("invalid short option '%s': "
"must be a single character or None") % short)
@@ -237,7 +237,7 @@ class FancyGetopt(object):
try:
opts, args = getopt.getopt(args, short_opts, self.long_opts)
- except getopt.error, msg:
+ except getopt.error as msg:
raise PackagingArgError(msg)
for opt, val in opts:
@@ -377,7 +377,7 @@ def fancy_getopt(options, negative_opt, object, args):
return parser.getopt(args, object)
-class OptionDummy(object):
+class OptionDummy:
"""Dummy class just used as a place to hold command-line option
values as instance attributes."""
diff --git a/distutils2/install.py b/distutils2/install.py
index 91cbd7a..832f5db 100644
--- a/distutils2/install.py
+++ b/distutils2/install.py
@@ -51,7 +51,7 @@ def _move_files(files, destination):
# try to make the paths.
try:
os.makedirs(os.path.dirname(new))
- except OSError, e:
+ except OSError as e:
if e.errno != errno.EEXIST:
raise
os.rename(old, new)
@@ -88,7 +88,7 @@ def _run_packaging_install(path):
dist.run_command('install_dist')
name = dist.metadata['Name']
return database.get_distribution(name) is not None
- except (IOError, os.error, PackagingError, CCompilerError), msg:
+ except (IOError, os.error, PackagingError, CCompilerError) as msg:
raise ValueError("Failed to install, " + str(msg))
@@ -160,7 +160,7 @@ def _run_install_from_dir(source_dir):
try:
func(source_dir)
return True
- except ValueError, err:
+ except ValueError as err:
# failed to install
logger.info(str(err))
return False
@@ -187,7 +187,7 @@ def install_dists(dists, path, paths=None):
try:
_install_dist(dist, path)
installed_dists.append(dist)
- except Exception, e:
+ except Exception as e:
logger.info('Failed: %s', e)
# reverting
@@ -396,7 +396,7 @@ def remove(project_name, paths=None, auto_confirm=True):
def _move_file(source, target):
try:
os.rename(source, target)
- except OSError, err:
+ except OSError as err:
return err
return None
@@ -495,12 +495,9 @@ def install(project):
# trying to write a file there
try:
- testfile = tempfile.NamedTemporaryFile(suffix=project,
- dir=purelib_path)
- try:
- testfile.write('test')
- finally:
- testfile.close()
+ with tempfile.NamedTemporaryFile(suffix=project,
+ dir=purelib_path) as testfile:
+ testfile.write(b'test')
except OSError:
# FIXME this should check the errno, or be removed altogether (race
# condition: the directory permissions could be changed between here
@@ -525,7 +522,7 @@ def install(project):
install_from_infos(install_path,
info['install'], info['remove'], info['conflict'])
- except InstallationConflict, e:
+ except InstallationConflict as e:
if logger.isEnabledFor(logging.INFO):
projects = ('%r %s' % (p.name, p.version) for p in e.args[0])
logger.info('%r conflicts with %s', project, ','.join(projects))
diff --git a/distutils2/manifest.py b/distutils2/manifest.py
index 9a8327b..64e8ebf 100644
--- a/distutils2/manifest.py
+++ b/distutils2/manifest.py
@@ -22,7 +22,7 @@ _COLLAPSE_PATTERN = re.compile('\\\w*\n', re.M)
_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S)
-class Manifest(object):
+class Manifest:
"""A list of files built by on exploring the filesystem and filtered by
applying various patterns to what we find there.
"""
@@ -67,7 +67,7 @@ class Manifest(object):
Updates the list accordingly.
"""
- if isinstance(path_or_file, basestring):
+ if isinstance(path_or_file, str):
f = open(path_or_file)
else:
f = path_or_file
@@ -89,7 +89,7 @@ class Manifest(object):
continue
try:
self._process_template_line(line)
- except PackagingTemplateError, msg:
+ except PackagingTemplateError as msg:
logger.warning("%s, %s", path_or_file, msg)
def write(self, path):
@@ -98,11 +98,8 @@ class Manifest(object):
named by 'self.manifest'.
"""
if os.path.isfile(path):
- fp = open(path)
- try:
+ with open(path) as fp:
first_line = fp.readline()
- finally:
- fp.close()
if first_line != '# file GENERATED by distutils2, do NOT edit\n':
logger.info("not writing to manually maintained "
@@ -122,12 +119,9 @@ class Manifest(object):
distribution.
"""
logger.info("reading manifest file %r", path)
- manifest = open(path)
- try:
+ with open(path) as manifest:
for line in manifest.readlines():
self.append(line)
- finally:
- manifest.close()
def exclude_pattern(self, pattern, anchor=True, prefix=None,
is_regex=False):
@@ -356,7 +350,7 @@ def _translate_pattern(pattern, anchor=True, prefix=None, is_regex=False):
or just returned as-is (assumes it's a regex object).
"""
if is_regex:
- if isinstance(pattern, basestring):
+ if isinstance(pattern, str):
return re.compile(pattern)
else:
return pattern
diff --git a/distutils2/markers.py b/distutils2/markers.py
index 0281179..b6fc65e 100644
--- a/distutils2/markers.py
+++ b/distutils2/markers.py
@@ -3,10 +3,9 @@
import os
import sys
import platform
-from tokenize import generate_tokens, NAME, OP, STRING, ENDMARKER
-from StringIO import StringIO as BytesIO
-from distutils2.compat import python_implementation
+from tokenize import tokenize, NAME, OP, STRING, ENDMARKER, ENCODING
+from io import BytesIO
__all__ = ['interpret']
@@ -33,11 +32,10 @@ _VARS = {'sys.platform': sys.platform,
'os.name': os.name,
'platform.version': platform.version(),
'platform.machine': platform.machine(),
- 'platform.python_implementation': python_implementation(),
- }
+ 'platform.python_implementation': platform.python_implementation()}
-class _Operation(object):
+class _Operation:
def __init__(self, execution_context=None):
self.left = None
@@ -98,7 +96,7 @@ class _Operation(object):
return _operate(self.op, left, right)
-class _OR(object):
+class _OR:
def __init__(self, left, right=None):
self.left = left
self.right = right
@@ -113,7 +111,7 @@ class _OR(object):
return self.left() or self.right()
-class _AND(object):
+class _AND:
def __init__(self, left, right=None):
self.left = left
self.right = right
@@ -133,10 +131,10 @@ def interpret(marker, execution_context=None):
marker = marker.strip().encode()
ops = []
op_starting = True
- for token in generate_tokens(BytesIO(marker).readline):
+ for token in tokenize(BytesIO(marker).readline):
# Unpack token
toktype, tokval, rowcol, line, logical_line = token
- if toktype not in (NAME, OP, STRING, ENDMARKER):
+ if toktype not in (NAME, OP, STRING, ENDMARKER, ENCODING):
raise SyntaxError('Type not supported "%s"' % tokval)
if op_starting:
diff --git a/distutils2/metadata.py b/distutils2/metadata.py
index 15fae95..8db86e2 100644
--- a/distutils2/metadata.py
+++ b/distutils2/metadata.py
@@ -4,10 +4,9 @@ Supports all metadata formats (1.0, 1.1, 1.2).
"""
import re
-import codecs
import logging
-from StringIO import StringIO
+from io import StringIO
from email import message_from_file
from distutils2 import logger
from distutils2.markers import interpret
@@ -185,7 +184,7 @@ _MISSING = object()
_FILESAFE = re.compile('[^A-Za-z0-9.]+')
-class Metadata(object):
+class Metadata:
"""The metadata of a release.
Supports versions 1.0, 1.1 and 1.2 (auto-detected). You can
@@ -218,7 +217,7 @@ class Metadata(object):
self._fields['Metadata-Version'] = _best_version(self._fields)
def _write_field(self, file, name, value):
- file.write(u'%s: %s\n' % (name, value))
+ file.write('%s: %s\n' % (name, value))
def __getitem__(self, name):
return self.get(name)
@@ -311,11 +310,8 @@ class Metadata(object):
def read(self, filepath):
"""Read the metadata values from a file path."""
- fp = codecs.open(filepath, 'r', encoding='utf-8')
- try:
+ with open(filepath, 'r', encoding='utf-8') as fp:
self.read_file(fp)
- finally:
- fp.close()
def read_file(self, fileob):
"""Read the metadata values from a file object."""
@@ -337,11 +333,8 @@ class Metadata(object):
def write(self, filepath):
"""Write the metadata fields to filepath."""
- fp = codecs.open(filepath, 'w', encoding='utf-8')
- try:
+ with open(filepath, 'w', encoding='utf-8') as fp:
self.write_file(fp)
- finally:
- fp.close()
def write_file(self, fileobject):
"""Write the PKG-INFO format data to a file object."""
@@ -404,13 +397,13 @@ class Metadata(object):
if ((name in _ELEMENTSFIELD or name == 'Platform') and
not isinstance(value, (list, tuple))):
- if isinstance(value, basestring):
+ if isinstance(value, str):
value = [v.strip() for v in value.split(',')]
else:
value = []
elif (name in _LISTFIELDS and
not isinstance(value, (list, tuple))):
- if isinstance(value, basestring):
+ if isinstance(value, str):
value = [value]
else:
value = []
@@ -472,7 +465,7 @@ class Metadata(object):
valid, value = self._platform(self._fields[name])
if not valid:
return []
- if isinstance(value, basestring):
+ if isinstance(value, str):
return value.split(',')
valid, value = self._platform(self._fields[name])
if not valid:
@@ -559,7 +552,7 @@ class Metadata(object):
return data
# Mapping API
- # TODO could add iter* variants
+ # XXX these methods should return views or sets in 3.x
def keys(self):
return list(_version2fieldlist(self['Metadata-Version']))
diff --git a/distutils2/pypi/base.py b/distutils2/pypi/base.py
index e9a9944..9502a57 100644
--- a/distutils2/pypi/base.py
+++ b/distutils2/pypi/base.py
@@ -3,7 +3,7 @@
from distutils2.pypi.dist import ReleasesList
-class BaseClient(object):
+class BaseClient:
"""Base class containing common methods for the index crawlers/clients"""
def __init__(self, prefer_final, prefer_source):
diff --git a/distutils2/pypi/dist.py b/distutils2/pypi/dist.py
index 533ba09..23e7bd9 100644
--- a/distutils2/pypi/dist.py
+++ b/distutils2/pypi/dist.py
@@ -8,9 +8,12 @@ distribution objects contain download-related information.
"""
import re
+import hashlib
import tempfile
-import urllib
-import urlparse
+import urllib.request
+import urllib.parse
+import urllib.error
+
from distutils2.errors import IrrationalVersionError
from distutils2.version import (suggest_normalized_version, NormalizedVersion,
get_version_predicate)
@@ -18,10 +21,6 @@ from distutils2.metadata import Metadata
from distutils2.pypi.errors import (HashDoesNotMatch, UnsupportedHashName,
CantParseArchiveName)
from distutils2._backport.shutil import unpack_archive
-try:
- import hashlib
-except ImportError:
- from distutils2._backport import hashlib
__all__ = ['ReleaseInfo', 'DistInfo', 'ReleasesList', 'get_infos_from_url']
@@ -31,7 +30,7 @@ MD5_HASH = re.compile(r'^.*#md5=([a-f0-9]+)$')
DIST_TYPES = ['bdist', 'sdist']
-class IndexReference(object):
+class IndexReference:
"""Mixin used to store the index reference"""
def set_index(self, index=None):
self._index = index
@@ -297,8 +296,8 @@ class DistInfo(IndexReference):
# if we do not have downloaded it yet, do it.
if self.downloaded_location is None:
url = self.url['url']
- archive_name = urlparse.urlparse(url)[2].split('/')[-1]
- filename, headers = urllib.urlretrieve(url,
+ archive_name = urllib.parse.urlparse(url)[2].split('/')[-1]
+ filename, headers = urllib.request.urlretrieve(url,
path + "/" + archive_name)
self.downloaded_location = filename
self._check_md5(filename)
@@ -327,12 +326,9 @@ class DistInfo(IndexReference):
hashname = self.url['hashname']
expected_hashval = self.url['hashval']
if None not in (expected_hashval, hashname):
- f = open(filename, 'rb')
- try:
+ with open(filename, 'rb') as f:
hashval = hashlib.new(hashname)
hashval.update(f.read())
- finally:
- f.close()
if hashval.hexdigest() != expected_hashval:
raise HashDoesNotMatch("got %s instead of %s"
@@ -491,7 +487,7 @@ def get_infos_from_url(url, probable_dist_name=None, is_external=True):
url = url.replace("#md5=%s" % md5_hash, "")
# parse the archive name to find dist name and version
- archive_name = urlparse.urlparse(url)[2].split('/')[-1]
+ archive_name = urllib.parse.urlparse(url)[2].split('/')[-1]
extension_matched = False
# remove the extension from the name
for ext in EXTENSIONS:
diff --git a/distutils2/pypi/simple.py b/distutils2/pypi/simple.py
index 50b2c9c..b5432a4 100644
--- a/distutils2/pypi/simple.py
+++ b/distutils2/pypi/simple.py
@@ -6,17 +6,18 @@ can be used to find and retrieve distributions from a project index
reference implementation available at http://pypi.python.org/simple/).
"""
-import httplib
+import http.client
import re
import socket
import sys
-import urllib2
-import urlparse
+import urllib.request
+import urllib.parse
+import urllib.error
import os
from fnmatch import translate
+from functools import wraps
from distutils2 import logger
-from distutils2.compat import wraps
from distutils2.metadata import Metadata
from distutils2.version import get_version_predicate
from distutils2 import __version__ as distutils2_version
@@ -123,7 +124,7 @@ class Crawler(BaseClient):
self.follow_externals = follow_externals
# mirroring attributes.
- parsed = urlparse.urlparse(index_url)
+ parsed = urllib.parse.urlparse(index_url)
self.scheme = parsed[0]
if self.scheme == 'file':
ender = os.path.sep
@@ -156,20 +157,17 @@ class Crawler(BaseClient):
Return a list of names.
"""
- if u'*' in name:
- name.replace(u'*', u'.*')
+ if '*' in name:
+ name.replace('*', '.*')
else:
- name = u"%s%s%s" % (u'*.?', name, u'*.?')
- name = name.replace(u'*', u'[^<]*') # avoid matching end tag
- pattern = (u'<a[^>]*>(%s)</a>' % name).encode('utf-8')
+ name = "%s%s%s" % ('*.?', name, '*.?')
+ name = name.replace('*', '[^<]*') # avoid matching end tag
+ pattern = ('<a[^>]*>(%s)</a>' % name).encode('utf-8')
projectname = re.compile(pattern, re.I)
matching_projects = []
- index = self._open_url(self.index_url)
- try:
+ with self._open_url(self.index_url) as index:
index_content = index.read()
- finally:
- index.close()
for match in projectname.finditer(index_content):
project_name = match.group(1).decode('utf-8')
@@ -231,10 +229,8 @@ class Crawler(BaseClient):
"""
self._mirrors_used.add(self.index_url)
index_url = self._mirrors.pop()
- # XXX use urlparse for a real check of missing scheme part
- if not (index_url.startswith("http://") or
- index_url.startswith("https://") or
- index_url.startswith("file://")):
+ # XXX use urllib.parse for a real check of missing scheme part
+ if not index_url.startswith(("http://", "https://", "file://")):
index_url = "http://%s" % index_url
if not index_url.endswith("/simple"):
@@ -251,10 +247,10 @@ class Crawler(BaseClient):
# if _index_url is contained in the given URL, we are browsing the
# index, and it's always "browsable".
# local files are always considered browable resources
- if self.index_url in url or urlparse.urlparse(url)[0] == "file":
+ if self.index_url in url or urllib.parse.urlparse(url)[0] == "file":
return True
elif self.follow_externals:
- if self._allowed_hosts(urlparse.urlparse(url)[1]): # 1 is netloc
+ if self._allowed_hosts(urllib.parse.urlparse(url)[1]): # 1 is netloc
return True
else:
return False
@@ -311,8 +307,7 @@ class Crawler(BaseClient):
the links we find (eg. run recursively this
method on it)
"""
- f = self._open_url(url)
- try:
+ with self._open_url(url) as f:
base_url = f.url
if url not in self._processed_urls:
self._processed_urls.append(url)
@@ -325,7 +320,7 @@ class Crawler(BaseClient):
try:
infos = get_infos_from_url(link, project_name,
is_external=self.index_url not in url)
- except CantParseArchiveName, e:
+ except CantParseArchiveName as e:
logger.warning(
"version has not been parsed: %s", e)
else:
@@ -334,8 +329,6 @@ class Crawler(BaseClient):
if self._is_browsable(link) and follow_links:
self._process_url(link, project_name,
follow_links=False)
- finally:
- f.close()
def _get_link_matcher(self, url):
"""Returns the right link matcher function of the given url
@@ -346,7 +339,7 @@ class Crawler(BaseClient):
return self._default_link_matcher
def _get_full_url(self, url, base_url):
- return urlparse.urljoin(base_url, self._htmldecode(url))
+ return urllib.parse.urljoin(base_url, self._htmldecode(url))
def _simple_link_matcher(self, content, base_url):
"""Yield all links with a rel="download" or rel="homepage".
@@ -402,11 +395,11 @@ class Crawler(BaseClient):
files support.
"""
- scheme, netloc, path, params, query, frag = urlparse.urlparse(url)
+ scheme, netloc, path, params, query, frag = urllib.parse.urlparse(url)
# authentication stuff
if scheme in ('http', 'https'):
- auth, host = urllib2.splituser(netloc)
+ auth, host = urllib.parse.splituser(netloc)
else:
auth = None
@@ -418,27 +411,27 @@ class Crawler(BaseClient):
# add authorization headers if auth is provided
if auth:
auth = "Basic " + \
- urlparse.unquote(auth).encode('base64').strip()
- new_url = urlparse.urlunparse((
+ urllib.parse.unquote(auth).encode('base64').strip()
+ new_url = urllib.parse.urlunparse((
scheme, host, path, params, query, frag))
- request = urllib2.Request(new_url)
+ request = urllib.request.Request(new_url)
request.add_header("Authorization", auth)
else:
- request = urllib2.Request(url)
+ request = urllib.request.Request(url)
request.add_header('User-Agent', USER_AGENT)
try:
- fp = urllib2.urlopen(request)
- except (ValueError, httplib.InvalidURL), v:
+ fp = urllib.request.urlopen(request)
+ except (ValueError, http.client.InvalidURL) as v:
msg = ' '.join([str(arg) for arg in v.args])
raise PackagingPyPIError('%s %s' % (url, msg))
- except urllib2.HTTPError, v:
+ except urllib.error.HTTPError as v:
return v
- except urllib2.URLError, v:
+ except urllib.error.URLError as v:
raise DownloadError("Download error for %s: %s" % (url, v.reason))
- except httplib.BadStatusLine, v:
+ except http.client.BadStatusLine as v:
raise DownloadError('%s returned a bad status line. '
'The server might be down, %s' % (url, v.line))
- except httplib.HTTPException, v:
+ except http.client.HTTPException as v:
raise DownloadError("Download error for %s: %s" % (url, v))
except socket.timeout:
raise DownloadError("The server timeouted")
@@ -447,9 +440,9 @@ class Crawler(BaseClient):
# Put authentication info back into request URL if same host,
# so that links found on the page will work
s2, h2, path2, param2, query2, frag2 = \
- urlparse.urlparse(fp.url)
+ urllib.parse.urlparse(fp.url)
if s2 == scheme and h2 == host:
- fp.url = urlparse.urlunparse(
+ fp.url = urllib.parse.urlunparse(
(s2, netloc, path2, param2, query2, frag2))
return fp
diff --git a/distutils2/pypi/wrapper.py b/distutils2/pypi/wrapper.py
index 699beaa..ed8e34c 100644
--- a/distutils2/pypi/wrapper.py
+++ b/distutils2/pypi/wrapper.py
@@ -25,13 +25,13 @@ def switch_index_if_fails(func, wrapper):
exception = None
methods = [func]
for f in wrapper._indexes.values():
- if f != func.im_self and hasattr(f, func.f_name):
- methods.append(getattr(f, func.f_name))
+ if f != func.__self__ and hasattr(f, func.__name__):
+ methods.append(getattr(f, func.__name__))
for method in methods:
try:
response = method(*args, **kwargs)
retry = False
- except Exception, e:
+ except Exception as e:
exception = e
if not retry:
break
@@ -42,7 +42,7 @@ def switch_index_if_fails(func, wrapper):
return decorator
-class ClientWrapper(object):
+class ClientWrapper:
"""Wrapper around simple and xmlrpc clients,
Choose the best implementation to use depending the needs, using the given
diff --git a/distutils2/pypi/xmlrpc.py b/distutils2/pypi/xmlrpc.py
index dc2d970..7cd4f66 100644
--- a/distutils2/pypi/xmlrpc.py
+++ b/distutils2/pypi/xmlrpc.py
@@ -6,7 +6,7 @@ Index), using its XML-RPC API (see documentation of the reference
implementation at http://wiki.python.org/moin/PyPiXmlRpc).
"""
-import xmlrpclib
+import xmlrpc.client
from distutils2 import logger
from distutils2.errors import IrrationalVersionError
@@ -171,7 +171,7 @@ class Client(BaseClient):
project.add_release(release=ReleaseInfo(p['name'],
p['version'], metadata={'summary': p['summary']},
index=self._index))
- except IrrationalVersionError, e:
+ except IrrationalVersionError as e:
logger.warning("Irrational version error found: %s", e)
return [self._projects[p['name'].lower()] for p in projects]
@@ -195,6 +195,6 @@ class Client(BaseClient):
"""
if not hasattr(self, '_server_proxy'):
- self._server_proxy = xmlrpclib.ServerProxy(self.server_url)
+ self._server_proxy = xmlrpc.client.ServerProxy(self.server_url)
return self._server_proxy
diff --git a/distutils2/run.py b/distutils2/run.py
index 6aaa888..bebf070 100644
--- a/distutils2/run.py
+++ b/distutils2/run.py
@@ -74,7 +74,7 @@ def _parse_args(args, options, long_options):
return optdict
-class action_help(object):
+class action_help:
"""Prints a help message when the standard help flags: -h and --help
are used on the commandline.
"""
@@ -86,7 +86,7 @@ class action_help(object):
def wrapper(*args, **kwargs):
f_args = args[1]
if '--help' in f_args or '-h' in f_args:
- print self.help_msg
+ print(self.help_msg)
return
return f(*args, **kwargs)
return wrapper
@@ -132,7 +132,7 @@ def _graph(dispatcher, args, **kw):
else:
dists = get_distributions(use_egg_info=True)
graph = generate_graph(dists)
- print graph.repr_node(dist)
+ print(graph.repr_node(dist))
@action_help("""\
@@ -205,13 +205,13 @@ def _metadata(dispatcher, args, **kw):
for key in keys:
if key in metadata:
- print metadata._convert_name(key) + ':'
+ print(metadata._convert_name(key) + ':')
value = metadata[key]
if isinstance(value, list):
for v in value:
- print ' ', v
+ print(' ', v)
else:
- print ' ', value.replace('\n', '\n ')
+ print(' ', value.replace('\n', '\n '))
@action_help("""\
@@ -257,14 +257,14 @@ def _run(dispatcher, args, **kw):
commands = STANDARD_COMMANDS # + extra commands
if args == ['--list-commands']:
- print 'List of available commands:'
+ print('List of available commands:')
cmds = sorted(commands)
for cmd in cmds:
cls = dispatcher.cmdclass.get(cmd) or get_command_class(cmd)
desc = getattr(cls, 'description',
'(no description available)')
- print ' %s: %s' % (cmd, desc)
+ print(' %s: %s' % (cmd, desc))
return
while args:
@@ -311,7 +311,7 @@ def _list(dispatcher, args, **kw):
number = 0
for dist in results:
- print '%r %s (from %r)' % (dist.name, dist.version, dist.path)
+ print('%r %s (from %r)' % (dist.name, dist.version, dist.path))
number += 1
if number == 0:
@@ -372,7 +372,7 @@ actions = [
]
-class Dispatcher(object):
+class Dispatcher:
"""Reads the command-line options
"""
def __init__(self, args=None):
@@ -446,7 +446,7 @@ class Dispatcher(object):
# it takes.
try:
cmd_class = get_command_class(command)
- except PackagingModuleError, msg:
+ except PackagingModuleError as msg:
raise PackagingArgError(msg)
# XXX We want to push this in distutils2.command
@@ -546,18 +546,18 @@ class Dispatcher(object):
# late import because of mutual dependence between these modules
from distutils2.command.cmd import Command
- print 'Usage: pysetup [options] action [action_options]'
- print
+ print('Usage: pysetup [options] action [action_options]')
+ print()
if global_options_:
self.print_usage(self.parser)
- print
+ print()
if display_options_:
parser.set_option_table(display_options)
parser.print_help(
"Information display options (just display " +
"information, ignore any commands)")
- print
+ print()
for command in commands:
if isinstance(command, type) and issubclass(command, Command):
@@ -571,15 +571,15 @@ class Dispatcher(object):
parser.set_option_table(cls.user_options)
parser.print_help("Options for %r command:" % cls.__name__)
- print
+ print()
def _show_command_help(self, command):
- if isinstance(command, basestring):
+ if isinstance(command, str):
command = get_command_class(command)
desc = getattr(command, 'description', '(no description available)')
- print 'Description:', desc
- print
+ print('Description:', desc)
+ print()
if (hasattr(command, 'help_options') and
isinstance(command.help_options, list)):
@@ -589,7 +589,7 @@ class Dispatcher(object):
self.parser.set_option_table(command.user_options)
self.parser.print_help("Options:")
- print
+ print()
def _get_command_groups(self):
"""Helper function to retrieve all the command class names divided
@@ -616,7 +616,7 @@ class Dispatcher(object):
self.print_command_list(std_commands, "Standard commands", max_length)
if extra_commands:
- print
+ print()
self.print_command_list(extra_commands, "Extra commands",
max_length)
@@ -624,14 +624,14 @@ class Dispatcher(object):
"""Print a subset of the list of all commands -- used by
'print_commands()'.
"""
- print header + ":"
+ print(header + ":")
for cmd in commands:
cls = self.cmdclass.get(cmd) or get_command_class(cmd)
description = getattr(cls, 'description',
'(no description available)')
- print " %-*s %s" % (max_length, cmd, description)
+ print(" %-*s %s" % (max_length, cmd, description))
def __call__(self):
if self.action is None:
@@ -647,17 +647,16 @@ def main(args=None):
old_level = logger.level
old_handlers = list(logger.handlers)
try:
- try:
- dispatcher = Dispatcher(args)
- if dispatcher.action is None:
- return
- return dispatcher()
- except KeyboardInterrupt:
- logger.info('interrupted')
- return 1
- except (IOError, os.error, PackagingError, CCompilerError), exc:
- logger.exception(exc)
- return 1
+ dispatcher = Dispatcher(args)
+ if dispatcher.action is None:
+ return
+ return dispatcher()
+ except KeyboardInterrupt:
+ logger.info('interrupted')
+ return 1
+ except (IOError, os.error, PackagingError, CCompilerError) as exc:
+ logger.exception(exc)
+ return 1
finally:
logger.setLevel(old_level)
logger.handlers[:] = old_handlers
diff --git a/distutils2/tests/__init__.py b/distutils2/tests/__init__.py
index cc8927f..bcd944a 100644
--- a/distutils2/tests/__init__.py
+++ b/distutils2/tests/__init__.py
@@ -7,14 +7,14 @@ to return an initialized unittest.TestSuite instance.
Utility code is included in distutils2.tests.support.
-Always import unittest from this module, it will be the right version
+Always import unittest from this module: it will be unittest from the
standard library for packaging tests and unittest2 for distutils2 tests.
"""
import os
import sys
import unittest2 as unittest
-from StringIO import StringIO
+from io import StringIO
# XXX move helpers to support, add tests for them, remove things that
# duplicate test.support (or keep them for the backport; needs thinking)
@@ -42,7 +42,7 @@ class TestFailed(Error):
"""Test failed."""
-class BasicTestRunner(object):
+class BasicTestRunner:
def run(self, test):
result = unittest.TestResult()
test(result)
@@ -72,13 +72,13 @@ def _run_suite(suite, verbose_=1):
def run_unittest(classes, verbose_=1):
"""Run tests from unittest.TestCase-derived classes.
- Originally extracted from stdlib test.test_support and modified to
+ Originally extracted from stdlib test.support and modified to
support unittest2.
"""
valid_types = (unittest.TestSuite, unittest.TestCase)
suite = unittest.TestSuite()
for cls in classes:
- if isinstance(cls, basestring):
+ if isinstance(cls, str):
if cls in sys.modules:
suite.addTest(unittest.findTestCases(sys.modules[cls]))
else:
diff --git a/distutils2/tests/__main__.py b/distutils2/tests/__main__.py
index e238ed6..3609c64 100644
--- a/distutils2/tests/__main__.py
+++ b/distutils2/tests/__main__.py
@@ -4,7 +4,7 @@
import os
import sys
-from test.test_support import reap_children, reap_threads, run_unittest
+from test.support import reap_children, reap_threads, run_unittest
from distutils2.tests import unittest
diff --git a/distutils2/tests/pypi_server.py b/distutils2/tests/pypi_server.py
index c98e232..710e055 100644
--- a/distutils2/tests/pypi_server.py
+++ b/distutils2/tests/pypi_server.py
@@ -30,17 +30,15 @@ implementations (static HTTP and XMLRPC over HTTP).
"""
import os
-import Queue
+import queue
import select
import threading
-import SocketServer
-from BaseHTTPServer import HTTPServer
-from SimpleHTTPServer import SimpleHTTPRequestHandler
-from SimpleXMLRPCServer import SimpleXMLRPCServer
+import socketserver
+from functools import wraps
+from http.server import HTTPServer, SimpleHTTPRequestHandler
+from xmlrpc.server import SimpleXMLRPCServer
from distutils2.tests import unittest
-from distutils2.compat import wraps
-
PYPI_DEFAULT_STATIC_PATH = os.path.join(
@@ -116,7 +114,7 @@ class PyPIServer(threading.Thread):
self.server = HTTPServer(('127.0.0.1', 0), PyPIRequestHandler)
self.server.RequestHandlerClass.pypi_server = self
- self.request_queue = Queue.Queue()
+ self.request_queue = queue.Queue()
self._requests = []
self.default_response_status = 404
self.default_response_headers = [('Content-type', 'text/plain')]
@@ -153,7 +151,7 @@ class PyPIServer(threading.Thread):
def stop(self):
"""self shutdown is not supported for python < 2.6"""
self._run = False
- if self.isAlive():
+ if self.is_alive():
self.join()
self.server.server_close()
@@ -170,7 +168,7 @@ class PyPIServer(threading.Thread):
while True:
try:
self._requests.append(self.request_queue.get_nowait())
- except Queue.Empty:
+ except queue.Empty:
break
return self._requests
@@ -222,18 +220,12 @@ class PyPIRequestHandler(SimpleHTTPRequestHandler):
relative_path += "index.html"
if relative_path.endswith('.tar.gz'):
- file = open(fs_path + relative_path, 'rb')
- try:
+ with open(fs_path + relative_path, 'rb') as file:
data = file.read()
- finally:
- file.close()
headers = [('Content-type', 'application/x-gtar')]
else:
- file = open(fs_path + relative_path)
- try:
+ with open(fs_path + relative_path) as file:
data = file.read().encode()
- finally:
- file.close()
headers = [('Content-type', 'text/html')]
headers.append(('Content-Length', len(data)))
@@ -269,7 +261,7 @@ class PyPIRequestHandler(SimpleHTTPRequestHandler):
self.send_header(header, value)
self.end_headers()
- if isinstance(data, unicode):
+ if isinstance(data, str):
data = data.encode('utf-8')
self.wfile.write(data)
@@ -278,12 +270,12 @@ class PyPIRequestHandler(SimpleHTTPRequestHandler):
class PyPIXMLRPCServer(SimpleXMLRPCServer):
def server_bind(self):
"""Override server_bind to store the server name."""
- SocketServer.TCPServer.server_bind(self)
+ socketserver.TCPServer.server_bind(self)
host, port = self.socket.getsockname()[:2]
self.server_port = port
-class MockDist(object):
+class MockDist:
"""Fake distribution, used in the Mock PyPI Server"""
def __init__(self, name, version="1.0", hidden=False, url="http://url/",
@@ -398,7 +390,7 @@ class MockDist(object):
}
-class XMLRPCMockIndex(object):
+class XMLRPCMockIndex:
"""Mock XMLRPC server"""
def __init__(self, dists=[]):
diff --git a/distutils2/tests/pypi_test_server.py b/distutils2/tests/pypi_test_server.py
index 516e058..8c8c641 100644
--- a/distutils2/tests/pypi_test_server.py
+++ b/distutils2/tests/pypi_test_server.py
@@ -40,7 +40,7 @@ class PyPIServerTestCase(unittest.TestCase):
self.addCleanup(self.pypi.stop)
-class PyPIServer(object):
+class PyPIServer:
"""Shim to access testpypi.python.org, for testing a real server."""
def __init__(self, test_static_path=None,
diff --git a/distutils2/tests/support.py b/distutils2/tests/support.py
index 92e0241..9938d75 100644
--- a/distutils2/tests/support.py
+++ b/distutils2/tests/support.py
@@ -83,7 +83,7 @@ class _TestHandler(logging.handlers.BufferingHandler):
self.buffer.append(record)
-class LoggingCatcher(object):
+class LoggingCatcher:
"""TestCase-compatible mixin to receive logging calls.
Upon setUp, instances of this classes get a BufferingHandler that's
@@ -139,7 +139,7 @@ class LoggingCatcher(object):
return messages
-class TempdirManager(object):
+class TempdirManager:
"""TestCase-compatible mixin to create temporary directories and files.
Directories and files created in a test_* method will be removed after it
@@ -182,11 +182,8 @@ class TempdirManager(object):
"""
if isinstance(path, (list, tuple)):
path = os.path.join(*path)
- f = codecs.open(path, 'w', encoding=encoding)
- try:
+ with open(path, 'w', encoding=encoding) as f:
f.write(content)
- finally:
- f.close()
def create_dist(self, **kw):
"""Create a stub distribution object and files.
@@ -224,7 +221,7 @@ class TempdirManager(object):
self.assertFalse(os.path.isfile(path), "%r exists" % path)
-class EnvironRestorer(object):
+class EnvironRestorer:
"""TestCase-compatible mixin to restore or delete environment variables.
The variables to restore (or delete if they were not originally present)
@@ -251,7 +248,7 @@ class EnvironRestorer(object):
super(EnvironRestorer, self).tearDown()
-class DummyCommand(object):
+class DummyCommand:
"""Class to store options for retrieval via set_undefined_options().
Useful for mocking one dependency command in the tests for another
@@ -339,6 +336,11 @@ def fixup_build_ext(cmd):
cmd = build_ext(dist)
support.fixup_build_ext(cmd)
cmd.ensure_finalized()
+
+ In addition, this function also fixes cmd.distribution.include_dirs if
+ the running Python is an uninstalled Python 3.3. (This fix is not done in
+ packaging, which does not need it, nor in distutils2 for Python 2, which
+ has no in-development version that can't be expected to be installed.)
"""
if os.name == 'nt':
cmd.debug = sys.executable.endswith('_d.exe')
@@ -354,12 +356,17 @@ def fixup_build_ext(cmd):
name, equals, value = runshared.partition('=')
cmd.library_dirs = value.split(os.pathsep)
+ # Allow tests to run with an uninstalled Python 3.3
+ if sys.version_info[:2] == (3, 3) and sysconfig.is_python_build():
+ pysrcdir = sysconfig.get_config_var('projectbase')
+ cmd.distribution.include_dirs.append(os.path.join(pysrcdir, 'Include'))
+
try:
- from test.test_support import skip_unless_symlink
+ from test.support import skip_unless_symlink
except ImportError:
skip_unless_symlink = unittest.skip(
- 'requires test.test_support.skip_unless_symlink')
+ 'requires test.support.skip_unless_symlink')
requires_zlib = unittest.skipUnless(zlib, 'requires zlib')
@@ -368,7 +375,7 @@ requires_zlib = unittest.skipUnless(zlib, 'requires zlib')
def unlink(filename):
try:
os.unlink(filename)
- except OSError, error:
+ except OSError as error:
# The filename need not exist.
if error.errno not in (errno.ENOENT, errno.ENOTDIR):
raise
@@ -381,7 +388,7 @@ def strip_python_stderr(stderr):
This will typically be run on the result of the communicate() method
of a subprocess.Popen object.
"""
- stderr = re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr).strip()
+ stderr = re.sub(br"\[\d+ refs\]\r?\n?$", b"", stderr).strip()
return stderr
diff --git a/distutils2/tests/test_command_build_clib.py b/distutils2/tests/test_command_build_clib.py
index da306e7..9c1eb04 100644
--- a/distutils2/tests/test_command_build_clib.py
+++ b/distutils2/tests/test_command_build_clib.py
@@ -68,7 +68,7 @@ class BuildCLibTestCase(support.TempdirManager,
pkg_dir, dist = self.create_dist()
cmd = build_clib(dist)
- class FakeCompiler(object):
+ class FakeCompiler:
def compile(*args, **kw):
pass
create_static_lib = compile
diff --git a/distutils2/tests/test_command_build_ext.py b/distutils2/tests/test_command_build_ext.py
index 4ad0ec5..06b5992 100644
--- a/distutils2/tests/test_command_build_ext.py
+++ b/distutils2/tests/test_command_build_ext.py
@@ -3,7 +3,7 @@ import sys
import site
import shutil
import textwrap
-from StringIO import StringIO
+from io import StringIO
from distutils2.dist import Distribution
from distutils2.errors import (UnknownFileError, CompileError,
PackagingPlatformError)
@@ -21,18 +21,13 @@ class BuildExtTestCase(support.TempdirManager,
def setUp(self):
super(BuildExtTestCase, self).setUp()
self.tmp_dir = self.mkdtemp()
- if sys.version > "2.6":
- self.old_user_base = site.USER_BASE
- site.USER_BASE = self.mkdtemp()
+ self.old_user_base = site.USER_BASE
+ site.USER_BASE = self.mkdtemp()
def tearDown(self):
- if sys.version > "2.6":
- site.USER_BASE = self.old_user_base
-
+ site.USER_BASE = self.old_user_base
super(BuildExtTestCase, self).tearDown()
- @unittest.skipIf(sys.version_info[:2] < (2, 6),
- "can't compile xxmodule successfully")
def test_build_ext(self):
support.copy_xxmodule_c(self.tmp_dir)
xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')
@@ -94,7 +89,6 @@ class BuildExtTestCase(support.TempdirManager,
# make sure we get some library dirs under solaris
self.assertGreater(len(cmd.library_dirs), 0)
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_user_site(self):
dist = Distribution({'name': 'xx'})
cmd = build_ext(dist)
@@ -362,8 +356,7 @@ class BuildExtTestCase(support.TempdirManager,
deptarget_c = os.path.join(self.tmp_dir, 'deptargetmodule.c')
- fp = open(deptarget_c, 'w')
- try:
+ with open(deptarget_c, 'w') as fp:
fp.write(textwrap.dedent('''\
#include <AvailabilityMacros.h>
@@ -375,8 +368,6 @@ class BuildExtTestCase(support.TempdirManager,
#endif
''' % operator))
- finally:
- fp.close()
# get the deployment target that the interpreter was built with
target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
diff --git a/distutils2/tests/test_command_build_py.py b/distutils2/tests/test_command_build_py.py
index b659895..fa152ec 100644
--- a/distutils2/tests/test_command_build_py.py
+++ b/distutils2/tests/test_command_build_py.py
@@ -2,6 +2,7 @@
import os
import sys
+import imp
from distutils2.command.build_py import build_py
from distutils2.dist import Distribution
@@ -58,13 +59,21 @@ class BuildPyTestCase(support.TempdirManager,
self.assertEqual(len(cmd.get_outputs()), 3)
pkgdest = os.path.join(destination, "pkg")
files = os.listdir(pkgdest)
+ pycache_dir = os.path.join(pkgdest, "__pycache__")
self.assertIn("__init__.py", files)
self.assertIn("README.txt", files)
- # XXX even with -O, distutils writes pyc, not pyo; bug?
- if getattr(sys , 'dont_write_bytecode', False):
- self.assertNotIn("__init__.pyc", files)
+ if sys.dont_write_bytecode:
+ if sys.version_info[1] == 1:
+ self.assertNotIn("__init__.pyc", files)
+ else:
+ self.assertFalse(os.path.exists(pycache_dir))
else:
- self.assertIn("__init__.pyc", files)
+ # XXX even with -O, distutils2 writes pyc, not pyo; bug?
+ if sys.version_info[1] == 1:
+ self.assertIn("__init__.pyc", files)
+ else:
+ pyc_files = os.listdir(pycache_dir)
+ self.assertIn("__init__.%s.pyc" % imp.get_tag(), pyc_files)
def test_empty_package_dir(self):
# See SF 1668596/1720897.
@@ -99,8 +108,6 @@ class BuildPyTestCase(support.TempdirManager,
os.chdir(cwd)
sys.stdout = old_stdout
- @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'),
- 'sys.dont_write_bytecode not supported')
def test_dont_write_bytecode(self):
# makes sure byte_compile is not used
pkg_dir, dist = self.create_dist()
diff --git a/distutils2/tests/test_command_build_scripts.py b/distutils2/tests/test_command_build_scripts.py
index ab41bee..9abd5c3 100644
--- a/distutils2/tests/test_command_build_scripts.py
+++ b/distutils2/tests/test_command_build_scripts.py
@@ -71,11 +71,8 @@ class BuildScriptsTestCase(support.TempdirManager,
return expected
def write_script(self, dir, name, text):
- f = open(os.path.join(dir, name), "w")
- try:
+ with open(os.path.join(dir, name), "w") as f:
f.write(text)
- finally:
- f.close()
def test_version_int(self):
source = self.mkdtemp()
diff --git a/distutils2/tests/test_command_check.py b/distutils2/tests/test_command_check.py
index 67c4682..638bdaf 100644
--- a/distutils2/tests/test_command_check.py
+++ b/distutils2/tests/test_command_check.py
@@ -57,11 +57,11 @@ class CheckTestCase(support.LoggingCatcher,
self.assertEqual([], self.get_logs(logging.WARNING))
# now a test with non-ASCII characters
- metadata = {'home_page': u'xxx', 'author': u'\u00c9ric',
- 'author_email': u'xxx', 'name': u'xxx',
- 'version': u'1.2',
- 'summary': u'Something about esszet \u00df',
- 'description': u'More things about esszet \u00df'}
+ metadata = {'home_page': 'xxx', 'author': '\u00c9ric',
+ 'author_email': 'xxx', 'name': 'xxx',
+ 'version': '1.2',
+ 'summary': 'Something about esszet \u00df',
+ 'description': 'More things about esszet \u00df'}
cmd = self._run(metadata)
self.assertEqual([], self.get_logs(logging.WARNING))
@@ -123,7 +123,7 @@ class CheckTestCase(support.LoggingCatcher,
self.loghandler.flush()
# and non-broken rest, including a non-ASCII character to test #12114
- dist = self.create_dist(description=u'title\n=====\n\ntest \u00df')[1]
+ dist = self.create_dist(description='title\n=====\n\ntest \u00df')[1]
cmd = check(dist)
cmd.check_restructuredtext()
self.assertEqual([], self.get_logs(logging.WARNING))
diff --git a/distutils2/tests/test_command_config.py b/distutils2/tests/test_command_config.py
index 5bb27e3..97304a6 100644
--- a/distutils2/tests/test_command_config.py
+++ b/distutils2/tests/test_command_config.py
@@ -13,11 +13,8 @@ class ConfigTestCase(support.LoggingCatcher,
def test_dump_file(self):
this_file = __file__.rstrip('co')
- f = open(this_file)
- try:
+ with open(this_file) as f:
numlines = len(f.readlines())
- finally:
- f.close()
dump_file(this_file, 'I am the header')
diff --git a/distutils2/tests/test_command_install_dist.py b/distutils2/tests/test_command_install_dist.py
index 409de06..c477299 100644
--- a/distutils2/tests/test_command_install_dist.py
+++ b/distutils2/tests/test_command_install_dist.py
@@ -72,7 +72,6 @@ class InstallTestCase(support.TempdirManager,
check_path(cmd.install_scripts, os.path.join(destination, "bin"))
check_path(cmd.install_data, destination)
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_user_site(self):
# test install with --user
# preparing the environment for the test
@@ -173,19 +172,18 @@ class InstallTestCase(support.TempdirManager,
cmd.home = 'home'
self.assertRaises(PackagingOptionError, cmd.finalize_options)
- if sys.version >= '2.6':
- # can't combine user with with prefix/exec_prefix/home or
- # install_(plat)base
- cmd.prefix = None
- cmd.user = 'user'
- self.assertRaises(PackagingOptionError, cmd.finalize_options)
+ # can't combine user with with prefix/exec_prefix/home or
+ # install_(plat)base
+ cmd.prefix = None
+ cmd.user = 'user'
+ self.assertRaises(PackagingOptionError, cmd.finalize_options)
def test_old_record(self):
# test pre-PEP 376 --record option (outside dist-info dir)
install_dir = self.mkdtemp()
project_dir, dist = self.create_dist(scripts=['hello'])
os.chdir(project_dir)
- self.write_file('hello', "print 'o hai'")
+ self.write_file('hello', "print('o hai')")
cmd = install_dist(dist)
dist.command_obj['install_dist'] = cmd
@@ -194,11 +192,8 @@ class InstallTestCase(support.TempdirManager,
cmd.ensure_finalized()
cmd.run()
- f = open(cmd.record)
- try:
+ with open(cmd.record) as f:
content = f.read()
- finally:
- f.close()
found = [os.path.basename(line) for line in content.splitlines()]
expected = ['hello', 'METADATA', 'INSTALLER', 'REQUESTED', 'RECORD']
@@ -207,8 +202,6 @@ class InstallTestCase(support.TempdirManager,
# XXX test that fancy_getopt is okay with options named
# record and no-record but unrelated
- @unittest.skipIf(sys.version_info[:2] < (2, 6),
- "can't compile xxmodule successfully")
def test_old_record_extensions(self):
# test pre-PEP 376 --record option with ext modules
install_dir = self.mkdtemp()
@@ -229,11 +222,8 @@ class InstallTestCase(support.TempdirManager,
cmd.ensure_finalized()
cmd.run()
- f = open(cmd.record)
- try:
+ with open(cmd.record) as f:
content = f.read()
- finally:
- f.close()
found = [os.path.basename(line) for line in content.splitlines()]
expected = [_make_ext_name('xx'),
diff --git a/distutils2/tests/test_command_install_distinfo.py b/distutils2/tests/test_command_install_distinfo.py
index 7bfd05f..9e77e47 100644
--- a/distutils2/tests/test_command_install_distinfo.py
+++ b/distutils2/tests/test_command_install_distinfo.py
@@ -2,7 +2,7 @@
import os
import csv
-import codecs
+import hashlib
from distutils2.command.install_distinfo import install_distinfo
from distutils2.command.cmd import Command
@@ -10,10 +10,6 @@ from distutils2.compiler.extension import Extension
from distutils2.metadata import Metadata
from distutils2.tests import unittest, support
from distutils2._backport import sysconfig
-try:
- import hashlib
-except:
- from distutils2._backport import hashlib
class DummyInstallCmd(Command):
@@ -59,18 +55,10 @@ class InstallDistinfoTestCase(support.TempdirManager,
dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
self.checkLists(os.listdir(dist_info),
['METADATA', 'RECORD', 'REQUESTED', 'INSTALLER'])
- fp = open(os.path.join(dist_info, 'INSTALLER'))
- try:
+ with open(os.path.join(dist_info, 'INSTALLER')) as fp:
self.assertEqual(fp.read(), 'distutils')
- finally:
- fp.close()
-
- fp = open(os.path.join(dist_info, 'REQUESTED'))
- try:
+ with open(os.path.join(dist_info, 'REQUESTED')) as fp:
self.assertEqual(fp.read(), '')
- finally:
- fp.close()
-
meta_path = os.path.join(dist_info, 'METADATA')
self.assertTrue(Metadata(path=meta_path).check())
@@ -91,11 +79,8 @@ class InstallDistinfoTestCase(support.TempdirManager,
cmd.run()
dist_info = os.path.join(install_dir, 'foo-1.0.dist-info')
- fp = open(os.path.join(dist_info, 'INSTALLER'))
- try:
+ with open(os.path.join(dist_info, 'INSTALLER')) as fp:
self.assertEqual(fp.read(), 'bacon-python')
- finally:
- fp.close()
def test_requested(self):
pkg_dir, dist = self.create_dist(name='foo',
@@ -171,21 +156,15 @@ class InstallDistinfoTestCase(support.TempdirManager,
# platform-dependent (line endings)
metadata = os.path.join(modules_dest, 'Spamlib-0.1.dist-info',
'METADATA')
- fp = open(metadata, 'rb')
- try:
+ with open(metadata, 'rb') as fp:
content = fp.read()
- finally:
- fp.close()
metadata_size = str(len(content))
metadata_md5 = hashlib.md5(content).hexdigest()
record = os.path.join(modules_dest, 'Spamlib-0.1.dist-info', 'RECORD')
- fp = codecs.open(record, encoding='utf-8')
- try:
+ with open(record, encoding='utf-8') as fp:
content = fp.read()
- finally:
- fp.close()
found = []
for line in content.splitlines():
@@ -240,29 +219,23 @@ class InstallDistinfoTestCase(support.TempdirManager,
expected = []
for f in install.get_outputs():
- if (f.endswith('.pyc') or f.endswith('.pyo') or f == os.path.join(
+ if (f.endswith(('.pyc', '.pyo')) or f == os.path.join(
install_dir, 'foo-1.0.dist-info', 'RECORD')):
expected.append([f, '', ''])
else:
size = os.path.getsize(f)
md5 = hashlib.md5()
- fp = open(f, 'rb')
- try:
+ with open(f, 'rb') as fp:
md5.update(fp.read())
- finally:
- fp.close()
hash = md5.hexdigest()
expected.append([f, hash, str(size)])
parsed = []
- f = open(os.path.join(dist_info, 'RECORD'), 'r')
- try:
+ with open(os.path.join(dist_info, 'RECORD'), 'r') as f:
reader = csv.reader(f, delimiter=',',
lineterminator=os.linesep,
quotechar='"')
parsed = list(reader)
- finally:
- f.close()
self.maxDiff = None
self.checkLists(parsed, expected)
diff --git a/distutils2/tests/test_command_install_lib.py b/distutils2/tests/test_command_install_lib.py
index 3f241ea..78b539c 100644
--- a/distutils2/tests/test_command_install_lib.py
+++ b/distutils2/tests/test_command_install_lib.py
@@ -1,6 +1,7 @@
"""Tests for distutils2.command.install_data."""
-import sys
import os
+import sys
+import imp
from distutils2.tests import unittest, support
from distutils2.command.install_lib import install_lib
@@ -33,10 +34,10 @@ class InstallLibTestCase(support.TempdirManager,
cmd.finalize_options()
self.assertEqual(cmd.optimize, 2)
- @unittest.skipIf(getattr(sys, 'dont_write_bytecode', False),
- 'byte-compile disabled')
+ @unittest.skipIf(sys.dont_write_bytecode, 'byte-compile disabled')
def test_byte_compile(self):
pkg_dir, dist = self.create_dist()
+ os.chdir(pkg_dir)
cmd = install_lib(dist)
cmd.compile = True
cmd.optimize = 1
@@ -44,8 +45,14 @@ class InstallLibTestCase(support.TempdirManager,
f = os.path.join(pkg_dir, 'foo.py')
self.write_file(f, '# python file')
cmd.byte_compile([f])
- self.assertTrue(os.path.exists(os.path.join(pkg_dir, 'foo.pyc')))
- self.assertTrue(os.path.exists(os.path.join(pkg_dir, 'foo.pyo')))
+ if sys.version_info[1] == 1:
+ pyc_file = 'foo.pyc'
+ pyo_file = 'foo.pyo'
+ else:
+ pyc_file = imp.cache_from_source('foo.py')
+ pyo_file = imp.cache_from_source('foo.py', debug_override=False)
+ self.assertTrue(os.path.exists(pyc_file))
+ self.assertTrue(os.path.exists(pyo_file))
def test_get_outputs(self):
pkg_dir, dist = self.create_dist()
@@ -83,8 +90,6 @@ class InstallLibTestCase(support.TempdirManager,
# get_input should return 2 elements
self.assertEqual(len(cmd.get_inputs()), 2)
- @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'),
- 'sys.dont_write_bytecode not supported')
def test_dont_write_bytecode(self):
# makes sure byte_compile is not used
pkg_dir, dist = self.create_dist()
diff --git a/distutils2/tests/test_command_install_scripts.py b/distutils2/tests/test_command_install_scripts.py
index da5ad94..551cd8c 100644
--- a/distutils2/tests/test_command_install_scripts.py
+++ b/distutils2/tests/test_command_install_scripts.py
@@ -38,11 +38,8 @@ class InstallScriptsTestCase(support.TempdirManager,
def write_script(name, text):
expected.append(name)
- f = open(os.path.join(source, name), "w")
- try:
+ with open(os.path.join(source, name), "w") as f:
f.write(text)
- finally:
- f.close()
write_script("script1.py", ("#! /usr/bin/env python2.3\n"
"# bogus script w/ Python sh-bang\n"
diff --git a/distutils2/tests/test_command_register.py b/distutils2/tests/test_command_register.py
index a0326f9..2cc9f70 100644
--- a/distutils2/tests/test_command_register.py
+++ b/distutils2/tests/test_command_register.py
@@ -1,8 +1,10 @@
-# encoding: utf-8
"""Tests for distutils2.command.register."""
import os
import getpass
-import urllib2
+import urllib.request
+import urllib.error
+import urllib.parse
+
try:
import docutils
DOCUTILS_SUPPORT = True
@@ -36,7 +38,7 @@ password:password
"""
-class Inputs(object):
+class Inputs:
"""Fakes user inputs."""
def __init__(self, *answers):
self.answers = answers
@@ -49,7 +51,7 @@ class Inputs(object):
self.index += 1
-class FakeOpener(object):
+class FakeOpener:
"""Fakes a PyPI server"""
def __init__(self):
self.reqs = []
@@ -85,12 +87,12 @@ class RegisterTestCase(support.TempdirManager,
return 'password'
getpass.getpass = _getpass
- self.old_opener = urllib2.build_opener
- self.conn = urllib2.build_opener = FakeOpener()
+ self.old_opener = urllib.request.build_opener
+ self.conn = urllib.request.build_opener = FakeOpener()
def tearDown(self):
getpass.getpass = self._old_getpass
- urllib2.build_opener = self.old_opener
+ urllib.request.build_opener = self.old_opener
if hasattr(register_module, 'input'):
del register_module.input
super(RegisterTestCase, self).tearDown()
@@ -121,7 +123,7 @@ class RegisterTestCase(support.TempdirManager,
# Password : 'password'
# Save your login (y/N)? : 'y'
inputs = Inputs('1', 'tarek', 'y')
- register_module.raw_input = inputs
+ register_module.input = inputs
cmd.ensure_finalized()
cmd.run()
@@ -129,11 +131,8 @@ class RegisterTestCase(support.TempdirManager,
self.assertTrue(os.path.exists(self.rc))
# with the content similar to WANTED_PYPIRC
- fp = open(self.rc)
- try:
+ with open(self.rc) as fp:
content = fp.read()
- finally:
- fp.close()
self.assertEqual(content, WANTED_PYPIRC)
# now let's make sure the .pypirc file generated
@@ -153,7 +152,7 @@ class RegisterTestCase(support.TempdirManager,
req1 = dict(self.conn.reqs[0].headers)
req2 = dict(self.conn.reqs[1].headers)
self.assertEqual(req2['Content-length'], req1['Content-length'])
- self.assertIn('xxx', self.conn.reqs[1].data)
+ self.assertIn(b'xxx', self.conn.reqs[1].data)
def test_password_not_in_file(self):
@@ -171,7 +170,7 @@ class RegisterTestCase(support.TempdirManager,
# this test runs choice 2
cmd = self._get_cmd()
inputs = Inputs('2', 'tarek', 'tarek@ziade.org')
- register_module.raw_input = inputs
+ register_module.input = inputs
# let's run the command
# FIXME does this send a real request? use a mock server
cmd.ensure_finalized()
@@ -182,13 +181,13 @@ class RegisterTestCase(support.TempdirManager,
req = self.conn.reqs[0]
headers = dict(req.headers)
self.assertEqual(headers['Content-length'], '628')
- self.assertIn('tarek', req.data)
+ self.assertIn(b'tarek', req.data)
def test_password_reset(self):
# this test runs choice 3
cmd = self._get_cmd()
inputs = Inputs('3', 'tarek@ziade.org')
- register_module.raw_input = inputs
+ register_module.input = inputs
cmd.ensure_finalized()
cmd.run()
@@ -197,7 +196,7 @@ class RegisterTestCase(support.TempdirManager,
req = self.conn.reqs[0]
headers = dict(req.headers)
self.assertEqual(headers['Content-length'], '298')
- self.assertIn('tarek', req.data)
+ self.assertIn(b'tarek', req.data)
@unittest.skipUnless(DOCUTILS_SUPPORT, 'needs docutils')
def test_strict(self):
@@ -211,7 +210,7 @@ class RegisterTestCase(support.TempdirManager,
cmd.ensure_finalized()
cmd.strict = True
inputs = Inputs('1', 'tarek', 'y')
- register_module.raw_input = inputs
+ register_module.input = inputs
self.assertRaises(PackagingSetupError, cmd.run)
# metadata is OK but long_description is broken
@@ -232,7 +231,7 @@ class RegisterTestCase(support.TempdirManager,
cmd.ensure_finalized()
cmd.strict = True
inputs = Inputs('1', 'tarek', 'y')
- register_module.raw_input = inputs
+ register_module.input = inputs
cmd.ensure_finalized()
cmd.run()
@@ -240,22 +239,22 @@ class RegisterTestCase(support.TempdirManager,
cmd = self._get_cmd()
cmd.ensure_finalized()
inputs = Inputs('1', 'tarek', 'y')
- register_module.raw_input = inputs
+ register_module.input = inputs
cmd.ensure_finalized()
cmd.run()
# and finally a Unicode test (bug #12114)
- metadata = {'home_page': u'xxx', 'author': u'\u00c9ric',
- 'author_email': u'xxx', 'name': u'xxx',
- 'version': u'xxx',
- 'summary': u'Something about esszet \u00df',
- 'description': u'More things about esszet \u00df'}
+ metadata = {'home_page': 'xxx', 'author': '\u00c9ric',
+ 'author_email': 'xxx', 'name': 'xxx',
+ 'version': 'xxx',
+ 'summary': 'Something about esszet \u00df',
+ 'description': 'More things about esszet \u00df'}
cmd = self._get_cmd(metadata)
cmd.ensure_finalized()
cmd.strict = True
inputs = Inputs('1', 'tarek', 'y')
- register_module.raw_input = inputs
+ register_module.input = inputs
cmd.ensure_finalized()
cmd.run()
diff --git a/distutils2/tests/test_command_sdist.py b/distutils2/tests/test_command_sdist.py
index c056881..9bf1fcf 100644
--- a/distutils2/tests/test_command_sdist.py
+++ b/distutils2/tests/test_command_sdist.py
@@ -214,11 +214,8 @@ class SDistTestCase(support.TempdirManager,
self.assertEqual(len(content), 10)
# Checking the MANIFEST
- fp = open(join(self.tmp_dir, 'MANIFEST'))
- try:
+ with open(join(self.tmp_dir, 'MANIFEST')) as fp:
manifest = fp.read()
- finally:
- fp.close()
self.assertEqual(manifest, MANIFEST % {'sep': os.sep})
@requires_zlib
@@ -334,12 +331,9 @@ class SDistTestCase(support.TempdirManager,
# Should produce four lines. Those lines are one comment, one default
# (README) and two package files.
- f = open(cmd.manifest)
- try:
+ with open(cmd.manifest) as f:
manifest = [line.strip() for line in f.read().split('\n')
if line.strip() != '']
- finally:
- f.close()
self.assertEqual(len(manifest), 3)
# Adding a file
@@ -352,12 +346,9 @@ class SDistTestCase(support.TempdirManager,
cmd.run()
- f = open(cmd.manifest)
- try:
+ with open(cmd.manifest) as f:
manifest2 = [line.strip() for line in f.read().split('\n')
if line.strip() != '']
- finally:
- f.close()
# Do we have the new file in MANIFEST?
self.assertEqual(len(manifest2), 4)
@@ -370,12 +361,9 @@ class SDistTestCase(support.TempdirManager,
cmd.ensure_finalized()
cmd.run()
- f = open(cmd.manifest)
- try:
+ with open(cmd.manifest) as f:
manifest = [line.strip() for line in f.read().split('\n')
if line.strip() != '']
- finally:
- f.close()
self.assertEqual(manifest[0],
'# file GENERATED by distutils2, do NOT edit')
@@ -388,12 +376,9 @@ class SDistTestCase(support.TempdirManager,
self.write_file((self.tmp_dir, cmd.manifest), 'README.manual')
cmd.run()
- f = open(cmd.manifest)
- try:
+ with open(cmd.manifest) as f:
manifest = [line.strip() for line in f.read().split('\n')
if line.strip() != '']
- finally:
- f.close()
self.assertEqual(manifest, ['README.manual'])
@@ -404,11 +389,8 @@ class SDistTestCase(support.TempdirManager,
cmd.ensure_finalized()
self.write_file((self.tmp_dir, 'yeah'), 'xxx')
cmd.run()
- f = open(cmd.manifest)
- try:
+ with open(cmd.manifest) as f:
content = f.read()
- finally:
- f.close()
self.assertIn('yeah', content)
diff --git a/distutils2/tests/test_command_test.py b/distutils2/tests/test_command_test.py
index 2b832cb..9fb6fb9 100644
--- a/distutils2/tests/test_command_test.py
+++ b/distutils2/tests/test_command_test.py
@@ -113,7 +113,7 @@ class TestTest(TempdirManager,
record = []
a_module.recorder = lambda *args: record.append("suite")
- class MockTextTestRunner(object):
+ class MockTextTestRunner:
def __init__(*_, **__):
pass
@@ -177,7 +177,7 @@ class TestTest(TempdirManager,
self.assertEqual(["runner called"], record)
def prepare_mock_ut2(self):
- class MockUTClass(object):
+ class MockUTClass:
def __init__(*_, **__):
pass
@@ -187,7 +187,7 @@ class TestTest(TempdirManager,
def run(self, _):
pass
- class MockUTModule(object):
+ class MockUTModule:
TestLoader = MockUTClass
TextTestRunner = MockUTClass
diff --git a/distutils2/tests/test_command_upload.py b/distutils2/tests/test_command_upload.py
index 76281ca..5c58879 100644
--- a/distutils2/tests/test_command_upload.py
+++ b/distutils2/tests/test_command_upload.py
@@ -1,4 +1,3 @@
-# encoding: utf-8
"""Tests for distutils2.command.upload."""
import os
@@ -44,6 +43,7 @@ repository:http://another.pypi/
"""
+@unittest.skipIf(threading is None, 'needs threading')
class UploadTestCase(support.TempdirManager, support.EnvironRestorer,
support.LoggingCatcher, PyPIServerTestCase):
@@ -112,8 +112,8 @@ class UploadTestCase(support.TempdirManager, support.EnvironRestorer,
# what did we send?
handler, request_data = self.pypi.requests[-1]
headers = handler.headers
- self.assertIn('dédé', request_data)
- self.assertIn('xxx', request_data)
+ self.assertIn('dédé'.encode('utf-8'), request_data)
+ self.assertIn(b'xxx', request_data)
self.assertEqual(int(headers['content-length']), len(request_data))
self.assertLess(int(headers['content-length']), 2500)
@@ -148,12 +148,8 @@ class UploadTestCase(support.TempdirManager, support.EnvironRestorer,
"----------------GHSKFJDLGDS7543FJKLFHRE75642756743254"
.encode())[1:4]
- self.assertIn('name=":action"', action)
- self.assertIn('doc_upload', action)
-
-
-UploadTestCase = unittest.skipIf(threading is None, 'needs threading')(
- UploadTestCase)
+ self.assertIn(b'name=":action"', action)
+ self.assertIn(b'doc_upload', action)
def test_suite():
diff --git a/distutils2/tests/test_command_upload_docs.py b/distutils2/tests/test_command_upload_docs.py
index d6edc37..cf69af9 100644
--- a/distutils2/tests/test_command_upload_docs.py
+++ b/distutils2/tests/test_command_upload_docs.py
@@ -32,6 +32,7 @@ password = long_island
"""
+@unittest.skipIf(threading is None, "Needs threading")
class UploadDocsTestCase(support.TempdirManager,
support.EnvironRestorer,
support.LoggingCatcher,
@@ -94,39 +95,39 @@ class UploadDocsTestCase(support.TempdirManager,
self.assertEqual(len(self.pypi.requests), 1)
handler, request_data = self.pypi.requests[-1]
- self.assertIn("content", request_data)
+ self.assertIn(b"content", request_data)
self.assertIn("Basic", handler.headers['authorization'])
self.assertTrue(handler.headers['content-type']
.startswith('multipart/form-data;'))
action, name, version, content = request_data.split(
- '----------------GHSKFJDLGDS7543FJKLFHRE75642756743254')[1:5]
+ b'----------------GHSKFJDLGDS7543FJKLFHRE75642756743254')[1:5]
# check that we picked the right chunks
- self.assertIn('name=":action"', action)
- self.assertIn('name="name"', name)
- self.assertIn('name="version"', version)
- self.assertIn('name="content"', content)
+ self.assertIn(b'name=":action"', action)
+ self.assertIn(b'name="name"', name)
+ self.assertIn(b'name="version"', version)
+ self.assertIn(b'name="content"', content)
# check their contents
- self.assertIn('doc_upload', action)
- self.assertIn('distr-name', name)
- self.assertIn('docs/index.html', content)
- self.assertIn('Ce mortel ennui', content)
+ self.assertIn(b'doc_upload', action)
+ self.assertIn(b'distr-name', name)
+ self.assertIn(b'docs/index.html', content)
+ self.assertIn(b'Ce mortel ennui', content)
@unittest.skipIf(_ssl is None, 'Needs SSL support')
def test_https_connection(self):
self.https_called = False
self.addCleanup(
- setattr, upload_docs_mod.httplib, 'HTTPSConnection',
- upload_docs_mod.httplib.HTTPSConnection)
+ setattr, upload_docs_mod.http.client, 'HTTPSConnection',
+ upload_docs_mod.http.client.HTTPSConnection)
def https_conn_wrapper(*args):
self.https_called = True
# the testing server is http
- return upload_docs_mod.httplib.HTTPConnection(*args)
+ return upload_docs_mod.http.client.HTTPConnection(*args)
- upload_docs_mod.httplib.HTTPSConnection = https_conn_wrapper
+ upload_docs_mod.http.client.HTTPSConnection = https_conn_wrapper
self.prepare_command()
self.cmd.run()
@@ -174,9 +175,6 @@ class UploadDocsTestCase(support.TempdirManager,
self.assertTrue(record, "should report the response")
self.assertIn(self.pypi.default_response_data, record)
-UploadDocsTestCase = unittest.skipIf(threading is None, "Needs threading")(
- UploadDocsTestCase)
-
def test_suite():
return unittest.makeSuite(UploadDocsTestCase)
diff --git a/distutils2/tests/test_compiler.py b/distutils2/tests/test_compiler.py
index 3bc7c3f..d67805a 100644
--- a/distutils2/tests/test_compiler.py
+++ b/distutils2/tests/test_compiler.py
@@ -6,7 +6,7 @@ from distutils2.compiler import (get_default_compiler, customize_compiler,
from distutils2.tests import unittest, support
-class FakeCompiler(object):
+class FakeCompiler:
name = 'fake'
description = 'Fake'
@@ -36,7 +36,7 @@ class CompilerTestCase(support.EnvironRestorer, unittest.TestCase):
os.environ['ARFLAGS'] = '-arflags'
# make sure AR gets caught
- class compiler(object):
+ class compiler:
name = 'unix'
def set_executables(self, **kw):
diff --git a/distutils2/tests/test_config.py b/distutils2/tests/test_config.py
index 295f1ae..7c913ee 100644
--- a/distutils2/tests/test_config.py
+++ b/distutils2/tests/test_config.py
@@ -1,9 +1,8 @@
-# encoding: utf-8
"""Tests for distutils2.config."""
import os
import sys
import logging
-from StringIO import StringIO
+from io import StringIO
from distutils2 import command
from distutils2.dist import Distribution
@@ -15,7 +14,7 @@ from distutils2.tests import unittest, support
from distutils2.tests.support import requires_zlib
-SETUP_CFG = u"""
+SETUP_CFG = """
[metadata]
name = RestingParrot
version = 0.6.4
@@ -161,7 +160,7 @@ def logging_hook(config):
"""
-class DCompiler(object):
+class DCompiler:
name = 'd'
description = 'D Compiler'
@@ -181,7 +180,7 @@ def third_hook(config):
config['files']['modules'] += '\n third'
-class FooBarBazTest(object):
+class FooBarBazTest:
def __init__(self, dist):
self.distribution = dist
@@ -474,11 +473,8 @@ class ConfigTestCase(support.TempdirManager,
cmd.finalize_options()
cmd.get_file_list()
cmd.make_distribution()
- fp = open('MANIFEST')
- try:
+ with open('MANIFEST') as fp:
self.assertIn('README\nREADME2\n', fp.read())
- finally:
- fp.close()
def test_sub_commands(self):
self.write_setup()
diff --git a/distutils2/tests/test_create.py b/distutils2/tests/test_create.py
index a268c4f..7a0aa0d 100644
--- a/distutils2/tests/test_create.py
+++ b/distutils2/tests/test_create.py
@@ -1,9 +1,7 @@
-# encoding: utf-8
"""Tests for distutils2.create."""
import os
import sys
-import codecs
-from StringIO import StringIO
+from io import StringIO
from textwrap import dedent
from distutils2.create import MainProgram, ask_yn, ask, main
from distutils2._backport import sysconfig
@@ -98,7 +96,7 @@ class CreateTestCase(support.TempdirManager,
def test_convert_setup_py_to_cfg(self):
self.write_file((self.wdir, 'setup.py'),
- dedent(u"""
+ dedent("""
# coding: utf-8
from distutils.core import setup
@@ -133,18 +131,15 @@ class CreateTestCase(support.TempdirManager,
scripts=['my_script', 'bin/run'],
)
"""), encoding='utf-8')
- sys.stdin.write(u'y\n')
+ sys.stdin.write('y\n')
sys.stdin.seek(0)
main()
path = os.path.join(self.wdir, 'setup.cfg')
- fp = codecs.open(path, encoding='utf-8')
- try:
+ with open(path, encoding='utf-8') as fp:
contents = fp.read()
- finally:
- fp.close()
- self.assertEqual(contents, dedent(u"""\
+ self.assertEqual(contents, dedent("""\
[metadata]
name = pyxfoil
version = 0.2
@@ -184,14 +179,11 @@ class CreateTestCase(support.TempdirManager,
def test_convert_setup_py_to_cfg_with_description_in_readme(self):
self.write_file((self.wdir, 'setup.py'),
- dedent(u"""
+ dedent("""
# coding: utf-8
from distutils.core import setup
- fp = open('README.txt')
- try:
+ with open('README.txt') as fp:
long_description = fp.read()
- finally:
- fp.close()
setup(name='pyxfoil',
version='0.2',
@@ -221,13 +213,10 @@ ho, baby!
main()
path = os.path.join(self.wdir, 'setup.cfg')
- fp = codecs.open(path, encoding='utf-8')
- try:
+ with open(path, encoding='utf-8') as fp:
contents = fp.read()
- finally:
- fp.close()
- self.assertEqual(contents, dedent(u"""\
+ self.assertEqual(contents, dedent("""\
[metadata]
name = pyxfoil
version = 0.2
diff --git a/distutils2/tests/test_database.py b/distutils2/tests/test_database.py
index e524306..02c72da 100644
--- a/distutils2/tests/test_database.py
+++ b/distutils2/tests/test_database.py
@@ -1,12 +1,10 @@
import os
+import io
import csv
import sys
import shutil
import tempfile
-try:
- from hashlib import md5
-except ImportError:
- from distutils2._backport.hashlib import md5
+from hashlib import md5
from textwrap import dedent
from distutils2.tests.test_util import GlobTestCaseBase
@@ -28,11 +26,8 @@ from distutils2.database import (
def get_hexdigest(filename):
- fp = open(filename, 'rb')
- try:
- checksum = md5(fp.read())
- finally:
- fp.close()
+ with open(filename, 'rb') as file:
+ checksum = md5(file.read())
return checksum.hexdigest()
@@ -43,7 +38,7 @@ def record_pieces(path):
return path, digest, size
-class FakeDistsMixin(object):
+class FakeDistsMixin:
def setUp(self):
super(FakeDistsMixin, self).setUp()
@@ -65,11 +60,11 @@ class FakeDistsMixin(object):
# shutil gives no control over the mode of directories :(
# see http://bugs.python.org/issue1666318
for root, dirs, files in os.walk(self.fake_dists_path):
- os.chmod(root, 0755)
+ os.chmod(root, 0o755)
for f in files:
- os.chmod(os.path.join(root, f), 0644)
+ os.chmod(os.path.join(root, f), 0o644)
for d in dirs:
- os.chmod(os.path.join(root, d), 0755)
+ os.chmod(os.path.join(root, d), 0o755)
class CommonDistributionTests(FakeDistsMixin):
@@ -138,10 +133,9 @@ class TestDistribution(CommonDistributionTests, unittest.TestCase):
for distinfo_dir in self.dirs:
record_file = os.path.join(distinfo_dir, 'RECORD')
- fp = open(record_file, 'w')
- try:
+ with open(record_file, 'w') as file:
record_writer = csv.writer(
- fp, delimiter=',', quoting=csv.QUOTE_NONE,
+ file, delimiter=',', quoting=csv.QUOTE_NONE,
lineterminator='\n')
dist_location = distinfo_dir.replace('.dist-info', '')
@@ -152,12 +146,9 @@ class TestDistribution(CommonDistributionTests, unittest.TestCase):
for file in ('INSTALLER', 'METADATA', 'REQUESTED'):
record_writer.writerow(record_pieces((distinfo_dir, file)))
record_writer.writerow([record_file])
- finally:
- fp.close()
- fp = open(record_file)
- try:
- record_reader = csv.reader(fp, lineterminator='\n')
+ with open(record_file) as file:
+ record_reader = csv.reader(file, lineterminator='\n')
record_data = {}
for row in record_reader:
if row == []:
@@ -165,8 +156,6 @@ class TestDistribution(CommonDistributionTests, unittest.TestCase):
path, md5_, size = (row[:] +
[None for i in range(len(row), 3)])
record_data[path] = md5_, size
- finally:
- fp.close()
self.records[distinfo_dir] = record_data
def test_instantiation(self):
@@ -210,14 +199,11 @@ class TestDistribution(CommonDistributionTests, unittest.TestCase):
]
for distfile in distinfo_files:
- value = dist.get_distinfo_file(distfile)
- try:
- self.assertIsInstance(value, file)
+ with dist.get_distinfo_file(distfile) as value:
+ self.assertIsInstance(value, io.TextIOWrapper)
# Is it the correct file?
self.assertEqual(value.name,
os.path.join(distinfo_dir, distfile))
- finally:
- value.close()
# Test an absolute path that is part of another distributions dist-info
other_distinfo_file = os.path.join(
@@ -640,8 +626,7 @@ class DataFilesTestCase(GlobTestCaseBase):
metadata_path = os.path.join(dist_info, 'METADATA')
resources_path = os.path.join(dist_info, 'RESOURCES')
- fp = open(metadata_path, 'w')
- try:
+ with open(metadata_path, 'w') as fp:
fp.write(dedent("""\
Metadata-Version: 1.2
Name: test
@@ -649,25 +634,18 @@ class DataFilesTestCase(GlobTestCaseBase):
Summary: test
Author: me
"""))
- finally:
- fp.close()
+
test_path = 'test.cfg'
fd, test_resource_path = tempfile.mkstemp()
os.close(fd)
self.addCleanup(os.remove, test_resource_path)
- fp = open(test_resource_path, 'w')
- try:
+ with open(test_resource_path, 'w') as fp:
fp.write('Config')
- finally:
- fp.close()
- fp = open(resources_path, 'w')
- try:
+ with open(resources_path, 'w') as fp:
fp.write('%s,%s' % (test_path, test_resource_path))
- finally:
- fp.close()
# Add fake site-packages to sys.path to retrieve fake dist
self.addCleanup(sys.path.remove, temp_site_packages)
@@ -682,11 +660,8 @@ class DataFilesTestCase(GlobTestCaseBase):
test_resource_path)
self.assertRaises(KeyError, get_file_path, dist_name, 'i-dont-exist')
- fp = get_file(dist_name, test_path)
- try:
+ with get_file(dist_name, test_path) as fp:
self.assertEqual(fp.read(), 'Config')
- finally:
- fp.close()
self.assertRaises(KeyError, get_file, dist_name, 'i-dont-exist')
diff --git a/distutils2/tests/test_depgraph.py b/distutils2/tests/test_depgraph.py
index 145ce57..5c58971 100644
--- a/distutils2/tests/test_depgraph.py
+++ b/distutils2/tests/test_depgraph.py
@@ -2,7 +2,7 @@
import os
import re
import sys
-from StringIO import StringIO
+from io import StringIO
from distutils2 import depgraph
from distutils2.database import get_distribution, enable_cache, disable_cache
diff --git a/distutils2/tests/test_dist.py b/distutils2/tests/test_dist.py
index 0c1f036..22fd37b 100644
--- a/distutils2/tests/test_dist.py
+++ b/distutils2/tests/test_dist.py
@@ -1,7 +1,6 @@
"""Tests for distutils2.dist."""
import os
import sys
-import codecs
import logging
import textwrap
@@ -52,12 +51,9 @@ class DistributionTestCase(support.TempdirManager,
def test_debug_mode(self):
tmpdir = self.mkdtemp()
setupcfg = os.path.join(tmpdir, 'setup.cfg')
- f = open(setupcfg, "w")
- try:
+ with open(setupcfg, "w") as f:
f.write("[global]\n")
f.write("command_packages = foo.bar, splat")
- finally:
- f.close()
files = [setupcfg]
sys.argv.append("build")
@@ -128,11 +124,8 @@ class DistributionTestCase(support.TempdirManager,
temp_dir = self.mkdtemp()
user_filename = os.path.join(temp_dir, user_filename)
- f = open(user_filename, 'w')
- try:
+ with open(user_filename, 'w') as f:
f.write('.')
- finally:
- f.close()
dist = Distribution()
@@ -148,11 +141,8 @@ class DistributionTestCase(support.TempdirManager,
else:
user_filename = os.path.join(temp_home, "pydistutils.cfg")
- f = open(user_filename, 'w')
- try:
+ with open(user_filename, 'w') as f:
f.write('[distutils2]\n')
- finally:
- f.close()
def _expander(path):
return temp_home
diff --git a/distutils2/tests/test_install.py b/distutils2/tests/test_install.py
index d00116c..571133c 100644
--- a/distutils2/tests/test_install.py
+++ b/distutils2/tests/test_install.py
@@ -18,7 +18,7 @@ except ImportError:
use_xmlrpc_server = fake_dec
-class InstalledDist(object):
+class InstalledDist:
"""Distribution object, represent distributions currently installed on the
system"""
def __init__(self, name, version, deps):
@@ -33,7 +33,7 @@ class InstalledDist(object):
return '<InstalledDist %r>' % self.metadata['Name']
-class ToInstallDist(object):
+class ToInstallDist:
"""Distribution that will be installed"""
def __init__(self, files=False):
@@ -63,7 +63,7 @@ class ToInstallDist(object):
return self.list_installed_files()
-class MagicMock(object):
+class MagicMock:
def __init__(self, return_value=None, raise_exception=False):
self.called = False
self._times_called = 0
diff --git a/distutils2/tests/test_manifest.py b/distutils2/tests/test_manifest.py
index d7c4d6f..24f0510 100644
--- a/distutils2/tests/test_manifest.py
+++ b/distutils2/tests/test_manifest.py
@@ -1,7 +1,7 @@
"""Tests for distutils2.manifest."""
import os
import logging
-from StringIO import StringIO
+from io import StringIO
from distutils2.manifest import Manifest
from distutils2.tests import unittest, support
@@ -37,11 +37,8 @@ class ManifestTestCase(support.TempdirManager,
def test_manifest_reader(self):
tmpdir = self.mkdtemp()
MANIFEST = os.path.join(tmpdir, 'MANIFEST.in')
- f = open(MANIFEST, 'w')
- try:
+ with open(MANIFEST, 'w') as f:
f.write(_MANIFEST)
- finally:
- f.close()
manifest = Manifest()
manifest.read_template(MANIFEST)
@@ -54,11 +51,8 @@ class ManifestTestCase(support.TempdirManager,
self.assertIn('no files found matching', warning)
# manifest also accepts file-like objects
- f = open(MANIFEST)
- try:
+ with open(MANIFEST) as f:
manifest.read_template(f)
- finally:
- f.close()
# the manifest should have been read and 3 warnings issued
# (we didn't provide the files)
diff --git a/distutils2/tests/test_markers.py b/distutils2/tests/test_markers.py
index 67e9e9b..0e8b74e 100644
--- a/distutils2/tests/test_markers.py
+++ b/distutils2/tests/test_markers.py
@@ -2,7 +2,6 @@
import os
import sys
import platform
-from distutils2.compat import python_implementation
from distutils2.markers import interpret
from distutils2.tests import unittest
@@ -18,7 +17,7 @@ class MarkersTestCase(LoggingCatcher,
os_name = os.name
platform_version = platform.version()
platform_machine = platform.machine()
- platform_python_implementation = python_implementation()
+ platform_python_implementation = platform.python_implementation()
self.assertTrue(interpret("sys.platform == '%s'" % sys_platform))
self.assertTrue(interpret(
diff --git a/distutils2/tests/test_metadata.py b/distutils2/tests/test_metadata.py
index aceedc2..82f5212 100644
--- a/distutils2/tests/test_metadata.py
+++ b/distutils2/tests/test_metadata.py
@@ -1,11 +1,9 @@
-# encoding: utf-8
"""Tests for distutils2.metadata."""
import os
import sys
-import codecs
import logging
from textwrap import dedent
-from StringIO import StringIO
+from io import StringIO
from distutils2.errors import (MetadataConflictError, MetadataMissingError,
MetadataUnrecognizedVersionError)
@@ -37,12 +35,8 @@ class MetadataTestCase(LoggingCatcher,
def test_instantiation(self):
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
- f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
- try:
+ with open(PKG_INFO, 'r', encoding='utf-8') as f:
contents = f.read()
- finally:
- f.close()
-
fp = StringIO(contents)
m = Metadata()
@@ -70,11 +64,8 @@ class MetadataTestCase(LoggingCatcher,
def test_metadata_markers(self):
# see if we can be platform-aware
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
- f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
- try:
+ with open(PKG_INFO, 'r', encoding='utf-8') as f:
content = f.read() % sys.platform
- finally:
- f.close()
metadata = Metadata(platform_dependent=True)
metadata.read_file(StringIO(content))
@@ -92,11 +83,8 @@ class MetadataTestCase(LoggingCatcher,
def test_mapping_api(self):
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
- f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
- try:
+ with open(PKG_INFO, 'r', encoding='utf-8') as f:
content = f.read() % sys.platform
- finally:
- f.close()
metadata = Metadata(fileobj=StringIO(content))
self.assertIn('Version', metadata.keys())
self.assertIn('0.5', metadata.values())
@@ -111,6 +99,8 @@ class MetadataTestCase(LoggingCatcher,
metadata.update({'version': '1--2'})
self.assertEqual(len(self.get_logs()), 1)
+ # XXX caveat: the keys method and friends are not 3.x-style views
+ # should be changed or documented
self.assertEqual(list(metadata), metadata.keys())
def test_read_metadata(self):
@@ -143,21 +133,18 @@ class MetadataTestCase(LoggingCatcher,
tmp_dir = self.mkdtemp()
my_file = os.path.join(tmp_dir, 'f')
- metadata = Metadata(mapping={'author': u'Mister Café',
- 'name': u'my.project',
- 'author': u'Café Junior',
- 'summary': u'Café torréfié',
- 'description': u'Héhéhé',
- 'keywords': [u'café', u'coffee']})
+ metadata = Metadata(mapping={'author': 'Mister Café',
+ 'name': 'my.project',
+ 'author': 'Café Junior',
+ 'summary': 'Café torréfié',
+ 'description': 'Héhéhé',
+ 'keywords': ['café', 'coffee']})
metadata.write(my_file)
# the file should use UTF-8
metadata2 = Metadata()
- fp = codecs.open(my_file, encoding='utf-8')
- try:
+ with open(my_file, encoding='utf-8') as fp:
metadata2.read_file(fp)
- finally:
- fp.close()
# XXX when keywords are not defined, metadata will have
# 'Keywords': [] but metadata2 will have 'Keywords': ['']
@@ -165,19 +152,16 @@ class MetadataTestCase(LoggingCatcher,
self.assertEqual(metadata.items(), metadata2.items())
# ASCII also works, it's a subset of UTF-8
- metadata = Metadata(mapping={'author': u'Mister Cafe',
- 'name': u'my.project',
- 'author': u'Cafe Junior',
- 'summary': u'Cafe torrefie',
- 'description': u'Hehehe'})
+ metadata = Metadata(mapping={'author': 'Mister Cafe',
+ 'name': 'my.project',
+ 'author': 'Cafe Junior',
+ 'summary': 'Cafe torrefie',
+ 'description': 'Hehehe'})
metadata.write(my_file)
metadata2 = Metadata()
- fp = codecs.open(my_file, encoding='utf-8')
- try:
+ with open(my_file, encoding='utf-8') as fp:
metadata2.read_file(fp)
- finally:
- fp.close()
def test_metadata_read_write(self):
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
@@ -324,21 +308,15 @@ class MetadataTestCase(LoggingCatcher,
def test_description(self):
PKG_INFO = os.path.join(os.path.dirname(__file__), 'PKG-INFO')
- f = codecs.open(PKG_INFO, 'r', encoding='utf-8')
- try:
+ with open(PKG_INFO, 'r', encoding='utf-8') as f:
content = f.read() % sys.platform
- finally:
- f.close()
metadata = Metadata()
metadata.read_file(StringIO(content))
# see if we can read the description now
DESC = os.path.join(os.path.dirname(__file__), 'LONG_DESC.txt')
- f = open(DESC)
- try:
+ with open(DESC) as f:
wanted = f.read()
- finally:
- f.close()
self.assertEqual(wanted, metadata['Description'])
# save the file somewhere and make sure we can read it back
diff --git a/distutils2/tests/test_mixin2to3.py b/distutils2/tests/test_mixin2to3.py
index 1fe3574..4d1584b 100644
--- a/distutils2/tests/test_mixin2to3.py
+++ b/distutils2/tests/test_mixin2to3.py
@@ -9,30 +9,22 @@ class Mixin2to3TestCase(support.TempdirManager,
support.LoggingCatcher,
unittest.TestCase):
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_convert_code_only(self):
# used to check if code gets converted properly.
code = "print 'test'"
- fp = self.mktempfile()
- try:
+ with self.mktempfile() as fp:
fp.write(code)
- finally:
- fp.close()
mixin2to3 = Mixin2to3()
mixin2to3._run_2to3([fp.name])
expected = "print('test')"
- fp = open(fp.name)
- try:
+ with open(fp.name) as fp:
converted = fp.read()
- finally:
- fp.close()
self.assertEqual(expected, converted)
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_doctests_only(self):
# used to check if doctests gets converted properly.
doctest = textwrap.dedent('''\
@@ -44,11 +36,8 @@ class Mixin2to3TestCase(support.TempdirManager,
It works.
"""''')
- fp = self.mktempfile()
- try:
+ with self.mktempfile() as fp:
fp.write(doctest)
- finally:
- fp.close()
mixin2to3 = Mixin2to3()
mixin2to3._run_2to3([fp.name])
@@ -61,24 +50,17 @@ class Mixin2to3TestCase(support.TempdirManager,
It works.
"""\n''')
- fp = open(fp.name)
- try:
+ with open(fp.name) as fp:
converted = fp.read()
- finally:
- fp.close()
self.assertEqual(expected, converted)
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_additional_fixers(self):
# used to check if use_2to3_fixers works
code = 'type(x) is not T'
- fp = self.mktempfile()
- try:
+ with self.mktempfile() as fp:
fp.write(code)
- finally:
- fp.close()
mixin2to3 = Mixin2to3()
mixin2to3._run_2to3(files=[fp.name], doctests=[fp.name],
@@ -86,11 +68,8 @@ class Mixin2to3TestCase(support.TempdirManager,
expected = 'not isinstance(x, T)'
- fp = open(fp.name)
- try:
+ with open(fp.name) as fp:
converted = fp.read()
- finally:
- fp.close()
self.assertEqual(expected, converted)
diff --git a/distutils2/tests/test_msvc9compiler.py b/distutils2/tests/test_msvc9compiler.py
index 22e5cea..16382e7 100644
--- a/distutils2/tests/test_msvc9compiler.py
+++ b/distutils2/tests/test_msvc9compiler.py
@@ -118,22 +118,16 @@ class msvc9compilerTestCase(support.TempdirManager,
from distutils2.compiler.msvc9compiler import MSVCCompiler
tempdir = self.mkdtemp()
manifest = os.path.join(tempdir, 'manifest')
- f = open(manifest, 'w')
- try:
+ with open(manifest, 'w') as f:
f.write(_MANIFEST)
- finally:
- f.close()
compiler = MSVCCompiler()
compiler._remove_visual_c_ref(manifest)
# see what we got
- f = open(manifest)
- try:
+ with open(manifest) as f:
# removing trailing spaces
content = '\n'.join(line.rstrip() for line in f.readlines())
- finally:
- f.close()
# makes sure the manifest was properly cleaned
self.assertEqual(content, _CLEANED_MANIFEST)
diff --git a/distutils2/tests/test_pypi_server.py b/distutils2/tests/test_pypi_server.py
index 8027401..36eb3d4 100644
--- a/distutils2/tests/test_pypi_server.py
+++ b/distutils2/tests/test_pypi_server.py
@@ -1,5 +1,7 @@
"""Tests for distutils2.command.bdist."""
-import urllib2
+import urllib.request
+import urllib.parse
+import urllib.error
try:
import threading
@@ -13,6 +15,7 @@ except ImportError:
from distutils2.tests import unittest
+@unittest.skipIf(threading is None, "Needs threading")
class PyPIServerTest(unittest.TestCase):
def test_records_requests(self):
@@ -24,12 +27,13 @@ class PyPIServerTest(unittest.TestCase):
server.start()
self.assertEqual(len(server.requests), 0)
- data = 'Rock Around The Bunker'
+ data = b'Rock Around The Bunker'
headers = {"X-test-header": "Mister Iceberg"}
- request = urllib2.Request(server.full_address, data, headers)
- urllib2.urlopen(request)
+ request = urllib.request.Request(
+ server.full_address, data, headers)
+ urllib.request.urlopen(request)
self.assertEqual(len(server.requests), 1)
handler, request_data = server.requests[-1]
self.assertIn(data, request_data)
@@ -48,14 +52,11 @@ class PyPIServerTest(unittest.TestCase):
server is the same than the one made by a simple file read.
"""
url = server.full_address + url_path
- request = urllib2.Request(url)
- response = urllib2.urlopen(request)
- file = open(PYPI_DEFAULT_STATIC_PATH + "/test_pypi_server"
- + url_path)
- try:
+ request = urllib.request.Request(url)
+ response = urllib.request.urlopen(request)
+ with open(PYPI_DEFAULT_STATIC_PATH + "/test_pypi_server"
+ + url_path) as file:
return response.read().decode() == file.read()
- finally:
- file.close()
server = PyPIServer(static_uri_paths=["simple", "external"],
static_filesystem_paths=["test_pypi_server"])
@@ -63,10 +64,10 @@ class PyPIServerTest(unittest.TestCase):
try:
# the file does not exists on the disc, so it might not be served
url = server.full_address + "/simple/unexisting_page"
- request = urllib2.Request(url)
+ request = urllib.request.Request(url)
try:
- urllib2.urlopen(request)
- except urllib2.HTTPError, e:
+ urllib.request.urlopen(request)
+ except urllib.error.HTTPError as e:
self.assertEqual(e.code, 404)
# now try serving a content that do exists
@@ -80,10 +81,6 @@ class PyPIServerTest(unittest.TestCase):
server.stop()
-PyPIServerTest = unittest.skipIf(threading is None, "Needs threading")(
- PyPIServerTest)
-
-
def test_suite():
return unittest.makeSuite(PyPIServerTest)
diff --git a/distutils2/tests/test_pypi_simple.py b/distutils2/tests/test_pypi_simple.py
index a2d8787..93d6fac 100644
--- a/distutils2/tests/test_pypi_simple.py
+++ b/distutils2/tests/test_pypi_simple.py
@@ -2,8 +2,10 @@
import re
import os
import sys
-import httplib
-import urllib2
+import http.client
+import urllib.error
+import urllib.parse
+import urllib.request
from distutils2.pypi.simple import Crawler
@@ -12,7 +14,7 @@ from distutils2.tests.support import (TempdirManager, LoggingCatcher,
fake_dec)
try:
- import thread as _thread
+ import _thread
from distutils2.tests.pypi_server import (use_pypi_server, PyPIServer,
PYPI_DEFAULT_STATIC_PATH)
except ImportError:
@@ -43,11 +45,11 @@ class SimpleCrawlerTestCase(TempdirManager,
url = 'http://127.0.0.1:0/nonesuch/test_simple'
try:
v = crawler._open_url(url)
- except Exception, v:
+ except Exception as v:
self.assertIn(url, str(v))
else:
v.close()
- self.assertIsInstance(v, urllib2.HTTPError)
+ self.assertIsInstance(v, urllib.error.HTTPError)
# issue 16
# easy_install inquant.contentmirror.plone breaks because of a typo
@@ -57,35 +59,34 @@ class SimpleCrawlerTestCase(TempdirManager,
'inquant.contentmirror.plone/trunk')
try:
v = crawler._open_url(url)
- except Exception, v:
+ except Exception as v:
self.assertIn(url, str(v))
else:
v.close()
- self.assertIsInstance(v, urllib2.HTTPError)
+ self.assertIsInstance(v, urllib.error.HTTPError)
def _urlopen(*args):
- raise httplib.BadStatusLine('line')
+ raise http.client.BadStatusLine('line')
- old_urlopen = urllib2.urlopen
- urllib2.urlopen = _urlopen
+ old_urlopen = urllib.request.urlopen
+ urllib.request.urlopen = _urlopen
url = 'http://example.org'
try:
- try:
- v = crawler._open_url(url)
- except Exception, v:
- self.assertIn('line', str(v))
- else:
- v.close()
- # TODO use self.assertRaises
- raise AssertionError('Should have raise here!')
+ v = crawler._open_url(url)
+ except Exception as v:
+ self.assertIn('line', str(v))
+ else:
+ v.close()
+ # TODO use self.assertRaises
+ raise AssertionError('Should have raise here!')
finally:
- urllib2.urlopen = old_urlopen
+ urllib.request.urlopen = old_urlopen
# issue 20
url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk'
try:
crawler._open_url(url)
- except Exception, v:
+ except Exception as v:
self.assertIn('nonnumeric port', str(v))
# issue #160
@@ -274,22 +275,22 @@ class SimpleCrawlerTestCase(TempdirManager,
# Test that the simple link matcher yield the good links.
generator = crawler._simple_link_matcher(content, crawler.index_url)
self.assertEqual(('%stest/foobar-1.tar.gz#md5=abcdef' %
- crawler.index_url, True), generator.next())
- self.assertEqual(('http://dl-link1', True), generator.next())
+ crawler.index_url, True), next(generator))
+ self.assertEqual(('http://dl-link1', True), next(generator))
self.assertEqual(('%stest' % crawler.index_url, False),
- generator.next())
- self.assertRaises(StopIteration, generator.next)
+ next(generator))
+ self.assertRaises(StopIteration, generator.__next__)
# Follow the external links is possible (eg. homepages)
crawler.follow_externals = True
generator = crawler._simple_link_matcher(content, crawler.index_url)
self.assertEqual(('%stest/foobar-1.tar.gz#md5=abcdef' %
- crawler.index_url, True), generator.next())
- self.assertEqual(('http://dl-link1', True), generator.next())
- self.assertEqual(('http://dl-link2', False), generator.next())
+ crawler.index_url, True), next(generator))
+ self.assertEqual(('http://dl-link1', True), next(generator))
+ self.assertEqual(('http://dl-link2', False), next(generator))
self.assertEqual(('%stest' % crawler.index_url, False),
- generator.next())
- self.assertRaises(StopIteration, generator.next)
+ next(generator))
+ self.assertRaises(StopIteration, generator.__next__)
def test_browse_local_files(self):
# Test that we can browse local files"""
diff --git a/distutils2/tests/test_pypi_xmlrpc.py b/distutils2/tests/test_pypi_xmlrpc.py
index d286bf4..e123fff 100644
--- a/distutils2/tests/test_pypi_xmlrpc.py
+++ b/distutils2/tests/test_pypi_xmlrpc.py
@@ -13,6 +13,7 @@ except ImportError:
use_xmlrpc_server = fake_dec
+@unittest.skipIf(threading is None, "Needs threading")
class TestXMLRPCClient(unittest.TestCase):
def _get_client(self, server, *args, **kwargs):
return Client(server.full_address, *args, **kwargs)
@@ -91,10 +92,6 @@ class TestXMLRPCClient(unittest.TestCase):
self.assertEqual(['FooFoo'], release.metadata['obsoletes_dist'])
-TestXMLRPCClient = unittest.skipIf(threading is None, "Needs threading")(
- TestXMLRPCClient)
-
-
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestXMLRPCClient))
diff --git a/distutils2/tests/test_run.py b/distutils2/tests/test_run.py
index 21b76f1..8645f63 100644
--- a/distutils2/tests/test_run.py
+++ b/distutils2/tests/test_run.py
@@ -2,7 +2,7 @@
import os
import sys
-from StringIO import StringIO
+from io import StringIO
from distutils2 import install
from distutils2.tests import unittest, support
@@ -71,12 +71,11 @@ class RunTestCase(support.TempdirManager,
else:
pythonpath = d2parent
- status, out, err = assert_python_ok(
- '-c', 'from distutils2.run import main; main()', '--help',
- PYTHONPATH=pythonpath)
+ status, out, err = assert_python_ok('-m', 'distutils2.run', '--help',
+ PYTHONPATH=pythonpath)
self.assertEqual(status, 0)
- self.assertGreater(out, '')
- self.assertEqual(err, '')
+ self.assertGreater(out, b'')
+ self.assertEqual(err, b'')
def test_suite():
diff --git a/distutils2/tests/test_util.py b/distutils2/tests/test_util.py
index f369ce7..74e7ddc 100644
--- a/distutils2/tests/test_util.py
+++ b/distutils2/tests/test_util.py
@@ -5,7 +5,7 @@ import time
import logging
import tempfile
import subprocess
-from StringIO import StringIO
+from io import StringIO
from distutils2.tests import support, unittest
from distutils2.tests.test_config import SETUP_CFG
@@ -55,24 +55,24 @@ password:xxx
"""
EXPECTED_MULTIPART_OUTPUT = [
- '---x',
- 'Content-Disposition: form-data; name="username"',
- '',
- 'wok',
- '---x',
- 'Content-Disposition: form-data; name="password"',
- '',
- 'secret',
- '---x',
- 'Content-Disposition: form-data; name="picture"; filename="wok.png"',
- '',
- 'PNG89',
- '---x--',
- '',
+ b'---x',
+ b'Content-Disposition: form-data; name="username"',
+ b'',
+ b'wok',
+ b'---x',
+ b'Content-Disposition: form-data; name="password"',
+ b'',
+ b'secret',
+ b'---x',
+ b'Content-Disposition: form-data; name="picture"; filename="wok.png"',
+ b'',
+ b'PNG89',
+ b'---x--',
+ b'',
]
-class FakePopen(object):
+class FakePopen:
test_class = None
def __init__(self, args, bufsize=0, executable=None,
@@ -82,7 +82,7 @@ class FakePopen(object):
startupinfo=None, creationflags=0,
restore_signals=True, start_new_session=False,
pass_fds=()):
- if isinstance(args, basestring):
+ if isinstance(args, str):
args = args.split()
self.cmd = args[0]
exes = self.test_class._exes
@@ -319,8 +319,6 @@ class UtilTestCase(support.EnvironRestorer,
res = get_compiler_versions()
self.assertEqual(res[2], None)
- @unittest.skipUnless(hasattr(sys, 'dont_write_bytecode'),
- 'sys.dont_write_bytecode not supported')
def test_dont_write_bytecode(self):
# makes sure byte_compile raise a PackagingError
# if sys.dont_write_bytecode is True
@@ -377,7 +375,7 @@ class UtilTestCase(support.EnvironRestorer,
'pkg1.pkg3.pkg6']))
def test_resolve_name(self):
- self.assertIs(str, resolve_name('__builtin__.str'))
+ self.assertIs(str, resolve_name('builtins.str'))
self.assertEqual(
UtilTestCase.__name__,
resolve_name("distutils2.tests.test_util.UtilTestCase").__name__)
@@ -407,7 +405,6 @@ class UtilTestCase(support.EnvironRestorer,
finally:
sys.path.remove(tmp_dir)
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_run_2to3_on_code(self):
content = "print 'test'"
converted_content = "print('test')"
@@ -421,7 +418,6 @@ class UtilTestCase(support.EnvironRestorer,
file_handle.close()
self.assertEqual(new_content, converted_content)
- @unittest.skipIf(sys.version < '2.6', 'requires Python 2.6 or higher')
def test_run_2to3_on_doctests(self):
# to check if text files containing doctests only get converted.
content = ">>> print 'test'\ntest\n"
@@ -448,24 +444,24 @@ class UtilTestCase(support.EnvironRestorer,
if os.name == 'posix':
exe = os.path.join(tmpdir, 'foo.sh')
self.write_file(exe, '#!/bin/sh\nexit 1')
- os.chmod(exe, 0777)
+ os.chmod(exe, 0o777)
else:
exe = os.path.join(tmpdir, 'foo.bat')
self.write_file(exe, 'exit 1')
- os.chmod(exe, 0777)
+ os.chmod(exe, 0o777)
self.assertRaises(PackagingExecError, spawn, [exe])
# now something that works
if os.name == 'posix':
exe = os.path.join(tmpdir, 'foo.sh')
self.write_file(exe, '#!/bin/sh\nexit 0')
- os.chmod(exe, 0777)
+ os.chmod(exe, 0o777)
else:
exe = os.path.join(tmpdir, 'foo.bat')
self.write_file(exe, 'exit 0')
- os.chmod(exe, 0777)
+ os.chmod(exe, 0o777)
spawn([exe]) # should work without any error
def test_server_registration(self):
@@ -497,11 +493,8 @@ class UtilTestCase(support.EnvironRestorer,
self.assertFalse(os.path.exists(rc))
generate_pypirc('tarek', 'xxx')
self.assertTrue(os.path.exists(rc))
- f = open(rc)
- try:
+ with open(rc) as f:
content = f.read()
- finally:
- f.close()
self.assertEqual(content, WANTED)
def test_cfg_to_args(self):
@@ -538,10 +531,10 @@ class UtilTestCase(support.EnvironRestorer,
def test_encode_multipart(self):
fields = [('username', 'wok'), ('password', 'secret')]
- files = [('picture', 'wok.png', 'PNG89')]
- content_type, body = encode_multipart(fields, files, '-x')
- self.assertEqual('multipart/form-data; boundary=-x', content_type)
- self.assertEqual(EXPECTED_MULTIPART_OUTPUT, body.split('\r\n'))
+ files = [('picture', 'wok.png', b'PNG89')]
+ content_type, body = encode_multipart(fields, files, b'-x')
+ self.assertEqual(b'multipart/form-data; boundary=-x', content_type)
+ self.assertEqual(EXPECTED_MULTIPART_OUTPUT, body.split(b'\r\n'))
class GlobTestCaseBase(support.TempdirManager,
@@ -787,21 +780,16 @@ class EggInfoToDistInfoTestCase(support.TempdirManager,
dir_paths.append(path)
for f in files:
path = os.path.join(tempdir, f)
- _f = open(path, 'w')
- try:
+ with open(path, 'w') as _f:
_f.write(f)
- finally:
- _f.close()
file_paths.append(path)
- record_file = open(record_file_path, 'w')
- try:
+ with open(record_file_path, 'w') as record_file:
for fpath in file_paths:
record_file.write(fpath + '\n')
for dpath in dir_paths:
record_file.write(dpath + '\n')
- finally:
- record_file.close()
+
return (tempdir, record_file_path)
diff --git a/distutils2/tests/xxmodule.c b/distutils2/tests/xxmodule.c
index 6b498dd..a8a9360 100644
--- a/distutils2/tests/xxmodule.c
+++ b/distutils2/tests/xxmodule.c
@@ -10,7 +10,7 @@
your own types of attributes instead. Maybe you want to name your
local variables other than 'self'. If your object type is needed in
other files, you'll have to create a file "foobarobject.h"; see
- intobject.h for an example. */
+ floatobject.h for an example. */
/* Xxo objects */
@@ -19,23 +19,23 @@
static PyObject *ErrorObject;
typedef struct {
- PyObject_HEAD
- PyObject *x_attr; /* Attributes dictionary */
+ PyObject_HEAD
+ PyObject *x_attr; /* Attributes dictionary */
} XxoObject;
static PyTypeObject Xxo_Type;
-#define XxoObject_Check(v) (Py_TYPE(v) == &Xxo_Type)
+#define XxoObject_Check(v) (Py_TYPE(v) == &Xxo_Type)
static XxoObject *
newXxoObject(PyObject *arg)
{
- XxoObject *self;
- self = PyObject_New(XxoObject, &Xxo_Type);
- if (self == NULL)
- return NULL;
- self->x_attr = NULL;
- return self;
+ XxoObject *self;
+ self = PyObject_New(XxoObject, &Xxo_Type);
+ if (self == NULL)
+ return NULL;
+ self->x_attr = NULL;
+ return self;
}
/* Xxo methods */
@@ -43,101 +43,101 @@ newXxoObject(PyObject *arg)
static void
Xxo_dealloc(XxoObject *self)
{
- Py_XDECREF(self->x_attr);
- PyObject_Del(self);
+ Py_XDECREF(self->x_attr);
+ PyObject_Del(self);
}
static PyObject *
Xxo_demo(XxoObject *self, PyObject *args)
{
- if (!PyArg_ParseTuple(args, ":demo"))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
+ if (!PyArg_ParseTuple(args, ":demo"))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
}
static PyMethodDef Xxo_methods[] = {
- {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
- PyDoc_STR("demo() -> None")},
- {NULL, NULL} /* sentinel */
+ {"demo", (PyCFunction)Xxo_demo, METH_VARARGS,
+ PyDoc_STR("demo() -> None")},
+ {NULL, NULL} /* sentinel */
};
static PyObject *
-Xxo_getattr(XxoObject *self, char *name)
+Xxo_getattro(XxoObject *self, PyObject *name)
{
- if (self->x_attr != NULL) {
- PyObject *v = PyDict_GetItemString(self->x_attr, name);
- if (v != NULL) {
- Py_INCREF(v);
- return v;
- }
- }
- return Py_FindMethod(Xxo_methods, (PyObject *)self, name);
+ if (self->x_attr != NULL) {
+ PyObject *v = PyDict_GetItem(self->x_attr, name);
+ if (v != NULL) {
+ Py_INCREF(v);
+ return v;
+ }
+ }
+ return PyObject_GenericGetAttr((PyObject *)self, name);
}
static int
Xxo_setattr(XxoObject *self, char *name, PyObject *v)
{
- if (self->x_attr == NULL) {
- self->x_attr = PyDict_New();
- if (self->x_attr == NULL)
- return -1;
- }
- if (v == NULL) {
- int rv = PyDict_DelItemString(self->x_attr, name);
- if (rv < 0)
- PyErr_SetString(PyExc_AttributeError,
- "delete non-existing Xxo attribute");
- return rv;
- }
- else
- return PyDict_SetItemString(self->x_attr, name, v);
+ if (self->x_attr == NULL) {
+ self->x_attr = PyDict_New();
+ if (self->x_attr == NULL)
+ return -1;
+ }
+ if (v == NULL) {
+ int rv = PyDict_DelItemString(self->x_attr, name);
+ if (rv < 0)
+ PyErr_SetString(PyExc_AttributeError,
+ "delete non-existing Xxo attribute");
+ return rv;
+ }
+ else
+ return PyDict_SetItemString(self->x_attr, name, v);
}
static PyTypeObject Xxo_Type = {
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(NULL, 0)
- "xxmodule.Xxo", /*tp_name*/
- sizeof(XxoObject), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)Xxo_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- (getattrfunc)Xxo_getattr, /*tp_getattr*/
- (setattrfunc)Xxo_setattr, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- 0, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- 0, /*tp_init*/
- 0, /*tp_alloc*/
- 0, /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "xxmodule.Xxo", /*tp_name*/
+ sizeof(XxoObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)Xxo_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)0, /*tp_getattr*/
+ (setattrfunc)Xxo_setattr, /*tp_setattr*/
+ 0, /*tp_reserved*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ (getattrofunc)Xxo_getattro, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ Xxo_methods, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
};
/* --------------------------------------------------------------------- */
@@ -151,12 +151,12 @@ Return the sum of i and j.");
static PyObject *
xx_foo(PyObject *self, PyObject *args)
{
- long i, j;
- long res;
- if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
- return NULL;
- res = i+j; /* XXX Do something here */
- return PyInt_FromLong(res);
+ long i, j;
+ long res;
+ if (!PyArg_ParseTuple(args, "ll:foo", &i, &j))
+ return NULL;
+ res = i+j; /* XXX Do something here */
+ return PyLong_FromLong(res);
}
@@ -165,14 +165,14 @@ xx_foo(PyObject *self, PyObject *args)
static PyObject *
xx_new(PyObject *self, PyObject *args)
{
- XxoObject *rv;
-
- if (!PyArg_ParseTuple(args, ":new"))
- return NULL;
- rv = newXxoObject(args);
- if (rv == NULL)
- return NULL;
- return (PyObject *)rv;
+ XxoObject *rv;
+
+ if (!PyArg_ParseTuple(args, ":new"))
+ return NULL;
+ rv = newXxoObject(args);
+ if (rv == NULL)
+ return NULL;
+ return (PyObject *)rv;
}
/* Example with subtle bug from extensions manual ("Thin Ice"). */
@@ -180,20 +180,20 @@ xx_new(PyObject *self, PyObject *args)
static PyObject *
xx_bug(PyObject *self, PyObject *args)
{
- PyObject *list, *item;
+ PyObject *list, *item;
- if (!PyArg_ParseTuple(args, "O:bug", &list))
- return NULL;
+ if (!PyArg_ParseTuple(args, "O:bug", &list))
+ return NULL;
- item = PyList_GetItem(list, 0);
- /* Py_INCREF(item); */
- PyList_SetItem(list, 1, PyInt_FromLong(0L));
- PyObject_Print(item, stdout, 0);
- printf("\n");
- /* Py_DECREF(item); */
+ item = PyList_GetItem(list, 0);
+ /* Py_INCREF(item); */
+ PyList_SetItem(list, 1, PyLong_FromLong(0L));
+ PyObject_Print(item, stdout, 0);
+ printf("\n");
+ /* Py_DECREF(item); */
- Py_INCREF(Py_None);
- return Py_None;
+ Py_INCREF(Py_None);
+ return Py_None;
}
/* Test bad format character */
@@ -201,61 +201,61 @@ xx_bug(PyObject *self, PyObject *args)
static PyObject *
xx_roj(PyObject *self, PyObject *args)
{
- PyObject *a;
- long b;
- if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
+ PyObject *a;
+ long b;
+ if (!PyArg_ParseTuple(args, "O#:roj", &a, &b))
+ return NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
}
/* ---------- */
static PyTypeObject Str_Type = {
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(NULL, 0)
- "xxmodule.Str", /*tp_name*/
- 0, /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- 0, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- 0, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /* see initxx */ /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- 0, /*tp_init*/
- 0, /*tp_alloc*/
- 0, /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "xxmodule.Str", /*tp_name*/
+ 0, /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_reserved*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /* see PyInit_xx */ /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
};
/* ---------- */
@@ -263,54 +263,54 @@ static PyTypeObject Str_Type = {
static PyObject *
null_richcompare(PyObject *self, PyObject *other, int op)
{
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
}
static PyTypeObject Null_Type = {
- /* The ob_type field must be initialized in the module init function
- * to be portable to Windows without using C++. */
- PyVarObject_HEAD_INIT(NULL, 0)
- "xxmodule.Null", /*tp_name*/
- 0, /*tp_basicsize*/
- 0, /*tp_itemsize*/
- /* methods */
- 0, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- null_richcompare, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- 0, /*tp_methods*/
- 0, /*tp_members*/
- 0, /*tp_getset*/
- 0, /* see initxx */ /*tp_base*/
- 0, /*tp_dict*/
- 0, /*tp_descr_get*/
- 0, /*tp_descr_set*/
- 0, /*tp_dictoffset*/
- 0, /*tp_init*/
- 0, /*tp_alloc*/
- 0, /* see initxx */ /*tp_new*/
- 0, /*tp_free*/
- 0, /*tp_is_gc*/
+ /* The ob_type field must be initialized in the module init function
+ * to be portable to Windows without using C++. */
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "xxmodule.Null", /*tp_name*/
+ 0, /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_reserved*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ null_richcompare, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /* see PyInit_xx */ /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /* see PyInit_xx */ /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
};
@@ -320,60 +320,77 @@ static PyTypeObject Null_Type = {
/* List of functions defined in the module */
static PyMethodDef xx_methods[] = {
- {"roj", xx_roj, METH_VARARGS,
- PyDoc_STR("roj(a,b) -> None")},
- {"foo", xx_foo, METH_VARARGS,
- xx_foo_doc},
- {"new", xx_new, METH_VARARGS,
- PyDoc_STR("new() -> new Xx object")},
- {"bug", xx_bug, METH_VARARGS,
- PyDoc_STR("bug(o) -> None")},
- {NULL, NULL} /* sentinel */
+ {"roj", xx_roj, METH_VARARGS,
+ PyDoc_STR("roj(a,b) -> None")},
+ {"foo", xx_foo, METH_VARARGS,
+ xx_foo_doc},
+ {"new", xx_new, METH_VARARGS,
+ PyDoc_STR("new() -> new Xx object")},
+ {"bug", xx_bug, METH_VARARGS,
+ PyDoc_STR("bug(o) -> None")},
+ {NULL, NULL} /* sentinel */
};
PyDoc_STRVAR(module_doc,
"This is a template module just for instruction.");
-/* Initialization function for the module (*must* be called initxx) */
+/* Initialization function for the module (*must* be called PyInit_xx) */
+
+
+static struct PyModuleDef xxmodule = {
+ PyModuleDef_HEAD_INIT,
+ "xx",
+ module_doc,
+ -1,
+ xx_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
PyMODINIT_FUNC
-initxx(void)
+PyInit_xx(void)
{
- PyObject *m;
-
- /* Due to cross platform compiler issues the slots must be filled
- * here. It's required for portability to Windows without requiring
- * C++. */
- Null_Type.tp_base = &PyBaseObject_Type;
- Null_Type.tp_new = PyType_GenericNew;
- Str_Type.tp_base = &PyUnicode_Type;
-
- /* Finalize the type object including setting type of the new type
- * object; doing it here is required for portability, too. */
- if (PyType_Ready(&Xxo_Type) < 0)
- return;
-
- /* Create the module and add the functions */
- m = Py_InitModule3("xx", xx_methods, module_doc);
- if (m == NULL)
- return;
-
- /* Add some symbolic constants to the module */
- if (ErrorObject == NULL) {
- ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
- if (ErrorObject == NULL)
- return;
- }
- Py_INCREF(ErrorObject);
- PyModule_AddObject(m, "error", ErrorObject);
-
- /* Add Str */
- if (PyType_Ready(&Str_Type) < 0)
- return;
- PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
-
- /* Add Null */
- if (PyType_Ready(&Null_Type) < 0)
- return;
- PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
+ PyObject *m = NULL;
+
+ /* Due to cross platform compiler issues the slots must be filled
+ * here. It's required for portability to Windows without requiring
+ * C++. */
+ Null_Type.tp_base = &PyBaseObject_Type;
+ Null_Type.tp_new = PyType_GenericNew;
+ Str_Type.tp_base = &PyUnicode_Type;
+
+ /* Finalize the type object including setting type of the new type
+ * object; doing it here is required for portability, too. */
+ if (PyType_Ready(&Xxo_Type) < 0)
+ goto fail;
+
+ /* Create the module and add the functions */
+ m = PyModule_Create(&xxmodule);
+ if (m == NULL)
+ goto fail;
+
+ /* Add some symbolic constants to the module */
+ if (ErrorObject == NULL) {
+ ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
+ if (ErrorObject == NULL)
+ goto fail;
+ }
+ Py_INCREF(ErrorObject);
+ PyModule_AddObject(m, "error", ErrorObject);
+
+ /* Add Str */
+ if (PyType_Ready(&Str_Type) < 0)
+ goto fail;
+ PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
+
+ /* Add Null */
+ if (PyType_Ready(&Null_Type) < 0)
+ goto fail;
+ PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
+ return m;
+ fail:
+ Py_XDECREF(m);
+ return NULL;
}
diff --git a/distutils2/util.py b/distutils2/util.py
index a5d234f..8c629de 100644
--- a/distutils2/util.py
+++ b/distutils2/util.py
@@ -3,24 +3,18 @@
import os
import re
import csv
+import imp
import sys
import errno
-import codecs
import shutil
import string
+import hashlib
import posixpath
import subprocess
+from glob import iglob as std_iglob
from fnmatch import fnmatchcase
from inspect import getsource
-from ConfigParser import RawConfigParser
-try:
- from glob import iglob as std_iglob
-except ImportError:
- from glob import glob as std_iglob
-try:
- import hashlib
-except ImportError:
- from distutils2._backport import hashlib
+from configparser import RawConfigParser
from distutils2 import logger
from distutils2.errors import (PackagingPlatformError, PackagingFileError,
@@ -303,7 +297,8 @@ def strtobool(val):
def byte_compile(py_files, optimize=0, force=False, prefix=None,
base_dir=None, verbose=0, dry_run=False, direct=None):
"""Byte-compile a collection of Python source files to either .pyc
- or .pyo files in the same directory.
+ or .pyo files in the same directory (Python 3.1) or in a __pycache__
+ subdirectory (3.2 and newer).
'py_files' is a list of files to compile; any files that don't end in
".py" are silently skipped. 'optimize' must be one of the following:
@@ -333,7 +328,7 @@ def byte_compile(py_files, optimize=0, force=False, prefix=None,
"""
# nothing is done if sys.dont_write_bytecode is True
# FIXME this should not raise an error
- if getattr(sys, 'dont_write_bytecode', False):
+ if sys.dont_write_bytecode:
raise PackagingByteCompileError('byte-compiling is disabled.')
# First, if the caller didn't force us into direct or indirect mode,
@@ -362,9 +357,9 @@ def byte_compile(py_files, optimize=0, force=False, prefix=None,
if script_fd is not None:
script = os.fdopen(script_fd, "w", encoding='utf-8')
else:
- script = codecs.open(script_name, "w", encoding='utf-8')
+ script = open(script_name, "w", encoding='utf-8')
- try:
+ with script:
script.write("""\
from distutils2.util import byte_compile
files = [
@@ -391,8 +386,6 @@ byte_compile(files, optimize=%r, force=%r,
verbose=%r, dry_run=False,
direct=True)
""" % (optimize, force, prefix, base_dir, verbose))
- finally:
- script.close()
cmd = [sys.executable, script_name]
if optimize == 1:
@@ -424,7 +417,16 @@ byte_compile(files, optimize=%r, force=%r,
# Terminology from the py_compile module:
# cfile - byte-compiled file
# dfile - purported source filename (same as 'file' by default)
- cfile = file + (__debug__ and "c" or "o")
+ if sys.version_info[1] == 1:
+ cfile = file + (__debug__ and "c" or "o")
+ else:
+ # comply with PEP 3147 in 3.2+
+ if optimize >= 0:
+ cfile = imp.cache_from_source(file,
+ debug_override=not optimize)
+ else:
+ cfile = imp.cache_from_source(file)
+
dfile = file
if prefix:
if file[:len(prefix)] != prefix:
@@ -549,12 +551,10 @@ def write_file(filename, contents):
idiom in all cases, only with Command.execute, which runs depending on
the dry_run argument and also logs its arguments).
"""
- f = open(filename, "w")
- try:
+ with open(filename, "w") as f:
for line in contents:
f.write(line + "\n")
- finally:
- f.close()
+
def _is_package(path):
return os.path.isdir(path) and os.path.isfile(
@@ -657,7 +657,7 @@ def resolve_name(name):
for part in parts[1:]:
try:
ret = getattr(ret, part)
- except AttributeError, exc:
+ except AttributeError as exc:
raise ImportError(exc)
return ret
@@ -773,13 +773,10 @@ def get_pypirc_path():
def generate_pypirc(username, password):
"""Create a default .pypirc file."""
rc = get_pypirc_path()
- f = open(rc, 'w')
- try:
+ with open(rc, 'w') as f:
f.write(DEFAULT_PYPIRC % (username, password))
- finally:
- f.close()
try:
- os.chmod(rc, 0600)
+ os.chmod(rc, 0o600)
except OSError:
# should do something better here
pass
@@ -863,7 +860,7 @@ def run_2to3(files, doctests_only=False, fixer_names=None,
r.refactor(files, write=True, doctests_only=doctests_only)
-class Mixin2to3(object):
+class Mixin2to3:
""" Wrapper class for commands that run 2to3.
To configure 2to3, setup scripts may either change
the class variables, or inherit from this class
@@ -986,11 +983,8 @@ def cfg_to_args(path='setup.cfg'):
if not os.path.exists(path):
raise PackagingFileError("file '%s' does not exist" %
os.path.abspath(path))
- f = codecs.open(path, encoding='utf-8')
- try:
+ with open(path, encoding='utf-8') as f:
config.readfp(f)
- finally:
- f.close()
kwargs = {}
for arg in D1_D2_SETUP_ARGS:
@@ -1012,11 +1006,8 @@ def cfg_to_args(path='setup.cfg'):
filenames = split_multiline(filenames)
in_cfg_value = []
for filename in filenames:
- fp = open(filename)
- try:
+ with open(filename) as fp:
in_cfg_value.append(fp.read())
- finally:
- fp.close()
in_cfg_value = '\n\n'.join(in_cfg_value)
else:
continue
@@ -1053,11 +1044,8 @@ def generate_setup_py():
if os.path.exists("setup.py"):
raise PackagingFileError("a setup.py file already exists")
- fp = codecs.open("setup.py", "w", encoding='utf-8')
- try:
+ with open("setup.py", "w", encoding='utf-8') as fp:
fp.write(_SETUP_TMPL % {'func': getsource(cfg_to_args)})
- finally:
- fp.close()
# Taken from the pip project
@@ -1065,19 +1053,18 @@ def generate_setup_py():
def ask(message, options):
"""Prompt the user with *message*; *options* contains allowed responses."""
while True:
- response = raw_input(message)
+ response = input(message)
response = response.strip().lower()
if response not in options:
- print 'invalid response:', repr(response)
- print 'choose one of', ', '.join(repr(o) for o in options)
+ print('invalid response:', repr(response))
+ print('choose one of', ', '.join(repr(o) for o in options))
else:
return response
def _parse_record_file(record_file):
distinfo, extra_metadata, installed = ({}, [], [])
- rfile = open(record_file, 'r')
- try:
+ with open(record_file, 'r') as rfile:
for path in rfile:
path = path.strip()
if path.endswith('egg-info') and os.path.isfile(path):
@@ -1098,8 +1085,6 @@ def _parse_record_file(record_file):
continue
else:
installed.append(path)
- finally:
- rfile.close()
distinfo['egginfo'] = egginfo
distinfo['metadata'] = metadata
@@ -1115,8 +1100,7 @@ def _parse_record_file(record_file):
def _write_record_file(record_path, installed_files):
- f = codecs.open(record_path, 'w', encoding='utf-8')
- try:
+ with open(record_path, 'w', encoding='utf-8') as f:
writer = csv.writer(f, delimiter=',', lineterminator=os.linesep,
quotechar='"')
@@ -1126,19 +1110,14 @@ def _write_record_file(record_path, installed_files):
writer.writerow((fpath, '', ''))
else:
hash = hashlib.md5()
- fp = open(fpath, 'rb')
- try:
+ with open(fpath, 'rb') as fp:
hash.update(fp.read())
- finally:
- fp.close()
md5sum = hash.hexdigest()
size = os.path.getsize(fpath)
writer.writerow((fpath, md5sum, size))
# add the RECORD file itself
writer.writerow((record_path, '', ''))
- finally:
- f.close()
return record_path
@@ -1173,11 +1152,8 @@ def egginfo_to_distinfo(record_file, installer=_DEFAULT_INSTALLER,
installer_path = distinfo['installer_path']
logger.info('creating %s', installer_path)
- f = open(installer_path, 'w')
- try:
+ with open(installer_path, 'w') as f:
f.write(installer)
- finally:
- f.close()
if requested:
requested_path = distinfo['requested_path']
@@ -1218,27 +1194,20 @@ def _has_distutils_text(setup_py):
def _has_text(setup_py, installer):
- installer_pattern = re.compile('import %s|from %s' %
- (installer, installer))
- setup = codecs.open(setup_py, 'r', encoding='utf-8')
- try:
+ installer_pattern = re.compile('import {0}|from {0}'.format(installer))
+ with open(setup_py, 'r', encoding='utf-8') as setup:
for line in setup:
if re.search(installer_pattern, line):
logger.debug("Found %s text in setup.py.", installer)
return True
- finally:
- setup.close()
logger.debug("No %s text found in setup.py.", installer)
return False
def _has_required_metadata(setup_cfg):
config = RawConfigParser()
- f = codecs.open(setup_cfg, 'r', encoding='utf8')
- try:
+ with open(setup_cfg, 'r', encoding='utf8') as f:
config.readfp(f)
- finally:
- f.close()
return (config.has_section('metadata') and
'name' in config.options('metadata') and
'version' in config.options('metadata'))
@@ -1341,7 +1310,7 @@ def copy_tree(src, dst, preserve_mode=True, preserve_times=True,
"cannot copy tree '%s': not a directory" % src)
try:
names = os.listdir(src)
- except os.error, e:
+ except os.error as e:
errstr = e[1]
if dry_run:
names = []
@@ -1387,9 +1356,9 @@ _path_created = set()
# I don't use os.makedirs because a) it's new to Python 1.5.2, and
# b) it blows up if the directory already exists (I want to silently
# succeed in that case).
-def _mkpath(name, mode=0777, verbose=True, dry_run=False):
+def _mkpath(name, mode=0o777, verbose=True, dry_run=False):
# Detect a common bug -- name is None
- if not isinstance(name, basestring):
+ if not isinstance(name, str):
raise PackagingInternalError(
"mkpath: 'name' must be a string (got %r)" % (name,))
@@ -1428,7 +1397,7 @@ def _mkpath(name, mode=0777, verbose=True, dry_run=False):
if not dry_run:
try:
os.mkdir(head, mode)
- except OSError, exc:
+ except OSError as exc:
if not (exc.errno == errno.EEXIST and os.path.isdir(head)):
raise PackagingFileError(
"could not create '%s': %s" % (head, exc.args[-1]))
@@ -1445,15 +1414,15 @@ def encode_multipart(fields, files, boundary=None):
form fields, *files* is a sequence of (name: str, filename: str, value:
bytes) elements for data to be uploaded as files.
- Returns (content_type: bytes, body: bytes) ready for httplib.HTTP.
+ Returns (content_type: bytes, body: bytes) ready for http.client.HTTP.
"""
# Taken from
# http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/
if boundary is None:
- boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
- elif not isinstance(boundary, str):
- raise TypeError('boundary must be str, not %r' % type(boundary))
+ boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+ elif not isinstance(boundary, bytes):
+ raise TypeError('boundary must be bytes, not %r' % type(boundary))
l = []
for key, values in fields:
@@ -1463,21 +1432,23 @@ def encode_multipart(fields, files, boundary=None):
for value in values:
l.extend((
- '--' + boundary,
- # XXX should encode to match packaging but it causes bugs
- ('Content-Disposition: form-data; name="%s"' % key), '', value))
+ b'--' + boundary,
+ ('Content-Disposition: form-data; name="%s"' %
+ key).encode('utf-8'),
+ b'',
+ value.encode('utf-8')))
for key, filename, value in files:
l.extend((
- '--' + boundary,
+ b'--' + boundary,
('Content-Disposition: form-data; name="%s"; filename="%s"' %
- (key, filename)),
- '',
+ (key, filename)).encode('utf-8'),
+ b'',
value))
- l.append('--' + boundary + '--')
- l.append('')
+ l.append(b'--' + boundary + b'--')
+ l.append(b'')
- body = '\r\n'.join(l)
- content_type = 'multipart/form-data; boundary=' + boundary
+ body = b'\r\n'.join(l)
+ content_type = b'multipart/form-data; boundary=' + boundary
return content_type, body
diff --git a/distutils2/version.py b/distutils2/version.py
index 4eedb0b..7ff1c84 100644
--- a/distutils2/version.py
+++ b/distutils2/version.py
@@ -38,7 +38,7 @@ _VERSION_RE = re.compile(r'''
$''', re.VERBOSE)
-class NormalizedVersion(object):
+class NormalizedVersion:
"""A rational version.
Good:
@@ -342,7 +342,7 @@ def _split_predicate(predicate):
return comp, NormalizedVersion(version)
-class VersionPredicate(object):
+class VersionPredicate:
"""Defines a predicate: ProjectName (>ver1,ver2, ..)"""
_operators = {"<": lambda x, y: x < y,
@@ -384,7 +384,7 @@ class VersionPredicate(object):
def match(self, version):
"""Check if the provided version matches the predicates."""
- if isinstance(version, basestring):
+ if isinstance(version, str):
version = NormalizedVersion(version)
for operator, predicate in self.predicates:
if not self._operators[operator](version, predicate):
@@ -444,6 +444,6 @@ def get_version_predicate(requirements):
"""Return a VersionPredicate object, from a string or an already
existing object.
"""
- if isinstance(requirements, basestring):
+ if isinstance(requirements, str):
requirements = VersionPredicate(requirements)
return requirements
diff --git a/runtests.py b/runtests.py
index 1c5c4d4..7891acf 100644
--- a/runtests.py
+++ b/runtests.py
@@ -131,10 +131,4 @@ def run_tests(verbose):
if __name__ == "__main__":
- if sys.version < '2.5':
- try:
- from distutils2._backport import hashlib
- except ImportError:
- import subprocess
- subprocess.call([sys.executable, 'setup.py', 'build_ext'])
sys.exit(test_main())
diff --git a/setup.py b/setup.py
index caf49ee..c6ef66a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,13 +1,6 @@
-#!/usr/bin/env python
-# -*- encoding: utf-8 -*-
-import os
-import re
-import sys
-import codecs
-from distutils import sysconfig
-from distutils.core import setup, Extension
-from distutils.ccompiler import new_compiler
-from ConfigParser import RawConfigParser
+#!/usr/bin/env python3
+from distutils.core import setup
+from configparser import RawConfigParser
def split_multiline(value):
@@ -48,11 +41,8 @@ def cfg_to_args(path='setup.cfg'):
}
config = RawConfigParser()
config.optionxform = lambda x: x.lower().replace('_', '-')
- fp = codecs.open(path, encoding='utf-8')
- try:
+ with open(path, encoding='utf-8') as fp:
config.readfp(fp)
- finally:
- fp.close()
kwargs = {}
for section in opts_to_args:
for optname, argname, xform in opts_to_args[section]:
@@ -67,11 +57,8 @@ def cfg_to_args(path='setup.cfg'):
filenames = config.get('metadata', 'description-file')
for filename in split_multiline(filenames):
descriptions = []
- fp = open(filename)
- try:
+ with open(filename) as fp:
descriptions.append(fp.read())
- finally:
- fp.close()
kwargs['long_description'] = '\n\n'.join(descriptions)
# Handle `package_data`
if 'package_data' in kwargs:
@@ -83,126 +70,6 @@ def cfg_to_args(path='setup.cfg'):
kwargs['package_data'] = package_data
return kwargs
-# (from Python's setup.py, in PyBuildExt.detect_modules())
-def prepare_hashlib_extensions():
- """Decide which C extensions to build and create the appropriate
- Extension objects to build them. Return a list of Extensions.
- """
- ssl_libs = None
- ssl_inc_dir = None
- ssl_lib_dirs = []
- ssl_inc_dirs = []
- if os.name == 'posix':
- # (from Python's setup.py, in PyBuildExt.detect_modules())
- # lib_dirs and inc_dirs are used to search for files;
- # if a file is found in one of those directories, it can
- # be assumed that no additional -I,-L directives are needed.
- lib_dirs = []
- inc_dirs = []
- if os.path.normpath(sys.prefix) != '/usr':
- lib_dirs.append(sysconfig.get_config_var('LIBDIR'))
- inc_dirs.append(sysconfig.get_config_var('INCLUDEDIR'))
- # Ensure that /usr/local is always used
- lib_dirs.append('/usr/local/lib')
- inc_dirs.append('/usr/local/include')
- # Add the compiler defaults; this compiler object is only used
- # to locate the OpenSSL files.
- compiler = new_compiler()
- lib_dirs.extend(compiler.library_dirs)
- inc_dirs.extend(compiler.include_dirs)
- # Now the platform defaults
- lib_dirs.extend(['/lib64', '/usr/lib64', '/lib', '/usr/lib'])
- inc_dirs.extend(['/usr/include'])
- # Find the SSL library directory
- ssl_libs = ['ssl', 'crypto']
- ssl_lib = compiler.find_library_file(lib_dirs, 'ssl')
- if ssl_lib is None:
- ssl_lib_dirs = ['/usr/local/ssl/lib', '/usr/contrib/ssl/lib']
- ssl_lib = compiler.find_library_file(ssl_lib_dirs, 'ssl')
- if ssl_lib is not None:
- ssl_lib_dirs.append(os.path.dirname(ssl_lib))
- else:
- ssl_libs = None
- # Locate the SSL headers
- for ssl_inc_dir in inc_dirs + ['/usr/local/ssl/include',
- '/usr/contrib/ssl/include']:
- ssl_h = os.path.join(ssl_inc_dir, 'openssl', 'ssl.h')
- if os.path.exists(ssl_h):
- if ssl_inc_dir not in inc_dirs:
- ssl_inc_dirs.append(ssl_inc_dir)
- break
- elif os.name == 'nt':
- # (from Python's PCbuild/build_ssl.py, in find_best_ssl_dir())
- # Look for SSL 1 level up from here. That is, the same place the
- # other externals for Python core live.
- # note: do not abspath src_dir; the build will fail if any
- # higher up directory name has spaces in it.
- src_dir = '..'
- try:
- fnames = os.listdir(src_dir)
- except OSError:
- fnames = []
- ssl_dir = None
- best_parts = []
- for fname in fnames:
- fqn = os.path.join(src_dir, fname)
- if os.path.isdir(fqn) and fname.startswith("openssl-"):
- # We have a candidate, determine the best
- parts = re.split("[.-]", fname)[1:]
- # Ignore all "beta" or any other qualifiers;
- # eg - openssl-0.9.7-beta1
- if len(parts) < 4 and parts > best_parts:
- best_parts = parts
- ssl_dir = fqn
- if ssl_dir is not None:
- ssl_libs = ['gdi32', 'user32', 'advapi32',
- os.path.join(ssl_dir, 'out32', 'libeay32')]
- ssl_inc_dir = os.path.join(ssl_dir, 'inc32')
- ssl_inc_dirs.append(ssl_inc_dir)
-
- # Find out which version of OpenSSL we have
- openssl_ver = 0
- openssl_ver_re = re.compile(
- '^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
- if ssl_inc_dir is not None:
- opensslv_h = os.path.join(ssl_inc_dir, 'openssl', 'opensslv.h')
- try:
- incfile = open(opensslv_h, 'r')
- for line in incfile:
- m = openssl_ver_re.match(line)
- if m:
- openssl_ver = int(m.group(1), 16)
- except IOError:
- e = str(sys.last_value)
- print("IOError while reading %s: %s" % (opensslv_h, e))
-
- # Now we can determine which extension modules need to be built.
- exts = []
- if ssl_libs is not None and openssl_ver >= 0x907000:
- # The _hashlib module wraps optimized implementations
- # of hash functions from the OpenSSL library.
- exts.append(Extension('distutils2._backport._hashlib',
- ['distutils2/_backport/_hashopenssl.c'],
- include_dirs=ssl_inc_dirs,
- library_dirs=ssl_lib_dirs,
- libraries=ssl_libs))
- else:
- # no openssl at all, use our own md5 and sha1
- exts.append(Extension('distutils2._backport._sha',
- ['distutils2/_backport/shamodule.c']))
- exts.append(Extension('distutils2._backport._md5',
- sources=['distutils2/_backport/md5module.c',
- 'distutils2/_backport/md5.c'],
- depends=['distutils2/_backport/md5.h']) )
- if openssl_ver < 0x908000:
- # OpenSSL doesn't do these until 0.9.8 so we'll bring our own
- exts.append(Extension('distutils2._backport._sha256',
- ['distutils2/_backport/sha256module.c']))
- exts.append(Extension('distutils2._backport._sha512',
- ['distutils2/_backport/sha512module.c']))
- return exts
setup_kwargs = cfg_to_args('setup.cfg')
-if sys.version < '2.5':
- setup_kwargs['ext_modules'] = prepare_hashlib_extensions()
setup(**setup_kwargs)
diff --git a/tests.sh b/tests.sh
index be81c3f..6c04426 100755
--- a/tests.sh
+++ b/tests.sh
@@ -1,40 +1,29 @@
#!/bin/sh
-echo -n "Running tests with Python 2.4... "
-python2.4 setup.py build_ext -f -q 2> /dev/null > /dev/null
-python2.4 -Wd runtests.py -q
+echo -n "Running tests with Python 3.1... "
+python3.1 -Wd runtests.py -q
if [ $? -ne 0 ];then
echo Failed, re-running
- python2.4 -Wd runtests.py
+ python3.1 -Wd runtests.py
exit 1
else
echo Success
fi
-echo -n "Running tests with Python 2.5... "
-python2.5 -Wd runtests.py -q
+echo -n "Running tests with Python 3.2... "
+python3.2 -Wd runtests.py -q
if [ $? -ne 0 ];then
echo Failed, re-running
- python2.5 -Wd runtests.py
+ python3.2 -Wd runtests.py
exit 1
else
echo Success
fi
-echo -n "Running tests with Python 2.6... "
-python2.6 -Wd runtests.py -q
+echo -n "Running tests with Python 3.3... "
+python3.3 -Wd runtests.py -q
if [ $? -ne 0 ];then
echo Failed, re-running
- python2.6 -Wd runtests.py
- exit 1
-else
- echo Success
-fi
-
-echo -n "Running tests with Python 2.7... "
-python2.7 -Wd -bb -3 runtests.py -q
-if [ $? -ne 0 ];then
- echo Failed, re-running
- python2.7 -Wd -bb -3 runtests.py
+ python3.3 -Wd runtests.py
exit 1
else
echo Success