Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3k
Changeset: r58867:50695e88ee5e
Date: 2012-11-13 22:47 +0100
http://bitbucket.org/pypy/pypy/changeset/50695e88ee5e/
Log: hg backout 3eeeb257e9ca The _md5 module is still present in python3!
diff --git a/pypy/module/_md5/__init__.py b/pypy/module/_md5/__init__.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_md5/__init__.py
@@ -0,0 +1,26 @@
+
+"""
+Mixed-module definition for the md5 module.
+Note that there is also a pure Python implementation in pypy/lib/md5.py;
+the present mixed-module version of md5 takes precedence if it is enabled.
+"""
+
+from pypy.interpreter.mixedmodule import MixedModule
+
+
+class Module(MixedModule):
+ """\
+This module implements the interface to RSA's MD5 message digest
+algorithm (see also Internet RFC 1321). Its use is quite
+straightforward: use new() to create an md5 object. You can now feed
+this object with arbitrary strings using the update() method, and at any
+point you can ask it for the digest (a strong kind of 128-bit checksum,
+a.k.a. ``fingerprint'') of the concatenation of the strings fed to it so
+far using the digest() method."""
+
+ interpleveldefs = {
+ 'md5': 'interp_md5.W_MD5',
+ }
+
+ appleveldefs = {
+ }
diff --git a/pypy/module/_md5/interp_md5.py b/pypy/module/_md5/interp_md5.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_md5/interp_md5.py
@@ -0,0 +1,55 @@
+from pypy.rlib import rmd5
+from pypy.interpreter.baseobjspace import Wrappable
+from pypy.interpreter.typedef import TypeDef
+from pypy.interpreter.gateway import interp2app, unwrap_spec
+
+
+class W_MD5(Wrappable, rmd5.RMD5):
+ """
+ A subclass of RMD5 that can be exposed to app-level.
+ """
+
+ def __init__(self, space):
+ self.space = space
+ self._init()
+
+ @unwrap_spec(string='bufferstr')
+ def update_w(self, string):
+ self.update(string)
+
+ def digest_w(self):
+ return self.space.wrapbytes(self.digest())
+
+ def hexdigest_w(self):
+ return self.space.wrap(self.hexdigest())
+
+ def copy_w(self):
+ clone = W_MD5(self.space)
+ clone._copyfrom(self)
+ return self.space.wrap(clone)
+
+
+@unwrap_spec(initialdata='bufferstr')
+def W_MD5___new__(space, w_subtype, initialdata=''):
+ """
+ Create a new md5 object and call its initializer.
+ """
+ w_md5 = space.allocate_instance(W_MD5, w_subtype)
+ md5 = space.interp_w(W_MD5, w_md5)
+ W_MD5.__init__(md5, space)
+ md5.update(initialdata)
+ return w_md5
+
+
+W_MD5.typedef = TypeDef(
+ 'MD5Type',
+ __new__ = interp2app(W_MD5___new__),
+ update = interp2app(W_MD5.update_w),
+ digest = interp2app(W_MD5.digest_w),
+ hexdigest = interp2app(W_MD5.hexdigest_w),
+ copy = interp2app(W_MD5.copy_w),
+ digest_size = 16,
+ block_size = 64,
+ __doc__ = """md5(arg) -> return new md5 object.
+
+If arg is present, the method call update(arg) is made.""")
diff --git a/pypy/module/_md5/test/test_md5.py
b/pypy/module/_md5/test/test_md5.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/_md5/test/test_md5.py
@@ -0,0 +1,98 @@
+"""
+Tests for the md5 module implemented at interp-level in pypy/module/_md5.
+"""
+
+import py, sys
+from pypy.conftest import gettestobjspace
+
+
+class AppTestMD5(object):
+
+ def setup_class(cls):
+ """
+ Create a space with the md5 module and import it for use by the
+ tests.
+ """
+ cls.space = gettestobjspace(usemodules=['_md5'])
+ cls.w_md5 = cls.space.appexec([], """():
+ import _md5
+ return _md5
+ """)
+
+
+ def test_digest_size(self):
+ """
+ md5.digest_size should be 16.
+ """
+ assert self.md5.md5().digest_size == 16
+
+
+ def test_MD5Type(self):
+ """
+ Test the construction of an md5 object.
+ """
+ md5 = self.md5
+ d = md5.md5()
+
+
+ def test_md5object(self):
+ """
+ Feed example strings into a md5 object and check the digest and
+ hexdigest.
+ """
+ md5 = self.md5
+ import binascii
+ cases = (
+ (b"",
+ "d41d8cd98f00b204e9800998ecf8427e"),
+ (b"a",
+ "0cc175b9c0f1b6a831c399e269772661"),
+ (b"abc",
+ "900150983cd24fb0d6963f7d28e17f72"),
+ (b"message digest",
+ "f96b697d7cb7938d525a2f31aaf161d0"),
+ (b"abcdefghijklmnopqrstuvwxyz",
+ "c3fcd3d76192e4007dfb496cca67e13b"),
+ (b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "d174ab98d277d9f5a5611c2c9f419d9f"),
+ (b"1234567890"*8,
+ "57edf4a22be3c955ac49da2e2107b67a"),
+ )
+ for input, expected in cases:
+ d = md5.md5(input)
+ assert d.hexdigest() == expected
+ assert d.digest() == binascii.unhexlify(expected.encode('ascii'))
+
+
+ def test_copy(self):
+ """
+ Test the copy() method.
+ """
+ md5 = self.md5
+ d1 = md5.md5()
+ d1.update(b"abcde")
+ d2 = d1.copy()
+ d2.update(b"fgh")
+ d1.update(b"jkl")
+ assert d1.hexdigest() == 'e570e7110ecef72fcb772a9c05d03373'
+ assert d2.hexdigest() == 'e8dc4081b13434b45189a720b77b6818'
+
+
+ def test_buffer(self):
+ """
+ Test passing a buffer object.
+ """
+ md5 = self.md5
+ d1 = md5.md5(buffer(b"abcde"))
+ d1.update(buffer(b"jkl"))
+ assert d1.hexdigest() == 'e570e7110ecef72fcb772a9c05d03373'
+
+
+ def test_unicode(self):
+ """
+ Test passing unicode strings.
+ """
+ md5 = self.md5
+ raises(TypeError, md5.md5, "abcde")
+ d1 = md5.md5()
+ raises(TypeError, d1.update, "jkl")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit