Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python 3 fixes #1

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# zbase62
A fork of [simplegeo/zbase62](https://github.com/simplegeo/zbase62).

Changes:
- Remove dependency on [pyutil](https://github.com/simplegeo/pyutil) so that file [zbase62.py](/zbase62/zbase62.py) is self-contained thus can be used in a drop-in way.
- Make code work on Python 3 too.

Python: 2.4+ and 3.0+
66 changes: 14 additions & 52 deletions ez_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

This file can also be run as a script to install or upgrade setuptools.
"""

from __future__ import print_function

import sys
DEFAULT_VERSION = "0.6c11"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
Expand Down Expand Up @@ -70,9 +73,9 @@ def _validate_md5(egg_name, data):
if egg_name in md5_data:
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print >>sys.stderr, (
print(
"md5 validation of %s failed! (Possible download problem?)"
% egg_name
% egg_name, file=sys.stderr
)
sys.exit(2)
return data
Expand Down Expand Up @@ -103,14 +106,13 @@ def do_download():
return do_download()
try:
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
except pkg_resources.VersionConflict as e:
if was_imported:
print >>sys.stderr, (
print(
"The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'."
"\n\n(Currently using %r)"
) % (version, e.args[0])
"\n\n(Currently using %r)" % (version, e.args[0]), file=sys.stderr)
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
Expand Down Expand Up @@ -165,41 +167,6 @@ def download_setuptools(
if dst: dst.close()
return os.path.realpath(saveto)




































def main(argv, version=DEFAULT_VERSION):
"""Install or upgrade setuptools and EasyInstall"""
try:
Expand All @@ -216,9 +183,10 @@ def main(argv, version=DEFAULT_VERSION):
os.unlink(egg)
else:
if setuptools.__version__ == '0.0.1':
print >>sys.stderr, (
print(
"You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script."
"remove it from your system entirely before rerunning this script.",
file=sys.stderr
)
sys.exit(2)

Expand All @@ -238,8 +206,8 @@ def main(argv, version=DEFAULT_VERSION):
from setuptools.command.easy_install import main
main(argv)
else:
print "Setuptools version",version,"or greater has been installed."
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
print("Setuptools version",version,"or greater has been installed.")
print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)')

def update_md5(filenames):
"""Update our built-in md5 registry"""
Expand All @@ -262,7 +230,7 @@ def update_md5(filenames):

match = re.search("\nmd5_data = {\n([^}]+)}", src)
if not match:
print >>sys.stderr, "Internal error!"
print("Internal error!", file=sys.stderr)
sys.exit(2)

src = src[:match.start(1)] + repl + src[match.end(1):]
Expand All @@ -276,9 +244,3 @@ def update_md5(filenames):
update_md5(sys.argv[2:])
else:
main(sys.argv[1:])






6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#
# See README.txt for licensing information.

from __future__ import print_function

import glob, os, re, sys

eggs = glob.glob('darcsver-*.egg')
Expand Down Expand Up @@ -51,7 +53,7 @@
if mo:
verstr = mo.group(1)
else:
print "unable to find version in %s" % (VERSIONFILE,)
print("unable to find version in %s" % (VERSIONFILE,))
raise RuntimeError("if %s.py exists, it must be well-formed" % (VERSIONFILE,))

setup_requires = []
Expand All @@ -66,7 +68,7 @@
# "sdist" or "bdist_egg"), unless there is a zbase62.egg-info/SOURCE.txt file
# present which contains a complete list of files that should be included.
# http://pypi.python.org/pypi/setuptools_darcs
setup_requires.append('setuptools_darcs >= 1.1.0')
#setup_requires.append('setuptools_darcs >= 1.1.0')

data_fnames=[ 'COPYING.GPL', 'COPYING.TGPPL.html', 'COPYING.SPL.txt', 'README.txt' ]

Expand Down
69 changes: 44 additions & 25 deletions zbase62/test/test_base62.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,25 @@
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this work to deal in this work without restriction (including the rights
# to use, modify, distribute, sublicense, and/or sell copies).

import os, sys
import random, unittest

# http://zooko.com/repos/pyutil
from pyutil import mathutil, randutil
IS_PY2 = sys.version_info[0] == 2
if not IS_PY2:
unicode = str

def div_ceil(n, d):
"""
The smallest integer k such that k*d >= n.

Copied from https://pypi.org/project/pyutil/
"""
return int((n//d) + (n%d != 0))

from zbase62 import zbase62

def insecurerandstr(n):
return ''.join(map(chr, map(random.randrange, [0]*n, [256]*n)))
def random_bytes(n):
return os.urandom(n)

class T(unittest.TestCase):
def _test_num_octets_that_encode_to_this_many_chars(self, chars, octets):
Expand All @@ -23,55 +32,65 @@ def _test_num_octets_that_encode_to_this_many_chars(self, chars, octets):
def _test_ende(self, bs):
alphas=zbase62.b2a(bs)
bs2=zbase62.a2b(alphas)
assert bs2 == bs, "bs2: %s:%s, bs: %s:%s, alphas: %s:%s" % (len(bs2), `bs2`, len(bs), `bs`, len(alphas), `alphas`)
assert bs2 == bs, "bs2: %s:%s, bs: %s:%s, alphas: %s:%s" % (len(bs2), repr(bs2), len(bs), repr(bs), len(alphas), repr(alphas))

def test_num_octets_that_encode_to_this_many_chars(self):
return self._test_num_octets_that_encode_to_this_many_chars(2, 1)
return self._test_num_octets_that_encode_to_this_many_chars(3, 2)
return self._test_num_octets_that_encode_to_this_many_chars(5, 3)
return self._test_num_octets_that_encode_to_this_many_chars(6, 4)
self._test_num_octets_that_encode_to_this_many_chars(2, 1)
self._test_num_octets_that_encode_to_this_many_chars(3, 2)
self._test_num_octets_that_encode_to_this_many_chars(5, 3)
self._test_num_octets_that_encode_to_this_many_chars(6, 4)

def test_empty(self):
self._test_ende(b'')

def test_ende_0x00(self):
return self._test_ende('\x00')
self._test_ende(b'\x00')

def test_ende_0x01(self):
return self._test_ende('\x01')
self._test_ende(b'\x01')

def test_ende_0x0100(self):
return self._test_ende('\x01\x00')
self._test_ende(b'\x01\x00')

def test_ende_0x000000(self):
return self._test_ende('\x00\x00\x00')
self._test_ende(b'\x00\x00\x00')

def test_ende_0x010000(self):
return self._test_ende('\x01\x00\x00')
self._test_ende(b'\x01\x00\x00')

def test_ende_randstr(self):
return self._test_ende(insecurerandstr(2**4))
self._test_ende(random_bytes(2 ** 4))

def test_ende_longrandstr(self):
return self._test_ende(insecurerandstr(random.randrange(0, 2**10)))
self._test_ende(random_bytes(random.randrange(0, 2 ** 10)))

def test_odd_sizes(self):
for j in range(2**6):
lib = random.randrange(1, 2**8)
numos = mathutil.div_ceil(lib, 8)
bs = insecurerandstr(numos)
numos = div_ceil(lib, 8)
bs = random_bytes(numos)
# zero-out unused least-sig bits
if lib%8:
b=ord(bs[-1])
b=ord(bs[-1]) if IS_PY2 else bs[-1]
b = b >> (8 - (lib%8))
b = b << (8 - (lib%8))
bs = bs[:-1] + chr(b)
asl = zbase62.b2a_l(bs, lib)
bs = bs[:-1] + (chr(b) if IS_PY2 else bytes([b]))
asl = zbase62.b2a(bs)
assert len(asl) == zbase62.num_chars_that_this_many_octets_encode_to(numos) # the size of the base-62 encoding must be just right
bs2l = zbase62.a2b_l(asl, lib)
assert len(bs2l) == numos # the size of the result must be just right
assert bs == bs2l

def suite():
suite = unittest.makeSuite(T, 'test')
return suite
def test_invalid(self):
# doesn't fail
zbase62.a2b('~!~')

def test_types(self):
assert type(zbase62.a2b(u'x')) == bytes
assert type(zbase62.a2b(b'x')) == bytes

assert type(zbase62.b2a(u'x')) == unicode
assert type(zbase62.b2a(b'x')) == unicode

if __name__ == "__main__":
unittest.main()
Expand Down
Loading