Anonymous avatar Anonymous committed 1613373

webhelpers/compat.py: Py2/Py3k compatibility.

Comments (0)

Files changed (1)

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:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.