mirror of https://github.com/mahmoud/boltons.git
initial commit
This commit is contained in:
commit
2c4595e327
|
@ -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
|
|
@ -0,0 +1,4 @@
|
|||
# Boltons
|
||||
|
||||
Like builtins, but boltons. Stuff that should probably be in the
|
||||
standard library, frankly speaking.
|
|
@ -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)')
|
|
@ -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()
|
|
@ -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
|
Loading…
Reference in New Issue