Moved several things from fix.py to utils.py.

This commit is contained in:
Jeremy Fincher 2003-09-04 20:42:37 +00:00
parent 708e8e553b
commit f65829b768
10 changed files with 175 additions and 153 deletions

View File

@ -95,7 +95,6 @@ class Utilities(callbacks.Privmsg):
Joins all the arguments together with <separator>. Joins all the arguments together with <separator>.
""" """
sep = args.pop(0) sep = args.pop(0)
args = flatten(map(callbacks.tokenize, args))
irc.reply(msg, sep.join(args)) irc.reply(msg, sep.join(args))
def strtranslate(self, irc, msg, args): def strtranslate(self, irc, msg, args):

View File

@ -18,6 +18,7 @@ import threading
import cdb import cdb
import conf import conf
import debug import debug
import utils
import world import world
import ircutils import ircutils
@ -104,7 +105,7 @@ class PeriodicFileDownloader(object):
def _downloadFile(self, filename, url, f): def _downloadFile(self, filename, url, f):
infd = urllib2.urlopen(url) infd = urllib2.urlopen(url)
newFilename = mktemp() newFilename = utils.mktemp()
outfd = file(newFilename, 'wb') outfd = file(newFilename, 'wb')
start = time.time() start = time.time()
s = infd.read(4096) s = infd.read(4096)

View File

@ -40,6 +40,7 @@ import struct
import os.path import os.path
import cPickle as pickle import cPickle as pickle
import utils
def hash(s): def hash(s):
h = 5381 h = 5381
@ -166,7 +167,7 @@ class Maker(object):
self.fd.write(pack2Ints(hashPos, hashLen)) self.fd.write(pack2Ints(hashPos, hashLen))
class Reader(IterableMap): class Reader(utils.IterableMap):
def __init__(self, filename): def __init__(self, filename):
self.filename = filename self.filename = filename
self.fd = file(filename, 'r') self.fd = file(filename, 'r')
@ -263,7 +264,7 @@ class Reader(IterableMap):
__getitem__ = find __getitem__ = find
class ReaderWriter(IterableMap): class ReaderWriter(utils.IterableMap):
def __init__(self, filename, journalName=None, maxmods=0): def __init__(self, filename, journalName=None, maxmods=0):
if journalName is None: if journalName is None:
journalName = filename + '.journal' journalName = filename + '.journal'
@ -315,7 +316,7 @@ class ReaderWriter(IterableMap):
except IOError: except IOError:
pass pass
if removals or adds: if removals or adds:
tempfilename = mktemp('.db') tempfilename = utils.mktemp('.db')
maker = Maker(tempfilename) maker = Maker(tempfilename)
cdb = Reader(self.filename) cdb = Reader(self.filename)
for (key, value) in cdb.iteritems(): for (key, value) in cdb.iteritems():
@ -423,7 +424,7 @@ class ReaderWriter(IterableMap):
return default return default
class Shelf(ReaderWriter, IterableMap): class Shelf(ReaderWriter, utils.IterableMap):
def __getitem__(self, key): def __getitem__(self, key):
return pickle.loads(ReaderWriter.__getitem__(self, key)) return pickle.loads(ReaderWriter.__getitem__(self, key))

View File

@ -36,11 +36,11 @@ Fixes stuff that Python should have but doesn't.
""" """
import sys import sys
import string
if 'others' not in sys.path: if 'others' not in sys.path:
sys.path.insert(0, 'others') sys.path.insert(0, 'others')
import string
string.ascii = string.maketrans('', '') string.ascii = string.maketrans('', '')
def ignore(*args, **kwargs): def ignore(*args, **kwargs):
@ -54,58 +54,6 @@ def catch(f, *args, **kwargs):
except: except:
return None return None
class IterableMap(object):
"""Define .iteritems() in a class and subclass this to get the other iters.
"""
def iteritems(self):
raise NotImplementedError
def iterkeys(self):
for (key, _) in self.iteritems():
yield key
def itervalues(self):
for (_, value) in self.iteritems():
yield value
def items(self):
return list(self.iteritems())
def keys(self):
return list(self.iterkeys())
def values(self):
return list(self.itervalues())
def __len__(self):
ret = 0
for _ in self.iteritems():
ret += 1
return ret
def __nonzero__(self):
for _ in self.iteritems():
return True
return False
def mktemp(suffix=''):
"""Gives a decent random string, suitable for a filename."""
import sha
import md5
import time
import random
r = random.Random()
m = md5.md5(suffix)
r.seed(time.time())
s = str(r.getstate())
for x in xrange(0, random.randrange(400), random.randrange(1, 5)):
m.update(str(x))
m.update(s)
m.update(str(time.time()))
s = m.hexdigest()
return sha.sha(s + str(time.time())).hexdigest() + suffix
def reviter(L): def reviter(L):
"""Iterates through a list in reverse.""" """Iterates through a list in reverse."""
for i in xrange(len(L) - 1, -1, -1): for i in xrange(len(L) - 1, -1, -1):
@ -118,12 +66,15 @@ def window(L, size):
for i in xrange(len(L) - (size-1)): for i in xrange(len(L) - (size-1)):
yield L[i:i+size] yield L[i:i+size]
import itertools
def ilen(iterator): def ilen(iterator):
"""Returns the length of an iterator.""" """Returns the length of an iterator."""
i = 0 i = 0
for _ in iterator: for _ in iterator:
i += 1 i += 1
return i return i
itertools.ilen = ilen
del ilen
def group(seq, groupSize, noneFill=True): def group(seq, groupSize, noneFill=True):
"""Groups a given sequence into sublists of length groupSize.""" """Groups a given sequence into sublists of length groupSize."""
@ -146,32 +97,6 @@ def group(seq, groupSize, noneFill=True):
ret.append(L) ret.append(L)
return ret return ret
def itersplit(iterable, isSeparator, yieldEmpty=False):
"""Splits an iterator based on a predicate isSeparator."""
acc = []
for element in iterable:
if isSeparator(element):
if acc or yieldEmpty:
yield acc
acc = []
else:
acc.append(element)
if acc or yieldEmpty:
yield acc
def flatten(seq, strings=False):
"""Flattens a list of lists into a single list. See the test for examples.
"""
for elt in seq:
if not strings and type(elt) == str or type(elt) == unicode:
yield elt
else:
try:
for x in flatten(elt):
yield x
except TypeError:
yield elt
def partition(p, L): def partition(p, L):
"""Partitions a list L based on a predicate p. Returns a (yes,no) tuple""" """Partitions a list L based on a predicate p. Returns a (yes,no) tuple"""
no = [] no = []
@ -183,11 +108,6 @@ def partition(p, L):
no.append(elt) no.append(elt)
return (yes, no) return (yes, no)
def flip((x, y)):
"""Flips a two-tuple around. (x, y) becomes (y, x)."""
return (y, x)
def any(p, seq): def any(p, seq):
"""Returns true if any element in seq satisfies predicate p.""" """Returns true if any element in seq satisfies predicate p."""
if p is None: if p is None:

View File

@ -39,6 +39,7 @@ import atexit
import conf import conf
import debug import debug
import utils
import world import world
import ircdb import ircdb
import ircmsgs import ircmsgs
@ -472,7 +473,8 @@ class Irc(object):
u.addHostmask(msg.prefix) u.addHostmask(msg.prefix)
ircdb.users.setUser(self.nick, u) ircdb.users.setUser(self.nick, u)
else: else:
u = ircdb.IrcUser(capabilities=['owner'], password=mktemp(), u = ircdb.IrcUser(capabilities=['owner'],
password=utils.mktemp(),
hostmasks=[msg.prefix]) hostmasks=[msg.prefix])
ircdb.users.setUser(self.nick, u) ircdb.users.setUser(self.nick, u)
atexit.register(lambda: catch(ircdb.users.delUser(self.nick))) atexit.register(lambda: catch(ircdb.users.delUser(self.nick)))

View File

@ -330,4 +330,83 @@ def sortBy(f, L, cmp=cmp):
for (i, elt) in enumerate(L): for (i, elt) in enumerate(L):
L[i] = L[i][1] L[i] = L[i][1]
def mktemp(suffix=''):
"""Gives a decent random string, suitable for a filename."""
import sha
import md5
import time
import random
r = random.Random()
m = md5.md5(suffix)
r.seed(time.time())
s = str(r.getstate())
for x in xrange(0, random.randrange(400), random.randrange(1, 5)):
m.update(str(x))
m.update(s)
m.update(str(time.time()))
s = m.hexdigest()
return sha.sha(s + str(time.time())).hexdigest() + suffix
def itersplit(isSeparator, iterable, maxsplit=-1, yieldEmpty=False):
"""Splits an iterator based on a predicate isSeparator."""
acc = []
for element in iterable:
if maxsplit == 0 or not isSeparator(element):
acc.append(element)
else:
maxsplit -= 1
if acc or yieldEmpty:
yield acc
acc = []
if acc or yieldEmpty:
yield acc
def flatten(seq, strings=False):
"""Flattens a list of lists into a single list. See the test for examples.
"""
for elt in seq:
if not strings and type(elt) == str or type(elt) == unicode:
yield elt
else:
try:
for x in flatten(elt):
yield x
except TypeError:
yield elt
class IterableMap(object):
"""Define .iteritems() in a class and subclass this to get the other iters.
"""
def iteritems(self):
raise NotImplementedError
def iterkeys(self):
for (key, _) in self.iteritems():
yield key
def itervalues(self):
for (_, value) in self.iteritems():
yield value
def items(self):
return list(self.iteritems())
def keys(self):
return list(self.iterkeys())
def values(self):
return list(self.itervalues())
def __len__(self):
ret = 0
for _ in self.iteritems():
ret += 1
return ret
def __nonzero__(self):
for _ in self.iteritems():
return True
return False
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

View File

@ -31,11 +31,13 @@
from test import * from test import *
import utils
class GameknotTestCase(PluginTestCase): class GameknotTestCase(PluginTestCase):
plugins = ('Gameknot',) plugins = ('Gameknot',)
def testGkstats(self): def testGkstats(self):
self.assertNotError('gkstats jemfinch') self.assertNotError('gkstats jemfinch')
self.assertError('gkstats %s' % mktemp()) self.assertError('gkstats %s' % utils.mktemp())
def testUrlSnarfer(self): def testUrlSnarfer(self):
self.assertNotError('http://gameknot.com/chess.pl?bd=1019508') self.assertNotError('http://gameknot.com/chess.pl?bd=1019508')
@ -47,11 +49,11 @@ class GameknotTestCase(PluginTestCase):
def testSnarfer(self): def testSnarfer(self):
self.assertRegexp('http://gameknot.com/chess.pl?bd=907498', self.assertRegexp('http://gameknot.com/chess.pl?bd=907498',
'\x02ddipaolo\x02 won') '\x02ddipaolo\x0f won')
self.assertRegexp('http://gameknot.com/chess.pl?bd=907498', self.assertRegexp('http://gameknot.com/chess.pl?bd=907498',
'\x02chroniqueur\x02 resigned') '\x02chroniqueur\x0f resigned')
self.assertRegexp('http://gameknot.com/chess.pl?bd=955432', self.assertRegexp('http://gameknot.com/chess.pl?bd=955432',
'\x02ddipaolo\x02 lost') '\x02ddipaolo\x0f lost')

View File

@ -29,19 +29,19 @@
# POSSIBILITY OF SUCH DAMAGE. # POSSIBILITY OF SUCH DAMAGE.
### ###
from test import * from test import *
import utils
class NotesTestCase(PluginTestCase): class NotesTestCase(PluginTestCase):
plugins = ('Notes',) plugins = ('Notes',)
def testSendnote(self): def testSendnote(self):
self.assertNotError('sendnote inkedmn test') self.assertNotError('sendnote inkedmn test')
self.assertError('sendnote %s %s' % (mktemp(), mktemp())) self.assertError('sendnote alsdkjfasldk foo')
def testNote(self): def testNote(self):
# self.assertNotError('note 1') # self.assertNotError('note 1')
self.assertError('note %s' % mktemp()) self.assertError('note blah')
def testNotes(self): def testNotes(self):
self.assertNotError('notes') self.assertNotError('notes')

View File

@ -32,6 +32,8 @@
from test import * from test import *
import itertools
class FunctionsTest(unittest.TestCase): class FunctionsTest(unittest.TestCase):
def testCatch(self): def testCatch(self):
def f(): def f():
@ -65,58 +67,6 @@ class FunctionsTest(unittest.TestCase):
self.assertRaises(ValueError, wwindow, [], 0) self.assertRaises(ValueError, wwindow, [], 0)
self.assertRaises(ValueError, wwindow, [], -1) self.assertRaises(ValueError, wwindow, [], -1)
def testItersplit(self):
L = [1, 2, 3] * 3
s = 'foo bar baz'
self.assertEqual(list(itersplit(L, lambda x: x == 3)),
[[1, 2], [1, 2], [1, 2]])
self.assertEqual(list(itersplit(L, lambda x: x == 3, True)),
[[1, 2], [1, 2], [1, 2], []])
self.assertEqual(list(itersplit([], lambda x: x)), [])
self.assertEqual(list(itersplit(s, lambda c: c.isspace())),
map(list, s.split()))
self.assertEqual(list(itersplit(['foo', 'for', 'bar'], 'for'.__eq__)),
[['foo'], ['bar']])
def testIterableMap(self):
class alist(IterableMap):
def __init__(self):
self.L = []
def __setitem__(self, key, value):
self.L.append((key, value))
def iteritems(self):
for (k, v) in self.L:
yield (k, v)
AL = alist()
self.failIf(AL)
AL[1] = 2
AL[2] = 3
AL[3] = 4
self.failUnless(AL)
self.assertEqual(AL.items(), [(1, 2), (2, 3), (3, 4)])
self.assertEqual(list(AL.iteritems()), [(1, 2), (2, 3), (3, 4)])
self.assertEqual(AL.keys(), [1, 2, 3])
self.assertEqual(list(AL.iterkeys()), [1, 2, 3])
self.assertEqual(AL.values(), [2, 3, 4])
self.assertEqual(list(AL.itervalues()), [2, 3, 4])
self.assertEqual(len(AL), 3)
def testFlatten(self):
def lflatten(seq):
return list(flatten(seq))
self.assertEqual(lflatten([]), [])
self.assertEqual(lflatten([1]), [1])
self.assertEqual(lflatten(range(10)), range(10))
twoRanges = range(10)*2
twoRanges.sort()
self.assertEqual(lflatten(zip(range(10), range(10))), twoRanges)
self.assertEqual(lflatten([1, [2, 3], 4]), [1, 2, 3, 4])
self.assertEqual(lflatten([[[[[[[[[[]]]]]]]]]]), [])
self.assertEqual(lflatten([1, [2, [3, 4], 5], 6]), [1, 2, 3, 4, 5, 6])
self.assertRaises(TypeError, lflatten, 1)
def testAny(self): def testAny(self):
self.failUnless(any(lambda i: i == 0, range(10))) self.failUnless(any(lambda i: i == 0, range(10)))
self.failIf(any(None, range(1))) self.failIf(any(None, range(1)))
@ -127,7 +77,16 @@ class FunctionsTest(unittest.TestCase):
self.failUnless(any(lambda i: i % 2, range(2))) self.failUnless(any(lambda i: i % 2, range(2)))
self.failIf(any(lambda i: i % 2 == 0, [1, 3, 5])) self.failIf(any(lambda i: i % 2 == 0, [1, 3, 5]))
def testPartition(self):
L = range(10)
def even(i):
return not(i % 2)
(yes, no) = partition(even, L)
self.assertEqual(yes, [0, 2, 4, 6, 8])
self.assertEqual(no, [1, 3, 5, 7, 9])
def testIlen(self):
self.assertEqual(itertools.ilen(iter(range(10))), 10)
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78:

View File

@ -176,5 +176,64 @@ class UtilsTest(unittest.TestCase):
self.assertEqual(utils.nItems(2, 'tool', 'crazy'), '2 crazy tools') self.assertEqual(utils.nItems(2, 'tool', 'crazy'), '2 crazy tools')
self.assertEqual(utils.nItems(2, 'tool'), '2 tools') self.assertEqual(utils.nItems(2, 'tool'), '2 tools')
def testItersplit(self):
from utils import itersplit
L = [1, 2, 3] * 3
s = 'foo bar baz'
self.assertEqual(list(itersplit(lambda x: x == 3, L)),
[[1, 2], [1, 2], [1, 2]])
self.assertEqual(list(itersplit(lambda x: x == 3, L, yieldEmpty=True)),
[[1, 2], [1, 2], [1, 2], []])
self.assertEqual(list(itersplit(lambda x: x, [])), [])
self.assertEqual(list(itersplit(lambda c: c.isspace(), s)),
map(list, s.split()))
self.assertEqual(list(itersplit('for'.__eq__, ['foo', 'for', 'bar'])),
[['foo'], ['bar']])
self.assertEqual(list(itersplit('for'.__eq__,
['foo','for','bar','for', 'baz'], 1)),
[['foo'], ['bar', 'for', 'baz']])
def testIterableMap(self):
class alist(utils.IterableMap):
def __init__(self):
self.L = []
def __setitem__(self, key, value):
self.L.append((key, value))
def iteritems(self):
for (k, v) in self.L:
yield (k, v)
AL = alist()
self.failIf(AL)
AL[1] = 2
AL[2] = 3
AL[3] = 4
self.failUnless(AL)
self.assertEqual(AL.items(), [(1, 2), (2, 3), (3, 4)])
self.assertEqual(list(AL.iteritems()), [(1, 2), (2, 3), (3, 4)])
self.assertEqual(AL.keys(), [1, 2, 3])
self.assertEqual(list(AL.iterkeys()), [1, 2, 3])
self.assertEqual(AL.values(), [2, 3, 4])
self.assertEqual(list(AL.itervalues()), [2, 3, 4])
self.assertEqual(len(AL), 3)
def testFlatten(self):
def lflatten(seq):
return list(utils.flatten(seq))
self.assertEqual(lflatten([]), [])
self.assertEqual(lflatten([1]), [1])
self.assertEqual(lflatten(range(10)), range(10))
twoRanges = range(10)*2
twoRanges.sort()
self.assertEqual(lflatten(zip(range(10), range(10))), twoRanges)
self.assertEqual(lflatten([1, [2, 3], 4]), [1, 2, 3, 4])
self.assertEqual(lflatten([[[[[[[[[[]]]]]]]]]]), [])
self.assertEqual(lflatten([1, [2, [3, 4], 5], 6]), [1, 2, 3, 4, 5, 6])
self.assertRaises(TypeError, lflatten, 1)
# vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: # vim:set shiftwidth=4 tabstop=8 expandtab textwidth=78: