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. ................
This commit is contained in:
parent
c06f34fa9b
commit
107690c2ff
|
@ -285,13 +285,6 @@ Initialization, Finalization, and Threads
|
||||||
modify its value. The value is available to Python code as :data:`sys.version`.
|
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()
|
.. cfunction:: const char* Py_GetPlatform()
|
||||||
|
|
||||||
.. index:: single: platform (in module sys)
|
.. index:: single: platform (in module sys)
|
||||||
|
|
|
@ -29,12 +29,6 @@ Reflection
|
||||||
currently executing.
|
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)
|
.. cfunction:: const char* PyEval_GetFuncName(PyObject *func)
|
||||||
|
|
||||||
Return the name of *func* if it is a function, class or instance object, else the
|
Return the name of *func* if it is a function, class or instance object, else the
|
||||||
|
|
|
@ -234,8 +234,10 @@ code breakage.
|
||||||
|
|
||||||
.. XXX talk about protocols?
|
.. XXX talk about protocols?
|
||||||
|
|
||||||
Note that for string operations Python has moved from external functions (the
|
.. note::
|
||||||
``string`` module) to methods. However, ``len()`` is still a function.
|
|
||||||
|
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?
|
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
|
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::
|
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]
|
value = dict[key]
|
||||||
else:
|
else:
|
||||||
dict[key] = getvalue(key)
|
dict[key] = getvalue(key)
|
||||||
value = dict[key]
|
value = dict[key]
|
||||||
|
|
||||||
(In Python 2.0 and higher, you can code this as ``value = dict.setdefault(key,
|
For this specific case, you could also use ``value = dict.setdefault(key,
|
||||||
getvalue(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?
|
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.
|
# Callers will never provide a third parameter for this function.
|
||||||
def expensive (arg1, arg2, _cache={}):
|
def expensive (arg1, arg2, _cache={}):
|
||||||
if _cache.has_key((arg1, arg2)):
|
if (arg1, arg2) in _cache:
|
||||||
return _cache[(arg1, arg2)]
|
return _cache[(arg1, arg2)]
|
||||||
|
|
||||||
# Calculate the value
|
# Calculate the value
|
||||||
|
|
|
@ -7,6 +7,9 @@ Extending/Embedding FAQ
|
||||||
.. highlight:: c
|
.. highlight:: c
|
||||||
|
|
||||||
|
|
||||||
|
.. XXX need review for Python 3.
|
||||||
|
|
||||||
|
|
||||||
Can I create my own functions in C?
|
Can I create my own functions in C?
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
|
|
||||||
|
@ -53,8 +56,7 @@ with a tool such as `SWIG <http://www.swig.org>`_. `SIP
|
||||||
<http://www.riverbankcomputing.co.uk/software/sip/>`__, `CXX
|
<http://www.riverbankcomputing.co.uk/software/sip/>`__, `CXX
|
||||||
<http://cxx.sourceforge.net/>`_ `Boost
|
<http://cxx.sourceforge.net/>`_ `Boost
|
||||||
<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave
|
<http://www.boost.org/libs/python/doc/index.html>`_, or `Weave
|
||||||
<http://www.scipy.org/Weave>`_ are also alternatives for wrapping
|
<http://www.scipy.org/Weave>`_ are also alternatives for wrapping C++ libraries.
|
||||||
C++ libraries.
|
|
||||||
|
|
||||||
|
|
||||||
How can I execute arbitrary Python statements from C?
|
How can I execute arbitrary Python statements from C?
|
||||||
|
@ -161,8 +163,8 @@ Sample code and use for catching stdout:
|
||||||
...
|
...
|
||||||
>>> import sys
|
>>> import sys
|
||||||
>>> sys.stdout = StdoutCatcher()
|
>>> sys.stdout = StdoutCatcher()
|
||||||
>>> print 'foo'
|
>>> print('foo')
|
||||||
>>> print 'hello world!'
|
>>> print('hello world!')
|
||||||
>>> sys.stderr.write(sys.stdout.data)
|
>>> sys.stderr.write(sys.stdout.data)
|
||||||
foo
|
foo
|
||||||
hello world!
|
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
|
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.
|
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
|
||||||
|
<http://www.riverbankcomputing.co.uk/sip/>`_, `CXX
|
||||||
|
<http://cxx.sourceforge.net/>`_, `Boost
|
||||||
|
<http://www.boost.org/libs/python/doc/index.html>`_, `Weave
|
||||||
|
<http://www.scipy.org/Weave>`_ or `SWIG <http://www.swig.org>`_
|
||||||
|
|
||||||
|
|
||||||
I added a module using the Setup file and the make fails; why?
|
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
|
>>> import sys
|
||||||
>>> if sys.maxunicode > 65535:
|
>>> if sys.maxunicode > 65535:
|
||||||
... print 'UCS4 build'
|
... print('UCS4 build')
|
||||||
... else:
|
... else:
|
||||||
... print 'UCS2 build'
|
... print('UCS2 build')
|
||||||
|
|
||||||
The only way to solve this problem is to use extension modules compiled with a
|
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.
|
Python binary built using the same size for Unicode characters.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ Graphic User Interface FAQ
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
|
.. XXX need review for Python 3.
|
||||||
|
|
||||||
|
|
||||||
General GUI Questions
|
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.
|
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
|
Usually a widget is given the keyboard focus by clicking in it (but not for
|
||||||
labels; see the takefocus option).
|
labels; see the takefocus option).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ There are (at least) three kinds of modules in Python:
|
||||||
type::
|
type::
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
print sys.builtin_module_names
|
print(sys.builtin_module_names)
|
||||||
|
|
||||||
|
|
||||||
How do I make a Python script executable on Unix?
|
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
|
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
|
using curses, but curses is a fairly large module to learn.
|
||||||
without curses::
|
|
||||||
|
.. 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
|
import termios, fcntl, sys, os
|
||||||
fd = sys.stdin.fileno()
|
fd = sys.stdin.fileno()
|
||||||
|
@ -202,23 +205,24 @@ without curses::
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
|
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while 1:
|
while True:
|
||||||
try:
|
try:
|
||||||
c = sys.stdin.read(1)
|
c = sys.stdin.read(1)
|
||||||
print "Got character", `c`
|
print("Got character", repr(c))
|
||||||
except IOError: pass
|
except IOError:
|
||||||
|
pass
|
||||||
finally:
|
finally:
|
||||||
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
|
termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
|
||||||
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
|
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
|
||||||
|
|
||||||
You need the :mod:`termios` and the :mod:`fcntl` module for any of this to work,
|
You need the :mod:`termios` and the :mod:`fcntl` module for any of this to
|
||||||
and I've only tried it on Linux, though it should work elsewhere. In this code,
|
work, and I've only tried it on Linux, though it should work elsewhere. In
|
||||||
characters are read and printed one at a time.
|
this code, characters are read and printed one at a time.
|
||||||
|
|
||||||
:func:`termios.tcsetattr` turns off stdin's echoing and disables canonical mode.
|
:func:`termios.tcsetattr` turns off stdin's echoing and disables canonical
|
||||||
:func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags and modify
|
mode. :func:`fcntl.fnctl` is used to obtain stdin's file descriptor flags
|
||||||
them for non-blocking mode. Since reading stdin when it is empty results in an
|
and modify them for non-blocking mode. Since reading stdin when it is empty
|
||||||
:exc:`IOError`, this error is caught and ignored.
|
results in an :exc:`IOError`, this error is caught and ignored.
|
||||||
|
|
||||||
|
|
||||||
Threads
|
Threads
|
||||||
|
@ -247,13 +251,13 @@ all the threads to finish::
|
||||||
import threading, time
|
import threading, time
|
||||||
|
|
||||||
def thread_task(name, n):
|
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):
|
for i in range(10):
|
||||||
T = threading.Thread(target=thread_task, args=(str(i), i))
|
T = threading.Thread(target=thread_task, args=(str(i), i))
|
||||||
T.start()
|
T.start()
|
||||||
|
|
||||||
time.sleep(10) # <----------------------------!
|
time.sleep(10) # <---------------------------!
|
||||||
|
|
||||||
But now (on many platforms) the threads don't run in parallel, but appear to run
|
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
|
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::
|
A simple fix is to add a tiny sleep to the start of the run function::
|
||||||
|
|
||||||
def thread_task(name, n):
|
def thread_task(name, n):
|
||||||
time.sleep(0.001) # <---------------------!
|
time.sleep(0.001) # <--------------------!
|
||||||
for i in range(n): print name, i
|
for i in range(n): print(name, i)
|
||||||
|
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
T = threading.Thread(target=thread_task, args=(str(i), i))
|
T = threading.Thread(target=thread_task, args=(str(i), i))
|
||||||
|
@ -289,28 +293,28 @@ once.
|
||||||
|
|
||||||
Here's a trivial example::
|
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
|
# The worker thread gets jobs off the queue. When the queue is empty, it
|
||||||
# assumes there will be no more work and exits.
|
# assumes there will be no more work and exits.
|
||||||
# (Realistically workers will run until terminated.)
|
# (Realistically workers will run until terminated.)
|
||||||
def worker ():
|
def worker ():
|
||||||
print 'Running worker'
|
print('Running worker')
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
arg = q.get(block=False)
|
arg = q.get(block=False)
|
||||||
except Queue.Empty:
|
except queue.Empty:
|
||||||
print 'Worker', threading.currentThread(),
|
print('Worker', threading.currentThread(), end=' ')
|
||||||
print 'queue empty'
|
print('queue empty')
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
print 'Worker', threading.currentThread(),
|
print('Worker', threading.currentThread(), end=' ')
|
||||||
print 'running with argument', arg
|
print('running with argument', arg)
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
# Create queue
|
# Create queue
|
||||||
q = Queue.Queue()
|
q = queue.Queue()
|
||||||
|
|
||||||
# Start a pool of 5 workers
|
# Start a pool of 5 workers
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
|
@ -322,10 +326,10 @@ Here's a trivial example::
|
||||||
q.put(i)
|
q.put(i)
|
||||||
|
|
||||||
# Give threads time to run
|
# Give threads time to run
|
||||||
print 'Main thread sleeping'
|
print('Main thread sleeping')
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
|
|
||||||
When run, this will produce the following output:
|
When run, this will produce the following output::
|
||||||
|
|
||||||
Running worker
|
Running worker
|
||||||
Running worker
|
Running worker
|
||||||
|
@ -333,12 +337,12 @@ When run, this will produce the following output:
|
||||||
Running worker
|
Running worker
|
||||||
Running worker
|
Running worker
|
||||||
Main thread sleeping
|
Main thread sleeping
|
||||||
Worker <Thread(worker 1, started)> running with argument 0
|
Worker <Thread(worker 1, started 130283832797456)> running with argument 0
|
||||||
Worker <Thread(worker 2, started)> running with argument 1
|
Worker <Thread(worker 2, started 130283824404752)> running with argument 1
|
||||||
Worker <Thread(worker 3, started)> running with argument 2
|
Worker <Thread(worker 3, started 130283816012048)> running with argument 2
|
||||||
Worker <Thread(worker 4, started)> running with argument 3
|
Worker <Thread(worker 4, started 130283807619344)> running with argument 3
|
||||||
Worker <Thread(worker 5, started)> running with argument 4
|
Worker <Thread(worker 5, started 130283799226640)> running with argument 4
|
||||||
Worker <Thread(worker 1, started)> running with argument 5
|
Worker <Thread(worker 1, started 130283832797456)> running with argument 5
|
||||||
...
|
...
|
||||||
|
|
||||||
Consult the module's documentation for more details; the ``Queue`` class
|
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
|
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
|
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
|
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 all the C implementation code reached from each instruction is
|
||||||
therefore atomic from the point of view of a Python program.
|
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
|
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.
|
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.
|
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)``.
|
``p.read(n)``.
|
||||||
|
|
||||||
|
|
||||||
How do I run a subprocess with pipes connected to both input and output?
|
.. XXX update to use subprocess. See the :ref:`subprocess-replacements` section.
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
.. XXX update to use subprocess
|
How do I run a subprocess with pipes connected to both input and output?
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
Use the :mod:`popen2` module. For example::
|
Use the :mod:`popen2` module. For example::
|
||||||
|
|
||||||
import popen2
|
import popen2
|
||||||
fromchild, tochild = popen2.popen2("command")
|
fromchild, tochild = popen2.popen2("command")
|
||||||
tochild.write("input\n")
|
tochild.write("input\n")
|
||||||
tochild.flush()
|
tochild.flush()
|
||||||
output = fromchild.readline()
|
output = fromchild.readline()
|
||||||
|
|
||||||
Warning: in general it is unwise to do this because you can easily cause a
|
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
|
deadlock where your process is blocked waiting for output from the child
|
||||||
the child is blocked waiting for input from you. This can be caused because the
|
while the child is blocked waiting for input from you. This can be caused
|
||||||
parent expects the child to output more text than it does, or it can be caused
|
because the parent expects the child to output more text than it does, or it
|
||||||
by data being stuck in stdio buffers due to lack of flushing. The Python parent
|
can be caused by data being stuck in stdio buffers due to lack of flushing.
|
||||||
can of course explicitly flush the data it sends to the child before it reads
|
The Python parent can of course explicitly flush the data it sends to the
|
||||||
any output, but if the child is a naive C program it may have been written to
|
child before it reads any output, but if the child is a naive C program it
|
||||||
never explicitly flush its output, even if it is interactive, since flushing is
|
may have been written to never explicitly flush its output, even if it is
|
||||||
normally automatic.
|
interactive, since flushing is normally automatic.
|
||||||
|
|
||||||
Note that a deadlock is also possible if you use :func:`popen3` to read stdout
|
Note that a deadlock is also possible if you use :func:`popen3` to read
|
||||||
and stderr. If one of the two is too large for the internal buffer (increasing
|
stdout and stderr. If one of the two is too large for the internal buffer
|
||||||
the buffer size does not help) and you ``read()`` the other one first, there is
|
(increasing the buffer size does not help) and you ``read()`` the other one
|
||||||
a deadlock, too.
|
first, there is a deadlock, too.
|
||||||
|
|
||||||
Note on a bug in popen2: unless your program calls ``wait()`` or ``waitpid()``,
|
Note on a bug in popen2: unless your program calls ``wait()`` or
|
||||||
finished child processes are never removed, and eventually calls to popen2 will
|
``waitpid()``, finished child processes are never removed, and eventually
|
||||||
fail because of a limit on the number of child processes. Calling
|
calls to popen2 will fail because of a limit on the number of child
|
||||||
:func:`os.waitpid` with the :data:`os.WNOHANG` option can prevent this; a good
|
processes. Calling :func:`os.waitpid` with the :data:`os.WNOHANG` option can
|
||||||
place to insert such a call would be before calling ``popen2`` again.
|
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
|
In many cases, all you really need is to run some data through a command and
|
||||||
the result back. Unless the amount of data is very large, the easiest way to do
|
get the result back. Unless the amount of data is very large, the easiest
|
||||||
this is to write it to a temporary file and run the command with that temporary
|
way to do this is to write it to a temporary file and run the command with
|
||||||
file as input. The standard module :mod:`tempfile` exports a ``mktemp()``
|
that temporary file as input. The standard module :mod:`tempfile` exports a
|
||||||
function to generate unique temporary file names. ::
|
``mktemp()`` function to generate unique temporary file names. ::
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import os
|
import os
|
||||||
|
|
||||||
class Popen3:
|
class Popen3:
|
||||||
"""
|
"""
|
||||||
This is a deadlock-safe version of popen that returns
|
This is a deadlock-safe version of popen that returns
|
||||||
an object with errorlevel, out (a string) and err (a string).
|
an object with errorlevel, out (a string) and err (a string).
|
||||||
(capturestderr may not work under windows.)
|
(capturestderr may not work under windows.)
|
||||||
Example: print Popen3('grep spam','\n\nhere spam\n\n').out
|
Example: print(Popen3('grep spam','\n\nhere spam\n\n').out)
|
||||||
"""
|
"""
|
||||||
def __init__(self,command,input=None,capturestderr=None):
|
def __init__(self,command,input=None,capturestderr=None):
|
||||||
outfile=tempfile.mktemp()
|
outfile=tempfile.mktemp()
|
||||||
command="( %s ) > %s" % (command,outfile)
|
command="( %s ) > %s" % (command,outfile)
|
||||||
if input:
|
if input:
|
||||||
infile=tempfile.mktemp()
|
infile=tempfile.mktemp()
|
||||||
open(infile,"w").write(input)
|
open(infile,"w").write(input)
|
||||||
command=command+" <"+infile
|
command=command+" <"+infile
|
||||||
if capturestderr:
|
if capturestderr:
|
||||||
errfile=tempfile.mktemp()
|
errfile=tempfile.mktemp()
|
||||||
command=command+" 2>"+errfile
|
command=command+" 2>"+errfile
|
||||||
self.errorlevel=os.system(command) >> 8
|
self.errorlevel=os.system(command) >> 8
|
||||||
self.out=open(outfile,"r").read()
|
self.out=open(outfile,"r").read()
|
||||||
os.remove(outfile)
|
os.remove(outfile)
|
||||||
if input:
|
if input:
|
||||||
os.remove(infile)
|
os.remove(infile)
|
||||||
if capturestderr:
|
if capturestderr:
|
||||||
self.err=open(errfile,"r").read()
|
self.err=open(errfile,"r").read()
|
||||||
os.remove(errfile)
|
os.remove(errfile)
|
||||||
|
|
||||||
Note that many interactive programs (e.g. vi) don't work well with pipes
|
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
|
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'
|
("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"
|
"expect" library. A Python extension that interfaces to expect is called
|
||||||
and available from http://expectpy.sourceforge.net. A pure Python solution that
|
"expy" and available from http://expectpy.sourceforge.net. A pure Python
|
||||||
works like expect is `pexpect <http://pypi.python.org/pypi/pexpect/>`_.
|
solution that works like expect is `pexpect
|
||||||
|
<http://pypi.python.org/pypi/pexpect/>`_.
|
||||||
|
|
||||||
|
|
||||||
How do I access the serial (RS232) port?
|
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
|
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?
|
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
|
#!/usr/local/bin/python
|
||||||
|
|
||||||
import httplib, sys, time
|
import urllib.request
|
||||||
|
|
||||||
### build the query string
|
### build the query string
|
||||||
qs = "First=Josephine&MI=Q&Last=Public"
|
qs = "First=Josephine&MI=Q&Last=Public"
|
||||||
|
|
||||||
### connect and send the server a path
|
### connect and send the server a path
|
||||||
httpobj = httplib.HTTP('www.some-server.out-there', 80)
|
req = urllib.request.urlopen('http://www.some-server.out-there'
|
||||||
httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')
|
'/cgi-bin/some-cgi-script', data=qs)
|
||||||
### now generate the rest of the HTTP headers...
|
msg, hdrs = req.read(), req.info()
|
||||||
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())
|
|
||||||
|
|
||||||
Note that in general for a percent-encoded POST operations, query strings must be
|
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."::
|
Jr."::
|
||||||
|
|
||||||
>>> from urllib import quote
|
>>> import urllib.parse
|
||||||
>>> x = quote("Guy Steele, Jr.")
|
>>> urllib.parse.urlencode({'name': 'Guy Steele, Jr.'})
|
||||||
>>> x
|
'name=Guy+Steele%2C+Jr.'
|
||||||
'Guy%20Steele,%20Jr.'
|
|
||||||
>>> query_string = "name="+x
|
.. seealso:: :ref:`urllib-howto` for extensive examples.
|
||||||
>>> query_string
|
|
||||||
'name=Guy%20Steele,%20Jr.'
|
|
||||||
|
|
||||||
|
|
||||||
What module should I use to help with generating HTML?
|
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
|
import sys, smtplib
|
||||||
|
|
||||||
fromaddr = raw_input("From: ")
|
fromaddr = input("From: ")
|
||||||
toaddrs = raw_input("To: ").split(',')
|
toaddrs = input("To: ").split(',')
|
||||||
print "Enter message, end with ^D:"
|
print("Enter message, end with ^D:")
|
||||||
msg = ''
|
msg = ''
|
||||||
while True:
|
while True:
|
||||||
line = sys.stdin.readline()
|
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
|
``/usr/sbin/sendmail``. The sendmail manual page will help you out. Here's
|
||||||
some sample code::
|
some sample code::
|
||||||
|
|
||||||
SENDMAIL = "/usr/sbin/sendmail" # sendmail location
|
SENDMAIL = "/usr/sbin/sendmail" # sendmail location
|
||||||
import os
|
import os
|
||||||
p = os.popen("%s -t -i" % SENDMAIL, "w")
|
p = os.popen("%s -t -i" % SENDMAIL, "w")
|
||||||
p.write("To: receiver@example.com\n")
|
p.write("To: receiver@example.com\n")
|
||||||
p.write("Subject: test\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 text\n")
|
||||||
p.write("some more text\n")
|
p.write("some more text\n")
|
||||||
sts = p.close()
|
sts = p.close()
|
||||||
if sts != 0:
|
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?
|
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
|
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
|
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.
|
socket to select to check if it's writable.
|
||||||
|
|
||||||
|
|
||||||
|
@ -807,22 +801,16 @@ than a third of a second. This often beats doing something more complex and
|
||||||
general such as using gdbm with pickle/shelve.
|
general such as using gdbm with pickle/shelve.
|
||||||
|
|
||||||
|
|
||||||
Why is cPickle so slow?
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
.. XXX update this, default protocol is 2/3
|
|
||||||
|
|
||||||
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::
|
|
||||||
|
|
||||||
largeString = 'z' * (100 * 1024)
|
|
||||||
myPickle = cPickle.dumps(largeString, protocol=1)
|
|
||||||
|
|
||||||
|
|
||||||
If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come?
|
If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come?
|
||||||
------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.. XXX move this FAQ entry elsewhere?
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The bsddb module is now available as a standalone package `pybsddb
|
||||||
|
<http://www.jcea.es/programacion/pybsddb.htm>`_.
|
||||||
|
|
||||||
Databases opened for write access with the bsddb module (and often by the anydbm
|
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
|
module, since it will preferentially use bsddb) must explicitly be closed using
|
||||||
the ``.close()`` method of the database. The underlying library caches database
|
the ``.close()`` method of the database. The underlying library caches database
|
||||||
|
@ -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?
|
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
|
||||||
|
<http://www.jcea.es/programacion/pybsddb.htm>`_.
|
||||||
|
|
||||||
Don't panic! Your data is probably intact. The most frequent cause for the error
|
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
|
is that you tried to open an earlier Berkeley DB file with a later version of
|
||||||
the Berkeley DB library.
|
the Berkeley DB library.
|
||||||
|
|
|
@ -8,6 +8,10 @@ Python on Windows FAQ
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
|
.. XXX need review for Python 3.
|
||||||
|
XXX need review for Windows Vista/Seven?
|
||||||
|
|
||||||
|
|
||||||
How do I run a Python program under Windows?
|
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
|
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::
|
by entering a few expressions of your choice and seeing the results::
|
||||||
|
|
||||||
>>> print "Hello"
|
>>> print("Hello")
|
||||||
Hello
|
Hello
|
||||||
>>> "Hello" * 3
|
>>> "Hello" * 3
|
||||||
HelloHelloHello
|
HelloHelloHello
|
||||||
|
@ -507,7 +511,7 @@ Example::
|
||||||
|
|
||||||
import win32pipe
|
import win32pipe
|
||||||
f = win32pipe.popen('dir /c c:\\')
|
f = win32pipe.popen('dir /c c:\\')
|
||||||
print f.readlines()
|
print(f.readlines())
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. _urllib-howto:
|
||||||
|
|
||||||
***********************************************************
|
***********************************************************
|
||||||
HOWTO Fetch Internet Resources Using The urllib Package
|
HOWTO Fetch Internet Resources Using The urllib Package
|
||||||
***********************************************************
|
***********************************************************
|
||||||
|
|
|
@ -31,9 +31,9 @@ random UUID.
|
||||||
UUID('{12345678-1234-5678-1234-567812345678}')
|
UUID('{12345678-1234-5678-1234-567812345678}')
|
||||||
UUID('12345678123456781234567812345678')
|
UUID('12345678123456781234567812345678')
|
||||||
UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
|
UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
|
||||||
UUID(bytes='\x12\x34\x56\x78'*4)
|
UUID(bytes=b'\x12\x34\x56\x78'*4)
|
||||||
UUID(bytes_le='\x78\x56\x34\x12\x34\x12\x78\x56' +
|
UUID(bytes_le=b'\x78\x56\x34\x12\x34\x12\x78\x56' +
|
||||||
'\x12\x34\x56\x78\x12\x34\x56\x78')
|
b'\x12\x34\x56\x78\x12\x34\x56\x78')
|
||||||
UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
|
UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
|
||||||
UUID(int=0x12345678123456781234567812345678)
|
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
|
# get the raw 16 bytes of the UUID
|
||||||
>>> x.bytes
|
>>> 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
|
# make a UUID from a 16-byte string
|
||||||
>>> uuid.UUID(bytes=x.bytes)
|
>>> uuid.UUID(bytes=x.bytes)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from test import support
|
from test import support
|
||||||
|
import builtins
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
def importable(name):
|
def importable(name):
|
||||||
|
@ -176,6 +177,11 @@ class TestUUID(TestCase):
|
||||||
for u in equivalents:
|
for u in equivalents:
|
||||||
for v in equivalents:
|
for v in equivalents:
|
||||||
equal(u, v)
|
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)
|
ascending.append(u)
|
||||||
|
|
||||||
# Test comparison of UUIDs.
|
# Test comparison of UUIDs.
|
||||||
|
|
|
@ -13,7 +13,7 @@ Typical usage:
|
||||||
>>> import uuid
|
>>> import uuid
|
||||||
|
|
||||||
# make a UUID based on the host ID and current time
|
# make a UUID based on the host ID and current time
|
||||||
>>> uuid.uuid1()
|
>>> uuid.uuid1() # doctest: +SKIP
|
||||||
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
|
UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
|
||||||
|
|
||||||
# make a UUID using an MD5 hash of a namespace UUID and a name
|
# 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')
|
UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
|
||||||
|
|
||||||
# make a random UUID
|
# make a random UUID
|
||||||
>>> uuid.uuid4()
|
>>> uuid.uuid4() # doctest: +SKIP
|
||||||
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
|
UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
|
||||||
|
|
||||||
# make a UUID using a SHA-1 hash of a namespace UUID and a name
|
# make a UUID using a SHA-1 hash of a namespace UUID and a name
|
||||||
|
@ -237,7 +237,7 @@ class UUID(object):
|
||||||
bytes = bytearray()
|
bytes = bytearray()
|
||||||
for shift in range(0, 128, 8):
|
for shift in range(0, 128, 8):
|
||||||
bytes.insert(0, (self.int >> shift) & 0xff)
|
bytes.insert(0, (self.int >> shift) & 0xff)
|
||||||
return bytes
|
return bytes_(bytes)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bytes_le(self):
|
def bytes_le(self):
|
||||||
|
|
Loading…
Reference in New Issue