mylar/lib/natsort/compat/py23.py

127 lines
3.3 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import (
print_function,
division,
unicode_literals,
absolute_import
)
import functools
import sys
# These functions are used to make the doctests compatible between
# python2 and python3, and also provide uniform functionality between
# the two versions. This code is pretty much lifted from the iPython
# project's py3compat.py file. Credit to the iPython devs.
# Numeric form of version
PY_VERSION = float(sys.version[:3])
NEWPY = PY_VERSION >= 3.3
# Assume all strings are Unicode in Python 2
py23_str = str if sys.version[0] == '3' else unicode
# Use the range iterator always
py23_range = range if sys.version[0] == '3' else xrange
# Uniform base string type
py23_basestring = str if sys.version[0] == '3' else basestring
# unichr function
py23_unichr = chr if sys.version[0] == '3' else unichr
def _py23_cmp(a, b):
return (a > b) - (a < b)
py23_cmp = _py23_cmp if sys.version[0] == '3' else cmp
# zip as an iterator
if sys.version[0] == '3':
py23_zip = zip
py23_map = map
py23_filter = filter
else:
import itertools
py23_zip = itertools.izip
py23_map = itertools.imap
py23_filter = itertools.ifilter
# cmp_to_key was not created till 2.7, so require this for 2.6
try:
from functools import cmp_to_key
except ImportError: # pragma: no cover
def cmp_to_key(mycmp):
"""Convert a cmp= function into a key= function"""
class K(object):
__slots__ = ['obj']
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
def __ne__(self, other):
return mycmp(self.obj, other.obj) != 0
def __hash__(self):
raise TypeError('hash not implemented')
return K
# This function is intended to decorate other functions that will modify
# either a string directly, or a function's docstring.
def _modify_str_or_docstring(str_change_func):
@functools.wraps(str_change_func)
def wrapper(func_or_str):
if isinstance(func_or_str, py23_basestring):
func = None
doc = func_or_str
else:
func = func_or_str
doc = func.__doc__
if doc is not None:
doc = str_change_func(doc)
if func:
func.__doc__ = doc
return func
return doc
return wrapper
# Properly modify a doctstring to either have the unicode literal or not.
if sys.version[0] == '3':
# Abstract u'abc' syntax:
@_modify_str_or_docstring
def u_format(s):
""""{u}'abc'" --> "'abc'" (Python 3)
Accepts a string or a function, so it can be used as a decorator."""
return s.format(u='')
else:
# Abstract u'abc' syntax:
@_modify_str_or_docstring
def u_format(s):
""""{u}'abc'" --> "u'abc'" (Python 2)
Accepts a string or a function, so it can be used as a decorator."""
return s.format(u='u')