mirror of
https://github.com/python/cpython.git
synced 2025-09-18 14:40:43 +00:00
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:
parent
f9c98b48bd
commit
dcf97b98ec
16 changed files with 249 additions and 56 deletions
|
@ -253,5 +253,5 @@ and classes for traversing abstract syntax trees:
|
||||||
debugging purposes. The returned string will show the names and the values
|
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
|
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
|
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``.
|
*include_attributes* can be set to ``True``.
|
||||||
|
|
|
@ -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
|
actually be instances of the class :class:`MiniFieldStorage`. In this case, the
|
||||||
:attr:`list`, :attr:`file`, and :attr:`filename` attributes are always ``None``.
|
: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
|
Higher Level Interface
|
||||||
----------------------
|
----------------------
|
||||||
|
|
|
@ -40,9 +40,9 @@ Definition::
|
||||||
|
|
||||||
In engineering the polar coordinate system is popular for complex numbers. In
|
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
|
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.
|
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 *-π*.
|
e.g. *1* has the angle *0*, *1j* has the angle *π/2* and *-1* the angle *-π*.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
@ -53,12 +53,12 @@ e.g. *1* has the angle *0*, *1j* has the angle *π/2* and *-1* the angle *-π*.
|
||||||
|
|
||||||
Definition::
|
Definition::
|
||||||
|
|
||||||
z = r * exp(1j * φ)
|
z = r * exp(1j * phi)
|
||||||
z = r * cis(φ)
|
z = r * cis(phi)
|
||||||
|
|
||||||
r := abs(z) := sqrt(real(z)**2 + imag(z)**2)
|
r := abs(z) := sqrt(real(z)**2 + imag(z)**2)
|
||||||
phi := phase(z) := atan2(imag(z), real(z))
|
phi := phase(z) := atan2(imag(z), real(z))
|
||||||
cis(φ) := cos(φ) + 1j * sin(φ)
|
cis(phi) := cos(phi) + 1j * sin(phi)
|
||||||
|
|
||||||
|
|
||||||
.. function:: phase(x)
|
.. function:: phase(x)
|
||||||
|
|
|
@ -418,7 +418,7 @@ Decimal objects
|
||||||
|
|
||||||
.. method:: conjugate()
|
.. 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.
|
Specification.
|
||||||
|
|
||||||
.. method:: copy_abs()
|
.. 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
|
The sign of the result, if non-zero, is the same as that of the original
|
||||||
dividend.
|
dividend.
|
||||||
|
|
||||||
|
|
||||||
.. method:: remainder_near(x, y)
|
.. 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*).
|
of `x / y` (if the result is `0` then its sign will be the sign of *x*).
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -337,21 +337,6 @@ These functions create new file objects. (See also :func:`open`.)
|
||||||
does on most platforms).
|
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:
|
.. _os-fd-ops:
|
||||||
|
|
||||||
File Descriptor Operations
|
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
|
(Note that the :mod:`subprocess` module provides more powerful facilities for
|
||||||
spawning new processes and retrieving their results; using that module is
|
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
|
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
|
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
|
The :mod:`subprocess` module provides more powerful facilities for spawning new
|
||||||
processes and retrieving their results; using that module is preferable to using
|
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()
|
.. function:: times()
|
||||||
|
|
|
@ -2145,6 +2145,11 @@ the particular object.
|
||||||
the system default encoding for converting strings.
|
the system default encoding for converting strings.
|
||||||
|
|
||||||
|
|
||||||
|
.. attribute:: file.errors
|
||||||
|
|
||||||
|
The Unicode error handler used along with the encoding.
|
||||||
|
|
||||||
|
|
||||||
.. attribute:: file.mode
|
.. attribute:: file.mode
|
||||||
|
|
||||||
The I/O mode for the file. If the file was created using the :func:`open`
|
The I/O mode for the file. If the file was created using the :func:`open`
|
||||||
|
|
|
@ -289,6 +289,8 @@ The following attributes are also available:
|
||||||
``N`` (Unix only).
|
``N`` (Unix only).
|
||||||
|
|
||||||
|
|
||||||
|
.. _subprocess-replacements:
|
||||||
|
|
||||||
Replacing Older Functions with the subprocess Module
|
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 = 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
|
pipe = Popen(cmd, shell=True, bufsize=bufsize, stdin=PIPE).stdin
|
||||||
|
|
||||||
|
|
|
@ -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
|
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
|
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
|
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.
|
*include_attributes* can be set to True.
|
||||||
"""
|
"""
|
||||||
def _format(node):
|
def _format(node):
|
||||||
|
|
11
Lib/cgi.py
11
Lib/cgi.py
|
@ -449,6 +449,7 @@ class FieldStorage:
|
||||||
self.strict_parsing = strict_parsing
|
self.strict_parsing = strict_parsing
|
||||||
if 'REQUEST_METHOD' in environ:
|
if 'REQUEST_METHOD' in environ:
|
||||||
method = environ['REQUEST_METHOD'].upper()
|
method = environ['REQUEST_METHOD'].upper()
|
||||||
|
self.qs_on_post = None
|
||||||
if method == 'GET' or method == 'HEAD':
|
if method == 'GET' or method == 'HEAD':
|
||||||
if 'QUERY_STRING' in environ:
|
if 'QUERY_STRING' in environ:
|
||||||
qs = environ['QUERY_STRING']
|
qs = environ['QUERY_STRING']
|
||||||
|
@ -467,6 +468,8 @@ class FieldStorage:
|
||||||
headers['content-type'] = "application/x-www-form-urlencoded"
|
headers['content-type'] = "application/x-www-form-urlencoded"
|
||||||
if 'CONTENT_TYPE' in environ:
|
if 'CONTENT_TYPE' in environ:
|
||||||
headers['content-type'] = environ['CONTENT_TYPE']
|
headers['content-type'] = environ['CONTENT_TYPE']
|
||||||
|
if 'QUERY_STRING' in environ:
|
||||||
|
self.qs_on_post = environ['QUERY_STRING']
|
||||||
if 'CONTENT_LENGTH' in environ:
|
if 'CONTENT_LENGTH' in environ:
|
||||||
headers['content-length'] = environ['CONTENT_LENGTH']
|
headers['content-length'] = environ['CONTENT_LENGTH']
|
||||||
self.fp = fp or sys.stdin
|
self.fp = fp or sys.stdin
|
||||||
|
@ -618,6 +621,8 @@ class FieldStorage:
|
||||||
def read_urlencoded(self):
|
def read_urlencoded(self):
|
||||||
"""Internal: read data in query string format."""
|
"""Internal: read data in query string format."""
|
||||||
qs = self.fp.read(self.length)
|
qs = self.fp.read(self.length)
|
||||||
|
if self.qs_on_post:
|
||||||
|
qs += '&' + self.qs_on_post
|
||||||
self.list = list = []
|
self.list = list = []
|
||||||
for key, value in parse_qsl(qs, self.keep_blank_values,
|
for key, value in parse_qsl(qs, self.keep_blank_values,
|
||||||
self.strict_parsing):
|
self.strict_parsing):
|
||||||
|
@ -632,6 +637,12 @@ class FieldStorage:
|
||||||
if not valid_boundary(ib):
|
if not valid_boundary(ib):
|
||||||
raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
|
raise ValueError('Invalid boundary in multipart form: %r' % (ib,))
|
||||||
self.list = []
|
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__
|
klass = self.FieldStorageClass or self.__class__
|
||||||
parser = email.parser.FeedParser()
|
parser = email.parser.FeedParser()
|
||||||
# Create bogus content-type header for proper multipart parsing
|
# Create bogus content-type header for proper multipart parsing
|
||||||
|
|
|
@ -68,7 +68,7 @@ class Fraction(numbers.Rational):
|
||||||
input = numerator
|
input = numerator
|
||||||
m = _RATIONAL_FORMAT.match(input)
|
m = _RATIONAL_FORMAT.match(input)
|
||||||
if m is None:
|
if m is None:
|
||||||
raise ValueError('Invalid literal for Fraction: ' + input)
|
raise ValueError('Invalid literal for Fraction: %r' % input)
|
||||||
numerator = m.group('num')
|
numerator = m.group('num')
|
||||||
decimal = m.group('decimal')
|
decimal = m.group('decimal')
|
||||||
if decimal:
|
if decimal:
|
||||||
|
|
|
@ -126,6 +126,16 @@ def first_elts(list):
|
||||||
def first_second_elts(list):
|
def first_second_elts(list):
|
||||||
return [(p[0], p[1][0]) for p in 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):
|
class CgiTests(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -241,6 +251,83 @@ Content-Disposition: form-data; name="submit"
|
||||||
got = getattr(fs.list[x], k)
|
got = getattr(fs.list[x], k)
|
||||||
self.assertEquals(got, exp)
|
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():
|
def test_main():
|
||||||
run_unittest(CgiTests)
|
run_unittest(CgiTests)
|
||||||
|
|
||||||
|
|
|
@ -83,38 +83,38 @@ class FractionTest(unittest.TestCase):
|
||||||
ZeroDivisionError, "Fraction(3, 0)",
|
ZeroDivisionError, "Fraction(3, 0)",
|
||||||
F, "3/0")
|
F, "3/0")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
ValueError, "Invalid literal for Fraction: 3/",
|
ValueError, "Invalid literal for Fraction: '3/'",
|
||||||
F, "3/")
|
F, "3/")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
ValueError, "Invalid literal for Fraction: 3 /2",
|
ValueError, "Invalid literal for Fraction: '3 /2'",
|
||||||
F, "3 /2")
|
F, "3 /2")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
# Denominators don't need a sign.
|
# Denominators don't need a sign.
|
||||||
ValueError, "Invalid literal for Fraction: 3/+2",
|
ValueError, "Invalid literal for Fraction: '3/+2'",
|
||||||
F, "3/+2")
|
F, "3/+2")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
# Imitate float's parsing.
|
# Imitate float's parsing.
|
||||||
ValueError, "Invalid literal for Fraction: + 3/2",
|
ValueError, "Invalid literal for Fraction: '+ 3/2'",
|
||||||
F, "+ 3/2")
|
F, "+ 3/2")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
# Avoid treating '.' as a regex special character.
|
# Avoid treating '.' as a regex special character.
|
||||||
ValueError, "Invalid literal for Fraction: 3a2",
|
ValueError, "Invalid literal for Fraction: '3a2'",
|
||||||
F, "3a2")
|
F, "3a2")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
# Only parse ordinary decimals, not scientific form.
|
# Only parse ordinary decimals, not scientific form.
|
||||||
ValueError, "Invalid literal for Fraction: 3.2e4",
|
ValueError, "Invalid literal for Fraction: '3.2e4'",
|
||||||
F, "3.2e4")
|
F, "3.2e4")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
# Don't accept combinations of decimals and rationals.
|
# 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")
|
F, "3/7.2")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
# Don't accept combinations of decimals and rationals.
|
# 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")
|
F, "3.2/7")
|
||||||
self.assertRaisesMessage(
|
self.assertRaisesMessage(
|
||||||
# Allow 3. and .3, but not .
|
# Allow 3. and .3, but not .
|
||||||
ValueError, "Invalid literal for Fraction: .",
|
ValueError, "Invalid literal for Fraction: '.'",
|
||||||
F, ".")
|
F, ".")
|
||||||
|
|
||||||
def testImmutable(self):
|
def testImmutable(self):
|
||||||
|
|
|
@ -10,6 +10,7 @@ except ImportError:
|
||||||
import time
|
import time
|
||||||
import os
|
import os
|
||||||
import pwd
|
import pwd
|
||||||
|
import shutil
|
||||||
import unittest
|
import unittest
|
||||||
import warnings
|
import warnings
|
||||||
warnings.filterwarnings('ignore', '.* potential security risk .*',
|
warnings.filterwarnings('ignore', '.* potential security risk .*',
|
||||||
|
@ -225,6 +226,44 @@ class PosixTester(unittest.TestCase):
|
||||||
self.assertEqual(type(k), str)
|
self.assertEqual(type(k), str)
|
||||||
self.assertEqual(type(v), 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():
|
def test_main():
|
||||||
support.run_unittest(PosixTester)
|
support.run_unittest(PosixTester)
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,13 @@ static PyObject* module_connect(PyObject* self, PyObject* args, PyObject*
|
||||||
return result;
|
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*
|
static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
|
||||||
kwargs)
|
kwargs)
|
||||||
{
|
{
|
||||||
|
@ -100,6 +107,11 @@ static PyObject* module_complete(PyObject* self, PyObject* args, PyObject*
|
||||||
return result;
|
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
|
#ifdef HAVE_SHARED_CACHE
|
||||||
static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
|
static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyObject*
|
||||||
kwargs)
|
kwargs)
|
||||||
|
@ -123,9 +135,15 @@ static PyObject* module_enable_shared_cache(PyObject* self, PyObject* args, PyOb
|
||||||
return Py_None;
|
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 */
|
#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;
|
PyTypeObject* type;
|
||||||
PyObject* caster;
|
PyObject* caster;
|
||||||
|
@ -147,7 +165,12 @@ static PyObject* module_register_adapter(PyObject* self, PyObject* args, PyObjec
|
||||||
return Py_None;
|
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* orig_name;
|
||||||
PyObject* name = NULL;
|
PyObject* name = NULL;
|
||||||
|
@ -175,7 +198,12 @@ error:
|
||||||
return retval;
|
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)) {
|
if (!PyArg_ParseTuple(args, "i", &_enable_callback_tracebacks)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -185,6 +213,11 @@ static PyObject* enable_callback_tracebacks(PyObject* self, PyObject* args, PyOb
|
||||||
return Py_None;
|
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)
|
static void converters_init(PyObject* dict)
|
||||||
{
|
{
|
||||||
converters = PyDict_New();
|
converters = PyDict_New();
|
||||||
|
@ -196,15 +229,22 @@ static void converters_init(PyObject* dict)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
{"connect", (PyCFunction)module_connect, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Creates a connection.")},
|
{"connect", (PyCFunction)module_connect,
|
||||||
{"complete_statement", (PyCFunction)module_complete, METH_VARARGS|METH_KEYWORDS, PyDoc_STR("Checks if a string contains a complete SQL statement. Non-standard.")},
|
METH_VARARGS | METH_KEYWORDS, module_connect_doc},
|
||||||
|
{"complete_statement", (PyCFunction)module_complete,
|
||||||
|
METH_VARARGS | METH_KEYWORDS, module_complete_doc},
|
||||||
#ifdef HAVE_SHARED_CACHE
|
#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
|
#endif
|
||||||
{"register_adapter", (PyCFunction)module_register_adapter, METH_VARARGS, PyDoc_STR("Registers an adapter with pysqlite's adapter registry. Non-standard.")},
|
{"register_adapter", (PyCFunction)module_register_adapter,
|
||||||
{"register_converter", (PyCFunction)module_register_converter, METH_VARARGS, PyDoc_STR("Registers a converter with pysqlite. Non-standard.")},
|
METH_VARARGS, module_register_adapter_doc},
|
||||||
{"adapt", (PyCFunction)psyco_microprotocols_adapt, METH_VARARGS, psyco_microprotocols_adapt_doc},
|
{"register_converter", (PyCFunction)module_register_converter,
|
||||||
{"enable_callback_tracebacks", (PyCFunction)enable_callback_tracebacks, METH_VARARGS, PyDoc_STR("Enable or disable callback functions throwing errors to stderr.")},
|
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}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -403,12 +443,12 @@ PyMODINIT_FUNC PyInit__sqlite3(void)
|
||||||
|
|
||||||
pysqlite_BaseTypeAdapted = 0;
|
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.
|
* needed nowadays for Python 2.3/2.4.
|
||||||
*
|
*
|
||||||
* PyEval_InitThreads is called here due to a quirk in python 1.5
|
* 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>:
|
* - 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
|
* thread is created using thread.start_new_thread() or fork() is
|
||||||
* called. that would cause the ALLOW_THREADS here to segfault due
|
* called. that would cause the ALLOW_THREADS here to segfault due
|
||||||
* to a null pointer reference if no threads or child processes
|
* to a null pointer reference if no threads or child processes
|
||||||
|
|
|
@ -1981,19 +1981,38 @@ Return a string representing the current working directory.");
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posix_getcwd(PyObject *self, PyObject *noargs)
|
posix_getcwd(PyObject *self, PyObject *noargs)
|
||||||
{
|
{
|
||||||
char buf[1026];
|
int bufsize_incr = 1024;
|
||||||
char *res;
|
int bufsize = 0;
|
||||||
|
char *tmpbuf = NULL;
|
||||||
|
char *res = NULL;
|
||||||
|
PyObject *dynamic_return;
|
||||||
|
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
|
do {
|
||||||
|
bufsize = bufsize + bufsize_incr;
|
||||||
|
tmpbuf = malloc(bufsize);
|
||||||
|
if (tmpbuf == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
||||||
res = _getcwd2(buf, sizeof buf);
|
res = _getcwd2(tmpbuf, bufsize);
|
||||||
#else
|
#else
|
||||||
res = getcwd(buf, sizeof buf);
|
res = getcwd(tmpbuf, bufsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (res == NULL) {
|
||||||
|
free(tmpbuf);
|
||||||
|
}
|
||||||
|
} while ((res == NULL) && (errno == ERANGE));
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
|
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
return posix_error();
|
return posix_error();
|
||||||
return PyUnicode_FromString(buf);
|
|
||||||
|
dynamic_return = PyUnicode_FromString(tmpbuf);
|
||||||
|
free(tmpbuf);
|
||||||
|
|
||||||
|
return dynamic_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(posix_getcwdu__doc__,
|
PyDoc_STRVAR(posix_getcwdu__doc__,
|
||||||
|
|
|
@ -2648,7 +2648,7 @@ PyDoc_STRVAR(pop__doc__,
|
||||||
"B.pop([index]) -> int\n\
|
"B.pop([index]) -> int\n\
|
||||||
\n\
|
\n\
|
||||||
Remove and return a single item from B. If no index\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 *
|
static PyObject *
|
||||||
bytes_pop(PyByteArrayObject *self, PyObject *args)
|
bytes_pop(PyByteArrayObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue