From: Georg Brandl Date: Wed, 6 Oct 2010 07:12:17 +0000 (+0000) Subject: Merged revisions 76884-76885,76887,76889-76890,76895 via svnmerge from X-Git-Tag: v3.1.3rc1~163 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=107690c2ff6ad95934b66df2d2566177b7560827;p=python Merged revisions 76884-76885,76887,76889-76890,76895 via svnmerge from svn+ssh://svn.python.org/python/branches/py3k ................ r76884 | georg.brandl | 2009-12-19 18:35:49 +0100 (Sa, 19 Dez 2009) | 9 lines Merged revisions 76883 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76883 | georg.brandl | 2009-12-19 18:34:32 +0100 (Sa, 19 Dez 2009) | 1 line #7521: remove Py_GetBuildNumber(), which was removed in favor of Py_GetBuildInfo(). ........ ................ r76885 | georg.brandl | 2009-12-19 18:36:20 +0100 (Sa, 19 Dez 2009) | 1 line #7521: remove PyEval_GetRestricted() from the docs. ................ r76887 | georg.brandl | 2009-12-19 18:46:40 +0100 (Sa, 19 Dez 2009) | 9 lines Recorded merge of revisions 76886 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r76886 | georg.brandl | 2009-12-19 18:43:33 +0100 (Sa, 19 Dez 2009) | 1 line #7493: review of Design FAQ by Florent Xicluna. ........ ................ r76889 | georg.brandl | 2009-12-19 18:57:51 +0100 (Sa, 19 Dez 2009) | 1 line #7499: Review of Library FAQ by Florent Xicluna. ................ r76890 | georg.brandl | 2009-12-19 18:59:59 +0100 (Sa, 19 Dez 2009) | 1 line #7500: add "Python 3 review needed" comments and fix a few obvious errors. ................ r76895 | georg.brandl | 2009-12-19 19:23:28 +0100 (Sa, 19 Dez 2009) | 1 line #7380: Fix some str/bytearray/bytes issues in uuid docs and implementation. ................ --- diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst index 1d8c38cc9a..c694abd90a 100644 --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -285,13 +285,6 @@ Initialization, Finalization, and Threads modify its value. The value is available to Python code as :data:`sys.version`. -.. cfunction:: const char* Py_GetBuildNumber() - - Return a string representing the Subversion revision that this Python executable - was built from. This number is a string because it may contain a trailing 'M' - if Python was built from a mixed revision source tree. - - .. cfunction:: const char* Py_GetPlatform() .. index:: single: platform (in module sys) diff --git a/Doc/c-api/reflection.rst b/Doc/c-api/reflection.rst index 822c59343c..4f46c7fae8 100644 --- a/Doc/c-api/reflection.rst +++ b/Doc/c-api/reflection.rst @@ -29,12 +29,6 @@ Reflection currently executing. -.. cfunction:: int PyEval_GetRestricted() - - If there is a current frame and it is executing in restricted mode, return true, - otherwise false. - - .. cfunction:: const char* PyEval_GetFuncName(PyObject *func) Return the name of *func* if it is a function, class or instance object, else the diff --git a/Doc/faq/design.rst b/Doc/faq/design.rst index c20de00b98..8e960f5de3 100644 --- a/Doc/faq/design.rst +++ b/Doc/faq/design.rst @@ -234,8 +234,10 @@ code breakage. .. XXX talk about protocols? -Note that for string operations Python has moved from external functions (the -``string`` module) to methods. However, ``len()`` is still a function. +.. note:: + + For string operations, Python has moved from external functions (the + ``string`` module) to methods. However, ``len()`` is still a function. Why is join() a string method instead of a list or tuple method? @@ -306,14 +308,15 @@ expensive. In versions of Python prior to 2.0 it was common to use this idiom:: This only made sense when you expected the dict to have the key almost all the time. If that wasn't the case, you coded it like this:: - if dict.has_key(key): + if key in dict(key): value = dict[key] else: dict[key] = getvalue(key) value = dict[key] -(In Python 2.0 and higher, you can code this as ``value = dict.setdefault(key, -getvalue(key))``.) +For this specific case, you could also use ``value = dict.setdefault(key, +getvalue(key))``, but only if the ``getvalue()`` call is cheap enough because it +is evaluated in all cases. Why isn't there a switch or case statement in Python? @@ -750,7 +753,7 @@ requested again. This is called "memoizing", and can be implemented like this:: # Callers will never provide a third parameter for this function. def expensive (arg1, arg2, _cache={}): - if _cache.has_key((arg1, arg2)): + if (arg1, arg2) in _cache: return _cache[(arg1, arg2)] # Calculate the value diff --git a/Doc/faq/extending.rst b/Doc/faq/extending.rst index 4b3d6d5150..6527ff189b 100644 --- a/Doc/faq/extending.rst +++ b/Doc/faq/extending.rst @@ -7,6 +7,9 @@ Extending/Embedding FAQ .. highlight:: c +.. XXX need review for Python 3. + + Can I create my own functions in C? ----------------------------------- @@ -53,8 +56,7 @@ with a tool such as `SWIG `_. `SIP `__, `CXX `_ `Boost `_, or `Weave -`_ are also alternatives for wrapping -C++ libraries. +`_ are also alternatives for wrapping C++ libraries. How can I execute arbitrary Python statements from C? @@ -161,8 +163,8 @@ Sample code and use for catching stdout: ... >>> import sys >>> sys.stdout = StdoutCatcher() - >>> print 'foo' - >>> print 'hello world!' + >>> print('foo') + >>> print('hello world!') >>> sys.stderr.write(sys.stdout.data) foo hello world! @@ -199,7 +201,11 @@ begin by reading :ref:`the "Extending and Embedding" document whole lot of difference between C and C++ -- so the strategy of building a new Python type around a C structure (pointer) type will also work for C++ objects. -For C++ libraries, see :ref:`c-wrapper-software`. +For C++ libraries, you can look at `SIP +`_, `CXX +`_, `Boost +`_, `Weave +`_ or `SWIG `_ I added a module using the Setup file and the make fails; why? @@ -468,12 +474,9 @@ checking the value of sys.maxunicode: >>> import sys >>> if sys.maxunicode > 65535: - ... print 'UCS4 build' + ... print('UCS4 build') ... else: - ... print 'UCS2 build' + ... print('UCS2 build') The only way to solve this problem is to use extension modules compiled with a Python binary built using the same size for Unicode characters. - - - diff --git a/Doc/faq/gui.rst b/Doc/faq/gui.rst index 57e4049661..03177c9586 100644 --- a/Doc/faq/gui.rst +++ b/Doc/faq/gui.rst @@ -6,6 +6,9 @@ Graphic User Interface FAQ .. contents:: +.. XXX need review for Python 3. + + General GUI Questions ===================== @@ -159,6 +162,3 @@ The most common cause is that the widget to which the binding applies doesn't have "keyboard focus". Check out the Tk documentation for the focus command. Usually a widget is given the keyboard focus by clicking in it (but not for labels; see the takefocus option). - - - diff --git a/Doc/faq/library.rst b/Doc/faq/library.rst index c59b38f528..aa698e4ab4 100644 --- a/Doc/faq/library.rst +++ b/Doc/faq/library.rst @@ -38,7 +38,7 @@ There are (at least) three kinds of modules in Python: type:: import sys - print sys.builtin_module_names + print(sys.builtin_module_names) How do I make a Python script executable on Unix? @@ -187,8 +187,11 @@ How do I get a single keypress at a time? ----------------------------------------- For Unix variants: There are several solutions. It's straightforward to do this -using curses, but curses is a fairly large module to learn. Here's a solution -without curses:: +using curses, but curses is a fairly large module to learn. + +.. XXX this doesn't work out of the box, some IO expert needs to check why + + Here's a solution without curses:: import termios, fcntl, sys, os fd = sys.stdin.fileno() @@ -202,23 +205,24 @@ without curses:: fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK) try: - while 1: + while True: try: c = sys.stdin.read(1) - print "Got character", `c` - except IOError: pass + print("Got character", repr(c)) + except IOError: + pass finally: termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags) -You need the :mod:`termios` and the :mod:`fcntl` module for any of this to work, -and I've only tried it on Linux, though it should work elsewhere. In this code, -characters are read and printed one at a time. + You need the :mod:`termios` and the :mod:`fcntl` module for any of this to + work, and I've only tried it on Linux, though it should work elsewhere. In + this code, characters are read and printed one at a time. -:func:`termios.tcsetattr` turns off stdin's echoing and disables canonical mode. -:func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags and modify -them for non-blocking mode. Since reading stdin when it is empty results in an -:exc:`IOError`, this error is caught and ignored. + :func:`termios.tcsetattr` turns off stdin's echoing and disables canonical + mode. :func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags + and modify them for non-blocking mode. Since reading stdin when it is empty + results in an :exc:`IOError`, this error is caught and ignored. Threads @@ -247,13 +251,13 @@ all the threads to finish:: import threading, time def thread_task(name, n): - for i in range(n): print name, i + for i in range(n): print(name, i) for i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) T.start() - time.sleep(10) # <----------------------------! + time.sleep(10) # <---------------------------! But now (on many platforms) the threads don't run in parallel, but appear to run sequentially, one at a time! The reason is that the OS thread scheduler doesn't @@ -262,8 +266,8 @@ start a new thread until the previous thread is blocked. A simple fix is to add a tiny sleep to the start of the run function:: def thread_task(name, n): - time.sleep(0.001) # <---------------------! - for i in range(n): print name, i + time.sleep(0.001) # <--------------------! + for i in range(n): print(name, i) for i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) @@ -289,28 +293,28 @@ once. Here's a trivial example:: - import threading, Queue, time + import threading, queue, time # The worker thread gets jobs off the queue. When the queue is empty, it # assumes there will be no more work and exits. # (Realistically workers will run until terminated.) def worker (): - print 'Running worker' + print('Running worker') time.sleep(0.1) while True: try: arg = q.get(block=False) - except Queue.Empty: - print 'Worker', threading.currentThread(), - print 'queue empty' + except queue.Empty: + print('Worker', threading.currentThread(), end=' ') + print('queue empty') break else: - print 'Worker', threading.currentThread(), - print 'running with argument', arg + print('Worker', threading.currentThread(), end=' ') + print('running with argument', arg) time.sleep(0.5) # Create queue - q = Queue.Queue() + q = queue.Queue() # Start a pool of 5 workers for i in range(5): @@ -322,10 +326,10 @@ Here's a trivial example:: q.put(i) # Give threads time to run - print 'Main thread sleeping' + print('Main thread sleeping') time.sleep(5) -When run, this will produce the following output: +When run, this will produce the following output:: Running worker Running worker @@ -333,12 +337,12 @@ When run, this will produce the following output: Running worker Running worker Main thread sleeping - Worker running with argument 0 - Worker running with argument 1 - Worker running with argument 2 - Worker running with argument 3 - Worker running with argument 4 - Worker running with argument 5 + Worker running with argument 0 + Worker running with argument 1 + Worker running with argument 2 + Worker running with argument 3 + Worker running with argument 4 + Worker running with argument 5 ... Consult the module's documentation for more details; the ``Queue`` class @@ -351,7 +355,7 @@ What kinds of global value mutation are thread-safe? A global interpreter lock (GIL) is used internally to ensure that only one thread runs in the Python VM at a time. In general, Python offers to switch among threads only between bytecode instructions; how frequently it switches can -be set via :func:`sys.setcheckinterval`. Each bytecode instruction and +be set via :func:`sys.setswitchinterval`. Each bytecode instruction and therefore all the C implementation code reached from each instruction is therefore atomic from the point of view of a Python program. @@ -443,7 +447,7 @@ How do I delete a file? (And other file questions...) ----------------------------------------------------- Use ``os.remove(filename)`` or ``os.unlink(filename)``; for documentation, see -the :mod:`os` module. The two functions are identical; :func:`unlink` is simply +the :mod:`os` module. The two functions are identical; :func:`~os.unlink` is simply the name of the Unix system call for this function. To remove a directory, use :func:`os.rmdir`; use :func:`os.mkdir` to create one. @@ -512,81 +516,83 @@ to read n bytes from a pipe p created with :func:`os.popen`, you need to use ``p.read(n)``. -How do I run a subprocess with pipes connected to both input and output? ------------------------------------------------------------------------- - -.. XXX update to use subprocess - -Use the :mod:`popen2` module. For example:: - - import popen2 - fromchild, tochild = popen2.popen2("command") - tochild.write("input\n") - tochild.flush() - output = fromchild.readline() - -Warning: in general it is unwise to do this because you can easily cause a -deadlock where your process is blocked waiting for output from the child while -the child is blocked waiting for input from you. This can be caused because the -parent expects the child to output more text than it does, or it can be caused -by data being stuck in stdio buffers due to lack of flushing. The Python parent -can of course explicitly flush the data it sends to the child before it reads -any output, but if the child is a naive C program it may have been written to -never explicitly flush its output, even if it is interactive, since flushing is -normally automatic. - -Note that a deadlock is also possible if you use :func:`popen3` to read stdout -and stderr. If one of the two is too large for the internal buffer (increasing -the buffer size does not help) and you ``read()`` the other one first, there is -a deadlock, too. - -Note on a bug in popen2: unless your program calls ``wait()`` or ``waitpid()``, -finished child processes are never removed, and eventually calls to popen2 will -fail because of a limit on the number of child processes. Calling -:func:`os.waitpid` with the :data:`os.WNOHANG` option can prevent this; a good -place to insert such a call would be before calling ``popen2`` again. - -In many cases, all you really need is to run some data through a command and get -the result back. Unless the amount of data is very large, the easiest way to do -this is to write it to a temporary file and run the command with that temporary -file as input. The standard module :mod:`tempfile` exports a ``mktemp()`` -function to generate unique temporary file names. :: - - import tempfile - import os - - class Popen3: - """ - This is a deadlock-safe version of popen that returns - an object with errorlevel, out (a string) and err (a string). - (capturestderr may not work under windows.) - Example: print Popen3('grep spam','\n\nhere spam\n\n').out - """ - def __init__(self,command,input=None,capturestderr=None): - outfile=tempfile.mktemp() - command="( %s ) > %s" % (command,outfile) - if input: - infile=tempfile.mktemp() - open(infile,"w").write(input) - command=command+" <"+infile - if capturestderr: - errfile=tempfile.mktemp() - command=command+" 2>"+errfile - self.errorlevel=os.system(command) >> 8 - self.out=open(outfile,"r").read() - os.remove(outfile) - if input: - os.remove(infile) - if capturestderr: - self.err=open(errfile,"r").read() - os.remove(errfile) - -Note that many interactive programs (e.g. vi) don't work well with pipes -substituted for standard input and output. You will have to use pseudo ttys -("ptys") instead of pipes. Or you can use a Python interface to Don Libes' -"expect" library. A Python extension that interfaces to expect is called "expy" -and available from http://expectpy.sourceforge.net. A pure Python solution that -works like expect is `pexpect `_. +.. XXX update to use subprocess. See the :ref:`subprocess-replacements` section. + + How do I run a subprocess with pipes connected to both input and output? + ------------------------------------------------------------------------ + + Use the :mod:`popen2` module. For example:: + + import popen2 + fromchild, tochild = popen2.popen2("command") + tochild.write("input\n") + tochild.flush() + output = fromchild.readline() + + Warning: in general it is unwise to do this because you can easily cause a + deadlock where your process is blocked waiting for output from the child + while the child is blocked waiting for input from you. This can be caused + because the parent expects the child to output more text than it does, or it + can be caused by data being stuck in stdio buffers due to lack of flushing. + The Python parent can of course explicitly flush the data it sends to the + child before it reads any output, but if the child is a naive C program it + may have been written to never explicitly flush its output, even if it is + interactive, since flushing is normally automatic. + + Note that a deadlock is also possible if you use :func:`popen3` to read + stdout and stderr. If one of the two is too large for the internal buffer + (increasing the buffer size does not help) and you ``read()`` the other one + first, there is a deadlock, too. + + Note on a bug in popen2: unless your program calls ``wait()`` or + ``waitpid()``, finished child processes are never removed, and eventually + calls to popen2 will fail because of a limit on the number of child + processes. Calling :func:`os.waitpid` with the :data:`os.WNOHANG` option can + prevent this; a good place to insert such a call would be before calling + ``popen2`` again. + + In many cases, all you really need is to run some data through a command and + get the result back. Unless the amount of data is very large, the easiest + way to do this is to write it to a temporary file and run the command with + that temporary file as input. The standard module :mod:`tempfile` exports a + ``mktemp()`` function to generate unique temporary file names. :: + + import tempfile + import os + + class Popen3: + """ + This is a deadlock-safe version of popen that returns + an object with errorlevel, out (a string) and err (a string). + (capturestderr may not work under windows.) + Example: print(Popen3('grep spam','\n\nhere spam\n\n').out) + """ + def __init__(self,command,input=None,capturestderr=None): + outfile=tempfile.mktemp() + command="( %s ) > %s" % (command,outfile) + if input: + infile=tempfile.mktemp() + open(infile,"w").write(input) + command=command+" <"+infile + if capturestderr: + errfile=tempfile.mktemp() + command=command+" 2>"+errfile + self.errorlevel=os.system(command) >> 8 + self.out=open(outfile,"r").read() + os.remove(outfile) + if input: + os.remove(infile) + if capturestderr: + self.err=open(errfile,"r").read() + os.remove(errfile) + + Note that many interactive programs (e.g. vi) don't work well with pipes + substituted for standard input and output. You will have to use pseudo ttys + ("ptys") instead of pipes. Or you can use a Python interface to Don Libes' + "expect" library. A Python extension that interfaces to expect is called + "expy" and available from http://expectpy.sourceforge.net. A pure Python + solution that works like expect is `pexpect + `_. How do I access the serial (RS232) port? @@ -654,41 +660,29 @@ How can I mimic CGI form submission (METHOD=POST)? I would like to retrieve web pages that are the result of POSTing a form. Is there existing code that would let me do this easily? -Yes. Here's a simple example that uses httplib:: +Yes. Here's a simple example that uses urllib.request:: #!/usr/local/bin/python - import httplib, sys, time + import urllib.request ### build the query string qs = "First=Josephine&MI=Q&Last=Public" ### connect and send the server a path - httpobj = httplib.HTTP('www.some-server.out-there', 80) - httpobj.putrequest('POST', '/cgi-bin/some-cgi-script') - ### now generate the rest of the HTTP headers... - httpobj.putheader('Accept', '*/*') - httpobj.putheader('Connection', 'Keep-Alive') - httpobj.putheader('Content-type', 'application/x-www-form-urlencoded') - httpobj.putheader('Content-length', '%d' % len(qs)) - httpobj.endheaders() - httpobj.send(qs) - ### find out what the server said in response... - reply, msg, hdrs = httpobj.getreply() - if reply != 200: - sys.stdout.write(httpobj.getfile().read()) + req = urllib.request.urlopen('http://www.some-server.out-there' + '/cgi-bin/some-cgi-script', data=qs) + msg, hdrs = req.read(), req.info() Note that in general for a percent-encoded POST operations, query strings must be -quoted by using :func:`urllib.quote`. For example to send name="Guy Steele, +quoted by using :func:`urllib.parse.urlencode`. For example to send name="Guy Steele, Jr.":: - >>> from urllib import quote - >>> x = quote("Guy Steele, Jr.") - >>> x - 'Guy%20Steele,%20Jr.' - >>> query_string = "name="+x - >>> query_string - 'name=Guy%20Steele,%20Jr.' + >>> import urllib.parse + >>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'}) + 'name=Guy+Steele%2C+Jr.' + +.. seealso:: :ref:`urllib-howto` for extensive examples. What module should I use to help with generating HTML? @@ -721,9 +715,9 @@ work on any host that supports an SMTP listener. :: import sys, smtplib - fromaddr = raw_input("From: ") - toaddrs = raw_input("To: ").split(',') - print "Enter message, end with ^D:" + fromaddr = input("From: ") + toaddrs = input("To: ").split(',') + print("Enter message, end with ^D:") msg = '' while True: line = sys.stdin.readline() @@ -741,17 +735,17 @@ varies between systems; sometimes it is ``/usr/lib/sendmail``, sometime ``/usr/sbin/sendmail``. The sendmail manual page will help you out. Here's some sample code:: - SENDMAIL = "/usr/sbin/sendmail" # sendmail location + SENDMAIL = "/usr/sbin/sendmail" # sendmail location import os p = os.popen("%s -t -i" % SENDMAIL, "w") p.write("To: receiver@example.com\n") p.write("Subject: test\n") - p.write("\n") # blank line separating headers from body + p.write("\n") # blank line separating headers from body p.write("Some text\n") p.write("some more text\n") sts = p.close() if sts != 0: - print "Sendmail exit status", sts + print("Sendmail exit status", sts) How do I avoid blocking in the connect() method of a socket? @@ -768,7 +762,7 @@ have to check what's returned on your system. You can use the ``connect_ex()`` method to avoid creating an exception. It will just return the errno value. To poll, you can call ``connect_ex()`` again later --- 0 or ``errno.EISCONN`` indicate that you're connected -- or you can pass this +-- ``0`` or ``errno.EISCONN`` indicate that you're connected -- or you can pass this socket to select to check if it's writable. @@ -807,21 +801,15 @@ than a third of a second. This often beats doing something more complex and general such as using gdbm with pickle/shelve. -Why is cPickle so slow? ------------------------ - -.. XXX update this, default protocol is 2/3 +If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come? +------------------------------------------------------------------------------------------ -The default format used by the pickle module is a slow one that results in -readable pickles. Making it the default, but it would break backward -compatibility:: +.. XXX move this FAQ entry elsewhere? - largeString = 'z' * (100 * 1024) - myPickle = cPickle.dumps(largeString, protocol=1) +.. note:: - -If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come? ------------------------------------------------------------------------------------------- + The bsddb module is now available as a standalone package `pybsddb + `_. Databases opened for write access with the bsddb module (and often by the anydbm module, since it will preferentially use bsddb) must explicitly be closed using @@ -836,6 +824,13 @@ encounter an exception the next time the file is opened. I tried to open Berkeley DB file, but bsddb produces bsddb.error: (22, 'Invalid argument'). Help! How can I restore my data? ---------------------------------------------------------------------------------------------------------------------------- +.. XXX move this FAQ entry elsewhere? + +.. note:: + + The bsddb module is now available as a standalone package `pybsddb + `_. + Don't panic! Your data is probably intact. The most frequent cause for the error is that you tried to open an earlier Berkeley DB file with a later version of the Berkeley DB library. diff --git a/Doc/faq/windows.rst b/Doc/faq/windows.rst index 2d701c843b..2a19c981fc 100644 --- a/Doc/faq/windows.rst +++ b/Doc/faq/windows.rst @@ -8,6 +8,10 @@ Python on Windows FAQ .. contents:: +.. XXX need review for Python 3. + XXX need review for Windows Vista/Seven? + + How do I run a Python program under Windows? -------------------------------------------- @@ -67,7 +71,7 @@ Python statements or expressions interactively and have them executed or evaluated while you wait. This is one of Python's strongest features. Check it by entering a few expressions of your choice and seeing the results:: - >>> print "Hello" + >>> print("Hello") Hello >>> "Hello" * 3 HelloHelloHello @@ -507,7 +511,7 @@ Example:: import win32pipe f = win32pipe.popen('dir /c c:\\') - print f.readlines() + print(f.readlines()) f.close() diff --git a/Doc/howto/urllib2.rst b/Doc/howto/urllib2.rst index fb5b1c3311..110b6de3b6 100644 --- a/Doc/howto/urllib2.rst +++ b/Doc/howto/urllib2.rst @@ -1,3 +1,5 @@ +.. _urllib-howto: + *********************************************************** HOWTO Fetch Internet Resources Using The urllib Package *********************************************************** diff --git a/Doc/library/uuid.rst b/Doc/library/uuid.rst index 0ec2ed3dee..835194675f 100644 --- a/Doc/library/uuid.rst +++ b/Doc/library/uuid.rst @@ -31,9 +31,9 @@ random UUID. UUID('{12345678-1234-5678-1234-567812345678}') UUID('12345678123456781234567812345678') UUID('urn:uuid:12345678-1234-5678-1234-567812345678') - UUID(bytes='\x12\x34\x56\x78'*4) - UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' + - '\x12\x34\x56\x78\x12\x34\x56\x78') + UUID(bytes=b'\x12\x34\x56\x78'*4) + UUID(bytes_le=b'\x78\x56\x34\x12\x34\x12\x78\x56' + + b'\x12\x34\x56\x78\x12\x34\x56\x78') UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678)) UUID(int=0x12345678123456781234567812345678) @@ -247,7 +247,7 @@ Here are some examples of typical usage of the :mod:`uuid` module:: # get the raw 16 bytes of the UUID >>> x.bytes - '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' + b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f' # make a UUID from a 16-byte string >>> uuid.UUID(bytes=x.bytes) diff --git a/Lib/test/test_uuid.py b/Lib/test/test_uuid.py index a1663c5596..43fa656102 100644 --- a/Lib/test/test_uuid.py +++ b/Lib/test/test_uuid.py @@ -1,5 +1,6 @@ from unittest import TestCase from test import support +import builtins import uuid def importable(name): @@ -176,6 +177,11 @@ class TestUUID(TestCase): for u in equivalents: for v in equivalents: equal(u, v) + + # Bug 7380: "bytes" and "bytes_le" should give the same type. + equal(type(u.bytes), builtins.bytes) + equal(type(u.bytes_le), builtins.bytes) + ascending.append(u) # Test comparison of UUIDs. diff --git a/Lib/uuid.py b/Lib/uuid.py index b17f1c85bd..6e687943d6 100644 --- a/Lib/uuid.py +++ b/Lib/uuid.py @@ -13,7 +13,7 @@ Typical usage: >>> import uuid # make a UUID based on the host ID and current time - >>> uuid.uuid1() + >>> uuid.uuid1() # doctest: +SKIP UUID('a8098c1a-f86e-11da-bd1a-00112444be1e') # make a UUID using an MD5 hash of a namespace UUID and a name @@ -21,7 +21,7 @@ Typical usage: UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e') # make a random UUID - >>> uuid.uuid4() + >>> uuid.uuid4() # doctest: +SKIP UUID('16fd2706-8baf-433b-82eb-8c7fada847da') # make a UUID using a SHA-1 hash of a namespace UUID and a name @@ -237,7 +237,7 @@ class UUID(object): bytes = bytearray() for shift in range(0, 128, 8): bytes.insert(0, (self.int >> shift) & 0xff) - return bytes + return bytes_(bytes) @property def bytes_le(self):