initial commit

This commit is contained in:
Mahmoud Hashemi 2013-02-19 18:04:47 -08:00
commit 2c4595e327
5 changed files with 186 additions and 0 deletions

41
.gitignore vendored Normal file
View File

@ -0,0 +1,41 @@
*.py[cod]
# emacs
*~
._*
.\#*
\#*\#
# C extensions
*.so
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
nosetests.xml
# Translations
*.mo
# Mr Developer
.mr.developer.cfg
.project
.pydevproject

4
README.md Normal file
View File

@ -0,0 +1,4 @@
# Boltons
Like builtins, but boltons. Stuff that should probably be in the
standard library, frankly speaking.

16
compat.py Normal file
View File

@ -0,0 +1,16 @@
# -*- coding: utf-8 -*-
import sys
IS_PY2 = sys.version_info[0] == 2
IS_PY3 = sys.version_info[0] == 3
if IS_PY2:
from StringIO import StringIO
unicode, str, bytes, basestring = unicode, str, str, basestring
elif IS_PY3:
from io import StringIO
unicode, str, bytes, basestring = str, bytes, bytes, str
else:
raise NotImplementedError('welcome to the future, I guess. (report this)')

78
funcutils.py Normal file
View File

@ -0,0 +1,78 @@
from functools import partial
from types import MethodType
from itertools import chain
def mro_items(obj_type):
# handle slots?
return chain.from_iterable([ct.__dict__.iteritems()
for ct in obj_type.__mro__])
def dir_dict(obj):
# separate function for handling descriptors on types?
ret = {}
for k in dir(obj):
ret[k] = getattr(obj, k)
return ret
class InstancePartial(partial):
def __get__(self, obj, obj_type):
return MethodType(self, obj, obj_type)
class CachedInstancePartial(partial):
def __init__(self, func, *a, **kw):
self.__name__ = None
self.__doc__ = func.__doc__
self.__module__ = func.__module__
def __get__(self, obj, obj_type):
name = self.__name__
if name is None:
for k, v in mro_items(obj_type):
if v is self:
self.__name__ = name = k
if obj is None:
return MethodType(self, obj, obj_type)
try:
# since this is a data descriptor, this block
# is probably only hit once (per object)
return obj.__dict__[name]
except KeyError:
obj.__dict__[name] = ret = MethodType(self, obj, obj_type)
return ret
class Greeter(object):
def __init__(self, greeting):
self.greeting = greeting
def greet(self, excitement='.'):
return self.greeting.capitalize() + excitement
partial_greet = InstancePartial(greet, excitement='!')
cached_partial_greet = CachedInstancePartial(greet, excitement='...')
def native_greet(self):
return self.greet(';')
class SubGreeter(Greeter):
pass
def main():
g = SubGreeter('hello')
print g.greet()
print g.native_greet()
print g.partial_greet()
print g.cached_partial_greet()
print CachedInstancePartial(g.greet, excitement='s')()
import pdb;pdb.set_trace()
if __name__ == '__main__':
main()

47
iterutils.py Normal file
View File

@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
def is_scalar(obj):
return not hasattr(obj, '__iter__') or isinstance(obj, basestring)
def split(src, key=None, maxsplit=None):
"""
Splits an iterable based on a separator, iterable of separators, or
function that evaluates to True when a separator is encountered.
Frankly, this feature should be part of the list builtin.
TODO: This works with iterators but could itself be an generator.
"""
if maxsplit is not None:
maxsplit = int(maxsplit)
if maxsplit == 0:
return [src]
if callable(key):
key_func = key
elif not is_scalar(key):
key = set(key)
key_func = lambda x: x in key
else:
key_func = lambda x: x == key
ret = []
cur_list = []
for s in src:
if key_func(s):
ret.append(cur_list)
cur_list = []
if maxsplit is not None and len(ret) >= maxsplit:
key_func = lambda x: False
else:
cur_list.append(s)
ret.append(cur_list)
if key is None:
# If sep is none, str.split() "groups" separators
# check the str.split() docs for more info
return [x for x in ret if x]
else:
return ret