GithubHelp home page GithubHelp logo

six's Introduction

six on PyPI six on TravisCI six's documentation on Read the Docs MIT License badge

Six is a Python 2 and 3 compatibility library. It provides utility functions for smoothing over the differences between the Python versions with the goal of writing Python code that is compatible on both Python versions. See the documentation for more information on what is provided.

Six supports Python 2.7 and 3.3+. It is contained in only one Python file, so it can be easily copied into your project. (The copyright and license notice must be retained.)

Online documentation is at https://six.readthedocs.io/.

Bugs can be reported to https://github.com/benjaminp/six. The code can also be found there.

six's People

Contributors

alexanderlukanin13 avatar asottile avatar bartvm avatar benjaminp avatar brettcannon avatar catleeball avatar cclauss avatar delirious-lettuce avatar fmoo avatar graingert avatar harlowja avatar hroncok avatar jaraco avatar jdufresne avatar jmoldow avatar mariatta avatar maxgrenderjones avatar mirkorossini avatar msabramo avatar pgrimaud avatar scop avatar shlomif avatar stanislavlevin avatar tgamblin avatar timgraham avatar toabctl avatar toslunar avatar vstinner avatar webknjaz avatar wolph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

six's Issues

six.assertCountEqual(self,

Originally reported by: Rémy HUBSCHER (Bitbucket: natim, GitHub: natim)


We should add

#!python

def assertCountEqual(self, first, second, msg=None):
    if six.PY2:
        return self.assertItemsEqual(first, second, msg)
    return self.assertCountEqual(first, second, msg)

"from six.moves.tkinter import *" and similar give ImportError

Originally reported by: peterjc (Bitbucket: peterjc, GitHub: peterjc)


Consider these Python 2 snippets:

from Tkinter import *
from Tkinter import mainloop

And the Python 3 equivalents after 2to3 conversion:

from tkinter import *
from tkinter import mainloop

The expected equivalents via six fails,

from six.moves.tkinter import *
from six.moves.tkinter import mainloop

e.g.

$ python2.7
Python 2.7.2 (default, Oct 11 2012, 20:14:37) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from six.moves.tkinter import *
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named tkinter

Or,

>>> from six.moves.tkinter import mainloop
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named tkinter

As a limited workaround, this works, but requires editing all usage of the terms, e.g. replacing mainloop with tinter.mainloop:

from six.moves import tkinter

iterkeys(), itervalues() and iteritems() should return iterators

Originally reported by: Sven Marnach (Bitbucket: smarnach, GitHub: smarnach)


The docstring of iterkeys() is "Return an iterator over the keys of a dictionary." Yet, it doesn't:

>>> it = six.iterkeys({})
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: dict_keys object is not an iterator

The function should call iter() on its return value to actually return an iterator. This would also be consistent with what 2to3 does: http://hg.python.org/cpython/file/a970054a93fb/Lib/lib2to3/fixes/fix_dict.py#l10


Additional object model compatibility methods

Originally reported by: Aymeric Augustin (Bitbucket: aaugustin, GitHub: aaugustin)


http://docs.python.org/3/whatsnew/3.0.html?#operators-and-special-methods says:

func_closure, func_code, func_defaults, func_dict, func_doc, func_globals, func_name were renamed to __closure__, __code__, __defaults__, __dict__, __doc__, __globals__, __name__, respectively.

Currently six only provides compatibility methods for the second and the third of these seven attributes: get_function_code and get_function_defaults.

Apparently, some of the new names already work under CPython 2.x. But they aren't documented and some alternative implementations don't have them. For instance, PyPy 1.9 doesn't have __globals__: https://code.djangoproject.com/ticket/19944

I suggest to add compatibility methods for the five other function attributes; or if there's a good reason I'm not aware of for not providing them, to explain it in the docs :)

I can fix this in the patched version of six shipped with Django (it already adds a few Django-specific compatibility functions), but since that problem isn't specific to Django, I'm filing this ticket here too.


six.moves.urllib_* don't work when six is bundled in another package

Originally reported by: Aymeric Augustin (Bitbucket: aaugustin, GitHub: aaugustin)


Django ships a copy of six as django.utils.six.

With version 1.2 everything worked as expected. In particular, six took care of using the __name__ + ".moves.xxx" idiom to support this use case.

Unfortunately, version 1.4 contains some hardcoded references "six.moves.xxx". The code looks like these references are kept simple on purpose. They're used for dummy import paths that one isn't supposed to use. However, in practice, it doesn't work for me.

(django-dev)myk@mYk django % cd django/utils
(django-dev)myk@mYk utils % python
Python 2.7.2 (default, Oct 11 2012, 20:14:37) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from six.moves import urllib_parse
>>> ^D
(django-dev)myk@mYk utils % cd ../..
(django-dev)myk@mYk django % python
Python 2.7.2 (default, Oct 11 2012, 20:14:37) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from django.utils.six.moves import urllib_parse
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "django/utils/six.py", line 86, in __get__
    result = self._resolve()
  File "django/utils/six.py", line 105, in _resolve
    return _import_module(self.mod)
  File "django/utils/six.py", line 76, in _import_module
    __import__(name)
ImportError: No module named six.moves.urllib_parse
>>> ^D

Let me know if you need any additional information!


Python 2.6.8 unicode issue

Originally reported by: Artur Barseghyan (Bitbucket: barseghyanartur, GitHub: barseghyanartur)


  • six version 1.4.1
  • Python version 2.6.8
  • System Ubuntu 12.04 LTS

Consider the following string:

u'\u053c\u0585\u0580\u0565\u0574 \u056b\u057a\u057d\u0578\u0582\u0574 \u0564\u0585\u056c\u0585\u0580 \u057d\u056b\u057f \u0561\u0574\u0565\u057f'

Works

print u'\u053c\u0585\u0580\u0565\u0574 \u056b\u057a\u057d\u0578\u0582\u0574 \u0564\u0585\u056c\u0585\u0580 \u057d\u056b\u057f \u0561\u0574\u0565\u057f'

Fails

from six import print_
print_(u'\u053c\u0585\u0580\u0565\u0574 \u056b\u057a\u057d\u0578\u0582\u0574 \u0564\u0585\u056c\u0585\u0580 \u057d\u056b\u057f \u0561\u0574\u0565\u057f')

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)

At the moment, I'm encoding the strings that fail to print, but there should be a better solution.

On Python 2.7 and 3.3 the same code works smoothly.


Support UserString in six.moves

Originally reported by: Alex Gaynor (Bitbucket: alex_gaynor, GitHub: Unknown)


It moved from its own module to collections. Patch to support it:

diff -r 09499de25717 six.py
--- a/six.py	Wed Aug 21 23:04:37 2013 -0500
+++ b/six.py	Thu Aug 29 14:18:43 2013 -0700
@@ -148,6 +148,7 @@
     MovedAttribute("zip", "itertools", "builtins", "izip", "zip"),
     MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"),
     MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"),
+    MovedAttribute("UserString", "UserString", "collections"),
 
     MovedModule("builtins", "__builtin__"),
     MovedModule("configparser", "ConfigParser"),


Jython compatibility in setup.py

Originally reported by: squeaky (Bitbucket: squeaky, GitHub: squeaky)


Jython internally uses Java Integer type which is 32bit on the JVM regardless of the CPU for Python int representation. Jython also requires
len to return an Python integer and not long. The following code breaks on Jython because it returns Python long.

class X(object):
        def __len__(self):
            return 1 << 31
    try:
        len(X())
    except OverflowError:
        # 32-bit
        MAXSIZE = int((1 << 31) - 1)

because len returns Python long.

except (OverflowError, TypeError):

fixes the issue.

See https://bitbucket.org/squeaky/six/changeset/05d26f6faf8f


Include test suite in tarball

Originally reported by: cjwatson (Bitbucket: cjwatson, GitHub: cjwatson)


Thanks for six! I just sent off a patch series to python-debian using it, and I expect to use it in a few more ports too when 2to3 isn't feasible for one reason or another.

It would be great if the test suite (test_six.py and tox.ini, I think) were included in the distributed tarball; that way people like me who've uploaded packages of six to distributions (hi!) can easily arrange for the test suite to be run as part of our package builds as well as in your own pre-release processes.


six.u(r'\\') behaves differently on Python 2.x and 3.x

Originally reported by: daviddrysdale (Bitbucket: daviddrysdale, GitHub: daviddrysdale)


Python 3 preserves the two backslashes, Python 2 converts to a single backslash.

#!bash

$ python -c 'import six; print(six.u(r"\\"))'
\
$ python3 -c 'import six; print(six.u(r"\\"))'
\\

I guess this is down to the underlying unicode_escape codec, but it does give a visible behaviour difference between 2/3.


u() function does not support unicode character escapes

Originally reported by: Matt Chaput (Bitbucket: mchaput, GitHub: mchaput)


If I do:

six.u("\u1234")

in Python 2.x I should get:

u'\u1234'

but instead I get:

u'\\uABCD'

Unfortunately the only way I can think of to fix this is to loop through the unicode string with a regular expression and rebuild the string to replace \\u([0-9a-fA-F]{4}) with unichr(int(match.group(1), 16)) if you see what I mean.


Script to “six-ify” source

Originally reported by: Zearin (Bitbucket: Zearin, GitHub: Zearin)


**Wouldn’t it be cool if six had a script in the spirit of 2to3? **

Imagine if this (invented) example were possible:

$ python -m "six" spam.py eggs.py food/*.py

…Adding "import six" to source…
Success!

…Converting "isinstance" and "issubclass" to six constants for:
    …six.class_types…
    Success!
    
    …six.integer_types…
    Success!
    
    …six.string_types…
    Success!

…Converting "print" to "six.print_"…
    Success on 38 of 40 occurrences; couldn’t convert the following:
    
    spam.py:135 : Ambiguous print arguments.  Please fix manually.
    spam.py:202 : Ambiguous print arguments.  Please fix manually.
    
    Comments labelled "# @SIXME" have been inserted to mark these locations.

Basically:

Six is awesome, and there are plenty of cases where existing could needs the scrutiny of a human to determine how to integrate six. But there are plenty of cases where it’s a no-brainer:

  • uses of isinstance or issubclass
  • print
  • module renames (as seen in //[[http://packages.python.org/six/#module-six.moves|Renamed modules and attributes compatibility]]// of the documentation.)

Following 2to3’s example, the script should allow fine-grained control to opt-in or opt-out of any particular conversions.


map/filter issues

Originally reported by: Michael Salib (Bitbucket: msalib, GitHub: msalib)


Right now, I'm having trouble with map/filter in code that is supposed to run under 2.x and 3.x. I try to use from future_builtins import map, filter but py3 doesn't have a future_builtins module. I propose that six add MovedAttributes for both map and filter, using the itertools version in py2.x (which is what the future_builtins versions actually are anyway...) and the standard builtins version in py3.x. I've attached a patch that makes this change and adds tests; my patch also adds py32 to the tox environment list and adds .tox to .hgignore for convenience.

Thanks!


Could do with some decorators for the __unicode__ and __str__ rename

Originally reported by: Tom Grainger (Bitbucket: graingert, GitHub: graingert)


Django uses https://github.com/django/django/blob/master/django/utils/encoding.py#L26

to support both python2 and python3 style __unicode__ and __str__ renames.

the Python 3 porting guide suggests http://docs.python.org/3/howto/pyporting.html#str-unicode

This pattern is likely to be used in lots of projects hoping to support both 3k and 2, so I think it should be included in six.


dir(six.moves.<module>) is lazily populated

Originally reported by: Marc Abramowitz (Bitbucket: msabramo, GitHub: msabramo)


An unfortunate side effect of the lazy population of six.moves is that dir isn't very useful.

E.g.:

marca@marca-mac:~/dev/hg-repos/six$ hg tip
changeset:   148:7f239896f632
tag:         tip
user:        Benjamin Peterson <[email protected]>
date:        Thu Sep 05 16:54:07 2013 -0400
files:       documentation/index.rst
description:
mention urlparse.ParseResult (fixes #33)

marca@marca-mac:~/dev/hg-repos/six$ python
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr  9 2012, 20:52:43)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import six
>>> six.moves.urllib.parse
<module 'six.moves.urllib_parse' (built-in)>
>>> dir(six.moves.urllib.parse)
['__doc__', '__name__']
>>> six.moves.urllib.parse.ParseResult
<class 'urlparse.ParseResult'>
>>> dir(six.moves.urllib.parse)
['ParseResult', '__doc__', '__name__']

I wonder if a __dir__ method can be added so that dir returns useful output...?


six.moves.xrange name is inconsistent with six.moves naming conventions

Originally reported by: Dan Blanchard (Bitbucket: daniel_blanchard, GitHub: Unknown)


I've recently started using six, and I noticed something really puzzling in the naming conventions for some of the functions in six.moves that have to do with generators:

filter, map, and zip are all named after the Python 3 version.
xrange is named after the Python 2 version.

Why is this the case? With the current name, using "range" in Python 2 will give you a list and in Python 3 it'll give you a range object. This makes it really easy to make mistakes by writing code with Python 2 and not having it run correctly on Python 3. If the idea is that people should get used to writing constructions like list(range(...)), it would make more sense if you were forced to do that instead of being able to accidentally write code that only runs on Python 2.

This issue would be entirely prevented if the name was just "range" like with "zip". With zip you also have to put an outer list to make things work as expected on Python 3, but it won't work on Python 2 either because the default "zip" is overridden.


Multiple base classes for six.with_metaclass

Originally reported by: Miroslav Shubernetskiy (Bitbucket: miki725, GitHub: miki725)


Sometimes multiple bases are appropriate with a custom metaclass:

class Foo(Base1, Base2):
    __metaclass__ = Meta

The above example cannot be simulated with six because six.with_metaclass allows to only specify one base class:

class Foo(six.with_metaclass(Meta, Base1)):
    pass

It would be nice if such functionality can be enabled in six.


Add encoding utility

Originally reported by: Claude Paroz (Bitbucket: claudep, GitHub: claudep)


Hi,

We're planning to embed six in Django as the blessed Python 3 compatibility layer. One thing we're missing is a function that returns a byte string on Python 2 and Unicode in Python 3. This is typically useful when providing arguments for strftime() or type(). Our current implementation is:

  • Python 2: n = lambda n: n.encode('utf-8')
  • Python 3 (noop): n = lambda n: n

We could of course provide it in some of our own modules, but it would be nice to have it in six, unless you suggest a better replacement.


Six does not allow multiple distinct instances of the package in different namespaces.

Originally reported by: Bryce Boe (Bitbucket: bboe, GitHub: bboe)


See this issue on the urllib3 package which includes a package-specific version of six.

The problem has to do with the line

moves = sys.modules["six.moves"] = _MovedItems("moves")

which will overwrite any previously defined moves upon importing six from a separate namespace.

Rather than always using six.moves as the module name, would the following namespace-sensitive approach work?

moves = sys.modules["%s.moves" % __name__] = _MovedItems("moves")

add want_bytes

Originally reported by: Thomas Waldmann (Bitbucket: thomaswaldmann, GitHub: thomaswaldmann)


Sometimes it is useful for APIs to accept unicode as well as bytes (e.g. if it usually is just some simply ascii text or hex number and you don't want to force your users to use b'...' for giving a value, but also accept '...').

See there why I needed it and for an implementation:

https://github.com/ThomasWaldmann/itsdangerous/blob/modernize/itsdangerous.py#L42

Feel free to change the name if you have a better idea.


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.