benjaminp / six Goto Github PK
View Code? Open in Web Editor NEWPython 2 and 3 compatibility library
Home Page: https://six.readthedocs.io/
License: MIT License
Python 2 and 3 compatibility library
Home Page: https://six.readthedocs.io/
License: MIT License
Originally reported by: Artur Barseghyan (Bitbucket: barseghyanartur, GitHub: barseghyanartur)
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'
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'
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.
Originally reported by: Thomas Waldmann (Bitbucket: thomaswaldmann, GitHub: thomaswaldmann)
you already have int2byte, but the opposite is missing.
See there why I needed it / for a implementation:
https://github.com/ThomasWaldmann/itsdangerous/blob/modernize/itsdangerous.py#L36
Originally reported by: peterjc (Bitbucket: peterjc, GitHub: peterjc)
See http://docs.python.org/2/library/gdbm.html
Python 2:
import gdbm
Python 3 (or after running the 2to3 imports fixer):
import dbm.gnu
I would like to be able to use something like:
from six.moves import gdbm
or similar based on the Python 3 name.
Originally reported by: Jason R. Coombs (Bitbucket: jaraco, GitHub: jaraco)
As time permits, it would be useful to have a six.moves for xmlrpc.client.
Originally reported by: Ronny Pfannschmidt (Bitbucket: RonnyPfannschmidt, GitHub: RonnyPfannschmidt)
would help to have nice fast pypy compatible exception handling and support old python
Originally reported by: Ronny Pfannschmidt (Bitbucket: RonnyPfannschmidt, GitHub: RonnyPfannschmidt)
currently we cant import from modules in six.moves, cause six.move.X isnt added to sys.modules
if its reasonable, i'd do it
Originally reported by: Robert Robert (Bitbucket: rbtcollins, GitHub: rbtcollins)
Docs for print wrong : on http://pythonhosted.org/six/ it claims " six.print_(*args, *, file=sys.stdout, end="n", sep=" ")
Print args into file. Each argument will be separated with sep and end will be written to the file at the last."
but clearly that should be end= quote backslash n quote.
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.
Originally reported by: Vladislav Polukhin (Bitbucket: nuklea, GitHub: nuklea)
Unreachable string?
#!python
In [1]: import six
In [2]: six.u('строка')
Out[2]: u'\xd1\x81\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0'
In [3]: print six.u('строка')
ÑÑÑока
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!
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
Originally reported by: Konsta Vesterinen (Bitbucket: kvesteri, GitHub: kvesteri)
It would be great if six would provide OrderedDict for python versions below 2.7.
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.
Originally reported by: Bryce Boe (Bitbucket: bboe, GitHub: bboe)
Six should provide a six.input
method that uses either raw_input
in python2 or input
in python3.
Originally reported by: Zearin (Bitbucket: Zearin, GitHub: Zearin)
There are a few differences in the Exception hierarchies between Python 2 and 3.
(//Aside: Both Pythons allow you to interact with Exceptions without importing anything, but Python 2 also has an importable exceptions
module. Dunno why.//)
Could six provide a few mappings to address these differences?
Originally reported by: Aymeric Augustin (Bitbucket: aaugustin, GitHub: aaugustin)
It's available in six.moves.urllib.parse and I'm using it in Django.
I guess it's just an oversight and should be added to the docs.
Originally reported by: Andrej Antonov (Bitbucket: polymorphm, GitHub: polymorphm)
good day!
variable six.PY3
-- is time bomb :)
file six.py
now has code:
# True if we are running on Python 3.
PY3 = sys.version_info[0] == 3
...but must be somewhere like:
# True if we are running on Python version at least 3.
PY3 = sys.version_info[0] >= 3
thanks in advance! (and sorry for my bad english :))
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!
Originally reported by: Zearin (Bitbucket: Zearin, GitHub: Zearin)
Article that inspired my interest in this:
http://rhettinger.wordpress.com/2011/05/26/super-considered-super/
Python 3 allows the user of super()
without arguments, and it behaves in a way that just makes sense.
It would be awesome if six allowed me to use this form of super()
in projects that would work with both Python 2 and 3.
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...?
Originally reported by: James Cleveland (Bitbucket: radiosilence, GitHub: radiosilence)
Code:
import six; six.u(u'bawbag')
Error:
TypeError: decoding Unicode is not supported
I would suggest adding this in the u(s) function:
if isinstance(s, unicode):
return s
So that it behaves like the unicode() function, IE: liberal in what you accept, conservative in what you produce.
Originally reported by: Alex Gaynor (Bitbucket: alex_gaynor, GitHub: Unknown)
Little known fact, __slots__
can be a str
, for a single field, instead of a tuple
. Example program which breaks:
import six
@six.add_metaclass(type)
class X(object):
__slots__ = 'ab'
Originally reported by: Anonymous
It would be nice to have a function that emulates the qualname property of classes and functions for Python < 3.3.
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
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)
Originally reported by: Georg Brandl (Bitbucket: birkenfeld, GitHub: birkenfeld)
The docs say that the "five" package name has been snatched away; the respective link now goes to a 404.
Originally reported by: Ned Batchelder (Bitbucket: ned, GitHub: ned)
The builtin callable() is back in Python 3.2, but six always defines its own. Wouldn't it be better done as:
try:
callable = callable
except NameError:
def callable(obj):
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
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:
isinstance
or issubclass
print
Following 2to3
’s example, the script should allow fine-grained control to opt-in or opt-out of any particular conversions.
Originally reported by: Serge Matveenko (Bitbucket: lig, GitHub: lig)
There should be support for string.letters renamed to string.ascii_letters and other string module parts renamed in Python3.
Originally reported by: peterjc (Bitbucket: peterjc, GitHub: peterjc)
See http://docs.python.org/2/library/thread.html
Python 2:
import thread
Python 3 (or after running the 2to3 imports fixer):
import _thread
I would like to be able to use one of:
from six.moves import thread
or,
from six.moves import _thread
Originally reported by: kyleabeauchamp (Bitbucket: kyleabeauchamp, GitHub: kyleabeauchamp)
So the commands module was deprecated in python3. One of its useful functions, getoutput()
, is available in python3 in subprocess.
Is this migration something that six could facilitate? I suppose it's slightly more complex because it involves both a deleted module and a MovedAttribute.
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
Originally reported by: Petr Blaho (Bitbucket: petrblaho, GitHub: petrblaho)
Hi,
according to http://docs.python.org/2/library/xmlrpclib.html#module-xmlrpclib xmlrpclib was renamed to xmlrpc.client in python 3.
I cannot find it in six docs and code.
Originally reported by: Anonymous
In 2.4, this type of syntax is flagged as an error. It would be helpful if six provided a function that prevented this.
def _inline_if_else(t, c, f):
r = f
if c:
r = t
return r
Originally reported by: Anonymous
In cloud environments such as AWS we build our packages without X11 support since our systems are running headless anyway. The checks in python-six will fail because it assumes Python was built with tkinter support.
Attached is a patch which fixes the issue
Originally reported by: Sridhar Ratnakumar (Bitbucket: happyandharmless, GitHub: Unknown)
I just noticed that six 1.0b1 was released, but cannot find release notes. It'd be nice to maintain a, say, NEWS.rst file that gets included into long_description. Here's an example:
https://github.com/srid/mpt-sample#path
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.
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.
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.
Originally reported by: Elvis Pranskevichus (Bitbucket: elprans, GitHub: elprans)
The check for ValueError in test_MAXSIZE() on python2.4 seems to be bogus. Python2.4 throws OverflowError there, at least in CentOS 5.9.
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
.
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:
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.
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"),
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")
Originally reported by: Thomas Waldmann (Bitbucket: thomaswaldmann, GitHub: thomaswaldmann)
try:
unichr = unichr # py2
except NameError:
unichr = chr # py3
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.
Originally reported by: Jason R. Coombs (Bitbucket: jaraco, GitHub: jaraco)
In this SO question, it appears contextlib.ExitStack is the recommended replacement for contextlib.nested. It would be nice if six could supply the backport or native implementation.
Originally reported by: K-DawG (Bitbucket: K-DawG, GitHub: K-DawG)
In python 2 Tkinter themed widgets were imported as
#!python
import ttk
However in python 3 it was renamed to i
#!python
import tkinter.ttk
However six.moves doesn't contain Tkinter themed widgets why?
Originally reported by: Bernhard Gschaider (Bitbucket: bgschaid, GitHub: bgschaid)
In the documentation it says
#!python
six.exec_(code, globals=None, locals=None)
but the implementation is
#!python
def exec_(code, globs=None, locs=None):
"""Execute code in a namespace."""
for the Python 2.x-branch
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.