Source

WebHelpersWs / webhelpers / compat.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2013, Wolfgang Scherer, <Wolfgang.Scherer at gmx.de>
# Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
#
# This file is part of Wiedenmann Utilities.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>,
# or write to Wolfgang Scherer, <Wolfgang.Scherer at gmx.de>
"""\
compat.py - Py2/Py3k compatibility functions

======  ========================
usage:  import webhelpers.compat
======  ========================

Exports
-------

>>> for ex in __all__:
...     printf(sformat('from {0} import {1}', __name__, ex))
from webhelpers.compat import printf
from webhelpers.compat import sformat
from webhelpers.compat import isstring
from webhelpers.compat import UCHAR_FMT
from webhelpers.compat import ditems
from webhelpers.compat import dkeys
from webhelpers.compat import dvalues
from webhelpers.compat import uc_type
from webhelpers.compat import ucs
from webhelpers.compat import u8s
from webhelpers.compat import nts

.. _END_OF_HELP_compat:
"""

# --------------------------------------------------
# |||:sec:||| COMPATIBILITY
# --------------------------------------------------

__all__ = []

import sys

__all__.append('printf')
# (progn (forward-line 1) (snip-insert "py.b.printf" t t "py") (insert "\n"))
# adapted from http://www.daniweb.com/software-development/python/code/217214
try:
    printf = eval("print") # python 3.0 case
except SyntaxError:
    printf_dict = dict()
    try:
        exec("from __future__ import print_function\nprintf=print", printf_dict)
        printf = printf_dict["printf"] # 2.6 case
    except SyntaxError:
        def printf(*args, **kwd): # 2.4, 2.5, define our own Print function
            fout = kwd.get("file", sys.stdout)
            w = fout.write
            if args:
                w(str(args[0]))
            sep = kwd.get("sep", " ")
            for a in args[1:]:
                w(sep)
                w(str(a))
            w(kwd.get("end", "\n"))
    del printf_dict

__all__.append('sformat')
# (progn (forward-line 1) (snip-insert "py.b.sformat" t t "py") (insert "\n"))
try:
    ('{0}').format(0)
    def sformat (fmtspec, *args, **kwargs):
        return fmtspec.format(*args, **kwargs)
except AttributeError:
    try:
        import stringformat
        def sformat (fmtspec, *args, **kwargs):
            return stringformat.FormattableString(fmtspec).format(
                *args, **kwargs)
    except ImportError:
        printf('error: stringformat missing. Try `easy_install stringformat`.', file=sys.stderr)

__all__.append('isstring')
__all__.append('UCHAR_FMT')
# (progn (forward-line 1) (snip-insert "py.f.isstring" t t "py") (insert "\n"))
# Portable UNICODE character escapes:
#     uchar = eval(sformat(UCHAR_FMT,'\\', 0x1000))
# hide from 2to3
exec('''
def isstring(obj):
    return isinstance(obj, basestring)
''')
try:
    isstring("")
    UCHAR_FMT = 'u"{0}u{1:04x}"'
except NameError:
    def isstring(obj):
        return isinstance(obj, str) or isinstance(obj, bytes)
    UCHAR_FMT = '"{0}u{1:04x}"'

__all__.append('ditems')
__all__.append('dkeys')
__all__.append('dvalues')
# (progn (forward-line 1) (snip-insert "py.b.dict.items" t t "py") (insert "\n"))
try:
    getattr(dict(), 'iteritems')
except AttributeError:
    ditems  = lambda d: getattr(d, 'items')()
    dkeys   = lambda d: getattr(d, 'keys')()
    dvalues = lambda d: getattr(d, 'values')()
else:
    ditems  = lambda d: getattr(d, 'iteritems')()
    dkeys   = lambda d: getattr(d, 'iterkeys')()
    dvalues = lambda d: getattr(d, 'itervalues')()

# (progn (forward-line 1) (snip-insert "py.b.strings" t t "py") (insert "\n"))
def _ucs(string, charset=None):                            # ||:fnc:||
    return unicode(string, charset or 'utf-8')
try:
    _ucs("")
except NameError:
    _ucs = lambda s, c=None: s.decode(c or 'utf-8')

__all__.append('uc_type')
uc_type = type(_ucs(b""))

__all__.append('ucs')
def ucs(value, charset=None):                              # ||:fnc:||
    """\
    Convert `value` to unicode string using charset or UTF-8, if
    `value` is a string.

    If `value` is not a string, or if it is already a unicode string,
    return it unmodified.
    """
    if isstring(value) and not isinstance(value, uc_type):
        return _ucs(value, charset)
    return value

__all__.append('u8s')
def u8s(string, encoding=None):                            # ||:fnc:||
    """\
    Convert `string` to UTF-8-encoded byte string, if `string` is a
    unicode string.

    If `string` is not a unicode string, return it unmodified.
    """
    if isinstance(string, uc_type):
        return string.encode(encoding or 'utf-8')
    return string

__all__.append('nts')
def nts(string):                                           # ||:fnc:||
    """\
    Convert string to native string, if applicable.

    Python2 native strings are byte strings, while Python3 native
    strings are unicode.
    """
    # for python3, unicode strings have type str
    if isinstance(string, str):
        return string
    # for python2, encode unicode strings to utf-8 strings
    if isinstance(string, uc_type):
        return string.encode('utf-8')
    if isstring(string):
        try:
            return str(string.decode('utf-8'))
        except UnicodeDecodeError:
            #return str(string.decode('latin1'))
            pass
    return string

try:
    from UserDict import DictMixin
except ImportError:
    from collections import MutableMapping as DictMixin

try:
    import urlparse # as urlparse
except ImportError:
    import urllib.parse as urlparse # as urlparse

try:
    from urllib import quote as urllib_quote
except ImportError:
    from urllib.parse import quote as urllib_quote

try:
    from urllib import urlencode as urllib_urlencode
except ImportError:
    from urllib.parse import urlencode as urllib_urlencode

try:
    from urllib import quote as url_escape
except ImportError:
    from urllib.parse import quote as url_escape

# :ide: COMPILE: Run with python3 w/o args
# . (progn (save-buffer) (compile (concat "python3 ./" (file-name-nondirectory (buffer-file-name)) " ")))

# :ide: COMPILE: Run w/o args
# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))

# :ide: +-#+
# . Compile ()

#
# Local Variables:
# mode: python
# comment-start: "#"
# comment-start-skip: "#+"
# comment-column: 0
# truncate-lines: t
# End: