Hello community, here is the log from the commit of package python-six for openSUSE:Factory checked in at 2013-09-03 22:05:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-six (Old) and /work/SRC/openSUSE:Factory/.python-six.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-six" Changes: -------- --- /work/SRC/openSUSE:Factory/python-six/python-six.changes 2013-07-31 17:24:52.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python-six.new/python-six.changes 2013-09-03 22:05:55.000000000 +0200 @@ -1,0 +2,20 @@ +Mon Sep 2 15:34:12 UTC 2013 - dmuel...@suse.com + +- update to 1.4.1: + - Issue #31: Add six.moves mapping for UserString. + - Pull request #12: Add six.add_metaclass, a decorator for adding a metaclass to + a class. + - Add six.moves.zip_longest and six.moves.filterfalse, which correspond + respectively to itertools.izip_longest and itertools.ifilterfalse on Python 2 + and itertools.zip_longest and itertools.filterfalse on Python 3. + - Issue #25: Add the unichr function, which returns a string for a Unicode + codepoint. + - Issue #26: Add byte2int function, which complements int2byte. + - Issue #23: Allow multiple base classes to be passed to with_metaclass. + - Issue #24: Add six.moves.range alias. This exactly the same as the current + xrange alias. + - Pull request #5: Create six.moves.urllib, which contains abstractions for a + bunch of things which are in urllib in Python 3 and spread out across urllib, + urllib2, and urlparse in Python 2. + +------------------------------------------------------------------- Old: ---- six-1.3.0.tar.gz New: ---- six-1.4.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-six.spec ++++++ --- /var/tmp/diff_new_pack.fkU3cl/_old 2013-09-03 22:05:55.000000000 +0200 +++ /var/tmp/diff_new_pack.fkU3cl/_new 2013-09-03 22:05:55.000000000 +0200 @@ -18,7 +18,7 @@ %define modname six Name: python-six -Version: 1.3.0 +Version: 1.4.1 Release: 0 Url: http://pypi.python.org/pypi/six/ Summary: Python 2 and 3 compatibility utilities ++++++ six-1.3.0.tar.gz -> six-1.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.3.0/CHANGES new/six-1.4.1/CHANGES --- old/six-1.3.0/CHANGES 2013-03-18 21:35:07.000000000 +0100 +++ new/six-1.4.1/CHANGES 2013-09-02 15:09:15.000000000 +0200 @@ -3,6 +3,43 @@ This file lists the changes in each six version. +1.4.1 +----- + +- Issue #32: urllib module wrappings don't work when six is not a toplevel file. + +1.4.0 +----- + +- Issue #31: Add six.moves mapping for UserString. + +- Pull request #12: Add six.add_metaclass, a decorator for adding a metaclass to + a class. + +- Add six.moves.zip_longest and six.moves.filterfalse, which correspond + respectively to itertools.izip_longest and itertools.ifilterfalse on Python 2 + and itertools.zip_longest and itertools.filterfalse on Python 3. + +- Issue #25: Add the unichr function, which returns a string for a Unicode + codepoint. + +- Issue #26: Add byte2int function, which complements int2byte. + +- Add a PY2 constant with obvious semantics. + +- Add helpers for indexing and iterating over bytes: iterbytes and indexbytes. + +- Add create_bound_method() wrapper. + +- Issue #23: Allow multiple base classes to be passed to with_metaclass. + +- Issue #24: Add six.moves.range alias. This exactly the same as the current + xrange alias. + +- Pull request #5: Create six.moves.urllib, which contains abstractions for a + bunch of things which are in urllib in Python 3 and spread out across urllib, + urllib2, and urlparse in Python 2. + 1.3.0 ----- @@ -56,7 +93,6 @@ - Issue #3: Add six.moves mappings for filter, map, and zip. - 1.0.0 ----- @@ -64,7 +100,6 @@ - Expose an API for adding mappings to six.moves. - 1.0 beta 1 ---------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.3.0/PKG-INFO new/six-1.4.1/PKG-INFO --- old/six-1.3.0/PKG-INFO 2013-03-18 21:40:09.000000000 +0100 +++ new/six-1.4.1/PKG-INFO 2013-09-02 15:11:53.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: six -Version: 1.3.0 +Version: 1.4.1 Summary: Python 2 and 3 compatibility utilities Home-page: http://pypi.python.org/pypi/six/ Author: Benjamin Peterson @@ -11,9 +11,11 @@ writing Python code that is compatible on both Python versions. See the documentation for more information on what is provided. - Six supports Python 2.4+. + Six supports every Python version since 2.4. 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 http://packages.python.org/six/. + Online documentation is at http://pythonhosted.org/six/. Bugs can be reported to http://bitbucket.org/gutworth/six. The code can also be found there. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.3.0/README new/six-1.4.1/README --- old/six-1.3.0/README 2012-09-29 17:20:10.000000000 +0200 +++ new/six-1.4.1/README 2013-06-03 06:55:09.000000000 +0200 @@ -3,9 +3,11 @@ writing Python code that is compatible on both Python versions. See the documentation for more information on what is provided. -Six supports Python 2.4+. +Six supports every Python version since 2.4. 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 http://packages.python.org/six/. +Online documentation is at http://pythonhosted.org/six/. Bugs can be reported to http://bitbucket.org/gutworth/six. The code can also be found there. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.3.0/documentation/index.rst new/six-1.4.1/documentation/index.rst --- old/six-1.3.0/documentation/index.rst 2013-03-18 21:13:44.000000000 +0100 +++ new/six-1.4.1/documentation/index.rst 2013-09-01 23:12:47.000000000 +0200 @@ -31,6 +31,10 @@ Package contents ---------------- +.. data:: PY2 + + A boolean indicating if the code is running on Python 2. + .. data:: PY3 A boolean indicating if the code is running on Python 3. @@ -76,11 +80,12 @@ .. data:: MAXSIZE - The maximum size of a container. This is equivalent to - :data:`py3:sys.maxsize` in Python 2.6 and later (including 3.x). Note, this - is temptingly similar to, but not the same as :data:`py2:sys.maxint` in - Python 2. There is no direct equivalent to :data:`py2:sys.maxint` in Python - 3 because its integer type has no limits aside from memory. + The maximum size of a container like :func:`py3:list` or :func:`py3:dict`. + This is equivalent to :data:`py3:sys.maxsize` in Python 2.6 and later + (including 3.x). Note, this is temptingly similar to, but not the same as + :data:`py2:sys.maxint` in Python 2. There is no direct equivalent to + :data:`py2:sys.maxint` in Python 3 because its integer type has no limits + aside from memory. Here's example usage of the module:: @@ -199,6 +204,14 @@ *kwargs* are passed through to the underlying method. +.. function:: create_bound_method(func, obj) + + Return a method object wrapping *func* and bound to *obj*. On both Python 2 + and 3, this will return a :func:`py3:types.MethodType` object. The reason + this wrapper exists is that on Python 2, the ``MethodType`` constructor + requires the *obj*'s class to be passed. + + .. class:: Iterator A class for making portable iterators. The intention is that it be subclassed @@ -250,10 +263,10 @@ traceback can be specified with the *exc_traceback* parameter. -.. function:: with_metaclass(metaclass, base=object) +.. function:: with_metaclass(metaclass, *bases) - Create a new class with base class *base* and metaclass *metaclass*. This is - designed to be used in class declarations like this: :: + Create a new class with base classes *bases* and metaclass *metaclass*. This + is designed to be used in class declarations like this: :: from six import with_metaclass @@ -266,6 +279,40 @@ class MyClass(with_metaclass(Meta, Base)): pass + Another way to set a metaclass on a class is with the :func:`add_metaclass` + decorator. + + +.. function:: add_metaclass(metaclass) + + Class decorator that replaces a normally-constructed class with a + metaclass-constructed one. Unlike :func:`with_metaclass`, + :func:`add_metaclass` does not create an intermediate base class between the + class being created and its bases. Example usage: :: + + @add_metaclass(Meta) + class MyClass(object): + pass + + That code produces a class equivalent to :: + + class MyClass(object, metaclass=Meta): + pass + + on Python 3 or :: + + class MyClass(object): + __metaclass__ = MyMeta + + on Python 2. + + Note that class decorators require Python 2.6. However, the effect of the + decorator can be emulated on Python 2.4 and 2.5 like so:: + + class MyClass(object): + pass + MyClass = add_metaclass(Meta)(MyClass) + Binary and text data >>>>>>>>>>>>>>>>>>>> @@ -283,7 +330,7 @@ with the latin-1 encoding to bytes. -.. note:: + .. note:: Since all Python versions 2.6 and after support the ``b`` prefix, :func:`b`, code without 2.5 support doesn't need :func:`b`. @@ -311,10 +358,34 @@ ASCII data. +.. function:: unichr(c) + + Return the (Unicode) string representing the codepoint *c*. This is + equivalent to :func:`py2:unichr` on Python 2 and :func:`py3:chr` on Python 3. + + .. function:: int2byte(i) Converts *i* to a byte. *i* must be in ``range(0, 256)``. This is - equivalent to :class:`py2:chr` in Python 2 and ``bytes((i,))`` in Python 3. + equivalent to :func:`py2:chr` in Python 2 and ``bytes((i,))`` in Python 3. + + +.. function:: byte2int(bs) + + Converts the first byte of *bs* to an integer. This is equivalent to + ``ord(bs[0])`` on Python 2 and ``bs[0]`` on Python 3. + + +.. function:: indexbytes(buf, i) + + Return the byte at index *i* of *buf* as an integer. This is equivalent to + indexing a bytes object in Python 3. + + +.. function:: iterbytes(buf) + + Return an iterator over bytes in *buf* as integers. This is equivalent to + a bytes object iterator in Python 3. .. data:: StringIO @@ -372,93 +443,220 @@ Supported renames: -+------------------------------+-------------------------------------+---------------------------------+ -| Name | Python 2 name | Python 3 name | -+==============================+=====================================+=================================+ -| ``builtins`` | :mod:`py2:__builtin__` | :mod:`py3:builtins` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``configparser`` | :mod:`py2:ConfigParser` | :mod:`py3:configparser` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``copyreg`` | :mod:`py2:copy_reg` | :mod:`py3:copyreg` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``cPickle`` | :mod:`py2:cPickle` | :mod:`py3:pickle` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``cStringIO`` | :func:`py2:cStringIO.StringIO` | :class:`py3:io.StringIO` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``email_mime_multipart`` | :mod:`py2:email.MIMEMultipart` | :mod:`py3:email.mime.multipart` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``email_mime_text`` | :mod:`py2:email.MIMEText` | :mod:`py3:email.mime.text` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``email_mime_base`` | :mod:`py2:email.MIMEBase` | :mod:`py3:email.mime.base` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``filter`` | :func:`py2:itertools.ifilter` | :func:`py3:filter` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``http_cookiejar`` | :mod:`py2:cookielib` | :mod:`py3:http.cookiejar` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``http_cookies`` | :mod:`py2:Cookie` | :mod:`py3:http.cookies` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``html_entities`` | :mod:`py2:htmlentitydefs` | :mod:`py3:html.entities` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``html_parser`` | :mod:`py2:HTMLParser` | :mod:`py3:html.parser` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``http_client`` | :mod:`py2:httplib` | :mod:`py3:http.client` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``BaseHTTPServer`` | :mod:`py2:BaseHTTPServer` | :mod:`py3:http.server` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``CGIHTTPServer`` | :mod:`py2:CGIHTTPServer` | :mod:`py3:http.server` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``SimpleHTTPServer`` | :mod:`py2:SimpleHTTPServer` | :mod:`py3:http.server` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``input`` | :func:`py2:raw_input` | :func:`py3:input` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``map`` | :func:`py2:itertools.imap` | :func:`py3:map` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``queue`` | :mod:`py2:Queue` | :mod:`py3:queue` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``reduce`` | :func:`py2:reduce` | :func:`py3:functools.reduce` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``reload_module`` | :func:`py2:reload` | :func:`py3:imp.reload` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``reprlib`` | :mod:`py2:repr` | :mod:`py3:reprlib` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``socketserver`` | :mod:`py2:SocketServer` | :mod:`py3:socketserver` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter`` | :mod:`py2:Tkinter` | :mod:`py3:tkinter` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_dialog`` | :mod:`py2:Dialog` | :mod:`py3:tkinter.dialog` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_filedialog`` | :mod:`py2:FileDialog` | :mod:`py3:tkinter.FileDialog` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_scrolledtext`` | :mod:`py2:ScrolledText` | :mod:`py3:tkinter.scolledtext` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_simpledialog`` | :mod:`py2:SimpleDialog` | :mod:`py2:tkinter.simpledialog` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_tix`` | :mod:`py2:Tix` | :mod:`py3:tkinter.tix` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_constants`` | :mod:`py2:Tkconstants` | :mod:`py3:tkinter.constants` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_dnd`` | :mod:`py2:Tkdnd` | :mod:`py3:tkinter.dnd` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_colorchooser`` | :mod:`py2:tkColorChooser` | :mod:`py3:tkinter.colorchooser` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_commondialog`` | :mod:`py2:tkCommonDialog` | :mod:`py3:tkinter.commondialog` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_tkfiledialog`` | :mod:`py2:tkFileDialog` | :mod:`py3:tkinter.filedialog` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_font`` | :mod:`py2:tkFont` | :mod:`py3:tkinter.font` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_messagebox`` | :mod:`py2:tkMessageBox` | :mod:`py3:tkinter.messagebox` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``tkinter_tksimpledialog`` | :mod:`py2:tkSimpleDialog` | :mod:`py3:tkinter.simpledialog` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``urllib_robotparser`` | :mod:`py2:robotparser` | :mod:`py3:urllib.robotparser` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``winreg`` | :mod:`py2:_winreg` | :mod:`py3:winreg` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``xrange`` | :func:`py2:xrange` | :func:`py3:range` | -+------------------------------+-------------------------------------+---------------------------------+ -| ``zip`` | :func:`py2:itertools.izip` | :func:`py3:zip` | -+------------------------------+-------------------------------------+---------------------------------+ ++------------------------------+-------------------------------------+-------------------------------------+ +| Name | Python 2 name | Python 3 name | ++==============================+=====================================+=====================================+ +| ``builtins`` | :mod:`py2:__builtin__` | :mod:`py3:builtins` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``configparser`` | :mod:`py2:ConfigParser` | :mod:`py3:configparser` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``copyreg`` | :mod:`py2:copy_reg` | :mod:`py3:copyreg` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``cPickle`` | :mod:`py2:cPickle` | :mod:`py3:pickle` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``cStringIO`` | :func:`py2:cStringIO.StringIO` | :class:`py3:io.StringIO` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``email_mime_multipart`` | :mod:`py2:email.MIMEMultipart` | :mod:`py3:email.mime.multipart` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``email_mime_text`` | :mod:`py2:email.MIMEText` | :mod:`py3:email.mime.text` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``email_mime_base`` | :mod:`py2:email.MIMEBase` | :mod:`py3:email.mime.base` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``filter`` | :func:`py2:itertools.ifilter` | :func:`py3:filter` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``filterfalse`` | :func:`py2:itertools.ifilterfalse` | :func:`py3:itertools.filterfalse` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``http_cookiejar`` | :mod:`py2:cookielib` | :mod:`py3:http.cookiejar` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``http_cookies`` | :mod:`py2:Cookie` | :mod:`py3:http.cookies` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``html_entities`` | :mod:`py2:htmlentitydefs` | :mod:`py3:html.entities` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``html_parser`` | :mod:`py2:HTMLParser` | :mod:`py3:html.parser` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``http_client`` | :mod:`py2:httplib` | :mod:`py3:http.client` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``BaseHTTPServer`` | :mod:`py2:BaseHTTPServer` | :mod:`py3:http.server` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``CGIHTTPServer`` | :mod:`py2:CGIHTTPServer` | :mod:`py3:http.server` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``SimpleHTTPServer`` | :mod:`py2:SimpleHTTPServer` | :mod:`py3:http.server` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``input`` | :func:`py2:raw_input` | :func:`py3:input` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``map`` | :func:`py2:itertools.imap` | :func:`py3:map` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``queue`` | :mod:`py2:Queue` | :mod:`py3:queue` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``range`` | :func:`py2:xrange` | :func:`py3:range` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``reduce`` | :func:`py2:reduce` | :func:`py3:functools.reduce` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``reload_module`` | :func:`py2:reload` | :func:`py3:imp.reload` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``reprlib`` | :mod:`py2:repr` | :mod:`py3:reprlib` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``socketserver`` | :mod:`py2:SocketServer` | :mod:`py3:socketserver` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter`` | :mod:`py2:Tkinter` | :mod:`py3:tkinter` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_dialog`` | :mod:`py2:Dialog` | :mod:`py3:tkinter.dialog` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_filedialog`` | :mod:`py2:FileDialog` | :mod:`py3:tkinter.FileDialog` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_scrolledtext`` | :mod:`py2:ScrolledText` | :mod:`py3:tkinter.scolledtext` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_simpledialog`` | :mod:`py2:SimpleDialog` | :mod:`py2:tkinter.simpledialog` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_tix`` | :mod:`py2:Tix` | :mod:`py3:tkinter.tix` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_constants`` | :mod:`py2:Tkconstants` | :mod:`py3:tkinter.constants` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_dnd`` | :mod:`py2:Tkdnd` | :mod:`py3:tkinter.dnd` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_colorchooser`` | :mod:`py2:tkColorChooser` | :mod:`py3:tkinter.colorchooser` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_commondialog`` | :mod:`py2:tkCommonDialog` | :mod:`py3:tkinter.commondialog` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_tkfiledialog`` | :mod:`py2:tkFileDialog` | :mod:`py3:tkinter.filedialog` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_font`` | :mod:`py2:tkFont` | :mod:`py3:tkinter.font` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_messagebox`` | :mod:`py2:tkMessageBox` | :mod:`py3:tkinter.messagebox` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``tkinter_tksimpledialog`` | :mod:`py2:tkSimpleDialog` | :mod:`py3:tkinter.simpledialog` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``urllib.parse`` | See :mod:`six.moves.urllib.parse` | :mod:`py3:urllib.parse` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``urllib.error`` | See :mod:`six.moves.urllib.error` | :mod:`py3:urllib.error` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``urllib.request`` | See :mod:`six.moves.urllib.request` | :mod:`py3:urllib.request` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``urllib.response`` | See :mod:`six.moves.urllib.response`| :mod:`py3:urllib.response` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``urllib.robotparser`` | :mod:`py2:robotparser` | :mod:`py3:urllib.robotparser` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``urllib_robotparser`` | :mod:`py2:robotparser` | :mod:`py3:urllib.robotparser` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``UserString`` | :class:`py2:UserString.UserString` | :class:`py3:collections.UserString` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``winreg`` | :mod:`py2:_winreg` | :mod:`py3:winreg` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``xrange`` | :func:`py2:xrange` | :func:`py3:range` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``zip`` | :func:`py2:itertools.izip` | :func:`py3:zip` | ++------------------------------+-------------------------------------+-------------------------------------+ +| ``zip_longest`` | :func:`py2:itertools.izip_longest` | :func:`py3:itertools.zip_longest` | ++------------------------------+-------------------------------------+-------------------------------------+ + +urllib parse +<<<<<<<<<<<< + +.. module:: six.moves.urllib.parse + :synopsis: Stuff from :mod:`py2:urlparse` and :mod:`py2:urllib` in Python 2 and :mod:`py3:urllib.parse` in Python 3 + +Contains functions from Python 3's :mod:`py3:urllib.parse` and Python 2's: + +:mod:`py2:urlparse`: + +* :func:`py2:urlparse.urlparse` +* :func:`py2:urlparse.urlunparse` +* :func:`py2:urlparse.parse_qs` +* :func:`py2:urlparse.parse_qsl` +* :func:`py2:urlparse.urljoin` +* :func:`py2:urlparse.urldefrag` +* :func:`py2:urlparse.urlsplit` +* :func:`py2:urlparse.urlunsplit` + +and :mod:`py2:urllib`: + +* :func:`py2:urllib.quote` +* :func:`py2:urllib.quote_plus` +* :func:`py2:urllib.unquote` +* :func:`py2:urllib.unquote_plus` +* :func:`py2:urllib.urlencode` + + +urllib error +<<<<<<<<<<<< + +.. module:: six.moves.urllib.error + :synopsis: Stuff from :mod:`py2:urllib` and :mod:`py2:urllib2` in Python 2 and :mod:`py3:urllib.error` in Python 3 + +Contains exceptions from Python 3's :mod:`py3:urllib.error` and Python 2's: + +:mod:`py2:urllib`: + +* :exc:`py2:urllib.ContentTooShortError` + +and :mod:`py2:urllib2`: + +* :exc:`py2:urllib2.URLError` +* :exc:`py2:urllib2.HTTPError` + + +urllib request +<<<<<<<<<<<<<< + +.. module:: six.moves.urllib.request + :synopsis: Stuff from :mod:`py2:urllib` and :mod:`py2:urllib2` in Python 2 and :mod:`py3:urllib.request` in Python 3 + +Contains items from Python 3's :mod:`py3:urllib.request` and Python 2's: + +:mod:`py2:urllib`: + +* :func:`py2:urllib.pathname2url` +* :func:`py2:urllib.url2pathname` +* :func:`py2:urllib.getproxies` +* :func:`py2:urllib.urlretrieve` +* :func:`py2:urllib.urlcleanup` +* :class:`py2:urllib.URLopener` +* :class:`py2:urllib.FancyURLopener` + +and :mod:`py2:urllib2`: + +* :func:`py2:urllib2.urlopen` +* :func:`py2:urllib2.install_opener` +* :func:`py2:urllib2.build_opener` +* :class:`py2:urllib2.Request` +* :class:`py2:urllib2.OpenerDirector` +* :class:`py2:urllib2.HTTPDefaultErrorHandler` +* :class:`py2:urllib2.HTTPRedirectHandler` +* :class:`py2:urllib2.HTTPCookieProcessor` +* :class:`py2:urllib2.ProxyHandler` +* :class:`py2:urllib2.BaseHandler` +* :class:`py2:urllib2.HTTPPasswordMgr` +* :class:`py2:urllib2.HTTPPasswordMgrWithDefaultRealm` +* :class:`py2:urllib2.AbstractBasicAuthHandler` +* :class:`py2:urllib2.HTTPBasicAuthHandler` +* :class:`py2:urllib2.ProxyBasicAuthHandler` +* :class:`py2:urllib2.AbstractDigestAuthHandler` +* :class:`py2:urllib2.HTTPDigestAuthHandler` +* :class:`py2:urllib2.ProxyDigestAuthHandler` +* :class:`py2:urllib2.HTTPHandler` +* :class:`py2:urllib2.HTTPSHandler` +* :class:`py2:urllib2.FileHandler` +* :class:`py2:urllib2.FTPHandler` +* :class:`py2:urllib2.CacheFTPHandler` +* :class:`py2:urllib2.UnknownHandler` +* :class:`py2:urllib2.HTTPErrorProcessor` + + +urllib response +<<<<<<<<<<<<<<< + +.. module:: six.moves.urllib.response + :synopsis: Stuff from :mod:`py2:urllib` in Python 2 and :mod:`py3:urllib.response` in Python 3 + +Contains classes from Python 3's :mod:`py3:urllib.response` and Python 2's: + +:mod:`py2:urllib`: + +* :class:`py2:urllib.addbase` +* :class:`py2:urllib.addclosehook` +* :class:`py2:urllib.addinfo` +* :class:`py2:urllib.addinfourl` + Advanced - Customizing renames <<<<<<<<<<<<<<<<<<<<<<<<<<<<<< diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.3.0/six.py new/six-1.4.1/six.py --- old/six-1.3.0/six.py 2013-03-18 20:58:36.000000000 +0100 +++ new/six-1.4.1/six.py 2013-09-02 15:11:12.000000000 +0200 @@ -2,32 +2,34 @@ # Copyright (c) 2010-2013 Benjamin Peterson # -# Permission is hereby granted, free of charge, to any person obtaining a copy of -# this software and associated documentation files (the "Software"), to deal in -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -# the Software, and to permit persons to whom the Software is furnished to do so, -# subject to the following conditions: +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. import operator import sys import types __author__ = "Benjamin Peterson <benja...@python.org>" -__version__ = "1.3.0" +__version__ = "1.4.1" -# True if we are running on Python 3. +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 if PY3: @@ -61,7 +63,7 @@ else: # 64-bit MAXSIZE = int((1 << 63) - 1) - del X + del X def _add_doc(func, doc): @@ -136,13 +138,17 @@ _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("reload_module", "__builtin__", "imp", "reload"), MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), @@ -179,6 +185,9 @@ MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), MovedModule("winreg", "_winreg"), ] @@ -186,7 +195,144 @@ setattr(_MovedItems, attr.name, attr) del attr -moves = sys.modules[__name__ + ".moves"] = _MovedItems("moves") +moves = sys.modules[__name__ + ".moves"] = _MovedItems(__name__ + ".moves") + + + +class Module_six_moves_urllib_parse(types.ModuleType): + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +sys.modules[__name__ + ".moves.urllib_parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse") +sys.modules[__name__ + ".moves.urllib.parse"] = Module_six_moves_urllib_parse(__name__ + ".moves.urllib.parse") + + +class Module_six_moves_urllib_error(types.ModuleType): + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +sys.modules[__name__ + ".moves.urllib_error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib_error") +sys.modules[__name__ + ".moves.urllib.error"] = Module_six_moves_urllib_error(__name__ + ".moves.urllib.error") + + +class Module_six_moves_urllib_request(types.ModuleType): + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +sys.modules[__name__ + ".moves.urllib_request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib_request") +sys.modules[__name__ + ".moves.urllib.request"] = Module_six_moves_urllib_request(__name__ + ".moves.urllib.request") + + +class Module_six_moves_urllib_response(types.ModuleType): + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +sys.modules[__name__ + ".moves.urllib_response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib_response") +sys.modules[__name__ + ".moves.urllib.response"] = Module_six_moves_urllib_response(__name__ + ".moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(types.ModuleType): + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +sys.modules[__name__ + ".moves.urllib_robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib_robotparser") +sys.modules[__name__ + ".moves.urllib.robotparser"] = Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + parse = sys.modules[__name__ + ".moves.urllib_parse"] + error = sys.modules[__name__ + ".moves.urllib_error"] + request = sys.modules[__name__ + ".moves.urllib_request"] + response = sys.modules[__name__ + ".moves.urllib_response"] + robotparser = sys.modules[__name__ + ".moves.urllib_robotparser"] + + +sys.modules[__name__ + ".moves.urllib"] = Module_six_moves_urllib(__name__ + ".moves.urllib") def add_move(move): @@ -252,11 +398,16 @@ def get_unbound_function(unbound): return unbound + create_bound_method = types.MethodType + Iterator = object else: def get_unbound_function(unbound): return unbound.im_func + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + class Iterator(object): def next(self): @@ -297,12 +448,16 @@ return s.encode("latin-1") def u(s): return s + unichr = chr if sys.version_info[1] <= 1: def int2byte(i): return bytes((i,)) else: # This is about 2x faster than the implementation above on 3.2+ int2byte = operator.methodcaller("to_bytes", 1, "big") + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter import io StringIO = io.StringIO BytesIO = io.BytesIO @@ -311,7 +466,14 @@ return s def u(s): return unicode(s, "unicode_escape") + unichr = unichr int2byte = chr + def byte2int(bs): + return ord(bs[0]) + def indexbytes(buf, i): + return ord(buf[i]) + def iterbytes(buf): + return (ord(byte) for byte in buf) import StringIO StringIO = BytesIO = StringIO.StringIO _add_doc(b, """Byte literal""") @@ -399,6 +561,17 @@ _add_doc(reraise, """Reraise an exception.""") -def with_metaclass(meta, base=object): +def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" - return meta("NewBase", (base,), {}) + return meta("NewBase", bases, {}) + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + for slots_var in orig_vars.get('__slots__', ()): + orig_vars.pop(slots_var) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/six-1.3.0/test_six.py new/six-1.4.1/test_six.py --- old/six-1.3.0/test_six.py 2013-03-17 05:01:29.000000000 +0100 +++ new/six-1.4.1/test_six.py 2013-09-01 22:46:02.000000000 +0200 @@ -90,6 +90,9 @@ """Ensure that everything loads correctly.""" try: getattr(six.moves, item_name) + except AttributeError: + if item_name == "zip_longest" and sys.version_info < (2, 6): + py.test.skip("zip_longest only available on 2.6+") except ImportError: if item_name == "winreg" and not sys.platform.startswith("win"): py.test.skip("Windows only module") @@ -98,12 +101,58 @@ raise +@py.test.mark.parametrize("item_name", + [item.name for item in six._urllib_parse_moved_attributes]) +def test_move_items_urllib_parse(item_name): + """Ensure that everything loads correctly.""" + if item_name == "ParseResult" and sys.version_info < (2, 5): + py.test.skip("ParseResult is only found on 2.5+") + if item_name in ("parse_qs", "parse_qsl") and sys.version_info < (2, 6): + py.test.skip("parse_qs[l] is new in 2.6") + getattr(six.moves.urllib.parse, item_name) + + +@py.test.mark.parametrize("item_name", + [item.name for item in six._urllib_error_moved_attributes]) +def test_move_items_urllib_error(item_name): + """Ensure that everything loads correctly.""" + getattr(six.moves.urllib.error, item_name) + + +@py.test.mark.parametrize("item_name", + [item.name for item in six._urllib_request_moved_attributes]) +def test_move_items_urllib_request(item_name): + """Ensure that everything loads correctly.""" + getattr(six.moves.urllib.request, item_name) + + +@py.test.mark.parametrize("item_name", + [item.name for item in six._urllib_response_moved_attributes]) +def test_move_items_urllib_response(item_name): + """Ensure that everything loads correctly.""" + getattr(six.moves.urllib.response, item_name) + + +@py.test.mark.parametrize("item_name", + [item.name for item in six._urllib_robotparser_moved_attributes]) +def test_move_items_urllib_robotparser(item_name): + """Ensure that everything loads correctly.""" + getattr(six.moves.urllib.robotparser, item_name) + + def test_filter(): from six.moves import filter f = filter(lambda x: x % 2, range(10)) assert six.advance_iterator(f) == 1 +def test_filter_false(): + from six.moves import filterfalse + f = filterfalse(lambda x: x % 3, range(10)) + assert six.advance_iterator(f) == 0 + assert six.advance_iterator(f) == 3 + assert six.advance_iterator(f) == 6 + def test_map(): from six.moves import map assert six.advance_iterator(map(lambda x: x + 1, range(2))) == 1 @@ -114,6 +163,15 @@ assert six.advance_iterator(zip(range(2), range(2))) == (0, 0) +@py.test.mark.skipif("sys.version_info < (2, 6)") +def test_zip_longest(): + from six.moves import zip_longest + it = zip_longest(range(2), range(1)) + + assert six.advance_iterator(it) == (0, 0) + assert six.advance_iterator(it) == (1, None) + + class TestCustomizedMoves: def teardown_method(self, meth): @@ -306,6 +364,17 @@ assert not six.callable("string") +def test_create_bound_method(): + class X(object): + pass + def f(self): + return self + x = X() + b = six.create_bound_method(f, x) + assert isinstance(b, types.MethodType) + assert b() is x + + if six.PY3: def test_b(): @@ -340,11 +409,33 @@ assert len(s) == 1 +def test_unichr(): + assert six.u("\u1234") == six.unichr(0x1234) + assert type(six.u("\u1234")) is type(six.unichr(0x1234)) + + def test_int2byte(): assert six.int2byte(3) == six.b("\x03") py.test.raises((OverflowError, ValueError), six.int2byte, 256) +def test_byte2int(): + assert six.byte2int(six.b("\x03")) == 3 + assert six.byte2int(six.b("\x03\x04")) == 3 + py.test.raises(IndexError, six.byte2int, six.b("")) + + +def test_bytesindex(): + assert six.indexbytes(six.b("hello"), 3) == ord("l") + + +def test_bytesiter(): + it = six.iterbytes(six.b("hi")) + assert six.next(it) == ord("h") + assert six.next(it) == ord("i") + py.test.raises(StopIteration, six.next, it) + + def test_StringIO(): fp = six.StringIO() fp.write(six.u("hello")) @@ -456,3 +547,68 @@ pass assert type(X) is Meta assert issubclass(X, Base) + class Base2(object): + pass + class X(six.with_metaclass(Meta, Base, Base2)): + pass + assert type(X) is Meta + assert issubclass(X, Base) + assert issubclass(X, Base2) + + +def test_add_metaclass(): + class Meta(type): + pass + class X: + "success" + X = six.add_metaclass(Meta)(X) + assert type(X) is Meta + assert issubclass(X, object) + assert X.__module__ == __name__ + assert X.__doc__ == "success" + class Base(object): + pass + class X(Base): + pass + X = six.add_metaclass(Meta)(X) + assert type(X) is Meta + assert issubclass(X, Base) + class Base2(object): + pass + class X(Base, Base2): + pass + X = six.add_metaclass(Meta)(X) + assert type(X) is Meta + assert issubclass(X, Base) + assert issubclass(X, Base2) + + # Test a second-generation subclass of a type. + class Meta1(type): + m1 = "m1" + class Meta2(Meta1): + m2 = "m2" + class Base: + b = "b" + Base = six.add_metaclass(Meta1)(Base) + class X(Base): + x = "x" + X = six.add_metaclass(Meta2)(X) + assert type(X) is Meta2 + assert issubclass(X, Base) + assert type(Base) is Meta1 + assert "__dict__" not in vars(X) + instance = X() + instance.attr = "test" + assert vars(instance) == {"attr": "test"} + assert instance.b == Base.b + assert instance.x == X.x + + # test a class with slots + class MySlots(object): + __slots__ = ["a", "b"] + MySlots = six.add_metaclass(Meta1)(MySlots) + + assert MySlots.__slots__ == ["a", "b"] + instance = MySlots() + instance.a = "foo" + py.test.raises(AttributeError, setattr, instance, "c", "baz") -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org