[Python-checkins] python/dist/src/Modules _hashopenssl.c, NONE, 2.1.2.2 functionalmodule.c, NONE, 1.2.2.2 sha256module.c, NONE, 2.1.2.2 sha512module.c, NONE, 2.2.2.2 spwdmodule.c, NONE, 1.2.2.2 Setup.dist, 1.28.2.2, 1.28.2.3 _bisectmodule.c, 1.2.6.1, 1.2.6.2 _bsddb.c, 1.13.4.2, 1.13.4.3 _codecsmodule.c, 2.12.2.2, 2.12.2.3 _csv.c, 1.11.4.2, 1.11.4.3 _cursesmodule.c, 2.65.2.2, 2.65.2.3 _localemodule.c, 2.33.2.2, 2.33.2.3 _randommodule.c, 1.5.4.2, 1.5.4.3 _tkinter.c, 1.125.2.2, 1.125.2.3 arraymodule.c, 2.75.2.2, 2.75.2.3 bz2module.c, 1.17.2.2, 1.17.2.3 cStringIO.c, 2.36.2.2, 2.36.2.3 collectionsmodule.c, 1.36.4.1, 1.36.4.2 datetimemodule.c, 1.60.4.2, 1.60.4.3 fcntlmodule.c, 2.35.2.2, 2.35.2.3 gcmodule.c, 2.52.2.2, 2.52.2.3 getpath.c, 1.41.2.2, 1.41.2.3 grpmodule.c, 2.18.2.2, 2.18.2.3 itertoolsmodule.c, 1.10.4.2, 1.10.4.3 ld_so_aix, 2.5, 2.5.32.1 main.c, 1.64.2.3, 1.64.2.4 makexp_aix, 2.2, 2.2.32.1 mathmodule.c, 2.68.2.2, 2.68.2.3 md5module.c, 2.30.2.2, 2.30.2.3 mmapmodule.c, 2.39.2.2, 2.39.2.3 operator.c, 2.21.2.2, 2.21.2.3 ossaudiodev.c, 1.26.4.2, 1.26.4.3 parsermodule.c, 2.70.2.2, 2.70.2.3 posixmodule.c, 2.241.2.2, 2.241.2.3 pwdmodule.c, 1.34.2.2, 1.34.2.3 pyexpat.c, 2.67.2.2, 2.67.2.3 readline.c, 2.51.2.2, 2.51.2.3 shamodule.c, 2.19.2.1, 2.19.2.2 signalmodule.c, 2.70.2.2, 2.70.2.3 socketmodule.c, 1.229.2.2, 1.229.2.3 socketmodule.h, 1.8.2.1, 1.8.2.2 structmodule.c, 2.55.2.2, 2.55.2.3 threadmodule.c, 2.50.2.2, 2.50.2.3 unicodedata.c, 2.18.2.2, 2.18.2.3 zipimport.c, 1.13.4.2, 1.13.4.3

jhylton@users.sourceforge.net jhylton at users.sourceforge.net
Sun Oct 16 07:24:41 CEST 2005


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27718/Modules

Modified Files:
      Tag: ast-branch
	Setup.dist _bisectmodule.c _bsddb.c _codecsmodule.c _csv.c 
	_cursesmodule.c _localemodule.c _randommodule.c _tkinter.c 
	arraymodule.c bz2module.c cStringIO.c collectionsmodule.c 
	datetimemodule.c fcntlmodule.c gcmodule.c getpath.c 
	grpmodule.c itertoolsmodule.c ld_so_aix main.c makexp_aix 
	mathmodule.c md5module.c mmapmodule.c operator.c ossaudiodev.c 
	parsermodule.c posixmodule.c pwdmodule.c pyexpat.c readline.c 
	shamodule.c signalmodule.c socketmodule.c socketmodule.h 
	structmodule.c threadmodule.c unicodedata.c zipimport.c 
Added Files:
      Tag: ast-branch
	_hashopenssl.c functionalmodule.c sha256module.c 
	sha512module.c spwdmodule.c 
Log Message:
Merge head to branch (for the last time)


--- NEW FILE: _hashopenssl.c ---
/* Module that wraps all OpenSSL hash algorithms */

/*
 * Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
 * Licensed to PSF under a Contributor Agreement.
 *
 * Derived from a skeleton of shamodule.c containing work performed by:
 *
 * Andrew Kuchling (amk at amk.ca)
 * Greg Stein (gstein at lyra.org)
 *
 */

#include "Python.h"
#include "structmember.h"

/* EVP is the preferred interface to hashing in OpenSSL */
#include <openssl/evp.h>


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 *args)
{
    EVPobject *newobj;

    if (!PyArg_ParseTuple(args, ":copy"))
        return NULL;

    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 *args)
{
    unsigned char digest[EVP_MAX_MD_SIZE];
    EVP_MD_CTX temp_ctx;
    PyObject *retval;
    unsigned int digest_size;

    if (!PyArg_ParseTuple(args, ":digest"))
        return NULL;

    EVP_MD_CTX_copy(&temp_ctx, &self->ctx);
    digest_size = EVP_MD_CTX_size(&temp_ctx);
    EVP_DigestFinal(&temp_ctx, (char *)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 *args)
{
    unsigned char digest[EVP_MAX_MD_SIZE];
    EVP_MD_CTX temp_ctx;
    PyObject *retval;
    char *hex_digest;
    unsigned int i, j, digest_size;

    if (!PyArg_ParseTuple(args, ":hexdigest"))
        return NULL;

    /* 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;
    int len;

    if (!PyArg_ParseTuple(args, "s#:update", &cp, &len))
        return NULL;

    EVP_DigestUpdate(&self->ctx, cp, len);

    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_VARARGS, EVP_digest__doc__},
    {"hexdigest", (PyCFunction)EVP_hexdigest, METH_VARARGS, EVP_hexdigest__doc__},
    {"copy",	  (PyCFunction)EVP_copy,      METH_VARARGS, 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;
    unsigned int len;
    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)
        EVP_DigestUpdate(&self->ctx, cp, len);

    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 char *cp, unsigned int 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)
        EVP_DigestUpdate(&self->ctx, cp, len);

    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;
    unsigned int len;

    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; \
        unsigned int len; \
     \
        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);
}

--- NEW FILE: functionalmodule.c ---

#include "Python.h"
#include "structmember.h"

/* Functional module written and maintained 
   by Hye-Shik Chang <perky at FreeBSD.org>
   with adaptations by Raymond Hettinger <python at rcn.com>
   Copyright (c) 2004, 2005 Python Software Foundation.
   All rights reserved.
*/

/* partial object **********************************************************/

typedef struct {
	PyObject_HEAD
	PyObject *fn;
	PyObject *args;
	PyObject *kw;
	PyObject *dict;
	PyObject *weakreflist; /* List of weak references */
} partialobject;

static PyTypeObject partial_type;

static PyObject *
partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
	PyObject *func;
	partialobject *pto;

	if (PyTuple_GET_SIZE(args) < 1) {
		PyErr_SetString(PyExc_TypeError,
				"type 'partial' takes at least one argument");
		return NULL;
	}

	func = PyTuple_GET_ITEM(args, 0);
	if (!PyCallable_Check(func)) {
		PyErr_SetString(PyExc_TypeError,
				"the first argument must be callable");
		return NULL;
	}

	/* create partialobject structure */
	pto = (partialobject *)type->tp_alloc(type, 0);
	if (pto == NULL)
		return NULL;

	pto->fn = func;
	Py_INCREF(func);
	pto->args = PyTuple_GetSlice(args, 1, INT_MAX);
	if (pto->args == NULL) {
		pto->kw = NULL;
		Py_DECREF(pto);
		return NULL;
	}
	if (kw != NULL) {
		pto->kw = PyDict_Copy(kw);
		if (pto->kw == NULL) {
			Py_DECREF(pto);
			return NULL;
		}
	} else {
		pto->kw = Py_None;
		Py_INCREF(Py_None);
	}

	pto->weakreflist = NULL;
	pto->dict = NULL;

	return (PyObject *)pto;
}

static void
partial_dealloc(partialobject *pto)
{
	PyObject_GC_UnTrack(pto);
	if (pto->weakreflist != NULL)
		PyObject_ClearWeakRefs((PyObject *) pto);
	Py_XDECREF(pto->fn);
	Py_XDECREF(pto->args);
	Py_XDECREF(pto->kw);
	Py_XDECREF(pto->dict);
	pto->ob_type->tp_free(pto);
}

static PyObject *
partial_call(partialobject *pto, PyObject *args, PyObject *kw)
{
	PyObject *ret;
	PyObject *argappl = NULL, *kwappl = NULL;

	assert (PyCallable_Check(pto->fn));
	assert (PyTuple_Check(pto->args));
	assert (pto->kw == Py_None  ||  PyDict_Check(pto->kw));

	if (PyTuple_GET_SIZE(pto->args) == 0) {
		argappl = args;
		Py_INCREF(args);
	} else if (PyTuple_GET_SIZE(args) == 0) {
		argappl = pto->args;
		Py_INCREF(pto->args);
	} else {
		argappl = PySequence_Concat(pto->args, args);
		if (argappl == NULL)
			return NULL;
	}

	if (pto->kw == Py_None) {
		kwappl = kw;
		Py_XINCREF(kw);
	} else {
		kwappl = PyDict_Copy(pto->kw);
		if (kwappl == NULL) {
			Py_DECREF(argappl);
			return NULL;
		}
		if (kw != NULL) {
			if (PyDict_Merge(kwappl, kw, 1) != 0) {
				Py_DECREF(argappl);
				Py_DECREF(kwappl);
				return NULL;
			}
		}
	}

	ret = PyObject_Call(pto->fn, argappl, kwappl);
	Py_DECREF(argappl);
	Py_XDECREF(kwappl);
	return ret;
}

static int
partial_traverse(partialobject *pto, visitproc visit, void *arg)
{
	Py_VISIT(pto->fn);
	Py_VISIT(pto->args);
	Py_VISIT(pto->kw);
	Py_VISIT(pto->dict);
	return 0;
}

PyDoc_STRVAR(partial_doc,
"partial(func, *args, **keywords) - new function with partial application\n\
	of the given arguments and keywords.\n");

#define OFF(x) offsetof(partialobject, x)
static PyMemberDef partial_memberlist[] = {
	{"func",	T_OBJECT,	OFF(fn),	READONLY,
	 "function object to use in future partial calls"},
	{"args",	T_OBJECT,	OFF(args),	READONLY,
	 "tuple of arguments to future partial calls"},
	{"keywords",	T_OBJECT,	OFF(kw),	READONLY,
	 "dictionary of keyword arguments to future partial calls"},
	{NULL}  /* Sentinel */
};

static PyObject *
partial_get_dict(partialobject *pto)
{
	if (pto->dict == NULL) {
		pto->dict = PyDict_New();
		if (pto->dict == NULL)
			return NULL;
	}
	Py_INCREF(pto->dict);
	return pto->dict;
}

static int
partial_set_dict(partialobject *pto, PyObject *value)
{
	PyObject *tmp;

	/* It is illegal to del p.__dict__ */
	if (value == NULL) {
		PyErr_SetString(PyExc_TypeError,
				"a partial object's dictionary may not be deleted");
		return -1;
	}
	/* Can only set __dict__ to a dictionary */
	if (!PyDict_Check(value)) {
		PyErr_SetString(PyExc_TypeError,
				"setting partial object's dictionary to a non-dict");
		return -1;
	}
	tmp = pto->dict;
	Py_INCREF(value);
	pto->dict = value;
	Py_XDECREF(tmp);
	return 0;
}

static PyGetSetDef partail_getsetlist[] = {
	{"__dict__", (getter)partial_get_dict, (setter)partial_set_dict},
	{NULL} /* Sentinel */
};

static PyTypeObject partial_type = {
	PyObject_HEAD_INIT(NULL)
	0,				/* ob_size */
	"functional.partial",		/* tp_name */
	sizeof(partialobject),		/* tp_basicsize */
	0,				/* tp_itemsize */
	/* methods */
	(destructor)partial_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 */
	(ternaryfunc)partial_call,	/* tp_call */
	0,				/* tp_str */
	PyObject_GenericGetAttr,	/* tp_getattro */
	PyObject_GenericSetAttr,	/* tp_setattro */
	0,				/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
		Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,	/* tp_flags */
	partial_doc,			/* tp_doc */
	(traverseproc)partial_traverse,	/* tp_traverse */
	0,				/* tp_clear */
	0,				/* tp_richcompare */
	offsetof(partialobject, weakreflist),	/* tp_weaklistoffset */
	0,				/* tp_iter */
	0,				/* tp_iternext */
	0,				/* tp_methods */
	partial_memberlist,		/* tp_members */
	partail_getsetlist,		/* tp_getset */
	0,				/* tp_base */
	0,				/* tp_dict */
	0,				/* tp_descr_get */
	0,				/* tp_descr_set */
	offsetof(partialobject, dict),	/* tp_dictoffset */
	0,				/* tp_init */
	0,				/* tp_alloc */
	partial_new,			/* tp_new */
	PyObject_GC_Del,		/* tp_free */
};


/* module level code ********************************************************/

PyDoc_STRVAR(module_doc,
"Tools for functional programming.");

static PyMethodDef module_methods[] = {
 	{NULL,		NULL}		/* sentinel */
};

PyMODINIT_FUNC
initfunctional(void)
{
	int i;
	PyObject *m;
	char *name;
	PyTypeObject *typelist[] = {
		&partial_type,
		NULL
	};

	m = Py_InitModule3("functional", module_methods, module_doc);

	for (i=0 ; typelist[i] != NULL ; i++) {
		if (PyType_Ready(typelist[i]) < 0)
			return;
		name = strchr(typelist[i]->tp_name, '.');
		assert (name != NULL);
		Py_INCREF(typelist[i]);
		PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
	}
}

--- NEW FILE: sha256module.c ---
/* 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 at amk.ca)
   Greg Stein (gstein at lyra.org)
   Trevor Perrin (trevp at trevp.net)

   Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
   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 at 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 *args)
{
    SHAobject *newobj;

    if (!PyArg_ParseTuple(args, ":copy")) {
        return NULL;
    }

    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 *args)
{
    unsigned char digest[SHA_DIGESTSIZE];
    SHAobject temp;

    if (!PyArg_ParseTuple(args, ":digest"))
        return NULL;

    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 *args)
{
    unsigned char digest[SHA_DIGESTSIZE];
    SHAobject temp;
    PyObject *retval;
    char *hex_digest;
    int i, j;

    if (!PyArg_ParseTuple(args, ":hexdigest"))
        return NULL;

    /* 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_VARARGS, SHA256_copy__doc__},
    {"digest",	  (PyCFunction)SHA256_digest,    METH_VARARGS, SHA256_digest__doc__},
    {"hexdigest", (PyCFunction)SHA256_hexdigest, METH_VARARGS, 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);
}

--- NEW FILE: sha512module.c ---
/* 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 at amk.ca)
   Greg Stein (gstein at lyra.org)
   Trevor Perrin (trevp at trevp.net)

   Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
   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 at iahu.ca, http://libtomcrypt.org
 */


/* SHA512 by Tom St Denis */

/* Various logical functions */
#define ROR64(x, y) \
    ( ((((x) & 0xFFFFFFFFFFFFFFFF)>>((unsigned PY_LONG_LONG)(y) & 63)) | \
      ((x)<<((unsigned PY_LONG_LONG)(64-((y) & 63))))) & 0xFFFFFFFFFFFFFFFF)
#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) & 0xFFFFFFFFFFFFFFFF) >> ((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,0x428a2f98d728ae22);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x7137449123ef65cd);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcfec4d3b2f);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba58189dbbc);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25bf348b538);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1b605d019);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4af194f9b);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5da6d8118);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98a3030242);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b0145706fbe);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be4ee4b28c);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3d5ffb4e2);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74f27b896f);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe3b1696b1);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a725c71235);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174cf692694);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c19ef14ad2);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786384f25e3);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc68b8cd5b5);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc77ac9c65);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f592b0275);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa6ea6e483);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dcbd41fbd4);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da831153b5);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152ee66dfab);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d2db43210);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c898fb213f);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7beef0ee4);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf33da88fc2);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147930aa725);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351e003826f);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x142929670a0e6e70);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a8546d22ffc);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b21385c26c926);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc5ac42aed);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d139d95b3df);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a73548baf63de);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb3c77b2a8);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e47edaee6);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c851482353b);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a14cf10364);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664bbc423001);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70d0f89791);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a30654be30);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819d6ef5218);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd69906245565a910);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e35855771202a);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa07032bbd1b8);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116b8d2d0c8);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c085141ab53);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774cdf8eeb99);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5e19b48a8);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3c5c95a63);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4ae3418acb);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f7763e373);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3d6b2b8a3);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee5defb2fc);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f43172f60);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814a1f0ab72);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc702081a6439ec);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa23631e28);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506cebde82bde9);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7b2c67915);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2e372532b);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],64,0xca273eceea26619c);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],65,0xd186b8c721c0c207);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],66,0xeada7dd6cde0eb1e);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],67,0xf57d4f7fee6ed178);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],68,0x06f067aa72176fba);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],69,0x0a637dc5a2c898a6);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],70,0x113f9804bef90dae);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],71,0x1b710b35131c471b);
    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],72,0x28db77f523047d84);
    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],73,0x32caab7b40c72493);
    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],74,0x3c9ebe0a15c9bebc);
    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],75,0x431d67c49c100d4c);
    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],76,0x4cc5d4becb3e42b6);
    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],77,0x597f299cfc657e2a);
    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],78,0x5fcb6fab3ad6faec);
    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],79,0x6c44198c4a475817);

#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] = 0x6a09e667f3bcc908;
    sha_info->digest[1] = 0xbb67ae8584caa73b;
    sha_info->digest[2] = 0x3c6ef372fe94f82b;
    sha_info->digest[3] = 0xa54ff53a5f1d36f1;
    sha_info->digest[4] = 0x510e527fade682d1;
    sha_info->digest[5] = 0x9b05688c2b3e6c1f;
    sha_info->digest[6] = 0x1f83d9abfb41bd6b;
    sha_info->digest[7] = 0x5be0cd19137e2179;
    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] = 0xcbbb9d5dc1059ed8;
    sha_info->digest[1] = 0x629a292a367cd507;
    sha_info->digest[2] = 0x9159015a3070dd17;
    sha_info->digest[3] = 0x152fecd8f70e5939;
    sha_info->digest[4] = 0x67332667ffc00b31;
    sha_info->digest[5] = 0x8eb44a8768581511;
    sha_info->digest[6] = 0xdb0c2e0d64f98fa7;
    sha_info->digest[7] = 0x47b5481dbefa4fa4;
    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 *args)
{
    SHAobject *newobj;

    if (!PyArg_ParseTuple(args, ":copy")) {
        return NULL;
    }

    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 *args)
{
    unsigned char digest[SHA_DIGESTSIZE];
    SHAobject temp;

    if (!PyArg_ParseTuple(args, ":digest"))
        return NULL;

    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 *args)
{
    unsigned char digest[SHA_DIGESTSIZE];
    SHAobject temp;
    PyObject *retval;
    char *hex_digest;
    int i, j;

    if (!PyArg_ParseTuple(args, ":hexdigest"))
        return NULL;

    /* 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_VARARGS, SHA512_copy__doc__},
    {"digest",	  (PyCFunction)SHA512_digest,    METH_VARARGS, SHA512_digest__doc__},
    {"hexdigest", (PyCFunction)SHA512_hexdigest, METH_VARARGS, 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);
}

#endif

--- NEW FILE: spwdmodule.c ---

/* UNIX shadow password file access module */
/* A lot of code has been taken from pwdmodule.c */
/* For info also see http://www.unixpapa.com/incnote/passwd.html */

#include "Python.h"
#include "structseq.h"

#include <sys/types.h>
#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif


PyDoc_STRVAR(spwd__doc__,
"This module provides access to the Unix shadow password database.\n\
It is available on various Unix versions.\n\
\n\
Shadow password database entries are reported as 9-tuples of type struct_spwd,\n\
containing the following items from the password database (see `<shadow.h>'):\n\
sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max, sp_warn, sp_inact, sp_expire, sp_flag.\n\
The sp_namp and sp_pwdp are strings, the rest are integers.\n\
An exception is raised if the entry asked for cannot be found.\n\
You have to be root to be able to use this module.");


#if defined(HAVE_GETSPNAM) || defined(HAVE_GETSPENT)

static PyStructSequence_Field struct_spwd_type_fields[] = {
	{"sp_nam", "login name"},
	{"sp_pwd", "encrypted password"},
	{"sp_lstchg", "date of last change"},
	{"sp_min", "min #days between changes"}, 
	{"sp_max", "max #days between changes"}, 
	{"sp_warn", "#days before pw expires to warn user about it"}, 
	{"sp_inact", "#days after pw expires until account is blocked"},
	{"sp_expire", "#days since 1970-01-01 until account is disabled"},
	{"sp_flag", "reserved"},
	{0}
};

PyDoc_STRVAR(struct_spwd__doc__,
"spwd.struct_spwd: Results from getsp*() routines.\n\n\
This object may be accessed either as a 9-tuple of\n\
  (sp_nam,sp_pwd,sp_lstchg,sp_min,sp_max,sp_warn,sp_inact,sp_expire,sp_flag)\n\
or via the object attributes as named in the above tuple.");

static PyStructSequence_Desc struct_spwd_type_desc = {
	"spwd.struct_spwd",
	struct_spwd__doc__,
	struct_spwd_type_fields,
	9,
};

static PyTypeObject StructSpwdType;


static void
sets(PyObject *v, int i, char* val)
{
  if (val)
	  PyStructSequence_SET_ITEM(v, i, PyString_FromString(val));
  else {
	  PyStructSequence_SET_ITEM(v, i, Py_None);
	  Py_INCREF(Py_None);
  }
}

static PyObject *mkspent(struct spwd *p)
{
	int setIndex = 0;
	PyObject *v = PyStructSequence_New(&StructSpwdType);
	if (v == NULL)
		return NULL;

#define SETI(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
#define SETS(i,val) sets(v, i, val)

	SETS(setIndex++, p->sp_namp);
	SETS(setIndex++, p->sp_pwdp);
	SETI(setIndex++, p->sp_lstchg);
	SETI(setIndex++, p->sp_min);
	SETI(setIndex++, p->sp_max);
	SETI(setIndex++, p->sp_warn);
	SETI(setIndex++, p->sp_inact);
	SETI(setIndex++, p->sp_expire);
	SETI(setIndex++, p->sp_flag);

#undef SETS
#undef SETI

	if (PyErr_Occurred()) {
		Py_XDECREF(v);
		return NULL;
	}

	return v;
}

#endif  /* HAVE_GETSPNAM || HAVE_GETSPENT */


#ifdef HAVE_GETSPNAM

PyDoc_STRVAR(spwd_getspnam__doc__,
"getspnam(name) -> (sp_namp, sp_pwdp, sp_lstchg, sp_min, sp_max,\n\
                    sp_warn, sp_inact, sp_expire, sp_flag)\n\
Return the shadow password database entry for the given user name.\n\
See spwd.__doc__ for more on shadow password database entries.");

static PyObject* spwd_getspnam(PyObject *self, PyObject *args)
{
	char *name;
	struct spwd *p;
	if (!PyArg_ParseTuple(args, "s:getspnam", &name))
		return NULL;
	if ((p = getspnam(name)) == NULL) {
		PyErr_SetString(PyExc_KeyError, "getspnam(): name not found");
		return NULL;
	}
	return mkspent(p);
}

#endif /* HAVE_GETSPNAM */

#ifdef HAVE_GETSPENT

PyDoc_STRVAR(spwd_getspall__doc__,
"getspall() -> list_of_entries\n\
Return a list of all available shadow password database entries, \
in arbitrary order.\n\
See spwd.__doc__ for more on shadow password database entries.");

static PyObject *
spwd_getspall(PyObject *self, PyObject *args)
{
	PyObject *d;
	struct spwd *p;
	if ((d = PyList_New(0)) == NULL)
		return NULL;
	setspent();
	while ((p = getspent()) != NULL) {
		PyObject *v = mkspent(p);
		if (v == NULL || PyList_Append(d, v) != 0) {
			Py_XDECREF(v);
			Py_DECREF(d);
			endspent();
			return NULL;
		}
		Py_DECREF(v);
	}
	endspent();
	return d;
}

#endif /* HAVE_GETSPENT */

static PyMethodDef spwd_methods[] = {
#ifdef HAVE_GETSPNAM	
	{"getspnam",	spwd_getspnam, METH_VARARGS, spwd_getspnam__doc__},
#endif
#ifdef HAVE_GETSPENT
	{"getspall",	spwd_getspall, METH_NOARGS, spwd_getspall__doc__},
#endif
	{NULL,		NULL}		/* sentinel */
};


PyMODINIT_FUNC
initspwd(void)
{
	PyObject *m;
	m=Py_InitModule3("spwd", spwd_methods, spwd__doc__);
	PyStructSequence_InitType(&StructSpwdType, &struct_spwd_type_desc);
	Py_INCREF((PyObject *) &StructSpwdType);
	PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
}

Index: Setup.dist
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v
retrieving revision 1.28.2.2
retrieving revision 1.28.2.3
diff -u -d -r1.28.2.2 -r1.28.2.3
--- Setup.dist	7 Jan 2005 07:02:51 -0000	1.28.2.2
+++ Setup.dist	16 Oct 2005 05:24:04 -0000	1.28.2.3
@@ -170,6 +170,10 @@
 #operator operator.c	# operator.add() and similar goodies
 #_weakref _weakref.c	# basic weak reference support
 #_testcapi _testcapimodule.c    # Python C API test module
+#_random _randommodule.c	# Random number generator
+#collections collectionsmodule.c # Container types
+#itertools itertoolsmodule.c	# Functions creating iterators for efficient looping 
+#strop stropmodule.c		# String manipulations
 
 #unicodedata unicodedata.c    # static Unicode character database
 
@@ -183,6 +187,7 @@
 
 #fcntl fcntlmodule.c	# fcntl(2) and ioctl(2)
 #pwd pwdmodule.c		# pwd(3) 
+#spwd spwdmodule.c		# spwd(3) 
 #grp grpmodule.c		# grp(3)
 #select selectmodule.c	# select(2); not on ancient System V
 

Index: _bisectmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_bisectmodule.c,v
retrieving revision 1.2.6.1
retrieving revision 1.2.6.2
diff -u -d -r1.2.6.1 -r1.2.6.2
--- _bisectmodule.c	7 Jan 2005 07:02:51 -0000	1.2.6.1
+++ _bisectmodule.c	16 Oct 2005 05:24:04 -0000	1.2.6.2
@@ -34,15 +34,16 @@
 }
 
 static PyObject *
-bisect_right(PyObject *self, PyObject *args)
+bisect_right(PyObject *self, PyObject *args, PyObject *kw)
 {
 	PyObject *list, *item;
 	int lo = 0;
 	int hi = -1;
 	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
 
-	if (!PyArg_ParseTuple(args, "OO|ii:bisect_right",
-		&list, &item, &lo, &hi))
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_right",
+		keywords, &list, &item, &lo, &hi))
 		return NULL;
 	index = internal_bisect_right(list, item, lo, hi);
 	if (index < 0)
@@ -51,7 +52,7 @@
 }
 
 PyDoc_STRVAR(bisect_right_doc,
-"bisect_right(list, item[, lo[, hi]]) -> index\n\
+"bisect_right(a, x[, lo[, hi]]) -> index\n\
 \n\
 Return the index where to insert item x in list a, assuming a is sorted.\n\
 \n\
@@ -63,15 +64,16 @@
 slice of a to be searched.\n");
 
 static PyObject *
-insort_right(PyObject *self, PyObject *args)
+insort_right(PyObject *self, PyObject *args, PyObject *kw)
 {
 	PyObject *list, *item, *result;
 	int lo = 0;
 	int hi = -1;
 	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
 
-	if (!PyArg_ParseTuple(args, "OO|ii:insort_right",
-		&list, &item, &lo, &hi))
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_right",
+		keywords, &list, &item, &lo, &hi))
 		return NULL;
 	index = internal_bisect_right(list, item, lo, hi);
 	if (index < 0)
@@ -91,7 +93,7 @@
 }
 
 PyDoc_STRVAR(insort_right_doc,
-"insort_right(list, item[, lo[, hi]])\n\
+"insort_right(a, x[, lo[, hi]])\n\
 \n\
 Insert item x in list a, and keep it sorted assuming a is sorted.\n\
 \n\
@@ -129,15 +131,16 @@
 }
 
 static PyObject *
-bisect_left(PyObject *self, PyObject *args)
+bisect_left(PyObject *self, PyObject *args, PyObject *kw)
 {
 	PyObject *list, *item;
 	int lo = 0;
 	int hi = -1;
 	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
 
-	if (!PyArg_ParseTuple(args, "OO|ii:bisect_left",
-		&list, &item, &lo, &hi))
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:bisect_left",
+		keywords, &list, &item, &lo, &hi))
 		return NULL;
 	index = internal_bisect_left(list, item, lo, hi);
 	if (index < 0)
@@ -146,7 +149,7 @@
 }
 
 PyDoc_STRVAR(bisect_left_doc,
-"bisect_left(list, item[, lo[, hi]]) -> index\n\
+"bisect_left(a, x[, lo[, hi]]) -> index\n\
 \n\
 Return the index where to insert item x in list a, assuming a is sorted.\n\
 \n\
@@ -158,15 +161,16 @@
 slice of a to be searched.\n");
 
 static PyObject *
-insort_left(PyObject *self, PyObject *args)
+insort_left(PyObject *self, PyObject *args, PyObject *kw)
 {
 	PyObject *list, *item, *result;
 	int lo = 0;
 	int hi = -1;
 	int index;
+	static char *keywords[] = {"a", "x", "lo", "hi", NULL};
 
-	if (!PyArg_ParseTuple(args, "OO|ii:insort_left",
-		&list, &item, &lo, &hi))
+	if (!PyArg_ParseTupleAndKeywords(args, kw, "OO|ii:insort_left",
+		keywords, &list, &item, &lo, &hi))
 		return NULL;
 	index = internal_bisect_left(list, item, lo, hi);
 	if (index < 0)
@@ -186,7 +190,7 @@
 }
 
 PyDoc_STRVAR(insort_left_doc,
-"insort_left(list, item[, lo[, hi]])\n\
+"insort_left(a, x[, lo[, hi]])\n\
 \n\
 Insert item x in list a, and keep it sorted assuming a is sorted.\n\
 \n\
@@ -200,17 +204,17 @@
 
 static PyMethodDef bisect_methods[] = {
 	{"bisect_right", (PyCFunction)bisect_right,
-		METH_VARARGS, bisect_right_doc},
+		METH_VARARGS|METH_KEYWORDS, bisect_right_doc},
 	{"bisect", (PyCFunction)bisect_right,
-		METH_VARARGS, bisect_doc},
+		METH_VARARGS|METH_KEYWORDS, bisect_doc},
 	{"insort_right", (PyCFunction)insort_right,
-		METH_VARARGS, insort_right_doc},
+		METH_VARARGS|METH_KEYWORDS, insort_right_doc},
 	{"insort", (PyCFunction)insort_right,
-		METH_VARARGS, insort_doc},
+		METH_VARARGS|METH_KEYWORDS, insort_doc},
 	{"bisect_left", (PyCFunction)bisect_left,
-		METH_VARARGS, bisect_left_doc},
+		METH_VARARGS|METH_KEYWORDS, bisect_left_doc},
 	{"insort_left", (PyCFunction)insort_left,
-		METH_VARARGS, insort_left_doc},
+		METH_VARARGS|METH_KEYWORDS, insort_left_doc},
 	{NULL, NULL} /* sentinel */
 };
 

Index: _bsddb.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_bsddb.c,v
retrieving revision 1.13.4.2
retrieving revision 1.13.4.3
diff -u -d -r1.13.4.2 -r1.13.4.3
--- _bsddb.c	7 Jan 2005 07:02:51 -0000	1.13.4.2
+++ _bsddb.c	16 Oct 2005 05:24:04 -0000	1.13.4.3
@@ -97,7 +97,7 @@
 #error "eek! DBVER can't handle minor versions > 9"
 #endif
 
-#define PY_BSDDB_VERSION "4.3.0"
+#define PY_BSDDB_VERSION "4.3.3"
 static char *rcs_id = "$Id$";
 
 
@@ -153,7 +153,7 @@
 
 static PyObject* DBError;               /* Base class, all others derive from this */
 static PyObject* DBCursorClosedError;   /* raised when trying to use a closed cursor object */
-static PyObject* DBKeyEmptyError;       /* DB_KEYEMPTY */
+static PyObject* DBKeyEmptyError;       /* DB_KEYEMPTY: also derives from KeyError */
 static PyObject* DBKeyExistError;       /* DB_KEYEXIST */
 static PyObject* DBLockDeadlockError;   /* DB_LOCK_DEADLOCK */
 static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
@@ -212,10 +212,10 @@
 
 struct behaviourFlags {
     /* What is the default behaviour when DB->get or DBCursor->get returns a
-       DB_NOTFOUND error?  Return None or raise an exception? */
+       DB_NOTFOUND || DB_KEYEMPTY error?  Return None or raise an exception? */
     unsigned int getReturnsNone : 1;
     /* What is the default behaviour for DBCursor.set* methods when DBCursor->get
-     * returns a DB_NOTFOUND error?  Return None or raise an exception? */
+     * returns a DB_NOTFOUND || DB_KEYEMPTY  error?  Return None or raise? */
     unsigned int cursorSetReturnsNone : 1;
 };
 
@@ -244,6 +244,7 @@
     struct behaviourFlags moduleFlags;
 #if (DBVER >= 33)
     PyObject*       associateCallback;
+    PyObject*       btCompareCallback;
     int             primaryDBType;
 #endif
 #ifdef HAVE_WEAKREF
@@ -672,7 +673,8 @@
     err = self->dbc->c_get(self->dbc, &key, &data, flags);
     MYDB_END_ALLOW_THREADS;
 
-    if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -741,6 +743,7 @@
     self->myenvobj = NULL;
 #if (DBVER >= 33)
     self->associateCallback = NULL;
+    self->btCompareCallback = NULL;
     self->primaryDBType = 0;
 #endif
 #ifdef HAVE_WEAKREF
@@ -815,6 +818,10 @@
         Py_DECREF(self->associateCallback);
         self->associateCallback = NULL;
     }
+    if (self->btCompareCallback != NULL) {
+        Py_DECREF(self->btCompareCallback);
+        self->btCompareCallback = NULL;
+    }
 #endif
     PyObject_Del(self);
 }
@@ -1165,6 +1172,7 @@
         makeTypeError("DB", (PyObject*)secondaryDB);
         return NULL;
     }
+    CHECK_DB_NOT_CLOSED(secondaryDB);
     if (callback == Py_None) {
         callback = NULL;
     }
@@ -1174,9 +1182,7 @@
     }
 
     /* Save a reference to the callback in the secondary DB. */
-    if (self->associateCallback != NULL) {
-        Py_DECREF(self->associateCallback);
-    }
+    Py_XDECREF(secondaryDB->associateCallback);
     Py_INCREF(callback);
     secondaryDB->associateCallback = callback;
     secondaryDB->primaryDBType = _DB_get_type(self);
@@ -1210,8 +1216,8 @@
     MYDB_END_ALLOW_THREADS;
 
     if (err) {
-        Py_DECREF(self->associateCallback);
-        self->associateCallback = NULL;
+        Py_XDECREF(secondaryDB->associateCallback);
+        secondaryDB->associateCallback = NULL;
         secondaryDB->primaryDBType = 0;
     }
 
@@ -1279,7 +1285,8 @@
     err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
     MYDB_END_ALLOW_THREADS;
 
-    if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->moduleFlags.getReturnsNone) {
         err = 0;
         Py_INCREF(Py_None);
         retval = Py_None;
@@ -1424,12 +1431,13 @@
     err = self->db->get(self->db, txn, &key, &data, flags);
     MYDB_END_ALLOW_THREADS;
 
-    if ((err == DB_NOTFOUND) && (dfltobj != NULL)) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
         err = 0;
         Py_INCREF(dfltobj);
         retval = dfltobj;
     }
-    else if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	     && self->moduleFlags.getReturnsNone) {
         err = 0;
         Py_INCREF(Py_None);
         retval = Py_None;
@@ -1493,12 +1501,13 @@
     err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
     MYDB_END_ALLOW_THREADS;
 
-    if ((err == DB_NOTFOUND) && (dfltobj != NULL)) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
         err = 0;
         Py_INCREF(dfltobj);
         retval = dfltobj;
     }
-    else if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+    else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	     && self->moduleFlags.getReturnsNone) {
         err = 0;
         Py_INCREF(Py_None);
         retval = Py_None;
@@ -1623,7 +1632,8 @@
     err = self->db->get(self->db, txn, &key, &data, flags);
     MYDB_END_ALLOW_THREADS;
 
-    if ((err == DB_NOTFOUND) && self->moduleFlags.getReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->moduleFlags.getReturnsNone) {
         err = 0;
         Py_INCREF(Py_None);
         retval = Py_None;
@@ -1959,6 +1969,158 @@
     RETURN_NONE();
 }
 
+static int 
+_default_cmp (const DBT *leftKey,
+	      const DBT *rightKey)
+{
+  int res;
+  int lsize = leftKey->size, rsize = rightKey->size;
+
+  res = memcmp (leftKey->data, rightKey->data, 
+		lsize < rsize ? lsize : rsize);
+  
+  if (res == 0) {
+      if (lsize < rsize) {
+	  res = -1;
+      }
+      else if (lsize > rsize) {
+	  res = 1;
+      }
+  }
+  return res;
+}
+
+static int
+_db_compareCallback (DB* db, 
+		     const DBT *leftKey,
+		     const DBT *rightKey)
+{
+    int res = 0;
+    PyObject *args;
+    PyObject *result;
+    PyObject *leftObject;
+    PyObject *rightObject;
+    DBObject *self = (DBObject *) db->app_private;
+
+    if (self == NULL || self->btCompareCallback == NULL) {
+	MYDB_BEGIN_BLOCK_THREADS;
+	PyErr_SetString (PyExc_TypeError,
+			 (self == 0
+			  ? "DB_bt_compare db is NULL."
+			  : "DB_bt_compare callback is NULL."));
+	/* we're in a callback within the DB code, we can't raise */
+	PyErr_Print ();
+	res = _default_cmp (leftKey, rightKey);
+	MYDB_END_BLOCK_THREADS;
+    }
+    else {
+	MYDB_BEGIN_BLOCK_THREADS;
+
+	leftObject  = PyString_FromStringAndSize (leftKey->data, leftKey->size);
+	rightObject = PyString_FromStringAndSize (rightKey->data, rightKey->size);
+
+	args = PyTuple_New (2);
+	Py_INCREF (self);
+	PyTuple_SET_ITEM (args, 0, leftObject);  /* steals reference */
+	PyTuple_SET_ITEM (args, 1, rightObject); /* steals reference */
+    
+	result = PyEval_CallObject (self->btCompareCallback, args);
+	if (result == 0) {
+	    /* we're in a callback within the DB code, we can't raise */
+	    PyErr_Print ();
+	    res = _default_cmp (leftKey, rightKey);
+	}
+	else if (PyInt_Check (result)) {
+	    res = PyInt_AsLong (result);
+	}
+	else {
+	    PyErr_SetString (PyExc_TypeError,
+			     "DB_bt_compare callback MUST return an int.");
+	    /* we're in a callback within the DB code, we can't raise */
+	    PyErr_Print ();
+	    res = _default_cmp (leftKey, rightKey);
+	}
+    
+	Py_DECREF (args);
+	Py_XDECREF (result);
+
+	MYDB_END_BLOCK_THREADS;
+    }
+    return res;
+}
+
+static PyObject*
+DB_set_bt_compare (DBObject* self, PyObject* args)
+{
+    int err;
+    PyObject *comparator;
+    PyObject *tuple, *emptyStr, *result;
+
+    if (!PyArg_ParseTuple(args,"O:set_bt_compare", &comparator ))
+	return NULL;
+
+    CHECK_DB_NOT_CLOSED (self);
+
+    if (! PyCallable_Check (comparator)) {
+	makeTypeError ("Callable", comparator);
+	return NULL;
+    }
+
+    /* 
+     * Perform a test call of the comparator function with two empty
+     * string objects here.  verify that it returns an int (0).
+     * err if not.
+     */
+    tuple = PyTuple_New (2);
+
+    emptyStr = PyString_FromStringAndSize (NULL, 0);
+    Py_INCREF(emptyStr);
+    PyTuple_SET_ITEM (tuple, 0, emptyStr);
+    PyTuple_SET_ITEM (tuple, 1, emptyStr); /* steals reference */
+    result = PyEval_CallObject (comparator, tuple);
+    Py_DECREF (tuple);
+    if (result == 0 || !PyInt_Check(result)) {
+	PyErr_SetString (PyExc_TypeError,
+			 "callback MUST return an int");
+	return NULL;
+    }
+    else if (PyInt_AsLong(result) != 0) {
+	PyErr_SetString (PyExc_TypeError,
+			 "callback failed to return 0 on two empty strings");
+	return NULL;
+    }
+
+    /* We don't accept multiple set_bt_compare operations, in order to
+     * simplify the code. This would have no real use, as one cannot
+     * change the function once the db is opened anyway */
+    if (self->btCompareCallback != NULL) {
+	PyErr_SetString (PyExc_RuntimeError, "set_bt_compare () cannot be called more than once");
+	return NULL;
+    }
+
+    Py_INCREF (comparator);
+    self->btCompareCallback = comparator;
+
+    /* This is to workaround a problem with un-initialized threads (see
+       comment in DB_associate) */
+#ifdef WITH_THREAD
+    PyEval_InitThreads();
+#endif
+
+    err = self->db->set_bt_compare (self->db, 
+				    (comparator != NULL ? 
+				     _db_compareCallback : NULL));
+
+    if (err) {
+	/* restore the old state in case of error */
+	Py_DECREF (comparator);
+	self->btCompareCallback = NULL;
+    }
+
+    RETURN_IF_ERR ();
+    RETURN_NONE ();
+}
+
 
 static PyObject*
 DB_set_cachesize(DBObject* self, PyObject* args)
@@ -2584,7 +2746,15 @@
     err = self->db->get(self->db, txn, &key, &data, 0);
     MYDB_END_ALLOW_THREADS;
     FREE_DBT(key);
-    return PyInt_FromLong((err == DB_BUFFER_SMALL) || (err == 0));
+
+    if (err == DB_BUFFER_SMALL || err == 0) {
+        return PyInt_FromLong(1);
+    } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
+        return PyInt_FromLong(0);
+    }
+
+    makeDBError(err);
+    return NULL;
 }
 
 
@@ -2682,8 +2852,8 @@
         Py_DECREF(item);
     }
 
-    /* DB_NOTFOUND is okay, it just means we got to the end */
-    if (err != DB_NOTFOUND && makeDBError(err)) {
+    /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
+    if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
         Py_DECREF(list);
         list = NULL;
     }
@@ -2890,7 +3060,8 @@
     err = self->dbc->c_get(self->dbc, &key, &data, flags);
     MYDB_END_ALLOW_THREADS;
 
-    if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -2977,7 +3148,8 @@
     err = self->dbc->c_pget(self->dbc, &key, &pkey, &data, flags);
     MYDB_END_ALLOW_THREADS;
 
-    if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -3144,7 +3316,8 @@
     MYDB_BEGIN_ALLOW_THREADS;
     err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET);
     MYDB_END_ALLOW_THREADS;
-    if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -3216,7 +3389,8 @@
     MYDB_BEGIN_ALLOW_THREADS;
     err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
     MYDB_END_ALLOW_THREADS;
-    if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -3271,7 +3445,7 @@
     MYDB_BEGIN_ALLOW_THREADS;
     err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
     MYDB_END_ALLOW_THREADS;
-    if ((err == DB_NOTFOUND) && returnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -3411,7 +3585,8 @@
     MYDB_BEGIN_ALLOW_THREADS;
     err = self->dbc->c_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
     MYDB_END_ALLOW_THREADS;
-    if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.cursorSetReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.cursorSetReturnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -3479,7 +3654,8 @@
     MYDB_BEGIN_ALLOW_THREADS;
     err = self->dbc->c_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
     MYDB_END_ALLOW_THREADS;
-    if ((err == DB_NOTFOUND) && self->mydb->moduleFlags.getReturnsNone) {
+    if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
+	    && self->mydb->moduleFlags.getReturnsNone) {
         Py_INCREF(Py_None);
         retval = Py_None;
     }
@@ -3781,6 +3957,23 @@
 
 
 static PyObject*
+DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
+{
+    int err, lg_max;
+
+    if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
+        return NULL;
+    CHECK_ENV_NOT_CLOSED(self);
+
+    MYDB_BEGIN_ALLOW_THREADS;
+    err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
+    MYDB_END_ALLOW_THREADS;
+    RETURN_IF_ERR();
+    RETURN_NONE();
+}
+
+
+static PyObject*
 DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
 {
     int err, lk_detect;
@@ -4400,6 +4593,7 @@
     {"remove",          (PyCFunction)DB_remove,         METH_VARARGS|METH_KEYWORDS},
     {"rename",          (PyCFunction)DB_rename,         METH_VARARGS},
     {"set_bt_minkey",   (PyCFunction)DB_set_bt_minkey,  METH_VARARGS},
+    {"set_bt_compare",  (PyCFunction)DB_set_bt_compare, METH_VARARGS},
     {"set_cachesize",   (PyCFunction)DB_set_cachesize,  METH_VARARGS},
 #if (DBVER >= 41)
     {"set_encrypt",     (PyCFunction)DB_set_encrypt,    METH_VARARGS|METH_KEYWORDS},
@@ -4489,6 +4683,7 @@
     {"set_lg_bsize",    (PyCFunction)DBEnv_set_lg_bsize,     METH_VARARGS},
     {"set_lg_dir",      (PyCFunction)DBEnv_set_lg_dir,       METH_VARARGS},
     {"set_lg_max",      (PyCFunction)DBEnv_set_lg_max,       METH_VARARGS},
+    {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
     {"set_lk_detect",   (PyCFunction)DBEnv_set_lk_detect,    METH_VARARGS},
     {"set_lk_max",      (PyCFunction)DBEnv_set_lk_max,       METH_VARARGS},
 #if (DBVER >= 32)
@@ -5117,12 +5312,15 @@
     DBError = PyErr_NewException("bsddb._db.DBError", NULL, NULL);
     PyDict_SetItemString(d, "DBError", DBError);
 
-    /* Some magic to make DBNotFoundError derive from both DBError and
-       KeyError, since the API only supports using one base class. */
+    /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
+     * from both DBError and KeyError, since the API only supports
+     * using one base class. */
     PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
-    PyRun_String("class DBNotFoundError(DBError, KeyError): pass",
+    PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
+	         "class DBKeyEmptyError(DBError, KeyError): pass",
                  Py_file_input, d, d);
     DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
+    DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
     PyDict_DelItemString(d, "KeyError");
 
 

Index: _codecsmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v
retrieving revision 2.12.2.2
retrieving revision 2.12.2.3
diff -u -d -r2.12.2.2 -r2.12.2.3
--- _codecsmodule.c	7 Jan 2005 07:02:51 -0000	2.12.2.2
+++ _codecsmodule.c	16 Oct 2005 05:24:04 -0000	2.12.2.3
@@ -104,8 +104,15 @@
     if (!PyArg_ParseTuple(args, "O|ss:encode", &v, &encoding, &errors))
         return NULL;
 
+#ifdef Py_USING_UNICODE
     if (encoding == NULL)
 	encoding = PyUnicode_GetDefaultEncoding();
+#else
+    if (encoding == NULL) {
+	PyErr_SetString(PyExc_ValueError, "no encoding specified");
+	return NULL;
+    }
+#endif
 
     /* Encode via the codec registry */
     v = PyCodec_Encode(v, encoding, errors);
@@ -137,8 +144,15 @@
     if (!PyArg_ParseTuple(args, "O|ss:decode", &v, &encoding, &errors))
         return NULL;
 
+#ifdef Py_USING_UNICODE
     if (encoding == NULL)
 	encoding = PyUnicode_GetDefaultEncoding();
+#else
+    if (encoding == NULL) {
+	PyErr_SetString(PyExc_ValueError, "no encoding specified");
+	return NULL;
+    }
+#endif
 
     /* Decode via the codec registry */
     v = PyCodec_Decode(v, encoding, errors);
@@ -240,8 +254,8 @@
     else {
 	if (PyObject_AsReadBuffer(obj, (const void **)&data, &size))
 	    return NULL;
-	return codec_tuple(PyUnicode_FromUnicode((Py_UNICODE *)data,
-						 size / sizeof(Py_UNICODE)),
+
+	return codec_tuple(_PyUnicode_DecodeUnicodeInternal(data, size, errors),
 			   size);
     }
 }

Index: _csv.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_csv.c,v
retrieving revision 1.11.4.2
retrieving revision 1.11.4.3
diff -u -d -r1.11.4.2 -r1.11.4.3
--- _csv.c	7 Jan 2005 07:02:52 -0000	1.11.4.2
+++ _csv.c	16 Oct 2005 05:24:04 -0000	1.11.4.3
@@ -39,12 +39,17 @@
 #endif
 /* end 2.2 compatibility macros */
 
+#define IS_BASESTRING(o) \
+	PyObject_TypeCheck(o, &PyBaseString_Type)
+
 static PyObject *error_obj;	/* CSV exception */
 static PyObject *dialects;      /* Dialect registry */
+static long field_limit = 128 * 1024;	/* max parsed field size */
 
 typedef enum {
[...1406 lines suppressed...]
+	{ "register_dialect", (PyCFunction)csv_register_dialect, 
+		METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
+	{ "unregister_dialect", (PyCFunction)csv_unregister_dialect, 
+		METH_O, csv_unregister_dialect_doc},
+	{ "get_dialect", (PyCFunction)csv_get_dialect, 
+		METH_O, csv_get_dialect_doc},
+	{ "field_size_limit", (PyCFunction)csv_field_size_limit, 
+		METH_VARARGS, csv_field_size_limit_doc},
+	{ NULL, NULL }
 };
 
 PyMODINIT_FUNC
@@ -1545,6 +1587,7 @@
 	}
 
         /* Add the Dialect type */
+	Py_INCREF(&Dialect_Type);
         if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
                 return;
 

Index: _cursesmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v
retrieving revision 2.65.2.2
retrieving revision 2.65.2.3
diff -u -d -r2.65.2.2 -r2.65.2.3
--- _cursesmodule.c	7 Jan 2005 07:02:52 -0000	2.65.2.2
+++ _cursesmodule.c	16 Oct 2005 05:24:04 -0000	2.65.2.3
@@ -162,6 +162,10 @@
                                   "must call start_color() first"); \
                   return 0; }
 
+#ifndef MIN
+#define MIN(x,y) ((x) < (y) ? (x) : (y))
+#endif
+
 /* Utility Functions */
 
 /*
@@ -801,21 +805,21 @@
   switch (PyTuple_Size(args)) {
   case 0:
     Py_BEGIN_ALLOW_THREADS
-    rtn2 = wgetstr(self->win,rtn);
+    rtn2 = wgetnstr(self->win,rtn, 1023);
     Py_END_ALLOW_THREADS
     break;
   case 1:
     if (!PyArg_ParseTuple(args,"i;n", &n))
       return NULL;
     Py_BEGIN_ALLOW_THREADS
-    rtn2 = wgetnstr(self->win,rtn,n);
+    rtn2 = wgetnstr(self->win,rtn,MIN(n, 1023));
     Py_END_ALLOW_THREADS
     break;
   case 2:
     if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
       return NULL;
     Py_BEGIN_ALLOW_THREADS
-    rtn2 = mvwgetstr(self->win,y,x,rtn);
+    rtn2 = mvwgetnstr(self->win,y,x,rtn, 1023);
     Py_END_ALLOW_THREADS
     break;
   case 3:
@@ -825,11 +829,11 @@
  /* Untested */
     Py_BEGIN_ALLOW_THREADS
     rtn2 = wmove(self->win,y,x)==ERR ? ERR :
-      wgetnstr(self->win, rtn, n);
+      wgetnstr(self->win, rtn, MIN(n, 1023));
     Py_END_ALLOW_THREADS
 #else
     Py_BEGIN_ALLOW_THREADS
-    rtn2 = mvwgetnstr(self->win, y, x, rtn, n);
+    rtn2 = mvwgetnstr(self->win, y, x, rtn, MIN(n, 1023));
     Py_END_ALLOW_THREADS
 #endif
     break;
@@ -962,22 +966,22 @@
 
   switch (PyTuple_Size(args)) {
   case 0:
-    rtn2 = winstr(self->win,rtn);
+    rtn2 = winnstr(self->win,rtn, 1023);
     break;
   case 1:
     if (!PyArg_ParseTuple(args,"i;n", &n))
       return NULL;
-    rtn2 = winnstr(self->win,rtn,n);
+    rtn2 = winnstr(self->win,rtn,MIN(n,1023));
     break;
   case 2:
     if (!PyArg_ParseTuple(args,"ii;y,x",&y,&x))
       return NULL;
-    rtn2 = mvwinstr(self->win,y,x,rtn);
+    rtn2 = mvwinnstr(self->win,y,x,rtn,1023);
     break;
   case 3:
     if (!PyArg_ParseTuple(args, "iii;y,x,n", &y, &x, &n))
       return NULL;
-    rtn2 = mvwinnstr(self->win, y, x, rtn, n);
+    rtn2 = mvwinnstr(self->win, y, x, rtn, MIN(n,1023));
     break;
   default:
     PyErr_SetString(PyExc_TypeError, "instr requires 0 or 3 arguments");
@@ -2103,7 +2107,7 @@
     return NULL;
   }
 
-  if (!pair_content(pair, &f, &b)) {
+  if (pair_content(pair, &f, &b)==ERR) {
     PyErr_SetString(PyCursesError,
 		    "Argument 1 was out of range. (1..COLOR_PAIRS-1)");
     return NULL;

Index: _localemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_localemodule.c,v
retrieving revision 2.33.2.2
retrieving revision 2.33.2.3
diff -u -d -r2.33.2.2 -r2.33.2.3
--- _localemodule.c	7 Jan 2005 07:02:53 -0000	2.33.2.2
+++ _localemodule.c	16 Oct 2005 05:24:04 -0000	2.33.2.3
@@ -426,7 +426,7 @@
     /* XXX which one is mac-latin2? */
     }
     if (!name) {
-        /* This leaks a an object. */
+        /* This leaks an object. */
         name = CFStringConvertEncodingToIANACharSetName(enc);
     }
     return (char *)CFStringGetCStringPtr(name, 0); 

Index: _randommodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_randommodule.c,v
retrieving revision 1.5.4.2
retrieving revision 1.5.4.3
diff -u -d -r1.5.4.2 -r1.5.4.3
--- _randommodule.c	7 Jan 2005 07:02:53 -0000	1.5.4.2
+++ _randommodule.c	16 Oct 2005 05:24:04 -0000	1.5.4.3
@@ -481,6 +481,9 @@
 	RandomObject *self;
 	PyObject *tmp;
 
+	if (!_PyArg_NoKeywords("Random()", kwds))
+		return NULL;
+
 	self = (RandomObject *)type->tp_alloc(type, 0);
 	if (self == NULL)
 		return NULL;

Index: _tkinter.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_tkinter.c,v
retrieving revision 1.125.2.2
retrieving revision 1.125.2.3
diff -u -d -r1.125.2.2 -r1.125.2.3
--- _tkinter.c	7 Jan 2005 07:02:54 -0000	1.125.2.2
+++ _tkinter.c	16 Oct 2005 05:24:04 -0000	1.125.2.3
@@ -838,8 +838,10 @@
 };
 
 static PyMethodDef PyTclObject_methods[] = {
+#ifdef Py_USING_UNICODE
 	{"__unicode__",	(PyCFunction)PyTclObject_unicode, METH_NOARGS,
 	PyTclObject_unicode__doc__},
+#endif
 	{0}
 };
 
@@ -991,7 +993,7 @@
 			}
 		}
 #else
-		res = PyString_FromStringAndSize(value->bytes, value->length);
+		result = PyString_FromStringAndSize(value->bytes, value->length);
 #endif
 		return result;
 	}

Index: arraymodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/arraymodule.c,v
retrieving revision 2.75.2.2
retrieving revision 2.75.2.3
diff -u -d -r2.75.2.2 -r2.75.2.3
--- arraymodule.c	7 Jan 2005 07:02:55 -0000	2.75.2.2
+++ arraymodule.c	16 Oct 2005 05:24:04 -0000	2.75.2.3
@@ -1799,18 +1799,9 @@
 	char c;
 	PyObject *initial = NULL, *it = NULL;
 	struct arraydescr *descr;
-
-	if (kwds != NULL) {
-		int i = PyObject_Length(kwds);
-		if (i < 0)
-			return NULL;
-		else if (i > 0) {
-			PyErr_SetString(PyExc_TypeError,
-			    "array.array constructor takes "
-			    "no keyword arguments");
-			return NULL;
-		}
-	}
+	
+	if (!_PyArg_NoKeywords("array.array()", kwds))
+		return NULL;
 
 	if (!PyArg_ParseTuple(args, "c|O:array", &c, &initial))
 		return NULL;

Index: bz2module.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/bz2module.c,v
retrieving revision 1.17.2.2
retrieving revision 1.17.2.3
diff -u -d -r1.17.2.2 -r1.17.2.3
--- bz2module.c	7 Jan 2005 07:02:56 -0000	1.17.2.2
+++ bz2module.c	16 Oct 2005 05:24:04 -0000	1.17.2.3
@@ -22,6 +22,18 @@
     Gustavo Niemeyer <niemeyer at conectiva.com>\n\
 ";
 
+/* Our very own off_t-like type, 64-bit if possible */
+/* copied from Objects/fileobject.c */
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+typedef off_t Py_off_t;
+#elif SIZEOF_OFF_T >= 8
+typedef off_t Py_off_t;
+#elif SIZEOF_FPOS_T >= 8
+typedef fpos_t Py_off_t;
+#else
+#error "Large file support, but neither off_t nor fpos_t is large enough."
+#endif
+
 #define BUF(v) PyString_AS_STRING((PyStringObject *)v)
 
 #define MODE_CLOSED   0
@@ -98,8 +110,8 @@
 
 	BZFILE *fp;
 	int mode;
-	long pos;
-	long size;
+	Py_off_t pos;
+	Py_off_t size;
 #ifdef WITH_THREAD
 	PyThread_type_lock lock;
 #endif
@@ -405,7 +417,9 @@
 			Util_DropReadAhead(f);
 	}
 	if (f->mode == MODE_READ_EOF) {
-		return -1;
+		f->f_bufptr = f->f_buf;
+		f->f_bufend = f->f_buf;
+		return 0;
 	}
 	if ((f->f_buf = PyMem_Malloc(bufsize)) == NULL) {
 		return -1;
@@ -682,13 +696,13 @@
 		}
 		totalread += nread;
 		p = memchr(buffer+nfilled, '\n', nread);
-		if (p == NULL) {
+		if (!shortread && p == NULL) {
 			/* Need a larger buffer to fit this line */
 			nfilled += nread;
 			buffersize *= 2;
 			if (buffersize > INT_MAX) {
 				PyErr_SetString(PyExc_OverflowError,
-			    "line is longer than a Python string can hold");
+				"line is longer than a Python string can hold");
 				goto error;
 			}
 			if (big_buffer == NULL) {
@@ -705,11 +719,11 @@
 				_PyString_Resize(&big_buffer, buffersize);
 				buffer = PyString_AS_STRING(big_buffer);
 			}
-			continue;
+			continue;			
 		}
 		end = buffer+nfilled+nread;
 		q = buffer;
-		do {
+		while (p != NULL) {
 			/* Process complete lines */
 			p++;
 			line = PyString_FromStringAndSize(q, p-q);
@@ -721,7 +735,7 @@
 				goto error;
 			q = p;
 			p = memchr(q, '\n', end-q);
-		} while (p != NULL);
+		}
 		/* Move the remaining incomplete line to the start */
 		nfilled = end-q;
 		memmove(buffer, q, nfilled);
@@ -962,18 +976,27 @@
 BZ2File_seek(BZ2FileObject *self, PyObject *args)
 {
 	int where = 0;
-	long offset;
+	PyObject *offobj;
+	Py_off_t offset;
 	char small_buffer[SMALLCHUNK];
 	char *buffer = small_buffer;
 	size_t buffersize = SMALLCHUNK;
 	int bytesread = 0;
-	int readsize;
+	size_t readsize;
 	int chunksize;
 	int bzerror;
 	int rewind = 0;
 	PyObject *ret = NULL;
 
-	if (!PyArg_ParseTuple(args, "l|i:seek", &offset, &where))
+	if (!PyArg_ParseTuple(args, "O|i:seek", &offobj, &where))
+		return NULL;
+#if !defined(HAVE_LARGEFILE_SUPPORT)
+	offset = PyInt_AsLong(offobj);
+#else
+	offset = PyLong_Check(offobj) ?
+		PyLong_AsLongLong(offobj) : PyInt_AsLong(offobj);
+#endif
+	if (PyErr_Occurred())
 		return NULL;
 
 	ACQUIRE_LOCK(self);
@@ -1066,10 +1089,13 @@
 	/* Before getting here, offset must be set to the number of bytes
 	 * to walk forward. */
 	for (;;) {
-		if ((size_t)offset-bytesread > buffersize)
+		if (offset-bytesread > buffersize)
 			readsize = buffersize;
 		else
-			readsize = offset-bytesread;
+			/* offset might be wider that readsize, but the result
+			 * of the subtraction is bound by buffersize (see the
+			 * condition above). buffersize is 8192. */
+			readsize = (size_t)(offset-bytesread);
 		Py_BEGIN_ALLOW_THREADS
 		chunksize = Util_UnivNewlineRead(&bzerror, self->fp,
 						 buffer, readsize, self);
@@ -1114,7 +1140,11 @@
 		goto cleanup;
 	}
 
+#if !defined(HAVE_LARGEFILE_SUPPORT)
 	ret = PyInt_FromLong(self->pos);
+#else
+	ret = PyLong_FromLongLong(self->pos);
+#endif
 
 cleanup:
 	return ret;
@@ -1308,6 +1338,10 @@
 			break;
 	}
 
+	if (mode_char == 0) {
+		mode_char = 'r';
+	}
+
 	mode = (mode_char == 'r') ? "rb" : "wb";
 
 	self->file = PyObject_CallFunction((PyObject*)&PyFile_Type, "(Osi)",

Index: cStringIO.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/cStringIO.c,v
retrieving revision 2.36.2.2
retrieving revision 2.36.2.3
diff -u -d -r2.36.2.2 -r2.36.2.3
--- cStringIO.c	7 Jan 2005 07:02:57 -0000	2.36.2.2
+++ cStringIO.c	16 Oct 2005 05:24:04 -0000	2.36.2.3
@@ -241,7 +241,10 @@
 		line = PyString_FromStringAndSize (output, n);
 		if (!line) 
                         goto err;
-		PyList_Append (result, line);
+		if (PyList_Append (result, line) == -1) {
+			Py_DECREF (line);
+			goto err;
+		}
 		Py_DECREF (line);
                 length += n;
                 if (hint > 0 && length >= hint)
@@ -440,13 +443,18 @@
 			Py_DECREF(it);
 			Py_DECREF(s);
 			return NULL;
-		}
-		Py_DECREF(s);
-	}
-	Py_DECREF(it);
-	Py_RETURN_NONE;
-}
+               }
+               Py_DECREF(s);
+       }
 
+       Py_DECREF(it);
+
+       /* See if PyIter_Next failed */
+       if (PyErr_Occurred())
+               return NULL;
+
+       Py_RETURN_NONE;
+}
 static struct PyMethodDef O_methods[] = {
   /* Common methods: */
   {"flush",     (PyCFunction)IO_flush,    METH_NOARGS,  IO_flush__doc__},

Index: collectionsmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/collectionsmodule.c,v
retrieving revision 1.36.4.1
retrieving revision 1.36.4.2
diff -u -d -r1.36.4.1 -r1.36.4.2
--- collectionsmodule.c	7 Jan 2005 07:02:57 -0000	1.36.4.1
+++ collectionsmodule.c	16 Oct 2005 05:24:04 -0000	1.36.4.2
@@ -95,6 +95,9 @@
 	dequeobject *deque;
 	block *b;
 
+	if (!_PyArg_NoKeywords("deque()", kwds))
+		return NULL;
+
 	/* create dequeobject structure */
 	deque = (dequeobject *)type->tp_alloc(type, 0);
 	if (deque == NULL)
@@ -368,6 +371,41 @@
 	return deque->len;
 }
 
+static PyObject *
+deque_remove(dequeobject *deque, PyObject *value)
+{
+	int i, n=deque->len;
+
+	for (i=0 ; i<n ; i++) {
+		PyObject *item = deque->leftblock->data[deque->leftindex];
+		int cmp = PyObject_RichCompareBool(item, value, Py_EQ);
+
+		if (deque->len != n) {
+			PyErr_SetString(PyExc_IndexError, 
+				"deque mutated during remove().");
+			return NULL;
+		}
+		if (cmp > 0) {
+			PyObject *tgt = deque_popleft(deque, NULL);
+			assert (tgt != NULL);
+			Py_DECREF(tgt);
+			if (_deque_rotate(deque, i) == -1)
+				return NULL;
+			Py_RETURN_NONE;
+		}
+		else if (cmp < 0) {
+			_deque_rotate(deque, i);
+			return NULL;
+		}
+		_deque_rotate(deque, -1);
+	}
+	PyErr_SetString(PyExc_ValueError, "deque.remove(x): x not in deque");
+	return NULL;
+}
+
+PyDoc_STRVAR(remove_doc,
+"D.remove(value) -- remove first occurrence of value.");
+
 static int
 deque_clear(dequeobject *deque)
 {
@@ -764,7 +802,7 @@
 		METH_NOARGS,	 copy_doc},
 	{"extend",		(PyCFunction)deque_extend,
 		METH_O,		 extend_doc},
-	{"extendleft",	(PyCFunction)deque_extendleft,
+	{"extendleft",		(PyCFunction)deque_extendleft,
 		METH_O,		 extendleft_doc},
 	{"pop",			(PyCFunction)deque_pop,
 		METH_NOARGS,	 pop_doc},
@@ -772,6 +810,8 @@
 		METH_NOARGS,	 popleft_doc},
 	{"__reduce__",	(PyCFunction)deque_reduce,
 		METH_NOARGS,	 reduce_doc},
+	{"remove",		(PyCFunction)deque_remove,
+		METH_O,		 remove_doc},
 	{"__reversed__",	(PyCFunction)deque_reviter,
 		METH_NOARGS,	 reversed_doc},
 	{"rotate",		(PyCFunction)deque_rotate,
@@ -895,15 +935,17 @@
 	return item;
 }
 
-static int
+static PyObject *
 dequeiter_len(dequeiterobject *it)
 {
-	return it->counter;
+	return PyInt_FromLong(it->counter);
 }
 
-static PySequenceMethods dequeiter_as_sequence = {
-	(inquiry)dequeiter_len,		/* sq_length */
-	0,				/* sq_concat */
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef dequeiter_methods[] = {
+	{"_length_cue", (PyCFunction)dequeiter_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
 };
 
 PyTypeObject dequeiter_type = {
@@ -920,7 +962,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&dequeiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -936,6 +978,7 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)dequeiter_next,		/* tp_iternext */
+	dequeiter_methods,			/* tp_methods */
 	0,
 };
 
@@ -1002,7 +1045,7 @@
 	0,					/* tp_compare */
 	0,					/* tp_repr */
 	0,					/* tp_as_number */
-	&dequeiter_as_sequence,			/* tp_as_sequence */
+	0,					/* tp_as_sequence */
 	0,					/* tp_as_mapping */
 	0,					/* tp_hash */
 	0,					/* tp_call */
@@ -1018,6 +1061,7 @@
 	0,					/* tp_weaklistoffset */
 	PyObject_SelfIter,			/* tp_iter */
 	(iternextfunc)dequereviter_next,	/* tp_iternext */
+	dequeiter_methods,			/* tp_methods */
 	0,
 };
 

Index: datetimemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/datetimemodule.c,v
retrieving revision 1.60.4.2
retrieving revision 1.60.4.3
diff -u -d -r1.60.4.2 -r1.60.4.3
--- datetimemodule.c	7 Jan 2005 07:02:57 -0000	1.60.4.2
+++ datetimemodule.c	16 Oct 2005 05:24:04 -0000	1.60.4.3
@@ -3798,6 +3798,46 @@
 	return result;
 }
 
+/* Return new datetime from time.strptime(). */
+static PyObject *
+datetime_strptime(PyObject *cls, PyObject *args)
+{
+	PyObject *result = NULL, *obj, *module;
+	const char *string, *format;
+
+	if (!PyArg_ParseTuple(args, "ss:strptime", &string, &format))
+		return NULL;
+
+	if ((module = PyImport_ImportModule("time")) == NULL)
+		return NULL;
+	obj = PyObject_CallMethod(module, "strptime", "ss", string, format);
+	Py_DECREF(module);
+
+	if (obj != NULL) {
+		int i, good_timetuple = 1;
+		long int ia[6];
+		if (PySequence_Check(obj) && PySequence_Size(obj) >= 6)
+			for (i=0; i < 6; i++) {
+				PyObject *p = PySequence_GetItem(obj, i);
+				if (PyInt_Check(p))
+					ia[i] = PyInt_AsLong(p);
+				else
+					good_timetuple = 0;
+				Py_DECREF(p);
+			}
+		else
+			good_timetuple = 0;
+		if (good_timetuple)
+			result = PyObject_CallFunction(cls, "iiiiii",
+				ia[0], ia[1], ia[2], ia[3], ia[4], ia[5]);
+		else
+			PyErr_SetString(PyExc_ValueError,
+				"unexpected value from time.strptime");
+		Py_DECREF(obj);
+	}
+	return result;
+}
+
 /* Return new datetime from date/datetime and time arguments. */
 static PyObject *
 datetime_combine(PyObject *cls, PyObject *args, PyObject *kw)
@@ -4419,6 +4459,11 @@
 	 PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp "
 	 	   "(like time.time()).")},
 
+	{"strptime", (PyCFunction)datetime_strptime,
+	 METH_VARARGS | METH_CLASS,
+	 PyDoc_STR("string, format -> new datetime parsed from a string "
+	 	   "(like time.strptime()).")},
+
 	{"combine", (PyCFunction)datetime_combine,
 	 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
 	 PyDoc_STR("date, time -> datetime with same date and time fields")},

Index: fcntlmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/fcntlmodule.c,v
retrieving revision 2.35.2.2
retrieving revision 2.35.2.3
diff -u -d -r2.35.2.2 -r2.35.2.3
--- fcntlmodule.c	7 Jan 2005 07:02:58 -0000	2.35.2.2
+++ fcntlmodule.c	16 Oct 2005 05:24:04 -0000	2.35.2.3
@@ -102,7 +102,7 @@
 	int mutate_arg = 1;
 	char buf[1024];
 
-	if (PyArg_ParseTuple(args, "O&iw#|i:ioctl",
+	if (PyArg_ParseTuple(args, "O&Iw#|i:ioctl",
                              conv_descriptor, &fd, &code, 
 			     &str, &len, &mutate_arg)) {
 		char *arg;
@@ -151,7 +151,7 @@
 	}
 
 	PyErr_Clear();
-	if (PyArg_ParseTuple(args, "O&is#:ioctl",
+	if (PyArg_ParseTuple(args, "O&Is#:ioctl",
                              conv_descriptor, &fd, &code, &str, &len)) {
 		if (len > sizeof buf) {
 			PyErr_SetString(PyExc_ValueError,
@@ -172,8 +172,8 @@
 	PyErr_Clear();
 	arg = 0;
 	if (!PyArg_ParseTuple(args,
-	     "O&i|i;ioctl requires a file or file descriptor,"
-	     " an integer and optionally a integer or buffer argument",
+	     "O&I|i;ioctl requires a file or file descriptor,"
+	     " an integer and optionally an integer or buffer argument",
 			      conv_descriptor, &fd, &code, &arg)) {
 	  return NULL;
 	}

Index: gcmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/gcmodule.c,v
retrieving revision 2.52.2.2
retrieving revision 2.52.2.3
diff -u -d -r2.52.2.2 -r2.52.2.3
--- gcmodule.c	7 Jan 2005 07:02:59 -0000	2.52.2.2
+++ gcmodule.c	16 Oct 2005 05:24:04 -0000	2.52.2.3
@@ -413,10 +413,8 @@
 		assert(delstr != NULL);
 		return _PyInstance_Lookup(op, delstr) != NULL;
 	}
-	else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE))
+	else 
 		return op->ob_type->tp_del != NULL;
-	else
-		return 0;
 }
 
 /* Move the objects in unreachable with __del__ methods into `finalizers`.
@@ -1166,6 +1164,7 @@
 		if (garbage == NULL)
 			return;
 	}
+	Py_INCREF(garbage);
 	if (PyModule_AddObject(m, "garbage", garbage) < 0)
 		return;
 #define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return

Index: getpath.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/getpath.c,v
retrieving revision 1.41.2.2
retrieving revision 1.41.2.3
diff -u -d -r1.41.2.2 -r1.41.2.3
--- getpath.c	7 Jan 2005 07:03:00 -0000	1.41.2.2
+++ getpath.c	16 Oct 2005 05:24:04 -0000	1.41.2.3
@@ -381,7 +381,7 @@
     NSModule pythonModule;
 #endif
 #ifdef __APPLE__
-    unsigned long nsexeclength = MAXPATHLEN;
+    uint32_t nsexeclength = MAXPATHLEN;
 #endif
 
 	/* If there is no slash in the argv0 path, then we have to

Index: grpmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/grpmodule.c,v
retrieving revision 2.18.2.2
retrieving revision 2.18.2.3
diff -u -d -r2.18.2.2 -r2.18.2.3
--- grpmodule.c	7 Jan 2005 07:03:00 -0000	2.18.2.2
+++ grpmodule.c	16 Oct 2005 05:24:04 -0000	2.18.2.3
@@ -85,9 +85,9 @@
 static PyObject *
 grp_getgrgid(PyObject *self, PyObject *args)
 {
-    int gid;
+    unsigned int gid;
     struct group *p;
-    if (!PyArg_ParseTuple(args, "i:getgrgid", &gid))
+    if (!PyArg_ParseTuple(args, "I:getgrgid", &gid))
         return NULL;
     if ((p = getgrgid(gid)) == NULL) {
 	PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);

Index: itertoolsmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/itertoolsmodule.c,v
retrieving revision 1.10.4.2
retrieving revision 1.10.4.3
diff -u -d -r1.10.4.2 -r1.10.4.3
--- itertoolsmodule.c	7 Jan 2005 07:03:00 -0000	1.10.4.2
+++ itertoolsmodule.c	16 Oct 2005 05:24:04 -0000	1.10.4.3
@@ -618,6 +618,9 @@
 	PyObject *saved;
 	cycleobject *lz;
 
+	if (!_PyArg_NoKeywords("cycle()", kwds))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "cycle", 1, 1, &iterable))
 		return NULL;
 
@@ -765,6 +768,9 @@
 	PyObject *it;
 	dropwhileobject *lz;
 
+	if (!_PyArg_NoKeywords("dropwhile()", kwds))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "dropwhile", 2, 2, &func, &seq))
 		return NULL;
 
@@ -906,6 +912,9 @@
 	PyObject *it;
 	takewhileobject *lz;
 
+	if (!_PyArg_NoKeywords("takewhile()", kwds))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "takewhile", 2, 2, &func, &seq))
 		return NULL;
 
@@ -1048,6 +1057,9 @@
 	int numargs;
 	isliceobject *lz;
 
+	if (!_PyArg_NoKeywords("islice()", kwds))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "islice", 2, 4, &seq, &a1, &a2, &a3))
 		return NULL;
 
@@ -1236,6 +1248,9 @@
 	PyObject *it;
 	starmapobject *lz;
 
+	if (!_PyArg_NoKeywords("starmap()", kwds))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "starmap", 2, 2, &func, &seq))
 		return NULL;
 
@@ -1365,6 +1380,9 @@
 	imapobject *lz;
 	int numargs, i;
 
+	if (!_PyArg_NoKeywords("imap()", kwds))
+		return NULL;
+
 	numargs = PyTuple_Size(args);
 	if (numargs < 2) {
 		PyErr_SetString(PyExc_TypeError,
@@ -1544,6 +1562,9 @@
 	int i;
 	PyObject *ittuple;
 
+	if (!_PyArg_NoKeywords("chain()", kwds))
+		return NULL;
+
 	/* obtain iterators */
 	assert(PyTuple_Check(args));
 	ittuple = PyTuple_New(tuplesize);
@@ -1684,6 +1705,9 @@
 	PyObject *it;
 	ifilterobject *lz;
 
+	if (!_PyArg_NoKeywords("ifilter()", kwds))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "ifilter", 2, 2, &func, &seq))
 		return NULL;
 
@@ -1825,6 +1849,9 @@
 	PyObject *it;
 	ifilterfalseobject *lz;
 
+	if (!_PyArg_NoKeywords("ifilterfalse()", kwds))
+		return NULL;
+
 	if (!PyArg_UnpackTuple(args, "ifilterfalse", 2, 2, &func, &seq))
 		return NULL;
 
@@ -1964,6 +1991,9 @@
 	countobject *lz;
 	long cnt = 0;
 
+	if (!_PyArg_NoKeywords("count()", kwds))
+		return NULL;
+
 	if (!PyArg_ParseTuple(args, "|l:count", &cnt))
 		return NULL;
 
@@ -2060,6 +2090,9 @@
 	PyObject *result;
 	int tuplesize = PySequence_Length(args);
 
+	if (!_PyArg_NoKeywords("izip()", kwds))
+		return NULL;
+
 	/* args must be a tuple */
 	assert(PyTuple_Check(args));
 
@@ -2240,6 +2273,9 @@
 	PyObject *element;
 	long cnt = -1;
 
+	if (!_PyArg_NoKeywords("repeat()", kwds))
+		return NULL;
+
 	if (!PyArg_ParseTuple(args, "O|l:repeat", &element, &cnt))
 		return NULL;
 
@@ -2300,17 +2336,21 @@
 	return result;
 }	
 
-static int
+static PyObject *
 repeat_len(repeatobject *ro)
 {
-        if (ro->cnt == -1)
+        if (ro->cnt == -1) {
                 PyErr_SetString(PyExc_TypeError, "len() of unsized object");
-        return (int)(ro->cnt);
+		return NULL;
+	}
+        return PyInt_FromLong(ro->cnt);
 }
 
-static PySequenceMethods repeat_as_sequence = {
-	(inquiry)repeat_len,		/* sq_length */
-	0,				/* sq_concat */
+PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
+
+static PyMethodDef repeat_methods[] = {
+	{"_length_cue", (PyCFunction)repeat_len, METH_NOARGS, length_cue_doc},
+ 	{NULL,		NULL}		/* sentinel */
 };
 
 PyDoc_STRVAR(repeat_doc,
@@ -2332,7 +2372,7 @@
 	0,				/* tp_compare */
 	(reprfunc)repeat_repr,		/* tp_repr */
 	0,				/* tp_as_number */
-	&repeat_as_sequence,		/* tp_as_sequence */
+	0,				/* tp_as_sequence */
 	0,				/* tp_as_mapping */
 	0,				/* tp_hash */
 	0,				/* tp_call */
@@ -2349,7 +2389,7 @@
 	0,				/* tp_weaklistoffset */
 	PyObject_SelfIter,		/* tp_iter */
 	(iternextfunc)repeat_next,	/* tp_iternext */
-	0,				/* tp_methods */
+	repeat_methods,			/* tp_methods */
 	0,				/* tp_members */
 	0,				/* tp_getset */
 	0,				/* tp_base */

Index: ld_so_aix
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/ld_so_aix,v
retrieving revision 2.5
retrieving revision 2.5.32.1
diff -u -d -r2.5 -r2.5.32.1
--- ld_so_aix	3 Sep 1997 00:45:30 -0000	2.5
+++ ld_so_aix	16 Oct 2005 05:24:04 -0000	2.5.32.1
@@ -168,6 +168,10 @@
 
 CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4"
 CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -lm -o $objfile"
+# Note: to use dynamic libraries like libtcl8.4.so and libtk8.4.so 
+# you may need to replace the second CCOPT line above with the following:
+# CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -brtl -bnortllib -lm -o $objfile"
+
 CCARGS="$args"
 
 # Export list generation.

Index: main.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v
retrieving revision 1.64.2.3
retrieving revision 1.64.2.4
diff -u -d -r1.64.2.3 -r1.64.2.4
--- main.c	7 Jan 2005 07:03:00 -0000	1.64.2.3
+++ main.c	16 Oct 2005 05:24:04 -0000	1.64.2.4
@@ -359,6 +359,14 @@
 					}
 				}
 			}
+			{
+				/* XXX: does this work on Win/Win64? (see posix_fstat) */
+				struct stat sb;
+				if (fstat(fileno(fp), &sb) == 0 &&
+				    S_ISDIR(sb.st_mode)) {
+					fprintf(stderr, "%s: warning '%s' is a directory\n", argv[0], filename);
+				}
+			}
 		}
 	}
 

Index: makexp_aix
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/makexp_aix,v
retrieving revision 2.2
retrieving revision 2.2.32.1
diff -u -d -r2.2 -r2.2.32.1
--- makexp_aix	9 Apr 1998 21:46:02 -0000	2.2
+++ makexp_aix	16 Oct 2005 05:24:04 -0000	2.2.32.1
@@ -70,6 +70,12 @@
 #    left with just the symbol name.
 # 7. Eliminate all entries containing two colons, like Class::method
 #
-/usr/ccs/bin/nm -Bex $inputFiles				\
+
+# Use -X32_64 if it appears to be implemented in this version of 'nm'.
+NM=/usr/ccs/bin/nm
+xopt=-X32_64
+$NM -e $xopt $1 >/dev/null 2>&1 || xopt=""
+
+$NM -Bex $xopt $inputFiles					\
 | sed -e '/ [^BDT] /d' -e '/\./d' -e 's/.* [BDT] //' -e '/::/d'	\
 | sort | uniq >> $expFileName

Index: mathmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v
retrieving revision 2.68.2.2
retrieving revision 2.68.2.3
diff -u -d -r2.68.2.2 -r2.68.2.3
--- mathmodule.c	7 Jan 2005 07:03:00 -0000	2.68.2.2
+++ mathmodule.c	16 Oct 2005 05:24:04 -0000	2.68.2.3
@@ -1,7 +1,7 @@
 /* Math module -- standard C math library functions, pi and e */
 
 #include "Python.h"
-#include "longintrepr.h"
+#include "longintrepr.h" /* just for SHIFT */
 
 #ifndef _MSC_VER
 #ifndef __STDC__

Index: md5module.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/md5module.c,v
retrieving revision 2.30.2.2
retrieving revision 2.30.2.3
diff -u -d -r2.30.2.2 -r2.30.2.3
--- md5module.c	7 Jan 2005 07:03:00 -0000	2.30.2.2
+++ md5module.c	16 Oct 2005 05:24:04 -0000	2.30.2.3
@@ -10,6 +10,7 @@
 /* MD5 objects */
 
 #include "Python.h"
+#include "structmember.h"
 #include "md5.h"
 
 typedef struct {
@@ -150,15 +151,46 @@
 };
 
 static PyObject *
-md5_getattr(md5object *self, char *name)
+md5_get_block_size(PyObject *self, void *closure)
 {
-        if (strcmp(name, "digest_size") == 0) {
-    		return PyInt_FromLong(16);
-        }
+    return PyInt_FromLong(64);
+}
 
-	return Py_FindMethod(md5_methods, (PyObject *)self, name);
+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\
@@ -191,13 +223,13 @@
 static PyTypeObject MD5type = {
 	PyObject_HEAD_INIT(NULL)
 	0,			  /*ob_size*/
-	"md5.md5",		  /*tp_name*/
+	"_md5.md5",		  /*tp_name*/
 	sizeof(md5object),	  /*tp_size*/
 	0,			  /*tp_itemsize*/
 	/* methods */
 	(destructor)md5_dealloc,  /*tp_dealloc*/
 	0,			  /*tp_print*/
-	(getattrfunc)md5_getattr, /*tp_getattr*/
+	0,                        /*tp_getattr*/
 	0,			  /*tp_setattr*/
 	0,			  /*tp_compare*/
 	0,			  /*tp_repr*/
@@ -210,8 +242,17 @@
 	0,			  /*tp_getattro*/
 	0,			  /*tp_setattro*/
 	0,	                  /*tp_as_buffer*/
-	0,			  /*tp_xxx4*/
+	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*/
 };
 
 
@@ -247,7 +288,6 @@
 
 static PyMethodDef md5_functions[] = {
 	{"new",		(PyCFunction)MD5_new, METH_VARARGS, new_doc},
-	{"md5",		(PyCFunction)MD5_new, METH_VARARGS, new_doc}, /* Backward compatibility */
 	{NULL,		NULL}	/* Sentinel */
 };
 
@@ -255,12 +295,14 @@
 /* Initialize this module. */
 
 PyMODINIT_FUNC
-initmd5(void)
+init_md5(void)
 {
 	PyObject *m, *d;
 
         MD5type.ob_type = &PyType_Type;
-	m = Py_InitModule3("md5", md5_functions, module_doc);
+        if (PyType_Ready(&MD5type) < 0)
+            return;
+	m = Py_InitModule3("_md5", md5_functions, module_doc);
 	d = PyModule_GetDict(m);
 	PyDict_SetItemString(d, "MD5Type", (PyObject *)&MD5type);
 	PyModule_AddIntConstant(m, "digest_size", 16);

Index: mmapmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v
retrieving revision 2.39.2.2
retrieving revision 2.39.2.3
diff -u -d -r2.39.2.2 -r2.39.2.3
--- mmapmodule.c	7 Jan 2005 07:03:00 -0000	2.39.2.2
+++ mmapmodule.c	16 Oct 2005 05:24:04 -0000	2.39.2.3
@@ -423,6 +423,11 @@
 	} else {
 		void *newmap;
 
+		if (ftruncate(self->fd, new_size) == -1) {
+			PyErr_SetFromErrno(mmap_module_error);
+			return NULL;
+		}
+
 #ifdef MREMAP_MAYMOVE
 		newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE);
 #else
@@ -896,18 +901,26 @@
 	/* on OpenVMS we must ensure that all bytes are written to the file */
 	fsync(fd);
 #  endif
-	if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
-	    (size_t)map_size > st.st_size) {
-		PyErr_SetString(PyExc_ValueError, 
-				"mmap length is greater than file size");
-		return NULL;
+	if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
+		if (map_size == 0) {
+			map_size = (int)st.st_size;
+		} else if ((size_t)map_size > st.st_size) {
+			PyErr_SetString(PyExc_ValueError, 
+					"mmap length is greater than file size");
+			return NULL;
+		}
 	}
 #endif
 	m_obj = PyObject_New (mmap_object, &mmap_object_type);
 	if (m_obj == NULL) {return NULL;}
 	m_obj->size = (size_t) map_size;
 	m_obj->pos = (size_t) 0;
-	m_obj->fd = fd;
+	m_obj->fd = dup(fd);
+	if (m_obj->fd == -1) {
+		Py_DECREF(m_obj);
+		PyErr_SetFromErrno(mmap_module_error);
+		return NULL;
+	}
 	m_obj->data = mmap(NULL, map_size, 
 			   prot, flags,
 			   fd, 0);

Index: operator.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/operator.c,v
retrieving revision 2.21.2.2
retrieving revision 2.21.2.3
diff -u -d -r2.21.2.2 -r2.21.2.3
--- operator.c	7 Jan 2005 07:03:00 -0000	2.21.2.2
+++ operator.c	16 Oct 2005 05:24:04 -0000	2.21.2.3
@@ -256,6 +256,7 @@
 
 typedef struct {
 	PyObject_HEAD
+	int nitems;
 	PyObject *item;
 } itemgetterobject;
 
@@ -266,10 +267,18 @@
 {
 	itemgetterobject *ig;
 	PyObject *item;
+	int nitems;
 
-	if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
+	if (!_PyArg_NoKeywords("itemgetter()", kwds))
 		return NULL;
 
+	nitems = PyTuple_GET_SIZE(args);
+	if (nitems <= 1) {
+		if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &item))
+			return NULL;
+	} else 
+		item = args;
+
 	/* create itemgetterobject structure */
 	ig = PyObject_GC_New(itemgetterobject, &itemgetter_type);
 	if (ig == NULL) 
@@ -277,6 +286,7 @@
 	
 	Py_INCREF(item);
 	ig->item = item;
+	ig->nitems = nitems;
 
 	PyObject_GC_Track(ig);
 	return (PyObject *)ig;
@@ -301,18 +311,40 @@
 static PyObject *
 itemgetter_call(itemgetterobject *ig, PyObject *args, PyObject *kw)
 {
-	PyObject * obj;
+	PyObject *obj, *result;
+	int i, nitems=ig->nitems;
 
 	if (!PyArg_UnpackTuple(args, "itemgetter", 1, 1, &obj))
 		return NULL;
-	return PyObject_GetItem(obj, ig->item);
+	if (nitems == 1)
+		return PyObject_GetItem(obj, ig->item);
+
+	assert(PyTuple_Check(ig->item));
+	assert(PyTuple_GET_SIZE(ig->item) == nitems);
+
+	result = PyTuple_New(nitems);
+	if (result == NULL)
+		return NULL;
+
+	for (i=0 ; i < nitems ; i++) {
+		PyObject *item, *val;
+		item = PyTuple_GET_ITEM(ig->item, i);
+		val = PyObject_GetItem(obj, item);
+		if (val == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(result, i, val);
+	}
+	return result;
 }
 
 PyDoc_STRVAR(itemgetter_doc,
-"itemgetter(item) --> itemgetter object\n\
+"itemgetter(item, ...) --> itemgetter object\n\
 \n\
-Return a callable object that fetches the given item from its operand.\n\
-After, f=itemgetter(2), the call f(b) returns b[2].");
+Return a callable object that fetches the given item(s) from its operand.\n\
+After, f=itemgetter(2), the call f(r) returns r[2].\n\
+After, g=itemgetter(2,5,3), the call g(r) returns (r[2], r[5], r[3])");
 
 static PyTypeObject itemgetter_type = {
 	PyObject_HEAD_INIT(NULL)
@@ -363,6 +395,7 @@
 
 typedef struct {
 	PyObject_HEAD
+	int nattrs;
 	PyObject *attr;
 } attrgetterobject;
 
@@ -373,10 +406,18 @@
 {
 	attrgetterobject *ag;
 	PyObject *attr;
+	int nattrs;
 
-	if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
+	if (!_PyArg_NoKeywords("attrgetter()", kwds))
 		return NULL;
 
+	nattrs = PyTuple_GET_SIZE(args);
+	if (nattrs <= 1) {
+		if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &attr))
+			return NULL;
+	} else 
+		attr = args;
+
 	/* create attrgetterobject structure */
 	ag = PyObject_GC_New(attrgetterobject, &attrgetter_type);
 	if (ag == NULL) 
@@ -384,6 +425,7 @@
 	
 	Py_INCREF(attr);
 	ag->attr = attr;
+	ag->nattrs = nattrs;
 
 	PyObject_GC_Track(ag);
 	return (PyObject *)ag;
@@ -408,18 +450,40 @@
 static PyObject *
 attrgetter_call(attrgetterobject *ag, PyObject *args, PyObject *kw)
 {
-	PyObject * obj;
+	PyObject *obj, *result;
+	int i, nattrs=ag->nattrs;
 
 	if (!PyArg_UnpackTuple(args, "attrgetter", 1, 1, &obj))
 		return NULL;
-	return PyObject_GetAttr(obj, ag->attr);
+	if (ag->nattrs == 1)
+		return PyObject_GetAttr(obj, ag->attr);
+
+	assert(PyTuple_Check(ag->attr));
+	assert(PyTuple_GET_SIZE(ag->attr) == nattrs);
+
+	result = PyTuple_New(nattrs);
+	if (result == NULL)
+		return NULL;
+
+	for (i=0 ; i < nattrs ; i++) {
+		PyObject *attr, *val;
+		attr = PyTuple_GET_ITEM(ag->attr, i);
+		val = PyObject_GetAttr(obj, attr);
+		if (val == NULL) {
+			Py_DECREF(result);
+			return NULL;
+		}
+		PyTuple_SET_ITEM(result, i, val);
+	}
+	return result;
 }
 
 PyDoc_STRVAR(attrgetter_doc,
-"attrgetter(attr) --> attrgetter object\n\
+"attrgetter(attr, ...) --> attrgetter object\n\
 \n\
-Return a callable object that fetches the given attribute from its operand.\n\
-After, f=attrgetter('name'), the call f(b) returns b.name.");
+Return a callable object that fetches the given attribute(s) from its operand.\n\
+After, f=attrgetter('name'), the call f(r) returns r.name.\n\
+After, g=attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).");
 
 static PyTypeObject attrgetter_type = {
 	PyObject_HEAD_INIT(NULL)

Index: ossaudiodev.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/ossaudiodev.c,v
retrieving revision 1.26.4.2
retrieving revision 1.26.4.3
diff -u -d -r1.26.4.2 -r1.26.4.3
--- ossaudiodev.c	7 Jan 2005 07:03:00 -0000	1.26.4.2
+++ ossaudiodev.c	16 Oct 2005 05:24:04 -0000	1.26.4.3
@@ -46,11 +46,12 @@
 
 typedef struct {
     PyObject_HEAD;
-    int      fd;                      /* The open file */
-    int      mode;                    /* file mode */
-    int      icount;                  /* Input count */
-    int      ocount;                  /* Output count */
-    uint32_t afmts;                   /* Audio formats supported by hardware */
+    char    *devicename;              /* name of the device file */
+    int      fd;                      /* file descriptor */
+    int      mode;                    /* file mode (O_RDONLY, etc.) */
+    int      icount;                  /* input count */
+    int      ocount;                  /* output count */
+    uint32_t afmts;                   /* audio formats supported by hardware */
 } oss_audio_t;
 
 typedef struct {
@@ -74,7 +75,7 @@
 {
     oss_audio_t *self;
     int fd, afmts, imode;
-    char *basedev = NULL;
+    char *devicename = NULL;
     char *mode = NULL;
 
     /* Two ways to call open():
@@ -82,11 +83,11 @@
          open(mode)         (for backwards compatibility)
        because the *first* argument is optional, parsing args is
        a wee bit tricky. */
-    if (!PyArg_ParseTuple(arg, "s|s:open", &basedev, &mode))
+    if (!PyArg_ParseTuple(arg, "s|s:open", &devicename, &mode))
        return NULL;
     if (mode == NULL) {                 /* only one arg supplied */
-       mode = basedev;
-       basedev = NULL;
+       mode = devicename;
+       devicename = NULL;
     }
 
     if (strcmp(mode, "r") == 0)
@@ -102,18 +103,18 @@
 
     /* Open the correct device: either the 'device' argument,
        or the AUDIODEV environment variable, or "/dev/dsp". */
-    if (basedev == NULL) {              /* called with one arg */
-       basedev = getenv("AUDIODEV");
-       if (basedev == NULL)             /* $AUDIODEV not set */
-          basedev = "/dev/dsp";
+    if (devicename == NULL) {              /* called with one arg */
+       devicename = getenv("AUDIODEV");
+       if (devicename == NULL)             /* $AUDIODEV not set */
+          devicename = "/dev/dsp";
     }
 
     /* Open with O_NONBLOCK to avoid hanging on devices that only allow
        one open at a time.  This does *not* affect later I/O; OSS
        provides a special ioctl() for non-blocking read/write, which is
        exposed via oss_nonblock() below. */
-    if ((fd = open(basedev, imode|O_NONBLOCK)) == -1) {
-        PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev);
+    if ((fd = open(devicename, imode|O_NONBLOCK)) == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
         return NULL;
     }
 
@@ -121,12 +122,12 @@
        expected write() semantics. */
     if (fcntl(fd, F_SETFL, 0) == -1) {
         close(fd);
-        PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev);
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
         return NULL;
     }
 
     if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
-        PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev);
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
         return NULL;
     }
     /* Create and initialize the object */
@@ -134,6 +135,7 @@
         close(fd);
         return NULL;
     }
+    self->devicename = devicename;
     self->fd = fd;
     self->mode = imode;
     self->icount = self->ocount = 0;
@@ -158,22 +160,22 @@
 static oss_mixer_t *
 newossmixerobject(PyObject *arg)
 {
-    char *basedev = NULL;
+    char *devicename = NULL;
     int fd;
     oss_mixer_t *self;
 
-    if (!PyArg_ParseTuple(arg, "|s", &basedev)) {
+    if (!PyArg_ParseTuple(arg, "|s", &devicename)) {
         return NULL;
     }
 
-    if (basedev == NULL) {
-        basedev = getenv("MIXERDEV");
-        if (basedev == NULL)            /* MIXERDEV not set */
-            basedev = "/dev/mixer";
+    if (devicename == NULL) {
+        devicename = getenv("MIXERDEV");
+        if (devicename == NULL)            /* MIXERDEV not set */
+            devicename = "/dev/mixer";
     }
 
-    if ((fd = open(basedev, O_RDWR)) == -1) {
-        PyErr_SetFromErrnoWithFilename(PyExc_IOError, basedev);
+    if ((fd = open(devicename, O_RDWR)) == -1) {
+        PyErr_SetFromErrnoWithFilename(PyExc_IOError, devicename);
         return NULL;
     }
 
@@ -827,7 +829,33 @@
 static PyObject *
 oss_getattr(oss_audio_t *self, char *name)
 {
-    return Py_FindMethod(oss_methods, (PyObject *)self, name);
+    PyObject * rval = NULL;
+    if (strcmp(name, "closed") == 0) {
+        rval = (self->fd == -1) ? Py_True : Py_False;
+        Py_INCREF(rval);
+    }
+    else if (strcmp(name, "name") == 0) {
+        rval = PyString_FromString(self->devicename);
+    }
+    else if (strcmp(name, "mode") == 0) {
+        /* No need for a "default" in this switch: from newossobject(),
+           self->mode can only be one of these three values. */
+        switch(self->mode) {
+            case O_RDONLY:
+                rval = PyString_FromString("r");
+                break;
+            case O_RDWR:
+                rval = PyString_FromString("rw");
+                break;
+            case O_WRONLY:
+                rval = PyString_FromString("w");
+                break;
+        }
+    }
+    else {
+        rval = Py_FindMethod(oss_methods, (PyObject *)self, name);
+    }
+    return rval;
 }
 
 static PyObject *
@@ -969,6 +997,18 @@
 #ifdef AFMT_S16_NE
     _EXPORT_INT(m, AFMT_S16_NE);
 #endif
+#ifdef AFMT_U16_NE
+    _EXPORT_INT(m, AFMT_U16_NE);
+#endif
+#ifdef AFMT_S32_LE
+    _EXPORT_INT(m, AFMT_S32_LE);
+#endif
+#ifdef AFMT_S32_BE
+    _EXPORT_INT(m, AFMT_S32_BE);
+#endif
+#ifdef AFMT_MPEG
+    _EXPORT_INT(m, AFMT_MPEG);
+#endif
 
     /* Expose the sound mixer device numbers. */
     _EXPORT_INT(m, SOUND_MIXER_NRDEVICES);

Index: parsermodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v
retrieving revision 2.70.2.2
retrieving revision 2.70.2.3
diff -u -d -r2.70.2.2 -r2.70.2.3
--- parsermodule.c	7 Jan 2005 07:03:01 -0000	2.70.2.2
+++ parsermodule.c	16 Oct 2005 05:24:04 -0000	2.70.2.3
@@ -859,7 +859,8 @@
 VALIDATER(listmaker);           VALIDATER(yield_stmt);
 VALIDATER(testlist1);           VALIDATER(gen_for);
 VALIDATER(gen_iter);            VALIDATER(gen_if);
-VALIDATER(testlist_gexp);
+VALIDATER(testlist_gexp);	VALIDATER(yield_expr);
+VALIDATER(yield_or_testlist);	
 
 #undef VALIDATER
 
@@ -947,7 +948,8 @@
 validate_class(node *tree)
 {
     int nch = NCH(tree);
-    int res = validate_ntype(tree, classdef) && ((nch == 4) || (nch == 7));
+    int res = (validate_ntype(tree, classdef) &&
+	       	((nch == 4) || (nch == 6) || (nch == 7)));
 
     if (res) {
         res = (validate_name(CHILD(tree, 0), "class")
@@ -955,12 +957,20 @@
                && validate_colon(CHILD(tree, nch - 2))
                && validate_suite(CHILD(tree, nch - 1)));
     }
-    else
+    else {
         (void) validate_numnodes(tree, 4, "class");
-    if (res && (nch == 7)) {
-        res = (validate_lparen(CHILD(tree, 2))
-               && validate_testlist(CHILD(tree, 3))
-               && validate_rparen(CHILD(tree, 4)));
+    }
+	
+    if (res) {
+	if (nch == 7) {
+		res = ((validate_lparen(CHILD(tree, 2)) &&
+			validate_testlist(CHILD(tree, 3)) &&
+			validate_rparen(CHILD(tree, 4))));
+	}
+	else if (nch == 6) {
+		res = (validate_lparen(CHILD(tree,2)) &&
+			validate_rparen(CHILD(tree,3)));
+	}
     }
     return (res);
 }
@@ -1498,6 +1508,15 @@
 
 
 static int
+validate_yield_or_testlist(node *tree)
+{
+	if (TYPE(tree) == yield_expr) 
+		return validate_yield_expr(tree);
+	else
+		return validate_testlist(tree);
+}
+
+static int
 validate_expr_stmt(node *tree)
 {
     int j;
@@ -1508,8 +1527,8 @@
 
     if (res && nch == 3
         && TYPE(CHILD(tree, 1)) == augassign) {
-        res = (validate_numnodes(CHILD(tree, 1), 1, "augassign")
-               && validate_testlist(CHILD(tree, 2)));
+        res = validate_numnodes(CHILD(tree, 1), 1, "augassign")
+		&& validate_yield_or_testlist(CHILD(tree, 2));
 
         if (res) {
             char *s = STR(CHILD(CHILD(tree, 1), 0));
@@ -1532,8 +1551,8 @@
     }
     else {
         for (j = 1; res && (j < nch); j += 2)
-            res = (validate_equal(CHILD(tree, j))
-                   && validate_testlist(CHILD(tree, j + 1)));
+            res = validate_equal(CHILD(tree, j))
+                   && validate_yield_or_testlist(CHILD(tree, j + 1));
     }
     return (res);
 }
@@ -1640,15 +1659,31 @@
 }
 
 
-/* yield_stmt: 'yield' testlist
+/* yield_expr: 'yield' [testlist]
+ */
+static int
+validate_yield_expr(node *tree)
+{
+    int nch = NCH(tree);
+    int res = (validate_ntype(tree, yield_expr)
+               && ((nch == 1) || (nch == 2))
+               && validate_name(CHILD(tree, 0), "yield"));
+
+    if (res && (nch == 2))
+        res = validate_testlist(CHILD(tree, 1));
+
+    return (res);
+}
+
+
+/* yield_stmt: yield_expr
  */
 static int
 validate_yield_stmt(node *tree)
 {
     return (validate_ntype(tree, yield_stmt)
-            && validate_numnodes(tree, 2, "yield_stmt")
-            && validate_name(CHILD(tree, 0), "yield")
-            && validate_testlist(CHILD(tree, 1)));
+            && validate_numnodes(tree, 1, "yield_stmt")
+            && validate_yield_expr(CHILD(tree, 0)));
 }
 
 
@@ -2291,8 +2326,12 @@
             res = ((nch <= 3)
                    && (validate_rparen(CHILD(tree, nch - 1))));
 
-            if (res && (nch == 3))
-                res = validate_testlist_gexp(CHILD(tree, 1));
+            if (res && (nch == 3)) {
+		if (TYPE(CHILD(tree, 1))==yield_expr)
+			res = validate_yield_expr(CHILD(tree, 1));
+		else
+                	res = validate_testlist_gexp(CHILD(tree, 1));
+	    }
             break;
           case LSQB:
             if (nch == 2)
@@ -2905,6 +2944,9 @@
           case testlist:
             res = validate_testlist(tree);
             break;
+          case yield_expr:
+            res = validate_yield_expr(tree);
+            break;
           case testlist1:
             res = validate_testlist1(tree);
             break;

Index: posixmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v
retrieving revision 2.241.2.2
retrieving revision 2.241.2.3
diff -u -d -r2.241.2.2 -r2.241.2.3
--- posixmodule.c	7 Jan 2005 07:03:02 -0000	2.241.2.2
+++ posixmodule.c	16 Oct 2005 05:24:04 -0000	2.241.2.3
@@ -674,8 +674,8 @@
   (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
 or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
 \n\
-Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,\n\
-they are available as attributes only.\n\
+Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
+or st_flags, they are available as attributes only.\n\
 \n\
 See os.stat for more information.");
 
@@ -703,6 +703,15 @@
 #ifdef HAVE_STRUCT_STAT_ST_RDEV
 	{"st_rdev",    "device type (if inode device)"},
 #endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+	{"st_flags",   "user defined flags for file"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+	{"st_gen",    "generation number"},
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+	{"st_birthtime",   "time of creation"},
+#endif
 	{0}
 };
 
@@ -724,6 +733,24 @@
 #define ST_RDEV_IDX ST_BLOCKS_IDX
 #endif
 
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
+#else
+#define ST_FLAGS_IDX ST_RDEV_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+#define ST_GEN_IDX (ST_FLAGS_IDX+1)
+#else
+#define ST_GEN_IDX ST_FLAGS_IDX
+#endif
+
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
+#else
+#define ST_BIRTHTIME_IDX ST_GEN_IDX
+#endif
+
 static PyStructSequence_Desc stat_result_desc = {
 	"stat_result", /* name */
 	stat_result__doc__, /* doc */
@@ -789,7 +816,7 @@
 
 
 /* If true, st_?time is float. */
-static int _stat_float_times = 0;
+static int _stat_float_times = 1;
 
 PyDoc_STRVAR(stat_float_times__doc__,
 "stat_float_times([newval]) -> oldval\n\n\
@@ -869,8 +896,14 @@
 	mnsec = st.st_mtim.tv_nsec;
 	cnsec = st.st_ctim.tv_nsec;
 #else
+#ifdef HAVE_STAT_TV_NSEC2
+	ansec = st.st_atimespec.tv_nsec;
+	mnsec = st.st_mtimespec.tv_nsec;
+	cnsec = st.st_ctimespec.tv_nsec;
+#else
 	ansec = mnsec = cnsec = 0;
 #endif
+#endif
 	fill_time(v, 7, st.st_atime, ansec);
 	fill_time(v, 8, st.st_mtime, mnsec);
 	fill_time(v, 9, st.st_ctime, cnsec);
@@ -887,6 +920,33 @@
 	PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
 			 PyInt_FromLong((long)st.st_rdev));
 #endif
+#ifdef HAVE_STRUCT_STAT_ST_GEN
+	PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
+			 PyInt_FromLong((long)st.st_gen));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
+	{
+	  PyObject *val;
+	  unsigned long bsec,bnsec;
+	  bsec = (long)st.st_birthtime;
+#ifdef HAVE_STAT_TV_NSEC2
+	  bnsec = st.st_birthtimespec.tv_nsec;
+#else
+	  bnsec = 0;
+#endif
+	  if (_stat_float_times) {
+	    val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
+	  } else {
+	    val = PyInt_FromLong((long)bsec);
+	  }
+	  PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
+				    val);
+	}
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_FLAGS
+	PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
+			 PyInt_FromLong((long)st.st_flags));
+#endif
 
 	if (PyErr_Occurred()) {
 		Py_DECREF(v);
@@ -1106,19 +1166,21 @@
 			   it is a simple dereference. */
 			res = _waccess(PyUnicode_AS_UNICODE(po), mode);
 			Py_END_ALLOW_THREADS
-			return(PyBool_FromLong(res == 0));
+			return PyBool_FromLong(res == 0);
 		}
 		/* Drop the argument parsing error as narrow strings
 		   are also valid. */
 		PyErr_Clear();
 	}
 #endif
-	if (!PyArg_ParseTuple(args, "si:access", &path, &mode))
+	if (!PyArg_ParseTuple(args, "eti:access", 
+			      Py_FileSystemDefaultEncoding, &path, &mode))
 		return NULL;
 	Py_BEGIN_ALLOW_THREADS
 	res = access(path, mode);
 	Py_END_ALLOW_THREADS
-	return(PyBool_FromLong(res == 0));
+	PyMem_Free(path);
+	return PyBool_FromLong(res == 0);
 }
 
 #ifndef F_OK
@@ -1160,8 +1222,8 @@
 	ret = ttyname(id);
 #endif
 	if (ret == NULL)
-		return(posix_error());
-	return(PyString_FromString(ret));
+		return posix_error();
+	return PyString_FromString(ret);
 }
 #endif
 
@@ -1182,8 +1244,8 @@
         ret = ctermid(buffer);
 #endif
 	if (ret == NULL)
-		return(posix_error());
-	return(PyString_FromString(buffer));
+		return posix_error();
+	return PyString_FromString(buffer);
 }
 #endif
 
@@ -1977,6 +2039,8 @@
 			return -1;
 		intval = PyInt_AsLong(intobj);
 		Py_DECREF(intobj);
+		if (intval == -1 && PyErr_Occurred())
+			return -1;
 		*sec = intval;
 		*usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
 		if (*usec < 0)
@@ -2949,7 +3013,7 @@
 static PyObject *
 posix_forkpty(PyObject *self, PyObject *noargs)
 {
-	int master_fd, pid;
+	int master_fd = -1, pid;
 
 	pid = forkpty(&master_fd, NULL, NULL, NULL);
 	if (pid == -1)
@@ -5349,6 +5413,10 @@
 	PyObject *buffer;
 	if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
 		return NULL;
+	if (size < 0) {
+		errno = EINVAL;
+		return posix_error();
+	}
 	buffer = PyString_FromStringAndSize((char *)NULL, size);
 	if (buffer == NULL)
 		return NULL;
@@ -7181,13 +7249,18 @@
 {
 	char *filepath;
 	HINSTANCE rc;
-	if (!PyArg_ParseTuple(args, "s:startfile", &filepath))
+	if (!PyArg_ParseTuple(args, "et:startfile", 
+				Py_FileSystemDefaultEncoding, &filepath))
 		return NULL;
 	Py_BEGIN_ALLOW_THREADS
 	rc = ShellExecute((HWND)0, NULL, filepath, NULL, NULL, SW_SHOWNORMAL);
 	Py_END_ALLOW_THREADS
-	if (rc <= (HINSTANCE)32)
-		return win32_error("startfile", filepath);
+	if (rc <= (HINSTANCE)32) {
+		PyObject *errval = win32_error("startfile", filepath);
+		PyMem_Free(filepath);
+		return errval;
+	}
+	PyMem_Free(filepath);
 	Py_INCREF(Py_None);
 	return Py_None;
 }
@@ -7713,6 +7786,12 @@
 #ifdef O_LARGEFILE
         if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
 #endif
+#ifdef O_SHLOCK
+        if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
+#endif
+#ifdef O_EXLOCK
+        if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
+#endif
 
 /* MS Windows */
 #ifdef O_NOINHERIT

Index: pwdmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/pwdmodule.c,v
retrieving revision 1.34.2.2
retrieving revision 1.34.2.3
diff -u -d -r1.34.2.2 -r1.34.2.3
--- pwdmodule.c	7 Jan 2005 07:03:18 -0000	1.34.2.2
+++ pwdmodule.c	16 Oct 2005 05:24:04 -0000	1.34.2.3
@@ -102,9 +102,9 @@
 static PyObject *
 pwd_getpwuid(PyObject *self, PyObject *args)
 {
-	int uid;
+	unsigned int uid;
 	struct passwd *p;
-	if (!PyArg_ParseTuple(args, "i:getpwuid", &uid))
+	if (!PyArg_ParseTuple(args, "I:getpwuid", &uid))
 		return NULL;
 	if ((p = getpwuid(uid)) == NULL) {
 		PyErr_Format(PyExc_KeyError,

Index: pyexpat.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v
retrieving revision 2.67.2.2
retrieving revision 2.67.2.3
diff -u -d -r2.67.2.2 -r2.67.2.3
--- pyexpat.c	7 Jan 2005 07:03:18 -0000	2.67.2.2
+++ pyexpat.c	16 Oct 2005 05:24:04 -0000	2.67.2.3
@@ -417,6 +417,9 @@
 {
     PyObject *result = STRING_CONV_FUNC(str);
     PyObject *value;
+    /* result can be NULL if the unicode conversion failed. */
+    if (!result)
+	return result;
     if (!self->intern)
 	return result;
     value = PyDict_GetItem(self->intern, result);
@@ -572,7 +575,9 @@
                 Py_DECREF(v);
             }
         }
-	args = Py_BuildValue("(NN)", string_intern(self, name), container);
+        args = string_intern(self, name);
+        if (args != NULL)
+            args = Py_BuildValue("(NN)", args, container);
         if (args == NULL) {
             Py_DECREF(container);
             return;
@@ -1082,7 +1087,7 @@
                 = XML_GetInputContext(self->itself, &offset, &size);
 
             if (buffer != NULL)
-                result = PyString_FromStringAndSize(buffer + offset, size);
+                result = PyString_FromStringAndSize(buffer + offset, size - offset);
             else {
                 result = Py_None;
                 Py_INCREF(result);

Index: readline.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v
retrieving revision 2.51.2.2
retrieving revision 2.51.2.3
diff -u -d -r2.51.2.2 -r2.51.2.3
--- readline.c	7 Jan 2005 07:03:19 -0000	2.51.2.2
+++ readline.c	16 Oct 2005 05:24:04 -0000	2.51.2.3
@@ -1,9 +1,7 @@
 /* This module makes GNU readline available to Python.  It has ideas
  * contributed by Lee Busby, LLNL, and William Magro, Cornell Theory
- * Center.  The completer interface was inspired by Lele Gaifax.
- *
- * More recently, it was largely rewritten by Guido van Rossum who is
- * now maintaining it.
+ * Center.  The completer interface was inspired by Lele Gaifax.  More
+ * recently, it was largely rewritten by Guido van Rossum.
  */
 
 /* Standard definitions */
@@ -161,8 +159,7 @@
 /* Generic hook function setter */
 
 static PyObject *
-set_hook(const char *funcname, PyObject **hook_var,
-	 PyThreadState **tstate, PyObject *args)
+set_hook(const char *funcname, PyObject **hook_var, PyObject *args)
 {
 	PyObject *function = Py_None;
 	char buf[80];
@@ -172,14 +169,12 @@
 	if (function == Py_None) {
 		Py_XDECREF(*hook_var);
 		*hook_var = NULL;
-		*tstate = NULL;
 	}
 	else if (PyCallable_Check(function)) {
 		PyObject *tmp = *hook_var;
 		Py_INCREF(function);
 		*hook_var = function;
 		Py_XDECREF(tmp);
-		*tstate = PyThreadState_GET();
 	}
 	else {
 		PyOS_snprintf(buf, sizeof(buf),
@@ -196,18 +191,15 @@
 /* Exported functions to specify hook functions in Python */
 
 static PyObject *startup_hook = NULL;
-static PyThreadState *startup_hook_tstate = NULL;
 
 #ifdef HAVE_RL_PRE_INPUT_HOOK
 static PyObject *pre_input_hook = NULL;
-static PyThreadState *pre_input_hook_tstate = NULL;
 #endif
 
 static PyObject *
 set_startup_hook(PyObject *self, PyObject *args)
 {
-	return set_hook("startup_hook", &startup_hook,
-			&startup_hook_tstate, args);
+	return set_hook("startup_hook", &startup_hook, args);
 }
 
 PyDoc_STRVAR(doc_set_startup_hook,
@@ -224,8 +216,7 @@
 static PyObject *
 set_pre_input_hook(PyObject *self, PyObject *args)
 {
-	return set_hook("pre_input_hook", &pre_input_hook,
-			&pre_input_hook_tstate, args);
+	return set_hook("pre_input_hook", &pre_input_hook, args);
 }
 
 PyDoc_STRVAR(doc_set_pre_input_hook,
@@ -241,7 +232,6 @@
 /* Exported function to specify a word completer in Python */
 
 static PyObject *completer = NULL;
-static PyThreadState *completer_tstate = NULL;
 
 static PyObject *begidx = NULL;
 static PyObject *endidx = NULL;
@@ -303,6 +293,11 @@
 
         if (!PyArg_ParseTuple(args, "i:remove_history", &entry_number))
                 return NULL;
+        if (entry_number < 0) {
+                PyErr_SetString(PyExc_ValueError,
+                                "History index cannot be negative");
+                return NULL;
+        }
         entry = remove_history(entry_number);
         if (!entry) {
                 PyErr_Format(PyExc_ValueError,
@@ -335,6 +330,11 @@
         if (!PyArg_ParseTuple(args, "is:replace_history", &entry_number, &line)) {
                 return NULL;
         }
+        if (entry_number < 0) {
+                PyErr_SetString(PyExc_ValueError,
+                                "History index cannot be negative");
+                return NULL;
+        }
         old_entry = replace_history_entry(entry_number, line, (void *)NULL);
         if (!old_entry) {
                 PyErr_Format(PyExc_ValueError,
@@ -395,7 +395,7 @@
 static PyObject *
 set_completer(PyObject *self, PyObject *args)
 {
-	return set_hook("completer", &completer, &completer_tstate, args);
+	return set_hook("completer", &completer, args);
 }
 
 PyDoc_STRVAR(doc_set_completer,
@@ -576,28 +576,34 @@
 /* C function to call the Python hooks. */
 
 static int
-on_hook(PyObject *func, PyThreadState **tstate)
+on_hook(PyObject *func)
 {
 	int result = 0;
 	if (func != NULL) {
 		PyObject *r;
-		/* Note that readline is called with the interpreter
-		   lock released! */
-		PyEval_RestoreThread(*tstate);
+#ifdef WITH_THREAD	      
+		PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
 		r = PyObject_CallFunction(func, NULL);
 		if (r == NULL)
 			goto error;
 		if (r == Py_None)
 			result = 0;
-		else
+		else {
 			result = PyInt_AsLong(r);
+			if (result == -1 && PyErr_Occurred()) 
+				goto error;
+		}
 		Py_DECREF(r);
 		goto done;
 	  error:
 		PyErr_Clear();
 		Py_XDECREF(r);
 	  done:
-		*tstate = PyEval_SaveThread();
+#ifdef WITH_THREAD	      
+		PyGILState_Release(gilstate);
+#endif
+		return result;
 	}
 	return result;
 }
@@ -605,14 +611,14 @@
 static int
 on_startup_hook(void)
 {
-	return on_hook(startup_hook, &startup_hook_tstate);
+	return on_hook(startup_hook);
 }
 
 #ifdef HAVE_RL_PRE_INPUT_HOOK
 static int
 on_pre_input_hook(void)
 {
-	return on_hook(pre_input_hook, &pre_input_hook_tstate);
+	return on_hook(pre_input_hook);
 }
 #endif
 
@@ -625,11 +631,9 @@
 	char *result = NULL;
 	if (completer != NULL) {
 		PyObject *r;
-		/* Note that readline is called with the interpreter
-		   lock released! */
-		PyEval_RestoreThread(completer_tstate);
-		/* Don't use the default filename completion if we
-		 * have a custom completion function... */
+#ifdef WITH_THREAD	      
+		PyGILState_STATE gilstate = PyGILState_Ensure();
+#endif
 		rl_attempted_completion_over = 1;
 		r = PyObject_CallFunction(completer, "si", text, state);
 		if (r == NULL)
@@ -649,7 +653,10 @@
 		PyErr_Clear();
 		Py_XDECREF(r);
 	  done:
-		completer_tstate = PyEval_SaveThread();
+#ifdef WITH_THREAD	      
+		PyGILState_Release(gilstate);
+#endif
+		return result;
 	}
 	return result;
 }
@@ -770,9 +777,13 @@
 		}
 		else if (errno == EINTR) {
 			int s;
+#ifdef WITH_THREAD
 			PyEval_RestoreThread(_PyOS_ReadlineTState);
+#endif
 			s = PyErr_CheckSignals();
+#ifdef WITH_THREAD
 			PyEval_SaveThread();	
+#endif
 			if (s < 0) {
 				rl_free_line_state();
 				rl_cleanup_after_signal();

Index: shamodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/shamodule.c,v
retrieving revision 2.19.2.1
retrieving revision 2.19.2.2
diff -u -d -r2.19.2.1 -r2.19.2.2
--- shamodule.c	28 Apr 2003 17:19:20 -0000	2.19.2.1
+++ shamodule.c	16 Oct 2005 05:24:04 -0000	2.19.2.2
@@ -7,11 +7,16 @@
 
    Andrew Kuchling (amk at amk.ca)
    Greg Stein (gstein at lyra.org)
+
+   Copyright (C) 2005   Gregory P. Smith (greg at electricrain.com)
+   Licensed to PSF under a Contributor Agreement.
+
 */
 
 /* SHA objects */
 
 #include "Python.h"
+#include "structmember.h"
 
 
 /* Endianness testing and definitions */
@@ -453,26 +458,78 @@
 };
 
 static PyObject *
-SHA_getattr(PyObject *self, char *name)
+SHA_get_block_size(PyObject *self, void *closure)
 {
-    if (strcmp(name, "blocksize")==0)
-        return PyInt_FromLong(1);
-    if (strcmp(name, "digest_size")==0 || strcmp(name, "digestsize")==0)
-        return PyInt_FromLong(20);
+    return PyInt_FromLong(SHA_BLOCKSIZE);
+}
 
-    return Py_FindMethod(SHA_methods, self, name);
+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*/
+    "_sha.sha",		/*tp_name*/
     sizeof(SHAobject),	/*tp_size*/
     0,			/*tp_itemsize*/
     /* methods */
     SHA_dealloc,	/*tp_dealloc*/
     0,			/*tp_print*/
-    SHA_getattr,	/*tp_getattr*/
+    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 */
 };
 
 
@@ -516,7 +573,6 @@
 
 static struct PyMethodDef SHA_functions[] = {
     {"new", (PyCFunction)SHA_new, METH_VARARGS|METH_KEYWORDS, SHA_new__doc__},
-    {"sha", (PyCFunction)SHA_new, METH_VARARGS|METH_KEYWORDS, SHA_new__doc__},
     {NULL,	NULL}		 /* Sentinel */
 };
 
@@ -526,12 +582,14 @@
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
 PyMODINIT_FUNC
-initsha(void)
+init_sha(void)
 {
     PyObject *m;
 
     SHAtype.ob_type = &PyType_Type;
-    m = Py_InitModule("sha", SHA_functions);
+    if (PyType_Ready(&SHAtype) < 0)
+        return;
+    m = Py_InitModule("_sha", SHA_functions);
 
     /* Add some symbolic constants to the module */
     insint("blocksize", 1);  /* For future use, in case some hash

Index: signalmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/signalmodule.c,v
retrieving revision 2.70.2.2
retrieving revision 2.70.2.3
diff -u -d -r2.70.2.2 -r2.70.2.3
--- signalmodule.c	7 Jan 2005 07:03:20 -0000	2.70.2.2
+++ signalmodule.c	16 Oct 2005 05:24:04 -0000	2.70.2.3
@@ -669,5 +669,6 @@
 	PyEval_ReInitThreads();
 	main_thread = PyThread_get_thread_ident();
 	main_pid = getpid();
+	_PyImport_ReInitLock();
 #endif
 }

Index: socketmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.c,v
retrieving revision 1.229.2.2
retrieving revision 1.229.2.3
diff -u -d -r1.229.2.2 -r1.229.2.3
--- socketmodule.c	7 Jan 2005 07:03:21 -0000	1.229.2.2
+++ socketmodule.c	16 Oct 2005 05:24:04 -0000	1.229.2.3
@@ -140,9 +140,14 @@
 # define USE_GETHOSTBYNAME_LOCK
 #endif
 
+/* To use __FreeBSD_version */
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
 /* On systems on which getaddrinfo() is believed to not be thread-safe,
    (this includes the getaddrinfo emulation) protect access with a lock. */
-#if defined(WITH_THREAD) && (defined(__APPLE__) || defined(__FreeBSD__) || \
+#if defined(WITH_THREAD) && (defined(__APPLE__) || \
+    (defined(__FreeBSD__) && __FreeBSD_version+0 < 503000) || \
     defined(__OpenBSD__) || defined(__NetBSD__) || !defined(HAVE_GETADDRINFO))
 #define USE_GETADDRINFO_LOCK
 #endif
@@ -1344,7 +1349,7 @@
 static PyObject *
 sock_accept(PySocketSockObject *s)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	SOCKET_T newfd;
 	socklen_t addrlen;
 	PyObject *sock = NULL;
@@ -1354,7 +1359,7 @@
 
 	if (!getsockaddrlen(s, &addrlen))
 		return NULL;
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 
 #ifdef MS_WINDOWS
 	newfd = INVALID_SOCKET;
@@ -1365,7 +1370,7 @@
 	Py_BEGIN_ALLOW_THREADS
 	timeout = internal_select(s, 0);
 	if (!timeout)
-		newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf,
+		newfd = accept(s->sock_fd, (struct sockaddr *) &addrbuf,
 			       &addrlen);
 	Py_END_ALLOW_THREADS
 
@@ -1392,7 +1397,7 @@
 		SOCKETCLOSE(newfd);
 		goto finally;
 	}
-	addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
+	addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
 			    addrlen, s->sock_proto);
 	if (addr == NULL)
 		goto finally;
@@ -1865,19 +1870,19 @@
 static PyObject *
 sock_getsockname(PySocketSockObject *s)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	int res;
 	socklen_t addrlen;
 
 	if (!getsockaddrlen(s, &addrlen))
 		return NULL;
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 	Py_BEGIN_ALLOW_THREADS
-	res = getsockname(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
+	res = getsockname(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen);
 	Py_END_ALLOW_THREADS
 	if (res < 0)
 		return s->errorhandler();
-	return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen,
+	return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen,
 			    s->sock_proto);
 }
 
@@ -1894,19 +1899,19 @@
 static PyObject *
 sock_getpeername(PySocketSockObject *s)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	int res;
 	socklen_t addrlen;
 
 	if (!getsockaddrlen(s, &addrlen))
 		return NULL;
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 	Py_BEGIN_ALLOW_THREADS
-	res = getpeername(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen);
+	res = getpeername(s->sock_fd, (struct sockaddr *) &addrbuf, &addrlen);
 	Py_END_ALLOW_THREADS
 	if (res < 0)
 		return s->errorhandler();
-	return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen,
+	return makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf, addrlen,
 			    s->sock_proto);
 }
 
@@ -2115,7 +2120,7 @@
 static PyObject *
 sock_recvfrom(PySocketSockObject *s, PyObject *args)
 {
-	char addrbuf[256];
+	sock_addr_t addrbuf;
 	PyObject *buf = NULL;
 	PyObject *addr = NULL;
 	PyObject *ret = NULL;
@@ -2132,18 +2137,18 @@
 		return NULL;
 
 	Py_BEGIN_ALLOW_THREADS
-	memset(addrbuf, 0, addrlen);
+	memset(&addrbuf, 0, addrlen);
 	timeout = internal_select(s, 0);
 	if (!timeout)
 		n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags,
 #ifndef MS_WINDOWS
 #if defined(PYOS_OS2) && !defined(PYCC_GCC)
-			     (struct sockaddr *)addrbuf, &addrlen
+			     (struct sockaddr *) &addrbuf, &addrlen
 #else
-			     (void *)addrbuf, &addrlen
+			     (void *) &addrbuf, &addrlen
 #endif
 #else
-			     (struct sockaddr *)addrbuf, &addrlen
+			     (struct sockaddr *) &addrbuf, &addrlen
 #endif
 			);
 	Py_END_ALLOW_THREADS
@@ -2161,7 +2166,7 @@
 	if (n != len && _PyString_Resize(&buf, n) < 0)
 		return NULL;
 
-	if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
+	if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *) &addrbuf,
 				  addrlen, s->sock_proto)))
 		goto finally;
 
@@ -2589,11 +2594,7 @@
 socket_gethostbyname(PyObject *self, PyObject *args)
 {
 	char *name;
-#ifdef ENABLE_IPV6
-	struct sockaddr_storage addrbuf;
-#else
-        struct sockaddr_in addrbuf;
-#endif
+	sock_addr_t addrbuf;
 
 	if (!PyArg_ParseTuple(args, "s:gethostbyname", &name))
 		return NULL;
@@ -3238,14 +3239,19 @@
 	return NULL;
 
 #else /* ! HAVE_INET_ATON */
-	/* XXX Problem here: inet_aton('255.255.255.255') raises
-	   an exception while it should be a valid address. */
-	packed_addr = inet_addr(ip_addr);
+	/* special-case this address as inet_addr might return INADDR_NONE
+	 * for this */
+	if (strcmp(ip_addr, "255.255.255.255") == 0) {
+		packed_addr = 0xFFFFFFFF;
+	} else {
+	
+		packed_addr = inet_addr(ip_addr);
 
-	if (packed_addr == INADDR_NONE) {	/* invalid address */
-		PyErr_SetString(socket_error,
-			"illegal IP address string passed to inet_aton");
-		return NULL;
+		if (packed_addr == INADDR_NONE) {	/* invalid address */
+			PyErr_SetString(socket_error,
+				"illegal IP address string passed to inet_aton");
+			return NULL;
+		}
 	}
 	return PyString_FromStringAndSize((char *) &packed_addr,
 					  sizeof(packed_addr));

Index: socketmodule.h
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/socketmodule.h,v
retrieving revision 1.8.2.1
retrieving revision 1.8.2.2
diff -u -d -r1.8.2.1 -r1.8.2.2
--- socketmodule.h	7 Jan 2005 07:03:22 -0000	1.8.2.1
+++ socketmodule.h	16 Oct 2005 05:24:04 -0000	1.8.2.2
@@ -72,6 +72,26 @@
 #	define SIZEOF_SOCKET_T SIZEOF_INT
 #endif
 
+/* Socket address */
+typedef union sock_addr {
+	struct sockaddr_in in;
+#ifdef AF_UNIX
+	struct sockaddr_un un;
+#endif
+#ifdef ENABLE_IPV6
+	struct sockaddr_in6 in6;
+	struct sockaddr_storage storage;
+#endif
+#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
+	struct sockaddr_l2 bt_l2;
+	struct sockaddr_rc bt_rc;
+	struct sockaddr_sco bt_sco;
+#endif
+#ifdef HAVE_NETPACKET_PACKET_H
+	struct sockaddr_ll ll;
+#endif
+} sock_addr_t;
+
 /* The object holding a socket.  It holds some extra information,
    like the address family, which is used to decode socket address
    arguments properly. */
@@ -82,24 +102,7 @@
 	int sock_family;	/* Address family, e.g., AF_INET */
 	int sock_type;		/* Socket type, e.g., SOCK_STREAM */
 	int sock_proto;		/* Protocol type, usually 0 */
-	union sock_addr {
-		struct sockaddr_in in;
-#ifdef AF_UNIX
-		struct sockaddr_un un;
-#endif
-#ifdef ENABLE_IPV6
-		struct sockaddr_in6 in6;
-		struct sockaddr_storage storage;
-#endif
-#ifdef HAVE_BLUETOOTH_BLUETOOTH_H
-		struct sockaddr_l2 bt_l2;
-		struct sockaddr_rc bt_rc;
-		struct sockaddr_sco bt_sco;
-#endif
-#ifdef HAVE_NETPACKET_PACKET_H
-		struct sockaddr_ll ll;
-#endif
-	} sock_addr;
+	sock_addr_t sock_addr;	/* Socket address */
 	PyObject *(*errorhandler)(void); /* Error handler; checks
 					    errno, returns NULL and
 					    sets a Python exception */

Index: structmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/structmodule.c,v
retrieving revision 2.55.2.2
retrieving revision 2.55.2.3
diff -u -d -r2.55.2.2 -r2.55.2.3
--- structmodule.c	7 Jan 2005 07:03:23 -0000	2.55.2.2
+++ structmodule.c	16 Oct 2005 05:24:04 -0000	2.55.2.3
@@ -959,7 +959,7 @@
 	s = fmt;
 	size = 0;
 	while ((c = *s++) != '\0') {
-		if (isspace((int)c))
+		if (isspace(Py_CHARMASK(c)))
 			continue;
 		if ('0' <= c && c <= '9') {
 			num = c - '0';
@@ -1059,7 +1059,7 @@
 	res = restart = PyString_AsString(result);
 
 	while ((c = *s++) != '\0') {
-		if (isspace((int)c))
+		if (isspace(Py_CHARMASK(c)))
 			continue;
 		if ('0' <= c && c <= '9') {
 			num = c - '0';
@@ -1191,7 +1191,7 @@
 	str = start;
 	s = fmt;
 	while ((c = *s++) != '\0') {
-		if (isspace((int)c))
+		if (isspace(Py_CHARMASK(c)))
 			continue;
 		if ('0' <= c && c <= '9') {
 			num = c - '0';

Index: threadmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/threadmodule.c,v
retrieving revision 2.50.2.2
retrieving revision 2.50.2.3
diff -u -d -r2.50.2.2 -r2.50.2.3
--- threadmodule.c	7 Jan 2005 07:03:24 -0000	2.50.2.2
+++ threadmodule.c	16 Oct 2005 05:24:04 -0000	2.50.2.3
@@ -63,12 +63,7 @@
 	i = PyThread_acquire_lock(self->lock_lock, i);
 	Py_END_ALLOW_THREADS
 
-	if (args == NULL) {
-		Py_INCREF(Py_None);
-		return Py_None;
-	}
-	else
-		return PyBool_FromLong((long)i);
+	return PyBool_FromLong((long)i);
 }
 
 PyDoc_STRVAR(acquire_doc,
@@ -163,11 +158,11 @@
 #include "structmember.h"
 
 typedef struct {
-    PyObject_HEAD
-    PyObject *key;
-    PyObject *args;
-    PyObject *kw;
-    PyObject *dict;
+	PyObject_HEAD
+	PyObject *key;
+	PyObject *args;
+	PyObject *kw;
+	PyObject *dict;
 } localobject;
 
 static PyTypeObject localtype;
@@ -175,91 +170,87 @@
 static PyObject *
 local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
 {
-    	localobject *self;
-        PyObject *tdict;
+	localobject *self;
+	PyObject *tdict;
 
-        if (type->tp_init == PyBaseObject_Type.tp_init
-            && ((args && PyObject_IsTrue(args))
-                ||
-                (kw && PyObject_IsTrue(kw))
-                )
-            ) {
-          	PyErr_SetString(PyExc_TypeError,
-                          "Initialization arguments are not supported");
-                return NULL;
-        }
+	if (type->tp_init == PyBaseObject_Type.tp_init
+	    && ((args && PyObject_IsTrue(args))
+		|| (kw && PyObject_IsTrue(kw)))) {
+		PyErr_SetString(PyExc_TypeError,
+			  "Initialization arguments are not supported");
+		return NULL;
+	}
 
-    	self = (localobject *)type->tp_alloc(type, 0);
-        if (self == NULL)
-          return NULL;
+	self = (localobject *)type->tp_alloc(type, 0);
+	if (self == NULL)
+		return NULL;
 
-        Py_XINCREF(args);
-        self->args = args;
-        Py_XINCREF(kw);
-        self->kw = kw;
-        self->dict = NULL;      /* making sure */
-        self->key = PyString_FromFormat("thread.local.%p", self);
-        if (self->key == NULL) 
-                goto err;
+	Py_XINCREF(args);
+	self->args = args;
+	Py_XINCREF(kw);
+	self->kw = kw;
+	self->dict = NULL;	/* making sure */
+	self->key = PyString_FromFormat("thread.local.%p", self);
+	if (self->key == NULL) 
+		goto err;
 
-        self->dict = PyDict_New();
-        if (self->dict == NULL)
-                goto err;
+	self->dict = PyDict_New();
+	if (self->dict == NULL)
+		goto err;
 
-        tdict = PyThreadState_GetDict();
-        if (tdict == NULL) {
-                PyErr_SetString(PyExc_SystemError,
-                                "Couldn't get thread-state dictionary");
-                goto err;
-        }
+	tdict = PyThreadState_GetDict();
+	if (tdict == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"Couldn't get thread-state dictionary");
+		goto err;
+	}
 
-        if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
-                goto err;
-       
-    	return (PyObject *)self;
+	if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
+		goto err;
 
- err:
-        Py_DECREF(self);
-        return NULL;
+	return (PyObject *)self;
+
+  err:
+	Py_DECREF(self);
+	return NULL;
 }
 
 static int
 local_traverse(localobject *self, visitproc visit, void *arg)
 {
-        Py_VISIT(self->args);
-        Py_VISIT(self->kw);
-        Py_VISIT(self->dict);
+	Py_VISIT(self->args);
+	Py_VISIT(self->kw);
+	Py_VISIT(self->dict);
 	return 0;
 }
 
 static int
 local_clear(localobject *self)
 {
-  	Py_CLEAR(self->key);
-        Py_CLEAR(self->args);
-        Py_CLEAR(self->kw);
-        Py_CLEAR(self->dict);
-        return 0;
+	Py_CLEAR(self->key);
+	Py_CLEAR(self->args);
+	Py_CLEAR(self->kw);
+	Py_CLEAR(self->dict);
+	return 0;
 }
 
 static void
 local_dealloc(localobject *self)
 {
-        PyThreadState *tstate;
-        if (self->key
-            && (tstate = PyThreadState_Get())
-            && tstate->interp) {
-                for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
-                    tstate;
-                    tstate = PyThreadState_Next(tstate)
-                    ) 
-                        if (tstate->dict &&
-                            PyDict_GetItem(tstate->dict, self->key))
-                                PyDict_DelItem(tstate->dict, self->key);
-        }
+	PyThreadState *tstate;
+	if (self->key
+	    && (tstate = PyThreadState_Get())
+	    && tstate->interp) {
+		for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
+		    tstate;
+		    tstate = PyThreadState_Next(tstate)) 
+			if (tstate->dict &&
+			    PyDict_GetItem(tstate->dict, self->key))
+				PyDict_DelItem(tstate->dict, self->key);
+	}
 
-  	local_clear(self);
-        self->ob_type->tp_free((PyObject*)self);
+	local_clear(self);
+	self->ob_type->tp_free((PyObject*)self);
 }
 
 static PyObject *
@@ -268,48 +259,47 @@
 	PyObject *tdict, *ldict;
 
 	tdict = PyThreadState_GetDict();
-        if (tdict == NULL) {
-        	PyErr_SetString(PyExc_SystemError,
-                                "Couldn't get thread-state dictionary");
-                return NULL;
-        }
+	if (tdict == NULL) {
+		PyErr_SetString(PyExc_SystemError,
+				"Couldn't get thread-state dictionary");
+		return NULL;
+	}
 
-        ldict = PyDict_GetItem(tdict, self->key);
-        if (ldict == NULL) {
-        	ldict = PyDict_New(); /* we own ldict */
+	ldict = PyDict_GetItem(tdict, self->key);
+	if (ldict == NULL) {
+		ldict = PyDict_New(); /* we own ldict */
 
-                if (ldict == NULL)
-                	return NULL;
-                else {
-                        int i = PyDict_SetItem(tdict, self->key, ldict);
-                        Py_DECREF(ldict); /* now ldict is borowed */
-                        if (i < 0) 
-                                return NULL;
-                }
+		if (ldict == NULL)
+			return NULL;
+		else {
+			int i = PyDict_SetItem(tdict, self->key, ldict);
+			Py_DECREF(ldict); /* now ldict is borowed */
+			if (i < 0) 
+				return NULL;
+		}
 
-                Py_CLEAR(self->dict);
-                Py_INCREF(ldict);
-                self->dict = ldict; /* still borrowed */
+		Py_CLEAR(self->dict);
+		Py_INCREF(ldict);
+		self->dict = ldict; /* still borrowed */
 
-                if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
-                    self->ob_type->tp_init((PyObject*)self, 
-                                           self->args, self->kw) < 0
-                    ) {
-                        /* we need to get rid of ldict from thread so
-                           we create a new one the next time we do an attr
-                           acces */
-                        PyDict_DelItem(tdict, self->key);
-                        return NULL;
-                }
-                
-        }
-        else if (self->dict != ldict) {
-                Py_CLEAR(self->dict);
-                Py_INCREF(ldict);
-                self->dict = ldict;
-        }
+		if (self->ob_type->tp_init != PyBaseObject_Type.tp_init &&
+		    self->ob_type->tp_init((PyObject*)self, 
+					   self->args, self->kw) < 0) {
+			/* we need to get rid of ldict from thread so
+			   we create a new one the next time we do an attr
+			   acces */
+			PyDict_DelItem(tdict, self->key);
+			return NULL;
+		}
+		
+	}
+	else if (self->dict != ldict) {
+		Py_CLEAR(self->dict);
+		Py_INCREF(ldict);
+		self->dict = ldict;
+	}
 
-  return ldict;
+	return ldict;
 }
 
 static PyObject *
@@ -317,54 +307,52 @@
 {
 	PyObject *ldict, *value;
 
-        ldict = _ldict(self);
-        if (ldict == NULL) 
-        	return NULL;
+	ldict = _ldict(self);
+	if (ldict == NULL) 
+		return NULL;
 
-        if (self->ob_type != &localtype)
-                /* use generic lookup for subtypes */
-                return PyObject_GenericGetAttr((PyObject *)self, name);
+	if (self->ob_type != &localtype)
+		/* use generic lookup for subtypes */
+		return PyObject_GenericGetAttr((PyObject *)self, name);
 
-        /* Optimization: just look in dict ourselves */
-        value = PyDict_GetItem(ldict, name);
-        if (value == NULL) 
-                /* Fall back on generic to get __class__ and __dict__ */
-                return PyObject_GenericGetAttr((PyObject *)self, name);
+	/* Optimization: just look in dict ourselves */
+	value = PyDict_GetItem(ldict, name);
+	if (value == NULL) 
+		/* Fall back on generic to get __class__ and __dict__ */
+		return PyObject_GenericGetAttr((PyObject *)self, name);
 
-        Py_INCREF(value);
-        return value;
+	Py_INCREF(value);
+	return value;
 }
 
 static int
 local_setattro(localobject *self, PyObject *name, PyObject *v)
 {
 	PyObject *ldict;
-        
-        ldict = _ldict(self);
-        if (ldict == NULL) 
-          	return -1;
+	
+	ldict = _ldict(self);
+	if (ldict == NULL) 
+		return -1;
 
-        return PyObject_GenericSetAttr((PyObject *)self, name, v);
+	return PyObject_GenericSetAttr((PyObject *)self, name, v);
 }
 
 static PyObject *
 local_getdict(localobject *self, void *closure)
 {
-        if (self->dict == NULL) {
-                PyErr_SetString(PyExc_AttributeError, "__dict__");
-                return NULL;
-        }
+	if (self->dict == NULL) {
+		PyErr_SetString(PyExc_AttributeError, "__dict__");
+		return NULL;
+	}
 
-    	Py_INCREF(self->dict);
-        return self->dict;
+	Py_INCREF(self->dict);
+	return self->dict;
 }
 
 static PyGetSetDef local_getset[] = {
-    {"__dict__", 
-     (getter)local_getdict, (setter)0,
-     "Local-data dictionary",
-     NULL},
-    {NULL}  /* Sentinel */
+	{"__dict__", (getter)local_getdict, (setter)NULL,
+	 "Local-data dictionary", NULL},
+	{NULL}  /* Sentinel */
 };
 
 static PyTypeObject localtype = {
@@ -385,28 +373,28 @@
 	/* tp_hash           */ (hashfunc)0,
 	/* tp_call           */ (ternaryfunc)0,
 	/* tp_str            */ (reprfunc)0,
-        /* tp_getattro       */ (getattrofunc)local_getattro,
-        /* tp_setattro       */ (setattrofunc)local_setattro,
-        /* tp_as_buffer      */ 0,
-        /* tp_flags          */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+	/* tp_getattro       */ (getattrofunc)local_getattro,
+	/* tp_setattro       */ (setattrofunc)local_setattro,
+	/* tp_as_buffer      */ 0,
+	/* tp_flags          */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
 	/* tp_doc            */ "Thread-local data",
-        /* tp_traverse       */ (traverseproc)local_traverse,
-        /* tp_clear          */ (inquiry)local_clear,
-        /* tp_richcompare    */ (richcmpfunc)0,
-        /* tp_weaklistoffset */ (long)0,
-        /* tp_iter           */ (getiterfunc)0,
-        /* tp_iternext       */ (iternextfunc)0,
-        /* tp_methods        */ 0,
-        /* tp_members        */ 0,
-        /* tp_getset         */ local_getset,
-        /* tp_base           */ 0,
-        /* tp_dict           */ 0, /* internal use */
-        /* tp_descr_get      */ (descrgetfunc)0,
-        /* tp_descr_set      */ (descrsetfunc)0,
-        /* tp_dictoffset     */ offsetof(localobject, dict),
-        /* tp_init           */ (initproc)0,
-        /* tp_alloc          */ (allocfunc)0,
-        /* tp_new            */ (newfunc)local_new,
+	/* tp_traverse       */ (traverseproc)local_traverse,
+	/* tp_clear          */ (inquiry)local_clear,
+	/* tp_richcompare    */ (richcmpfunc)0,
+	/* tp_weaklistoffset */ (long)0,
+	/* tp_iter           */ (getiterfunc)0,
+	/* tp_iternext       */ (iternextfunc)0,
+	/* tp_methods        */ 0,
+	/* tp_members        */ 0,
+	/* tp_getset         */ local_getset,
+	/* tp_base           */ 0,
+	/* tp_dict           */ 0, /* internal use */
+	/* tp_descr_get      */ (descrgetfunc)0,
+	/* tp_descr_set      */ (descrsetfunc)0,
+	/* tp_dictoffset     */ offsetof(localobject, dict),
+	/* tp_init           */ (initproc)0,
+	/* tp_alloc          */ (allocfunc)0,
+	/* tp_new            */ (newfunc)local_new,
 	/* tp_free           */ 0, /* Low-level free-mem routine */
 	/* tp_is_gc          */ (inquiry)0, /* For PyObject_IS_GC */
 };
@@ -425,10 +413,12 @@
 t_bootstrap(void *boot_raw)
 {
 	struct bootstate *boot = (struct bootstate *) boot_raw;
-	PyGILState_STATE gstate;
+	PyThreadState *tstate;
 	PyObject *res;
 
-	gstate = PyGILState_Ensure();
+	tstate = PyThreadState_New(boot->interp);
+
+	PyEval_AcquireThread(tstate);
 	res = PyEval_CallObjectWithKeywords(
 		boot->func, boot->args, boot->keyw);
 	if (res == NULL) {
@@ -453,7 +443,8 @@
 	Py_DECREF(boot->args);
 	Py_XDECREF(boot->keyw);
 	PyMem_DEL(boot_raw);
-	PyGILState_Release(gstate);
+	PyThreadState_Clear(tstate);
+	PyThreadState_DeleteCurrent();
 	PyThread_exit_thread();
 }
 
@@ -494,7 +485,7 @@
 	PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
 	ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
 	if (ident == -1) {
-		PyErr_SetString(ThreadError, "can't start new thread\n");
+		PyErr_SetString(ThreadError, "can't start new thread");
 		Py_DECREF(func);
 		Py_DECREF(args);
 		Py_XDECREF(keyw);
@@ -640,10 +631,10 @@
 initthread(void)
 {
 	PyObject *m, *d;
-        
-        /* Initialize types: */
-        if (PyType_Ready(&localtype) < 0)
-        	return;
+	
+	/* Initialize types: */
+	if (PyType_Ready(&localtype) < 0)
+		return;
 
 	/* Create the module and add the functions */
 	m = Py_InitModule3("thread", thread_methods, thread_doc);
@@ -656,8 +647,9 @@
 	Py_INCREF(&Locktype);
 	PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
 
-        if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
-        	return;
+	Py_INCREF(&localtype);
+	if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
+		return;
 
 	/* Initialize the C thread library */
 	PyThread_init_thread();

Index: unicodedata.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/unicodedata.c,v
retrieving revision 2.18.2.2
retrieving revision 2.18.2.3
diff -u -d -r2.18.2.2 -r2.18.2.3
--- unicodedata.c	7 Jan 2005 07:03:24 -0000	2.18.2.2
+++ unicodedata.c	16 Oct 2005 05:24:04 -0000	2.18.2.3
@@ -53,6 +53,13 @@
 
 /* --- Module API --------------------------------------------------------- */
 
+PyDoc_STRVAR(unicodedata_decimal__doc__,
+"decimal(unichr[, default])\n\
+\n\
+Returns the decimal value assigned to the Unicode character unichr\n\
+as integer. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
 static PyObject *
 unicodedata_decimal(PyObject *self, PyObject *args)
 {
@@ -82,6 +89,13 @@
     return PyInt_FromLong(rc);
 }
 
+PyDoc_STRVAR(unicodedata_digit__doc__,
+"digit(unichr[, default])\n\
+\n\
+Returns the digit value assigned to the Unicode character unichr as\n\
+integer. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
 static PyObject *
 unicodedata_digit(PyObject *self, PyObject *args)
 {
@@ -110,6 +124,13 @@
     return PyInt_FromLong(rc);
 }
 
+PyDoc_STRVAR(unicodedata_numeric__doc__,
+"numeric(unichr[, default])\n\
+\n\
+Returns the numeric value assigned to the Unicode character unichr\n\
+as float. If no such value is defined, default is returned, or, if\n\
+not given, ValueError is raised.");
+
 static PyObject *
 unicodedata_numeric(PyObject *self, PyObject *args)
 {
@@ -138,6 +159,12 @@
     return PyFloat_FromDouble(rc);
 }
 
+PyDoc_STRVAR(unicodedata_category__doc__,
+"category(unichr)\n\
+\n\
+Returns the general category assigned to the Unicode character\n\
+unichr as string.");
+
 static PyObject *
 unicodedata_category(PyObject *self, PyObject *args)
 {
@@ -156,6 +183,13 @@
     return PyString_FromString(_PyUnicode_CategoryNames[index]);
 }
 
+PyDoc_STRVAR(unicodedata_bidirectional__doc__,
+"bidirectional(unichr)\n\
+\n\
+Returns the bidirectional category assigned to the Unicode character\n\
+unichr as string. If no such value is defined, an empty string is\n\
+returned.");
+
 static PyObject *
 unicodedata_bidirectional(PyObject *self, PyObject *args)
 {
@@ -174,6 +208,13 @@
     return PyString_FromString(_PyUnicode_BidirectionalNames[index]);
 }
 
+PyDoc_STRVAR(unicodedata_combining__doc__,
+"combining(unichr)\n\
+\n\
+Returns the canonical combining class assigned to the Unicode\n\
+character unichr as integer. Returns 0 if no combining class is\n\
+defined.");
+
 static PyObject *
 unicodedata_combining(PyObject *self, PyObject *args)
 {
@@ -190,6 +231,13 @@
     return PyInt_FromLong((int) _getrecord(v)->combining);
 }
 
+PyDoc_STRVAR(unicodedata_mirrored__doc__,
+"mirrored(unichr)\n\
+\n\
+Returns the mirrored property assigned to the Unicode character\n\
+unichr as integer. Returns 1 if the character has been identified as\n\
+a \"mirrored\" character in bidirectional text, 0 otherwise.");
+
 static PyObject *
 unicodedata_mirrored(PyObject *self, PyObject *args)
 {
@@ -206,6 +254,12 @@
     return PyInt_FromLong((int) _getrecord(v)->mirrored);
 }
 
+PyDoc_STRVAR(unicodedata_east_asian_width__doc__,
+"east_asian_width(unichr)\n\
+\n\
+Returns the east asian width assigned to the Unicode character\n\
+unichr as string.");
+
 static PyObject *
 unicodedata_east_asian_width(PyObject *self, PyObject *args)
 {
@@ -224,6 +278,13 @@
     return PyString_FromString(_PyUnicode_EastAsianWidthNames[index]);
 }
 
+PyDoc_STRVAR(unicodedata_decomposition__doc__,
+"decomposition(unichr)\n\
+\n\
+Returns the character decomposition mapping assigned to the Unicode\n\
+character unichr as string. An empty string is returned in case no\n\
+such mapping is defined.");
+
 static PyObject *
 unicodedata_decomposition(PyObject *self, PyObject *args)
 {
@@ -525,6 +586,12 @@
     return result;
 }
 		
+PyDoc_STRVAR(unicodedata_normalize__doc__,
+"normalize(form, unistr)\n\
+\n\
+Return the normal form 'form' for the Unicode string unistr.  Valid\n\
+values for form are 'NFC', 'NFKC', 'NFD', and 'NFKD'.");
+
 static PyObject*
 unicodedata_normalize(PyObject *self, PyObject *args)
 {
@@ -753,7 +820,7 @@
 	pos += len;
 	find_syllable(pos, &len, &T, TCount, 2);
 	pos += len;
-	if (V != -1 && V != -1 && T != -1 && pos-name == namelen) {
+	if (L != -1 && V != -1 && T != -1 && pos-name == namelen) {
 	    *code = SBase + (L*VCount+V)*TCount + T;
 	    return 1;
 	}
@@ -826,6 +893,12 @@
 /* -------------------------------------------------------------------- */
 /* Python bindings */
 
+PyDoc_STRVAR(unicodedata_name__doc__,
+"name(unichr[, default])\n\
+Returns the name assigned to the Unicode character unichr as a\n\
+string. If no name is defined, default is returned, or, if not\n\
+given, ValueError is raised.");
+
 static PyObject *
 unicodedata_name(PyObject* self, PyObject* args)
 {
@@ -857,6 +930,13 @@
     return Py_BuildValue("s", name);
 }
 
+PyDoc_STRVAR(unicodedata_lookup__doc__,
+"lookup(name)\n\
+\n\
+Look up character by name.  If a character with the\n\
+given name is found, return the corresponding Unicode\n\
+character.  If not found, KeyError is raised.");
+
 static PyObject *
 unicodedata_lookup(PyObject* self, PyObject* args)
 {
@@ -884,22 +964,37 @@
 /* XXX Add doc strings. */
 
 static PyMethodDef unicodedata_functions[] = {
-    {"decimal", unicodedata_decimal, METH_VARARGS},
-    {"digit", unicodedata_digit, METH_VARARGS},
-    {"numeric", unicodedata_numeric, METH_VARARGS},
-    {"category", unicodedata_category, METH_VARARGS},
-    {"bidirectional", unicodedata_bidirectional, METH_VARARGS},
-    {"combining", unicodedata_combining, METH_VARARGS},
-    {"mirrored", unicodedata_mirrored, METH_VARARGS},
-    {"east_asian_width", unicodedata_east_asian_width, METH_VARARGS},
-    {"decomposition",unicodedata_decomposition, METH_VARARGS},
-    {"name", unicodedata_name, METH_VARARGS},
-    {"lookup", unicodedata_lookup, METH_VARARGS},
-    {"normalize", unicodedata_normalize, METH_VARARGS},
+    {"decimal", unicodedata_decimal, METH_VARARGS, unicodedata_decimal__doc__},
+    {"digit", unicodedata_digit, METH_VARARGS, unicodedata_digit__doc__},
+    {"numeric", unicodedata_numeric, METH_VARARGS, unicodedata_numeric__doc__},
+    {"category", unicodedata_category, METH_VARARGS,
+                 unicodedata_category__doc__},
+    {"bidirectional", unicodedata_bidirectional, METH_VARARGS,
+                      unicodedata_bidirectional__doc__},
+    {"combining", unicodedata_combining, METH_VARARGS,
+                  unicodedata_combining__doc__},
+    {"mirrored", unicodedata_mirrored, METH_VARARGS,
+                 unicodedata_mirrored__doc__},
+    {"east_asian_width", unicodedata_east_asian_width, METH_VARARGS,
+                         unicodedata_east_asian_width__doc__},
+    {"decomposition", unicodedata_decomposition, METH_VARARGS,
+                      unicodedata_decomposition__doc__},
+    {"name", unicodedata_name, METH_VARARGS, unicodedata_name__doc__},
+    {"lookup", unicodedata_lookup, METH_VARARGS, unicodedata_lookup__doc__},
+    {"normalize", unicodedata_normalize, METH_VARARGS,
+                  unicodedata_normalize__doc__},
     {NULL, NULL}		/* sentinel */
 };
 
-PyDoc_STRVAR(unicodedata_docstring, "unicode character database");
+PyDoc_STRVAR(unicodedata_docstring,
+"This module provides access to the Unicode Character Database which\n\
+defines character properties for all Unicode characters. The data in\n\
+this database is based on the UnicodeData.txt file version\n\
+3.2.0 which is publically available from ftp://ftp.unicode.org/.\n\
+\n\
+The module uses the same names and symbols as defined by the\n\
+UnicodeData File Format 3.2.0 (see\n\
+http://www.unicode.org/Public/3.2-Update/UnicodeData-3.2.0.html).");
 
 PyMODINIT_FUNC
 initunicodedata(void)

Index: zipimport.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/zipimport.c,v
retrieving revision 1.13.4.2
retrieving revision 1.13.4.3
diff -u -d -r1.13.4.2 -r1.13.4.3
--- zipimport.c	7 Jan 2005 07:03:32 -0000	1.13.4.2
+++ zipimport.c	16 Oct 2005 05:24:04 -0000	1.13.4.3
@@ -65,6 +65,9 @@
 	char *path, *p, *prefix, buf[MAXPATHLEN+2];
 	int len;
 
+	if (!_PyArg_NoKeywords("zipimporter()", kwds))
+		return -1;
+
 	if (!PyArg_ParseTuple(args, "s:zipimporter",
 			      &path))
 		return -1;



More information about the Python-checkins mailing list