Merged revisions 64434-64435,64440-64443,64445,64447-64448,64450,64452,64455,64461,64464,64466,64468 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r64434 | andrew.kuchling | 2008-06-20 18:13:58 -0500 (Fri, 20 Jun 2008) | 1 line

  Remove request for e-mail; it's unlikely these classes will be saved
........
  r64435 | andrew.kuchling | 2008-06-20 18:14:32 -0500 (Fri, 20 Jun 2008) | 1 line

  Grammar fixes
........
  r64440 | andrew.kuchling | 2008-06-21 08:29:12 -0500 (Sat, 21 Jun 2008) | 1 line

  Docstring typo
........
  r64441 | andrew.kuchling | 2008-06-21 08:47:20 -0500 (Sat, 21 Jun 2008) | 1 line

  Use repr() for bad input strings; this makes the empty string or binary characters more visible
........
  r64442 | andrew.kuchling | 2008-06-21 08:48:38 -0500 (Sat, 21 Jun 2008) | 1 line

  Docstring correction
........
  r64443 | georg.brandl | 2008-06-21 09:26:19 -0500 (Sat, 21 Jun 2008) | 2 lines

  Documentation fix.
........
  r64445 | facundo.batista | 2008-06-21 12:30:06 -0500 (Sat, 21 Jun 2008) | 3 lines


  Reviewed and updated the documentation. Fixes #3017.
........
  r64447 | facundo.batista | 2008-06-21 13:58:04 -0500 (Sat, 21 Jun 2008) | 6 lines


  Now a from submitted via POST that also has a query string
  will contain both FieldStorage and MiniFieldStorage items.

  Fixes #1817.
........
  r64448 | facundo.batista | 2008-06-21 14:48:19 -0500 (Sat, 21 Jun 2008) | 5 lines


  In the deprecated functions I added an alert to review
  specially a section of the subprocess documentation
  that helps with the replacing of those functionss.
........
  r64450 | georg.brandl | 2008-06-22 04:05:29 -0500 (Sun, 22 Jun 2008) | 2 lines

  Turn section references into proper cross-references.
........
  r64452 | facundo.batista | 2008-06-22 08:36:20 -0500 (Sun, 22 Jun 2008) | 5 lines


  Issue #2722. Now the char buffer to support the path string has
  not fixed length, it mallocs memory if needed. As a result, we
  don't have a maximum for the getcwd() method.
........
  r64455 | facundo.batista | 2008-06-22 10:27:10 -0500 (Sun, 22 Jun 2008) | 4 lines


  Issue 3164. Small fix to don't repeat a comparation
  without necessity.
........
  r64461 | georg.brandl | 2008-06-22 13:11:52 -0500 (Sun, 22 Jun 2008) | 2 lines

  #3085: Fix syntax error.
........
  r64464 | georg.brandl | 2008-06-22 13:31:54 -0500 (Sun, 22 Jun 2008) | 2 lines

  Expand docstrings of sqlite3 functions.
........
  r64466 | georg.brandl | 2008-06-22 14:07:59 -0500 (Sun, 22 Jun 2008) | 2 lines

  Write out "phi" consistently.
........
  r64468 | facundo.batista | 2008-06-22 14:35:24 -0500 (Sun, 22 Jun 2008) | 4 lines


  Just returning nothing instead of rising TestSkipped, because
  it makes the test fail in the trunk.loewis-sun buildbot.
........
This commit is contained in:
Benjamin Peterson 2008-07-02 17:30:14 +00:00
parent f9c98b48bd
commit dcf97b98ec
16 changed files with 249 additions and 56 deletions

View File

@ -253,5 +253,5 @@ and classes for traversing abstract syntax trees:
debugging purposes. The returned string will show the names and the values
for fields. This makes the code impossible to evaluate, so if evaluation is
wanted *annotate_fields* must be set to False. Attributes such as line
numbers and column offsets are dumped by default. If this is wanted,
numbers and column offsets are not dumped by default. If this is wanted,
*include_attributes* can be set to ``True``.

View File

@ -162,6 +162,8 @@ data part of type :mimetype:`application/x-www-form-urlencoded`), the items will
actually be instances of the class :class:`MiniFieldStorage`. In this case, the
:attr:`list`, :attr:`file`, and :attr:`filename` attributes are always ``None``.
A form submitted via POST that also has a query string will contain both
:class:`FieldStorage` and :class:`MiniFieldStorage` items.
Higher Level Interface
----------------------

View File

@ -40,9 +40,9 @@ Definition::
In engineering the polar coordinate system is popular for complex numbers. In
polar coordinates a complex number is defined by the radius *r* and the phase
angle *φ*. The radius *r* is the absolute value of the complex, which can be
angle *phi*. The radius *r* is the absolute value of the complex, which can be
viewed as distance from (0, 0). The radius *r* is always 0 or a positive float.
The phase angle *φ* is the counter clockwise angle from the positive x axis,
The phase angle *phi* is the counter clockwise angle from the positive x axis,
e.g. *1* has the angle *0*, *1j* has the angle *π/2* and *-1* the angle *-π*.
.. note::
@ -53,12 +53,12 @@ e.g. *1* has the angle *0*, *1j* has the angle *π/2* and *-1* the angle *-π*.
Definition::
z = r * exp(1j * φ)
z = r * cis(φ)
z = r * exp(1j * phi)
z = r * cis(phi)
r := abs(z) := sqrt(real(z)**2 + imag(z)**2)
phi := phase(z) := atan2(imag(z), real(z))
cis(φ) := cos(φ) + 1j * sin(φ)
cis(phi) := cos(phi) + 1j * sin(phi)
.. function:: phase(x)

View File

@ -418,7 +418,7 @@ Decimal objects
.. method:: conjugate()
Just returns itself, this method is only to comply with the Decimal
Just returns self, this method is only to comply with the Decimal
Specification.
.. method:: copy_abs()
@ -1192,9 +1192,10 @@ In addition to the three supplied contexts, new contexts can be created with the
The sign of the result, if non-zero, is the same as that of the original
dividend.
.. method:: remainder_near(x, y)
Returns `x - y * n`, where *n* is the integer nearest the exact value
Returns `x - y * n`, where *n* is the integer nearest the exact value
of `x / y` (if the result is `0` then its sign will be the sign of *x*).

View File

@ -337,21 +337,6 @@ These functions create new file objects. (See also :func:`open`.)
does on most platforms).
.. function:: popen(command[, mode[, bufsize]])
Open a pipe to or from *command*. The return value is an open file object
connected to the pipe, which can be read or written depending on whether *mode*
is ``'r'`` (default) or ``'w'``. The *bufsize* argument has the same meaning as
the corresponding argument to the built-in :func:`open` function. The exit
status of the command (encoded in the format specified for :func:`wait`) is
available as the return value of the :meth:`close` method of the file object,
except that when the exit status is zero (termination without errors), ``None``
is returned. Availability: Macintosh, Unix, Windows.
.. deprecated:: 2.6
This function is obsolete. Use the :mod:`subprocess` module.
.. _os-fd-ops:
File Descriptor Operations
@ -1449,7 +1434,8 @@ written in Python, such as a mail server's external command delivery program.
(Note that the :mod:`subprocess` module provides more powerful facilities for
spawning new processes and retrieving their results; using that module is
preferable to using these functions.)
preferable to using these functions. Check specially the *Replacing Older
Functions with the subprocess Module* section in that documentation page.)
If *mode* is :const:`P_NOWAIT`, this function returns the process id of the new
process; if *mode* is :const:`P_WAIT`, returns the process's exit code if it
@ -1571,7 +1557,8 @@ written in Python, such as a mail server's external command delivery program.
The :mod:`subprocess` module provides more powerful facilities for spawning new
processes and retrieving their results; using that module is preferable to using
this function.
this function. Use the :mod:`subprocess` module. Check especially the
:ref:`subprocess-replacements` section.
.. function:: times()

View File

@ -2145,6 +2145,11 @@ the particular object.
the system default encoding for converting strings.
.. attribute:: file.errors
The Unicode error handler used along with the encoding.
.. attribute:: file.mode
The I/O mode for the file. If the file was created using the :func:`open`

View File

@ -289,6 +289,8 @@ The following attributes are also available:
``N`` (Unix only).
.. _subprocess-replacements:
Replacing Older Functions with the subprocess Module
----------------------------------------------------
@ -386,13 +388,13 @@ Replacing os.popen\*
::
pipe = os.popen(cmd, mode='r', bufsize)
pipe = os.popen(cmd, 'r', bufsize)
==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdout=PIPE).stdout
::
pipe = os.popen(cmd, mode='w', bufsize)
pipe = os.popen(cmd, 'w', bufsize)
==>
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin

View File

@ -73,7 +73,7 @@ def dump(node, annotate_fields=True, include_attributes=False):
debugging purposes. The returned string will show the names and the values
for fields. This makes the code impossible to evaluate, so if evaluation is
wanted *annotate_fields* must be set to False. Attributes such as line
numbers and column offsets are dumped by default. If this is wanted,
numbers and column offsets are not dumped by default. If this is wanted,
*include_attributes* can be set to True.
"""
def _format(node):

View File

@ -449,6 +449,7 @@ class FieldStorage:
self.strict_parsing = strict_parsing
if 'REQUEST_METHOD' in environ:
method = environ['REQUEST_METHOD'].upper()
self.qs_on_post = None
if method == 'GET' or method == 'HEAD':
if 'QUERY_STRING' in environ:
qs = environ['QUERY_STRING']
@ -467,6 +468,8 @@ class FieldStorage:
headers['content-type'] = "application/x-www-form-urlencoded"
if 'CONTENT_TYPE' in environ:
headers['content-type'] = environ['CONTENT_TYPE']
if 'QUERY_STRING' in environ:
self.qs_on_post = environ['QUERY_STRING']
if 'CONTENT_LENGTH' in environ:
headers['content-length'] = environ['CONTENT_LENGTH']
self.fp = fp or sys.stdin
@ -618,6 +621,8 @@ class FieldStorage:
def read_urlencoded(self):
"""Internal: read data in query string format."""
qs = self.fp.read(self.length)
if self.qs_on_post:
qs += '&' + self.qs_on_post
self.list = list = []
for key, value in parse_qsl(qs, self.keep_blank_values,
self.strict_parsing):
@ -632,6 +637,12 @@ class FieldStorage:
if not valid_boundary(ib):
raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
self.list = []
if self.qs_on_post:
for key, value in parse_qsl(self.qs_on_post, self.keep_blank_values,
self.strict_parsing):
self.list.append(MiniFieldStorage(key, value))
FieldStorageClass = None
klass = self.FieldStorageClass or self.__class__
parser = email.parser.FeedParser()
# Create bogus content-type header for proper multipart parsing

View File

@ -68,7 +68,7 @@ class Fraction(numbers.Rational):
input = numerator
m = _RATIONAL_FORMAT.match(input)
if m is None:
raise ValueError('Invalid literal for Fraction: ' + input)
raise ValueError('Invalid literal for Fraction: %r' % input)
numerator = m.group('num')
decimal = m.group('decimal')
if decimal:

View File

@ -126,6 +126,16 @@ def first_elts(list):
def first_second_elts(list):
return [(p[0], p[1][0]) for p in list]
def gen_result(data, environ):
fake_stdin = StringIO(data)
fake_stdin.seek(0)
form = cgi.FieldStorage(fp=fake_stdin, environ=environ)
result = {}
for k, v in dict(form).items():
result[k] = type(v) is list and form.getlist(k) or v.value
return result
class CgiTests(unittest.TestCase):
@ -241,6 +251,83 @@ Content-Disposition: form-data; name="submit"
got = getattr(fs.list[x], k)
self.assertEquals(got, exp)
_qs_result = {
'key1': 'value1',
'key2': ['value2x', 'value2y'],
'key3': 'value3',
'key4': 'value4'
}
def testQSAndUrlEncode(self):
data = "key2=value2x&key3=value3&key4=value4"
environ = {
'CONTENT_LENGTH': str(len(data)),
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'QUERY_STRING': 'key1=value1&key2=value2y',
'REQUEST_METHOD': 'POST',
}
v = gen_result(data, environ)
self.assertEqual(self._qs_result, v)
def testQSAndFormData(self):
data = """
---123
Content-Disposition: form-data; name="key2"
value2y
---123
Content-Disposition: form-data; name="key3"
value3
---123
Content-Disposition: form-data; name="key4"
value4
---123--
"""
environ = {
'CONTENT_LENGTH': str(len(data)),
'CONTENT_TYPE': 'multipart/form-data; boundary=-123',
'QUERY_STRING': 'key1=value1&key2=value2x',
'REQUEST_METHOD': 'POST',
}
v = gen_result(data, environ)
self.assertEqual(self._qs_result, v)
def testQSAndFormDataFile(self):
data = """
---123
Content-Disposition: form-data; name="key2"
value2y
---123
Content-Disposition: form-data; name="key3"
value3
---123
Content-Disposition: form-data; name="key4"
value4
---123
Content-Disposition: form-data; name="upload"; filename="fake.txt"
Content-Type: text/plain
this is the content of the fake file
---123--
"""
environ = {
'CONTENT_LENGTH': str(len(data)),
'CONTENT_TYPE': 'multipart/form-data; boundary=-123',
'QUERY_STRING': 'key1=value1&key2=value2x',
'REQUEST_METHOD': 'POST',
}
result = self._qs_result.copy()
result.update({
'upload': 'this is the content of the fake file'
})
v = gen_result(data, environ)
self.assertEqual(result, v)
def test_main():
run_unittest(CgiTests)

View File

@ -83,38 +83,38 @@ class FractionTest(unittest.TestCase):
ZeroDivisionError, "Fraction(3, 0)",
F, "3/0")
self.assertRaisesMessage(
ValueError, "Invalid literal for Fraction: 3/",
ValueError, "Invalid literal for Fraction: '3/'",
F, "3/")
self.assertRaisesMessage(
ValueError, "Invalid literal for Fraction: 3 /2",
ValueError, "Invalid literal for Fraction: '3 /2'",
F, "3 /2")
self.assertRaisesMessage(
# Denominators don't need a sign.
ValueError, "Invalid literal for Fraction: 3/+2",
ValueError, "Invalid literal for Fraction: '3/+2'",
F, "3/+2")
self.assertRaisesMessage(
# Imitate float's parsing.
ValueError, "Invalid literal for Fraction: + 3/2",
ValueError, "Invalid literal for Fraction: '+ 3/2'",
F, "+ 3/2")
self.assertRaisesMessage(
# Avoid treating '.' as a regex special character.
ValueError, "Invalid literal for Fraction: 3a2",
ValueError, "Invalid literal for Fraction: '3a2'",
F, "3a2")
self.assertRaisesMessage(
# Only parse ordinary decimals, not scientific form.
ValueError, "Invalid literal for Fraction: 3.2e4",
ValueError, "Invalid literal for Fraction: '3.2e4'",
F, "3.2e4")
self.assertRaisesMessage(
# Don't accept combinations of decimals and rationals.
ValueError, "Invalid literal for Fraction: 3/7.2",
ValueError, "Invalid literal for Fraction: '3/7.2'",
F, "3/7.2")
self.assertRaisesMessage(
# Don't accept combinations of decimals and rationals.
ValueError, "Invalid literal for Fraction: 3.2/7",
ValueError, "Invalid literal for Fraction: '3.2/7'",
F, "3.2/7")
self.assertRaisesMessage(
# Allow 3. and .3, but not .
ValueError, "Invalid literal for Fraction: .",
ValueError, "Invalid literal for Fraction: '.'",
F, ".")
def testImmutable(self):

View File

@ -10,6 +10,7 @@ except ImportError:
import time
import os
import pwd
import shutil
import unittest
import warnings
warnings.filterwarnings('ignore', '.* potential security risk .*',
@ -225,6 +226,44 @@ class PosixTester(unittest.TestCase):
self.assertEqual(type(k), str)
self.assertEqual(type(v), str)
def test_getcwd_long_pathnames(self):
if hasattr(posix, 'getcwd'):
dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef'
curdir = os.getcwd()
base_path = os.path.abspath(support.TESTFN) + '.getcwd'
try:
os.mkdir(base_path)
os.chdir(base_path)
except:
# Just returning nothing instead of the TestSkipped exception,
# because the test results in Error in that case.
# Is that ok?
# raise support.TestSkipped, "cannot create directory for testing"
return
def _create_and_do_getcwd(dirname, current_path_length = 0):
try:
os.mkdir(dirname)
except:
raise support.TestSkipped("mkdir cannot create directory sufficiently deep for getcwd test")
os.chdir(dirname)
try:
os.getcwd()
if current_path_length < 1027:
_create_and_do_getcwd(dirname, current_path_length + len(dirname) + 1)
finally:
os.chdir('..')
os.rmdir(dirname)
_create_and_do_getcwd(dirname)
finally:
shutil.rmtree(base_path)
os.chdir(curdir)
def test_main():
support.run_unittest(PosixTester)

View File

@ -76,6 +76,13 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
return result;
}
PyDoc_STRVAR(module_connect_doc,
"connect(database[, timeout, isolation_level, detect_types, factory])\n\
\n\
Opens a connection to the SQLite database file *database*. You can use\n\
\":memory:\" to open a database connection to a database that resides in\n\
RAM instead of on disk.");
static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
kwargs)
{
@ -100,6 +107,11 @@ static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
return result;
}
PyDoc_STRVAR(module_complete_doc,
"complete_statement(sql)\n\
\n\
Checks if a string contains a complete SQL statement. Non-standard.");
#ifdef HAVE_SHARED_CACHE
static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
kwargs)
@ -123,9 +135,15 @@ static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyOb
return Py_None;
}
}
PyDoc_STRVAR(module_enable_shared_cache_doc,
"enable_shared_cache(do_enable)\n\
\n\
Enable or disable shared cache mode for the calling thread.\n\
Experimental/Non-standard.");
#endif /* HAVE_SHARED_CACHE */
static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObject* kwargs)
static PyObject* module_register_adapter(PyObject* self, PyObject* args)
{
PyTypeObject* type;
PyObject* caster;
@ -147,7 +165,12 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObjec
return Py_None;
}
static PyObject* module_register_converter(PyObject* self, PyObject* args, PyObject* kwargs)
PyDoc_STRVAR(module_register_adapter_doc,
"register_adapter(type, callable)\n\
\n\
Registers an adapter with pysqlite's adapter registry. Non-standard.");
static PyObject* module_register_converter(PyObject* self, PyObject* args)
{
PyObject* orig_name;
PyObject* name = NULL;
@ -175,7 +198,12 @@ error:
return retval;
}
static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args, PyObject* kwargs)
PyDoc_STRVAR(module_register_converter_doc,
"register_converter(typename, callable)\n\
\n\
Registers a converter with pysqlite. Non-standard.");
static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args)
{
if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) {
return NULL;
@ -185,6 +213,11 @@ static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args, PyOb
return Py_None;
}
PyDoc_STRVAR(enable_callback_tracebacks_doc,
"enable_callback_tracebacks(flag)\n\
\n\
Enable or disable callback functions throwing errors to stderr.");
static void converters_init(PyObject* dict)
{
converters = PyDict_New();
@ -196,15 +229,22 @@ static void converters_init(PyObject* dict)
}
static PyMethodDef module_methods[] = {
{"connect", (PyCFunction)module_connect, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
{"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement. Non-standard.")},
{"connect", (PyCFunction)module_connect,
METH_VARARGS | METH_KEYWORDS, module_connect_doc},
{"complete_statement", (PyCFunction)module_complete,
METH_VARARGS | METH_KEYWORDS, module_complete_doc},
#ifdef HAVE_SHARED_CACHE
{"enable_shared_cache", (PyCFunction)module_enable_shared_cache, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Enable or disable shared cache mode for the calling thread. Experimental/Non-standard.")},
{"enable_shared_cache", (PyCFunction)module_enable_shared_cache,
METH_VARARGS | METH_KEYWORDS, module_enable_shared_cache_doc},
#endif
{"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with pysqlite's adapter registry. Non-standard.")},
{"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with pysqlite. Non-standard.")},
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
{"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, METH_VARARGS, PyDoc_STR("Enable or disable callback functions throwing errors to stderr.")},
{"register_adapter", (PyCFunction)module_register_adapter,
METH_VARARGS, module_register_adapter_doc},
{"register_converter", (PyCFunction)module_register_converter,
METH_VARARGS, module_register_converter_doc},
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS,
psyco_microprotocols_adapt_doc},
{"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks,
METH_VARARGS, enable_callback_tracebacks_doc},
{NULL, NULL}
};
@ -403,12 +443,12 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
pysqlite_BaseTypeAdapted = 0;
/* Original comment form _bsddb.c in the Python core. This is also still
/* Original comment from _bsddb.c in the Python core. This is also still
* needed nowadays for Python 2.3/2.4.
*
* PyEval_InitThreads is called here due to a quirk in python 1.5
* - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
* The global interepreter lock is not initialized until the first
* The global interpreter lock is not initialized until the first
* thread is created using thread.start_new_thread() or fork() is
* called. that would cause the ALLOW_THREADS here to segfault due
* to a null pointer reference if no threads or child processes

View File

@ -1981,19 +1981,38 @@ Return a string representing the current working directory.");
static PyObject *
posix_getcwd(PyObject *self, PyObject *noargs)
{
char buf[1026];
char *res;
int bufsize_incr = 1024;
int bufsize = 0;
char *tmpbuf = NULL;
char *res = NULL;
PyObject *dynamic_return;
Py_BEGIN_ALLOW_THREADS
do {
bufsize = bufsize + bufsize_incr;
tmpbuf = malloc(bufsize);
if (tmpbuf == NULL) {
break;
}
#if defined(PYOS_OS2) && defined(PYCC_GCC)
res = _getcwd2(buf, sizeof buf);
res = _getcwd2(tmpbuf, bufsize);
#else
res = getcwd(buf, sizeof buf);
res = getcwd(tmpbuf, bufsize);
#endif
if (res == NULL) {
free(tmpbuf);
}
} while ((res == NULL) && (errno == ERANGE));
Py_END_ALLOW_THREADS
if (res == NULL)
return posix_error();
return PyUnicode_FromString(buf);
dynamic_return = PyUnicode_FromString(tmpbuf);
free(tmpbuf);
return dynamic_return;
}
PyDoc_STRVAR(posix_getcwdu__doc__,

View File

@ -2648,7 +2648,7 @@ PyDoc_STRVAR(pop__doc__,
"B.pop([index]) -> int\n\
\n\
Remove and return a single item from B. If no index\n\
argument is give, will pop the last value.");
argument is given, will pop the last value.");
static PyObject *
bytes_pop(PyByteArrayObject *self, PyObject *args)
{