From solipsis at pitrou.net Wed Sep 1 05:00:24 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Wed, 01 Sep 2010 05:00:24 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84381): sum=0
Message-ID:
py3k results for svn r84381 (hg cset 6f6672d442bc)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogyXGzk9', '-x']
From python-checkins at python.org Wed Sep 1 08:58:25 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 08:58:25 +0200 (CEST)
Subject: [Python-checkins] r84383 -
python/branches/py3k/Doc/library/bisect.rst
Message-ID: <20100901065825.C5226EEBB3@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 08:58:25 2010
New Revision: 84383
Log:
Clean-up bisect docs.
* Document the post conditions for bisect_left() and bisect_right().
* Fix the grades example to use more obvious breakpoints
and to use a list comprehension instead of map() which returns
an iterator in Py3.x.
* Improve and expand the examples of searching sorted lists.
* Issue 4356 -- move up reference to the SortedCollection recipe.
Modified:
python/branches/py3k/Doc/library/bisect.rst
Modified: python/branches/py3k/Doc/library/bisect.rst
==============================================================================
--- python/branches/py3k/Doc/library/bisect.rst (original)
+++ python/branches/py3k/Doc/library/bisect.rst Wed Sep 1 08:58:25 2010
@@ -4,6 +4,7 @@
.. module:: bisect
:synopsis: Array bisection algorithms for binary searching.
.. sectionauthor:: Fred L. Drake, Jr.
+.. sectionauthor:: Raymond Hettinger
.. example based on the PyModules FAQ entry by Aaron Watters
This module provides support for maintaining a list in sorted order without
@@ -18,13 +19,16 @@
.. function:: bisect_left(a, x, lo=0, hi=len(a))
- Locate the proper insertion point for *x* in *a* to maintain sorted order.
+ Locate the insertion point for *x* in *a* to maintain sorted order.
The parameters *lo* and *hi* may be used to specify a subset of the list
which should be considered; by default the entire list is used. If *x* is
already present in *a*, the insertion point will be before (to the left of)
any existing entries. The return value is suitable for use as the first
- parameter to ``list.insert()``. This assumes that *a* is already sorted.
+ parameter to ``list.insert()`` assuming that *a* is already sorted.
+ The returned insertion point *i* partitions the array *a* into two halves so
+ that ``all(val < x for val in a[lo:i])`` for the left side and
+ ``all(val >= x for val in a[i:hi])`` for the right side.
.. function:: bisect_right(a, x, lo=0, hi=len(a))
bisect(a, x, lo=0, hi=len(a))
@@ -32,16 +36,16 @@
Similar to :func:`bisect_left`, but returns an insertion point which comes
after (to the right of) any existing entries of *x* in *a*.
+ The returned insertion point *i* partitions the array *a* into two halves so
+ that ``all(val <= x for val in a[lo:i])`` for the left side and
+ ``all(val > x for val in a[i:hi])`` for the right side.
.. function:: insort_left(a, x, lo=0, hi=len(a))
Insert *x* in *a* in sorted order. This is equivalent to
- ``a.insert(bisect.bisect_left(a, x, lo, hi), x)``. This assumes that *a* is
- already sorted.
-
- Also note that while the fast search step is O(log n), the slower insertion
- step is O(n), so the overall operation is slow.
-
+ ``a.insert(bisect.bisect_left(a, x, lo, hi), x)`` assuming that *a* is
+ already sorted. Keep in mind that the O(log n) search is dominated by
+ the slow O(n) insertion step.
.. function:: insort_right(a, x, lo=0, hi=len(a))
insort(a, x, lo=0, hi=len(a))
@@ -49,71 +53,75 @@
Similar to :func:`insort_left`, but inserting *x* in *a* after any existing
entries of *x*.
- Also note that while the fast search step is O(log n), the slower insertion
- step is O(n), so the overall operation is slow.
+.. seealso::
+
+ `SortedCollection recipe
+ `_ that uses
+ bisect to build a full-featured collection class with straight-forward search
+ methods and support for a key-function. The keys are precomputed to save
+ unnecessary calls to the key function during searches.
+
Searching Sorted Lists
----------------------
-The above :func:`bisect` functions are useful for finding insertion points, but
-can be tricky or awkward to use for common searching tasks. The following three
+The above :func:`bisect` functions are useful for finding insertion points but
+can be tricky or awkward to use for common searching tasks. The following five
functions show how to transform them into the standard lookups for sorted
lists::
- def find(a, key):
- '''Find leftmost item exact equal to the key.
- Raise ValueError if no such item exists.
-
- '''
- i = bisect_left(a, key)
- if i < len(a) and a[i] == key:
+ def index(a, x):
+ 'Locate the leftmost value exactly equal to x'
+ i = bisect_left(a, x)
+ if i != len(a) and a[i] == x:
+ return i
+ raise ValueError
+
+ def find_lt(a, x):
+ 'Find rightmost value less than x'
+ i = bisect_left(a, x)
+ if i:
+ return a[i-1]
+ raise ValueError
+
+ def find_le(a, x):
+ 'Find rightmost value less than or equal to x'
+ i = bisect_right(a, x)
+ if i:
+ return a[i-1]
+ raise ValueError
+
+ def find_gt(a, x):
+ 'Find leftmost value greater than x'
+ i = bisect_right(a, x)
+ if i != len(a):
return a[i]
- raise ValueError('No item found with key equal to: %r' % (key,))
+ raise ValueError
- def find_le(a, key):
- '''Find largest item less-than or equal to key.
- Raise ValueError if no such item exists.
- If multiple keys are equal, return the leftmost.
-
- '''
- i = bisect_left(a, key)
- if i < len(a) and a[i] == key:
+ def find_ge(a, x):
+ 'Find leftmost item greater than or equal to x'
+ i = bisect_left(a, x)
+ if i != len(a):
return a[i]
- if i == 0:
- raise ValueError('No item found with key at or below: %r' % (key,))
- return a[i-1]
-
- def find_ge(a, key):
- '''Find smallest item greater-than or equal to key.
- Raise ValueError if no such item exists.
- If multiple keys are equal, return the leftmost.
-
- '''
- i = bisect_left(a, key)
- if i == len(a):
- raise ValueError('No item found with key at or above: %r' % (key,))
- return a[i]
+ raise ValueError
+
Other Examples
--------------
.. _bisect-example:
-The :func:`bisect` function is generally useful for categorizing numeric data.
-This example uses :func:`bisect` to look up a letter grade for an exam total
-(say) based on a set of ordered numeric breakpoints: 85 and up is an 'A', 75..84
-is a 'B', etc.
-
- >>> grades = "FEDCBA"
- >>> breakpoints = [30, 44, 66, 75, 85]
- >>> from bisect import bisect
- >>> def grade(total):
- ... return grades[bisect(breakpoints, total)]
+The :func:`bisect` function can be useful for numeric table lookups. This
+example uses :func:`bisect` to look up a letter grade for an exam score (say)
+based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is
+a 'B', and so on::
+
+ >>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
+ ... i = bisect(breakpoints, score)
+ ... return grades[i]
...
- >>> grade(66)
- 'C'
- >>> map(grade, [33, 99, 77, 44, 12, 88])
- ['E', 'A', 'B', 'D', 'F', 'A']
+ >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
+ ['F', 'A', 'C', 'C', 'B', 'A', 'A']
Unlike the :func:`sorted` function, it does not make sense for the :func:`bisect`
functions to have *key* or *reversed* arguments because that would lead to an
@@ -135,9 +143,3 @@
>>> data[bisect_left(keys, 8)]
('yellow', 8)
-.. seealso::
-
- `SortedCollection recipe
- `_ that
- encapsulates precomputed keys, allowing straight-forward insertion and
- searching using a *key* function.
From python-checkins at python.org Wed Sep 1 09:46:54 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 09:46:54 +0200 (CEST)
Subject: [Python-checkins] r84384 -
python/branches/py3k/Doc/library/operator.rst
Message-ID: <20100901074654.6ADA5EE9B8@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 09:46:54 2010
New Revision: 84384
Log:
2-to-3 fixup for map() example in docs
Modified:
python/branches/py3k/Doc/library/operator.rst
Modified: python/branches/py3k/Doc/library/operator.rst
==============================================================================
--- python/branches/py3k/Doc/library/operator.rst (original)
+++ python/branches/py3k/Doc/library/operator.rst Wed Sep 1 09:46:54 2010
@@ -387,7 +387,7 @@
>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> getcount = itemgetter(1)
- >>> map(getcount, inventory)
+ >>> list(map(getcount, inventory))
[3, 2, 5, 1]
>>> sorted(inventory, key=getcount)
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
From python-checkins at python.org Wed Sep 1 10:24:40 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 10:24:40 +0200 (CEST)
Subject: [Python-checkins] r84385 -
python/branches/release31-maint/Doc/library/bisect.rst
Message-ID: <20100901082440.6D77FF93D@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 10:24:40 2010
New Revision: 84385
Log:
Clean-up bisect docs
Modified:
python/branches/release31-maint/Doc/library/bisect.rst
Modified: python/branches/release31-maint/Doc/library/bisect.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/bisect.rst (original)
+++ python/branches/release31-maint/Doc/library/bisect.rst Wed Sep 1 10:24:40 2010
@@ -4,6 +4,7 @@
.. module:: bisect
:synopsis: Array bisection algorithms for binary searching.
.. sectionauthor:: Fred L. Drake, Jr.
+.. sectionauthor:: Raymond Hettinger
.. example based on the PyModules FAQ entry by Aaron Watters
This module provides support for maintaining a list in sorted order without
@@ -18,13 +19,16 @@
.. function:: bisect_left(a, x, lo=0, hi=len(a))
- Locate the proper insertion point for *x* in *a* to maintain sorted order.
+ Locate the insertion point for *x* in *a* to maintain sorted order.
The parameters *lo* and *hi* may be used to specify a subset of the list
which should be considered; by default the entire list is used. If *x* is
already present in *a*, the insertion point will be before (to the left of)
any existing entries. The return value is suitable for use as the first
- parameter to ``list.insert()``. This assumes that *a* is already sorted.
+ parameter to ``list.insert()`` assuming that *a* is already sorted.
+ The returned insertion point *i* partitions the array *a* into two halves so
+ that ``all(val < x for val in a[lo:i])`` for the left side and
+ ``all(val >= x for val in a[i:hi])`` for the right side.
.. function:: bisect_right(a, x, lo=0, hi=len(a))
bisect(a, x, lo=0, hi=len(a))
@@ -32,16 +36,16 @@
Similar to :func:`bisect_left`, but returns an insertion point which comes
after (to the right of) any existing entries of *x* in *a*.
+ The returned insertion point *i* partitions the array *a* into two halves so
+ that ``all(val <= x for val in a[lo:i])`` for the left side and
+ ``all(val > x for val in a[i:hi])`` for the right side.
.. function:: insort_left(a, x, lo=0, hi=len(a))
Insert *x* in *a* in sorted order. This is equivalent to
- ``a.insert(bisect.bisect_left(a, x, lo, hi), x)``. This assumes that *a* is
- already sorted.
-
- Also note that while the fast search step is O(log n), the slower insertion
- step is O(n), so the overall operation is slow.
-
+ ``a.insert(bisect.bisect_left(a, x, lo, hi), x)`` assuming that *a* is
+ already sorted. Keep in mind that the O(log n) search is dominated by
+ the slow O(n) insertion step.
.. function:: insort_right(a, x, lo=0, hi=len(a))
insort(a, x, lo=0, hi=len(a))
@@ -49,71 +53,75 @@
Similar to :func:`insort_left`, but inserting *x* in *a* after any existing
entries of *x*.
- Also note that while the fast search step is O(log n), the slower insertion
- step is O(n), so the overall operation is slow.
+.. seealso::
+
+ `SortedCollection recipe
+ `_ that uses
+ bisect to build a full-featured collection class with straight-forward search
+ methods and support for a key-function. The keys are precomputed to save
+ unnecessary calls to the key function during searches.
+
Searching Sorted Lists
----------------------
-The above :func:`bisect` functions are useful for finding insertion points, but
-can be tricky or awkward to use for common searching tasks. The following three
+The above :func:`bisect` functions are useful for finding insertion points but
+can be tricky or awkward to use for common searching tasks. The following five
functions show how to transform them into the standard lookups for sorted
lists::
- def find(a, key):
- '''Find leftmost item exact equal to the key.
- Raise ValueError if no such item exists.
-
- '''
- i = bisect_left(a, key)
- if i < len(a) and a[i] == key:
+ def index(a, x):
+ 'Locate the leftmost value exactly equal to x'
+ i = bisect_left(a, x)
+ if i != len(a) and a[i] == x:
+ return i
+ raise ValueError
+
+ def find_lt(a, x):
+ 'Find rightmost value less than x'
+ i = bisect_left(a, x)
+ if i:
+ return a[i-1]
+ raise ValueError
+
+ def find_le(a, x):
+ 'Find rightmost value less than or equal to x'
+ i = bisect_right(a, x)
+ if i:
+ return a[i-1]
+ raise ValueError
+
+ def find_gt(a, x):
+ 'Find leftmost value greater than x'
+ i = bisect_right(a, x)
+ if i != len(a):
return a[i]
- raise ValueError('No item found with key equal to: %r' % (key,))
+ raise ValueError
- def find_le(a, key):
- '''Find largest item less-than or equal to key.
- Raise ValueError if no such item exists.
- If multiple keys are equal, return the leftmost.
-
- '''
- i = bisect_left(a, key)
- if i < len(a) and a[i] == key:
+ def find_ge(a, x):
+ 'Find leftmost item greater than or equal to x'
+ i = bisect_left(a, x)
+ if i != len(a):
return a[i]
- if i == 0:
- raise ValueError('No item found with key at or below: %r' % (key,))
- return a[i-1]
-
- def find_ge(a, key):
- '''Find smallest item greater-than or equal to key.
- Raise ValueError if no such item exists.
- If multiple keys are equal, return the leftmost.
-
- '''
- i = bisect_left(a, key)
- if i == len(a):
- raise ValueError('No item found with key at or above: %r' % (key,))
- return a[i]
+ raise ValueError
+
Other Examples
--------------
.. _bisect-example:
-The :func:`bisect` function is generally useful for categorizing numeric data.
-This example uses :func:`bisect` to look up a letter grade for an exam total
-(say) based on a set of ordered numeric breakpoints: 85 and up is an 'A', 75..84
-is a 'B', etc.
-
- >>> grades = "FEDCBA"
- >>> breakpoints = [30, 44, 66, 75, 85]
- >>> from bisect import bisect
- >>> def grade(total):
- ... return grades[bisect(breakpoints, total)]
+The :func:`bisect` function can be useful for numeric table lookups. This
+example uses :func:`bisect` to look up a letter grade for an exam score (say)
+based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is
+a 'B', and so on::
+
+ >>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
+ ... i = bisect(breakpoints, score)
+ ... return grades[i]
...
- >>> grade(66)
- 'C'
- >>> map(grade, [33, 99, 77, 44, 12, 88])
- ['E', 'A', 'B', 'D', 'F', 'A']
+ >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
+ ['F', 'A', 'C', 'C', 'B', 'A', 'A']
Unlike the :func:`sorted` function, it does not make sense for the :func:`bisect`
functions to have *key* or *reversed* arguments because that would lead to an
@@ -135,9 +143,3 @@
>>> data[bisect_left(keys, 8)]
('yellow', 8)
-.. seealso::
-
- `SortedCollection recipe
- `_ that
- encapsulates precomputed keys, allowing straight-forward insertion and
- searching using a *key* function.
From python-checkins at python.org Wed Sep 1 10:27:16 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 10:27:16 +0200 (CEST)
Subject: [Python-checkins] r84386 -
python/branches/release31-maint/Doc/library/operator.rst
Message-ID: <20100901082716.8856CEE985@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 10:27:16 2010
New Revision: 84386
Log:
Fixup broken example
Modified:
python/branches/release31-maint/Doc/library/operator.rst
Modified: python/branches/release31-maint/Doc/library/operator.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/operator.rst (original)
+++ python/branches/release31-maint/Doc/library/operator.rst Wed Sep 1 10:27:16 2010
@@ -387,7 +387,7 @@
>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> getcount = itemgetter(1)
- >>> map(getcount, inventory)
+ >>> list(map(getcount, inventory))
[3, 2, 5, 1]
>>> sorted(inventory, key=getcount)
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
From python-checkins at python.org Wed Sep 1 10:56:10 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 10:56:10 +0200 (CEST)
Subject: [Python-checkins] r84387 -
python/branches/py3k/Modules/_bisectmodule.c
Message-ID: <20100901085610.BCD1DEE9C6@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 10:56:10 2010
New Revision: 84387
Log:
Fix line wrapping
Modified:
python/branches/py3k/Modules/_bisectmodule.c
Modified: python/branches/py3k/Modules/_bisectmodule.c
==============================================================================
--- python/branches/py3k/Modules/_bisectmodule.c (original)
+++ python/branches/py3k/Modules/_bisectmodule.c Wed Sep 1 10:56:10 2010
@@ -86,8 +86,7 @@
if (PyList_Insert(list, index, item) < 0)
return NULL;
} else {
- result = PyObject_CallMethod(list, "insert", "nO",
- index, item);
+ result = PyObject_CallMethod(list, "insert", "nO", index, item);
if (result == NULL)
return NULL;
Py_DECREF(result);
@@ -187,8 +186,7 @@
if (PyList_Insert(list, index, item) < 0)
return NULL;
} else {
- result = PyObject_CallMethod(list, "insert", "iO",
- index, item);
+ result = PyObject_CallMethod(list, "insert", "iO", index, item);
if (result == NULL)
return NULL;
Py_DECREF(result);
From python-checkins at python.org Wed Sep 1 10:57:16 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 10:57:16 +0200 (CEST)
Subject: [Python-checkins] r84388 - in python/branches/py3k/Doc: conf.py
using/index.rst
Message-ID: <20100901085716.683C2EE9E8@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 10:57:16 2010
New Revision: 84388
Log:
More descriptive title.
Modified:
python/branches/py3k/Doc/conf.py
python/branches/py3k/Doc/using/index.rst
Modified: python/branches/py3k/Doc/conf.py
==============================================================================
--- python/branches/py3k/Doc/conf.py (original)
+++ python/branches/py3k/Doc/conf.py Wed Sep 1 10:57:16 2010
@@ -131,7 +131,7 @@
('tutorial/index', 'tutorial.tex',
'Python Tutorial', _stdauthor, 'manual'),
('using/index', 'using.tex',
- 'Using Python', _stdauthor, 'manual'),
+ 'Python Setup', _stdauthor, 'manual'),
('whatsnew/' + version, 'whatsnew.tex',
'What\'s New in Python', 'A. M. Kuchling', 'howto'),
]
Modified: python/branches/py3k/Doc/using/index.rst
==============================================================================
--- python/branches/py3k/Doc/using/index.rst (original)
+++ python/branches/py3k/Doc/using/index.rst Wed Sep 1 10:57:16 2010
@@ -1,7 +1,7 @@
.. _using-index:
################
- Using Python
+ Python Setup
################
From python-checkins at python.org Wed Sep 1 11:15:42 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 11:15:42 +0200 (CEST)
Subject: [Python-checkins] r84389 - in python/branches/py3k/Doc/howto:
index.rst sorting.rst
Message-ID: <20100901091542.C7137EE985@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 11:15:42 2010
New Revision: 84389
Log:
Forward port sorting howto
Added:
python/branches/py3k/Doc/howto/sorting.rst (contents, props changed)
Modified:
python/branches/py3k/Doc/howto/index.rst
Modified: python/branches/py3k/Doc/howto/index.rst
==============================================================================
--- python/branches/py3k/Doc/howto/index.rst (original)
+++ python/branches/py3k/Doc/howto/index.rst Wed Sep 1 11:15:42 2010
@@ -21,6 +21,7 @@
functional.rst
regex.rst
sockets.rst
+ sorting.rst
unicode.rst
urllib2.rst
webservers.rst
Added: python/branches/py3k/Doc/howto/sorting.rst
==============================================================================
--- (empty file)
+++ python/branches/py3k/Doc/howto/sorting.rst Wed Sep 1 11:15:42 2010
@@ -0,0 +1,281 @@
+Sorting HOW TO
+**************
+
+:Author: Andrew Dalke and Raymond Hettinger
+:Release: 0.1
+
+
+Python lists have a built-in :meth:`list.sort` method that modifies the list
+in-place and a :func:`sorted` built-in function that builds a new sorted list
+from an iterable.
+
+In this document, we explore the various techniques for sorting data using Python.
+
+
+Sorting Basics
+==============
+
+A simple ascending sort is very easy: just call the :func:`sorted` function. It
+returns a new sorted list::
+
+ >>> sorted([5, 2, 3, 1, 4])
+ [1, 2, 3, 4, 5]
+
+You can also use the :meth:`list.sort` method of a list. It modifies the list
+in-place (and returns *None* to avoid confusion). Usually it's less convenient
+than :func:`sorted` - but if you don't need the original list, it's slightly
+more efficient.
+
+ >>> a = [5, 2, 3, 1, 4]
+ >>> a.sort()
+ >>> a
+ [1, 2, 3, 4, 5]
+
+Another difference is that the :meth:`list.sort` method is only defined for
+lists. In contrast, the :func:`sorted` function accepts any iterable.
+
+ >>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
+ [1, 2, 3, 4, 5]
+
+Key Functions
+=============
+
+Both :meth:`list.sort` and :func:`sorted` have *key* parameter to specify a
+function to be called on each list element prior to making comparisons.
+
+For example, here's a case-insensitive string comparison:
+
+ >>> sorted("This is a test string from Andrew".split(), key=str.lower)
+ ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
+
+The value of the *key* parameter should be a function that takes a single argument
+and returns a key to use for sorting purposes. This technique is fast because
+the key function is called exactly once for each input record.
+
+A common pattern is to sort complex objects using some of the object's indices
+as keys. For example:
+
+ >>> student_tuples = [
+ ('john', 'A', 15),
+ ('jane', 'B', 12),
+ ('dave', 'B', 10),
+ ]
+ >>> sorted(student_tuples, key=lambda student: student[2]) # sort by age
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+The same technique works for objects with named attributes. For example:
+
+ >>> class Student:
+ def __init__(self, name, grade, age):
+ self.name = name
+ self.grade = grade
+ self.age = age
+ def __repr__(self):
+ return repr((self.name, self.grade, self.age))
+
+ >>> student_objects = [
+ Student('john', 'A', 15),
+ Student('jane', 'B', 12),
+ Student('dave', 'B', 10),
+ ]
+ >>> sorted(student_objects, key=lambda student: student.age) # sort by age
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+Operator Module Functions
+=========================
+
+The key-function patterns shown above are very common, so Python provides
+convenience functions to make accessor functions easier and faster. The operator
+module has :func:`operator.itemgetter`, :func:`operator.attrgetter`, and
+an :func:`operator.methodcaller` function.
+
+Using those functions, the above examples become simpler and faster:
+
+ >>> from operator import itemgetter, attrgetter
+
+ >>> sorted(student_tuples, key=itemgetter(2))
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+ >>> sorted(student_objects, key=attrgetter('age'))
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+The operator module functions allow multiple levels of sorting. For example, to
+sort by *grade* then by *age*:
+
+ >>> sorted(student_tuples, key=itemgetter(1,2))
+ [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
+
+ >>> sorted(student_objects, key=attrgetter('grade', 'age'))
+ [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
+
+Ascending and Descending
+========================
+
+Both :meth:`list.sort` and :func:`sorted` accept a *reverse* parameter with a
+boolean value. This is using to flag descending sorts. For example, to get the
+student data in reverse *age* order:
+
+ >>> sorted(student_tuples, key=itemgetter(2), reverse=True)
+ [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
+
+ >>> sorted(student_objects, key=attrgetter('age'), reverse=True)
+ [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
+
+Sort Stability and Complex Sorts
+================================
+
+Sorts are guaranteed to be `stable
+`_\. That means that
+when multiple records have the same key, their original order is preserved.
+
+ >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
+ >>> sorted(data, key=itemgetter(0))
+ [('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]
+
+Notice how the two records for *blue* retain their original order so that
+``('blue', 1)`` is guaranteed to precede ``('blue', 2)``.
+
+This wonderful property lets you build complex sorts in a series of sorting
+steps. For example, to sort the student data by descending *grade* and then
+ascending *age*, do the *age* sort first and then sort again using *grade*:
+
+ >>> s = sorted(student_objects, key=attrgetter('age')) # sort on secondary key
+ >>> sorted(s, key=attrgetter('grade'), reverse=True) # now sort on primary key, descending
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+The `Timsort `_ algorithm used in Python
+does multiple sorts efficiently because it can take advantage of any ordering
+already present in a dataset.
+
+The Old Way Using Decorate-Sort-Undecorate
+==========================================
+
+This idiom is called Decorate-Sort-Undecorate after its three steps:
+
+* First, the initial list is decorated with new values that control the sort order.
+
+* Second, the decorated list is sorted.
+
+* Finally, the decorations are removed, creating a list that contains only the
+ initial values in the new order.
+
+For example, to sort the student data by *grade* using the DSU approach:
+
+ >>> decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]
+ >>> decorated.sort()
+ >>> [student for grade, i, student in decorated] # undecorate
+ [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
+
+This idiom works because tuples are compared lexicographically; the first items
+are compared; if they are the same then the second items are compared, and so
+on.
+
+It is not strictly necessary in all cases to include the index *i* in the
+decorated list, but including it gives two benefits:
+
+* The sort is stable -- if two items have the same key, their order will be
+ preserved in the sorted list.
+
+* The original items do not have to be comparable because the ordering of the
+ decorated tuples will be determined by at most the first two items. So for
+ example the original list could contain complex numbers which cannot be sorted
+ directly.
+
+Another name for this idiom is
+`Schwartzian transform `_\,
+after Randal L. Schwartz, who popularized it among Perl programmers.
+
+Now that Python sorting provides key-functions, this technique is not often needed.
+
+
+The Old Way Using the *cmp* Parameter
+=====================================
+
+Many constructs given in this HOWTO assume Python 2.4 or later. Before that,
+there was no :func:`sorted` builtin and :meth:`list.sort` took no keyword
+arguments. Instead, all of the Py2.x versions supported a *cmp* parameter to
+handle user specified comparison functions.
+
+In Py3.0, the *cmp* parameter was removed entirely (as part of a larger effort to
+simplify and unify the language, eliminating the conflict between rich
+comparisons and the :meth:`__cmp__` magic method).
+
+In Py2.x, sort allowed an optional function which can be called for doing the
+comparisons. That function should take two arguments to be compared and then
+return a negative value for less-than, return zero if they are equal, or return
+a positive value for greater-than. For example, we can do:
+
+ >>> def numeric_compare(x, y):
+ return x - y
+ >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
+ [1, 2, 3, 4, 5]
+
+Or you can reverse the order of comparison with:
+
+ >>> def reverse_numeric(x, y):
+ return y - x
+ >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric)
+ [5, 4, 3, 2, 1]
+
+When porting code from Python 2.x to 3.x, the situation can arise when you have
+the user supplying a comparison function and you need to convert that to a key
+function. The following wrapper makes that easy to do::
+
+ def cmp_to_key(mycmp):
+ 'Convert a cmp= function into a key= function'
+ class K(object):
+ def __init__(self, obj, *args):
+ self.obj = obj
+ def __lt__(self, other):
+ return mycmp(self.obj, other.obj) < 0
+ def __gt__(self, other):
+ return mycmp(self.obj, other.obj) > 0
+ def __eq__(self, other):
+ return mycmp(self.obj, other.obj) == 0
+ def __le__(self, other):
+ return mycmp(self.obj, other.obj) <= 0
+ def __ge__(self, other):
+ return mycmp(self.obj, other.obj) >= 0
+ def __ne__(self, other):
+ return mycmp(self.obj, other.obj) != 0
+ return K
+
+To convert to a key function, just wrap the old comparison function:
+
+ >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
+ [5, 4, 3, 2, 1]
+
+In Python 3.2, the :func:`functools.cmp_to_key` function was added to the
+functools module in the standard library.
+
+Odd and Ends
+============
+
+* For locale aware sorting, use :func:`locale.strxfrm` for a key function or
+ :func:`locale.strcoll` for a comparison function.
+
+* The *reverse* parameter still maintains sort stability (i.e. records with
+ equal keys retain the original order). Interestingly, that effect can be
+ simulated without the parameter by using the builtin :func:`reversed` function
+ twice:
+
+ >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
+ >>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))
+
+* The sort routines are guaranteed to use :meth:`__lt__` when making comparisons
+ between two objects. So, it is easy to add a standard sort order to a class by
+ defining an :meth:`__lt__` method::
+
+ >>> Student.__lt__ = lambda self, other: self.age < other.age
+ >>> sorted(student_objects)
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+* Key functions need not depend directly on the objects being sorted. A key
+ function can also access external resources. For instance, if the student grades
+ are stored in a dictionary, they can be used to sort a separate list of student
+ names:
+
+ >>> students = ['dave', 'john', 'jane']
+ >>> newgrades = {'john': 'F', 'jane':'A', 'dave': 'C'}
+ >>> sorted(students, key=newgrades.__getitem__)
+ ['jane', 'dave', 'john']
From python-checkins at python.org Wed Sep 1 11:17:24 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 11:17:24 +0200 (CEST)
Subject: [Python-checkins] r84390 - in
python/branches/release31-maint/Doc/howto: index.rst sorting.rst
Message-ID: <20100901091724.28827EE985@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 11:17:24 2010
New Revision: 84390
Log:
Forward port sorting howto
Added:
python/branches/release31-maint/Doc/howto/sorting.rst (contents, props changed)
Modified:
python/branches/release31-maint/Doc/howto/index.rst
Modified: python/branches/release31-maint/Doc/howto/index.rst
==============================================================================
--- python/branches/release31-maint/Doc/howto/index.rst (original)
+++ python/branches/release31-maint/Doc/howto/index.rst Wed Sep 1 11:17:24 2010
@@ -20,6 +20,7 @@
functional.rst
regex.rst
sockets.rst
+ sorting.rst
unicode.rst
urllib2.rst
webservers.rst
Added: python/branches/release31-maint/Doc/howto/sorting.rst
==============================================================================
--- (empty file)
+++ python/branches/release31-maint/Doc/howto/sorting.rst Wed Sep 1 11:17:24 2010
@@ -0,0 +1,279 @@
+Sorting HOW TO
+**************
+
+:Author: Andrew Dalke and Raymond Hettinger
+:Release: 0.1
+
+
+Python lists have a built-in :meth:`list.sort` method that modifies the list
+in-place and a :func:`sorted` built-in function that builds a new sorted list
+from an iterable.
+
+In this document, we explore the various techniques for sorting data using Python.
+
+
+Sorting Basics
+==============
+
+A simple ascending sort is very easy: just call the :func:`sorted` function. It
+returns a new sorted list::
+
+ >>> sorted([5, 2, 3, 1, 4])
+ [1, 2, 3, 4, 5]
+
+You can also use the :meth:`list.sort` method of a list. It modifies the list
+in-place (and returns *None* to avoid confusion). Usually it's less convenient
+than :func:`sorted` - but if you don't need the original list, it's slightly
+more efficient.
+
+ >>> a = [5, 2, 3, 1, 4]
+ >>> a.sort()
+ >>> a
+ [1, 2, 3, 4, 5]
+
+Another difference is that the :meth:`list.sort` method is only defined for
+lists. In contrast, the :func:`sorted` function accepts any iterable.
+
+ >>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
+ [1, 2, 3, 4, 5]
+
+Key Functions
+=============
+
+Both :meth:`list.sort` and :func:`sorted` have *key* parameter to specify a
+function to be called on each list element prior to making comparisons.
+
+For example, here's a case-insensitive string comparison:
+
+ >>> sorted("This is a test string from Andrew".split(), key=str.lower)
+ ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
+
+The value of the *key* parameter should be a function that takes a single argument
+and returns a key to use for sorting purposes. This technique is fast because
+the key function is called exactly once for each input record.
+
+A common pattern is to sort complex objects using some of the object's indices
+as keys. For example:
+
+ >>> student_tuples = [
+ ('john', 'A', 15),
+ ('jane', 'B', 12),
+ ('dave', 'B', 10),
+ ]
+ >>> sorted(student_tuples, key=lambda student: student[2]) # sort by age
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+The same technique works for objects with named attributes. For example:
+
+ >>> class Student:
+ def __init__(self, name, grade, age):
+ self.name = name
+ self.grade = grade
+ self.age = age
+ def __repr__(self):
+ return repr((self.name, self.grade, self.age))
+
+ >>> student_objects = [
+ Student('john', 'A', 15),
+ Student('jane', 'B', 12),
+ Student('dave', 'B', 10),
+ ]
+ >>> sorted(student_objects, key=lambda student: student.age) # sort by age
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+Operator Module Functions
+=========================
+
+The key-function patterns shown above are very common, so Python provides
+convenience functions to make accessor functions easier and faster. The operator
+module has :func:`operator.itemgetter`, :func:`operator.attrgetter`, and
+an :func:`operator.methodcaller` function.
+
+Using those functions, the above examples become simpler and faster:
+
+ >>> from operator import itemgetter, attrgetter
+
+ >>> sorted(student_tuples, key=itemgetter(2))
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+ >>> sorted(student_objects, key=attrgetter('age'))
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+The operator module functions allow multiple levels of sorting. For example, to
+sort by *grade* then by *age*:
+
+ >>> sorted(student_tuples, key=itemgetter(1,2))
+ [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
+
+ >>> sorted(student_objects, key=attrgetter('grade', 'age'))
+ [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
+
+Ascending and Descending
+========================
+
+Both :meth:`list.sort` and :func:`sorted` accept a *reverse* parameter with a
+boolean value. This is using to flag descending sorts. For example, to get the
+student data in reverse *age* order:
+
+ >>> sorted(student_tuples, key=itemgetter(2), reverse=True)
+ [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
+
+ >>> sorted(student_objects, key=attrgetter('age'), reverse=True)
+ [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
+
+Sort Stability and Complex Sorts
+================================
+
+Sorts are guaranteed to be `stable
+`_\. That means that
+when multiple records have the same key, their original order is preserved.
+
+ >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
+ >>> sorted(data, key=itemgetter(0))
+ [('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]
+
+Notice how the two records for *blue* retain their original order so that
+``('blue', 1)`` is guaranteed to precede ``('blue', 2)``.
+
+This wonderful property lets you build complex sorts in a series of sorting
+steps. For example, to sort the student data by descending *grade* and then
+ascending *age*, do the *age* sort first and then sort again using *grade*:
+
+ >>> s = sorted(student_objects, key=attrgetter('age')) # sort on secondary key
+ >>> sorted(s, key=attrgetter('grade'), reverse=True) # now sort on primary key, descending
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+The `Timsort `_ algorithm used in Python
+does multiple sorts efficiently because it can take advantage of any ordering
+already present in a dataset.
+
+The Old Way Using Decorate-Sort-Undecorate
+==========================================
+
+This idiom is called Decorate-Sort-Undecorate after its three steps:
+
+* First, the initial list is decorated with new values that control the sort order.
+
+* Second, the decorated list is sorted.
+
+* Finally, the decorations are removed, creating a list that contains only the
+ initial values in the new order.
+
+For example, to sort the student data by *grade* using the DSU approach:
+
+ >>> decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]
+ >>> decorated.sort()
+ >>> [student for grade, i, student in decorated] # undecorate
+ [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
+
+This idiom works because tuples are compared lexicographically; the first items
+are compared; if they are the same then the second items are compared, and so
+on.
+
+It is not strictly necessary in all cases to include the index *i* in the
+decorated list, but including it gives two benefits:
+
+* The sort is stable -- if two items have the same key, their order will be
+ preserved in the sorted list.
+
+* The original items do not have to be comparable because the ordering of the
+ decorated tuples will be determined by at most the first two items. So for
+ example the original list could contain complex numbers which cannot be sorted
+ directly.
+
+Another name for this idiom is
+`Schwartzian transform `_\,
+after Randal L. Schwartz, who popularized it among Perl programmers.
+
+Now that Python sorting provides key-functions, this technique is not often needed.
+
+
+The Old Way Using the *cmp* Parameter
+=====================================
+
+Many constructs given in this HOWTO assume Python 2.4 or later. Before that,
+there was no :func:`sorted` builtin and :meth:`list.sort` took no keyword
+arguments. Instead, all of the Py2.x versions supported a *cmp* parameter to
+handle user specified comparison functions.
+
+In Py3.0, the *cmp* parameter was removed entirely (as part of a larger effort to
+simplify and unify the language, eliminating the conflict between rich
+comparisons and the :meth:`__cmp__` magic method).
+
+In Py2.x, sort allowed an optional function which can be called for doing the
+comparisons. That function should take two arguments to be compared and then
+return a negative value for less-than, return zero if they are equal, or return
+a positive value for greater-than. For example, we can do:
+
+ >>> def numeric_compare(x, y):
+ return x - y
+ >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
+ [1, 2, 3, 4, 5]
+
+Or you can reverse the order of comparison with:
+
+ >>> def reverse_numeric(x, y):
+ return y - x
+ >>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric)
+ [5, 4, 3, 2, 1]
+
+When porting code from Python 2.x to 3.x, the situation can arise when you have
+the user supplying a comparison function and you need to convert that to a key
+function. The following wrapper makes that easy to do::
+
+ def cmp_to_key(mycmp):
+ 'Convert a cmp= function into a key= function'
+ class K(object):
+ def __init__(self, obj, *args):
+ self.obj = obj
+ def __lt__(self, other):
+ return mycmp(self.obj, other.obj) < 0
+ def __gt__(self, other):
+ return mycmp(self.obj, other.obj) > 0
+ def __eq__(self, other):
+ return mycmp(self.obj, other.obj) == 0
+ def __le__(self, other):
+ return mycmp(self.obj, other.obj) <= 0
+ def __ge__(self, other):
+ return mycmp(self.obj, other.obj) >= 0
+ def __ne__(self, other):
+ return mycmp(self.obj, other.obj) != 0
+ return K
+
+To convert to a key function, just wrap the old comparison function:
+
+ >>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
+ [5, 4, 3, 2, 1]
+
+
+Odd and Ends
+============
+
+* For locale aware sorting, use :func:`locale.strxfrm` for a key function or
+ :func:`locale.strcoll` for a comparison function.
+
+* The *reverse* parameter still maintains sort stability (i.e. records with
+ equal keys retain the original order). Interestingly, that effect can be
+ simulated without the parameter by using the builtin :func:`reversed` function
+ twice:
+
+ >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
+ >>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))
+
+* The sort routines are guaranteed to use :meth:`__lt__` when making comparisons
+ between two objects. So, it is easy to add a standard sort order to a class by
+ defining an :meth:`__lt__` method::
+
+ >>> Student.__lt__ = lambda self, other: self.age < other.age
+ >>> sorted(student_objects)
+ [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
+
+* Key functions need not depend directly on the objects being sorted. A key
+ function can also access external resources. For instance, if the student grades
+ are stored in a dictionary, they can be used to sort a separate list of student
+ names:
+
+ >>> students = ['dave', 'john', 'jane']
+ >>> newgrades = {'john': 'F', 'jane':'A', 'dave': 'C'}
+ >>> sorted(students, key=newgrades.__getitem__)
+ ['jane', 'dave', 'john']
From python-checkins at python.org Wed Sep 1 14:58:25 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 14:58:25 +0200 (CEST)
Subject: [Python-checkins] r84391 - in python/branches/py3k:
Include/abstract.h Misc/NEWS Objects/abstract.c
Objects/memoryobject.c
Message-ID: <20100901125825.55BB5EE98A@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 14:58:21 2010
New Revision: 84391
Log:
Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
_Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
Modified:
python/branches/py3k/Include/abstract.h
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/abstract.c
python/branches/py3k/Objects/memoryobject.c
Modified: python/branches/py3k/Include/abstract.h
==============================================================================
--- python/branches/py3k/Include/abstract.h (original)
+++ python/branches/py3k/Include/abstract.h Wed Sep 1 14:58:21 2010
@@ -1236,6 +1236,13 @@
PyAPI_FUNC(void) _Py_FreeCharPArray(char *const array[]);
+/* For internal use by buffer API functions */
+PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+
+
#ifdef __cplusplus
}
#endif
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 1 14:58:21 2010
@@ -354,6 +354,9 @@
Build
-----
+- Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
+ _Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
+
- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
S?bastien Sabl?.
Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c (original)
+++ python/branches/py3k/Objects/abstract.c Wed Sep 1 14:58:21 2010
@@ -413,7 +413,7 @@
void
-_add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -429,7 +429,7 @@
}
void
-_add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -453,7 +453,7 @@
PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
{
int k;
- void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
Py_ssize_t *indices, elements;
char *dest, *ptr;
@@ -480,10 +480,10 @@
}
if (fort == 'F') {
- addone = _add_one_to_index_F;
+ addone = _Py_add_one_to_index_F;
}
else {
- addone = _add_one_to_index_C;
+ addone = _Py_add_one_to_index_C;
}
dest = buf;
/* XXX : This is not going to be the fastest code in the world
@@ -504,7 +504,7 @@
PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
{
int k;
- void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
Py_ssize_t *indices, elements;
char *src, *ptr;
@@ -531,10 +531,10 @@
}
if (fort == 'F') {
- addone = _add_one_to_index_F;
+ addone = _Py_add_one_to_index_F;
}
else {
- addone = _add_one_to_index_C;
+ addone = _Py_add_one_to_index_C;
}
src = buf;
/* XXX : This is not going to be the fastest code in the world
@@ -611,7 +611,7 @@
elements *= view_src.shape[k];
}
while (elements--) {
- _add_one_to_index_C(view_src.ndim, indices, view_src.shape);
+ _Py_add_one_to_index_C(view_src.ndim, indices, view_src.shape);
dptr = PyBuffer_GetPointer(&view_dest, indices);
sptr = PyBuffer_GetPointer(&view_src, indices);
memcpy(dptr, sptr, view_src.itemsize);
Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c (original)
+++ python/branches/py3k/Objects/memoryobject.c Wed Sep 1 14:58:21 2010
@@ -172,9 +172,6 @@
return;
}
-void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape);
-void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);
-
static int
_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
{
@@ -203,10 +200,10 @@
elements *= view->shape[k];
}
if (fort == 'F') {
- func = _add_one_to_index_F;
+ func = _Py_add_one_to_index_F;
}
else {
- func = _add_one_to_index_C;
+ func = _Py_add_one_to_index_C;
}
while (elements--) {
func(view->ndim, indices, view->shape);
From python-checkins at python.org Wed Sep 1 15:01:35 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 15:01:35 +0200 (CEST)
Subject: [Python-checkins] r84392 - in python/branches/release31-maint:
Include/abstract.h Misc/NEWS Objects/abstract.c
Objects/memoryobject.c
Message-ID: <20100901130135.E7BEFEE98A@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 15:01:35 2010
New Revision: 84392
Log:
Merged revisions 84391 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84391 | antoine.pitrou | 2010-09-01 14:58:21 +0200 (mer., 01 sept. 2010) | 5 lines
Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
_Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Include/abstract.h
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Objects/abstract.c
python/branches/release31-maint/Objects/memoryobject.c
Modified: python/branches/release31-maint/Include/abstract.h
==============================================================================
--- python/branches/release31-maint/Include/abstract.h (original)
+++ python/branches/release31-maint/Include/abstract.h Wed Sep 1 15:01:35 2010
@@ -1233,6 +1233,13 @@
PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
+/* For internal use by buffer API functions */
+PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+
+
#ifdef __cplusplus
}
#endif
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Wed Sep 1 15:01:35 2010
@@ -514,6 +514,9 @@
Build
-----
+- Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
+ _Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
+
- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
S?bastien Sabl?.
Modified: python/branches/release31-maint/Objects/abstract.c
==============================================================================
--- python/branches/release31-maint/Objects/abstract.c (original)
+++ python/branches/release31-maint/Objects/abstract.c Wed Sep 1 15:01:35 2010
@@ -413,7 +413,7 @@
void
-_add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -429,7 +429,7 @@
}
void
-_add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -453,7 +453,7 @@
PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
{
int k;
- void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
Py_ssize_t *indices, elements;
char *dest, *ptr;
@@ -480,10 +480,10 @@
}
if (fort == 'F') {
- addone = _add_one_to_index_F;
+ addone = _Py_add_one_to_index_F;
}
else {
- addone = _add_one_to_index_C;
+ addone = _Py_add_one_to_index_C;
}
dest = buf;
/* XXX : This is not going to be the fastest code in the world
@@ -504,7 +504,7 @@
PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
{
int k;
- void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
Py_ssize_t *indices, elements;
char *src, *ptr;
@@ -531,10 +531,10 @@
}
if (fort == 'F') {
- addone = _add_one_to_index_F;
+ addone = _Py_add_one_to_index_F;
}
else {
- addone = _add_one_to_index_C;
+ addone = _Py_add_one_to_index_C;
}
src = buf;
/* XXX : This is not going to be the fastest code in the world
@@ -611,7 +611,7 @@
elements *= view_src.shape[k];
}
while (elements--) {
- _add_one_to_index_C(view_src.ndim, indices, view_src.shape);
+ _Py_add_one_to_index_C(view_src.ndim, indices, view_src.shape);
dptr = PyBuffer_GetPointer(&view_dest, indices);
sptr = PyBuffer_GetPointer(&view_src, indices);
memcpy(dptr, sptr, view_src.itemsize);
Modified: python/branches/release31-maint/Objects/memoryobject.c
==============================================================================
--- python/branches/release31-maint/Objects/memoryobject.c (original)
+++ python/branches/release31-maint/Objects/memoryobject.c Wed Sep 1 15:01:35 2010
@@ -172,9 +172,6 @@
return;
}
-void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape);
-void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);
-
static int
_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
{
@@ -203,10 +200,10 @@
elements *= view->shape[k];
}
if (fort == 'F') {
- func = _add_one_to_index_F;
+ func = _Py_add_one_to_index_F;
}
else {
- func = _add_one_to_index_C;
+ func = _Py_add_one_to_index_C;
}
while (elements--) {
func(view->ndim, indices, view->shape);
From python-checkins at python.org Wed Sep 1 15:02:50 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 15:02:50 +0200 (CEST)
Subject: [Python-checkins] r84393 - in python/branches/release27-maint:
Include/abstract.h Misc/NEWS Objects/abstract.c
Objects/memoryobject.c
Message-ID: <20100901130250.CCED2EEAC7@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 15:02:50 2010
New Revision: 84393
Log:
Merged revisions 84391 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84391 | antoine.pitrou | 2010-09-01 14:58:21 +0200 (mer., 01 sept. 2010) | 5 lines
Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
_Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Include/abstract.h
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Objects/abstract.c
python/branches/release27-maint/Objects/memoryobject.c
Modified: python/branches/release27-maint/Include/abstract.h
==============================================================================
--- python/branches/release27-maint/Include/abstract.h (original)
+++ python/branches/release27-maint/Include/abstract.h Wed Sep 1 15:02:50 2010
@@ -1383,6 +1383,13 @@
PyAPI_FUNC(int) _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls);
+/* For internal use by buffer API functions */
+PyAPI_FUNC(void) _Py_add_one_to_index_F(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+PyAPI_FUNC(void) _Py_add_one_to_index_C(int nd, Py_ssize_t *index,
+ const Py_ssize_t *shape);
+
+
#ifdef __cplusplus
}
#endif
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Wed Sep 1 15:02:50 2010
@@ -260,6 +260,12 @@
Build
-----
+- Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
+ _Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
+
+- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
+ S?bastien Sabl?.
+
- Issue #9280: Make sharedinstall depend on sharedmods.
- Issue #9275: The OSX installer once again installs links to binaries in
@@ -526,9 +532,6 @@
Build
-----
-- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
- S?bastien Sabl?.
-
- Display installer warning that Windows 2000 won't be supported in future
releases.
Modified: python/branches/release27-maint/Objects/abstract.c
==============================================================================
--- python/branches/release27-maint/Objects/abstract.c (original)
+++ python/branches/release27-maint/Objects/abstract.c Wed Sep 1 15:02:50 2010
@@ -443,7 +443,7 @@
void
-_add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+_Py_add_one_to_index_F(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -459,7 +459,7 @@
}
void
-_add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape)
+_Py_add_one_to_index_C(int nd, Py_ssize_t *index, const Py_ssize_t *shape)
{
int k;
@@ -483,7 +483,7 @@
PyBuffer_ToContiguous(void *buf, Py_buffer *view, Py_ssize_t len, char fort)
{
int k;
- void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
Py_ssize_t *indices, elements;
char *dest, *ptr;
@@ -510,10 +510,10 @@
}
if (fort == 'F') {
- addone = _add_one_to_index_F;
+ addone = _Py_add_one_to_index_F;
}
else {
- addone = _add_one_to_index_C;
+ addone = _Py_add_one_to_index_C;
}
dest = buf;
/* XXX : This is not going to be the fastest code in the world
@@ -534,7 +534,7 @@
PyBuffer_FromContiguous(Py_buffer *view, void *buf, Py_ssize_t len, char fort)
{
int k;
- void (*addone)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*addone)(int, Py_ssize_t *, const Py_ssize_t *);
Py_ssize_t *indices, elements;
char *src, *ptr;
@@ -561,10 +561,10 @@
}
if (fort == 'F') {
- addone = _add_one_to_index_F;
+ addone = _Py_add_one_to_index_F;
}
else {
- addone = _add_one_to_index_C;
+ addone = _Py_add_one_to_index_C;
}
src = buf;
/* XXX : This is not going to be the fastest code in the world
@@ -641,7 +641,7 @@
elements *= view_src.shape[k];
}
while (elements--) {
- _add_one_to_index_C(view_src.ndim, indices, view_src.shape);
+ _Py_add_one_to_index_C(view_src.ndim, indices, view_src.shape);
dptr = PyBuffer_GetPointer(&view_dest, indices);
sptr = PyBuffer_GetPointer(&view_src, indices);
memcpy(dptr, sptr, view_src.itemsize);
Modified: python/branches/release27-maint/Objects/memoryobject.c
==============================================================================
--- python/branches/release27-maint/Objects/memoryobject.c (original)
+++ python/branches/release27-maint/Objects/memoryobject.c Wed Sep 1 15:02:50 2010
@@ -172,9 +172,6 @@
return;
}
-void _add_one_to_index_F(int nd, Py_ssize_t *index, Py_ssize_t *shape);
-void _add_one_to_index_C(int nd, Py_ssize_t *index, Py_ssize_t *shape);
-
static int
_indirect_copy_nd(char *dest, Py_buffer *view, char fort)
{
@@ -203,10 +200,10 @@
elements *= view->shape[k];
}
if (fort == 'F') {
- func = _add_one_to_index_F;
+ func = _Py_add_one_to_index_F;
}
else {
- func = _add_one_to_index_C;
+ func = _Py_add_one_to_index_C;
}
while (elements--) {
func(view->ndim, indices, view->shape);
From python-checkins at python.org Wed Sep 1 17:10:13 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 17:10:13 +0200 (CEST)
Subject: [Python-checkins] r84394 - in python/branches/py3k: Misc/ACKS
Misc/NEWS Objects/unicodeobject.c
Message-ID: <20100901151013.1DF28EEA80@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 17:10:12 2010
New Revision: 84394
Log:
Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
Modified:
python/branches/py3k/Misc/ACKS
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS (original)
+++ python/branches/py3k/Misc/ACKS Wed Sep 1 17:10:12 2010
@@ -62,6 +62,7 @@
Robin Becker
Neal Becker
Bill Bedford
+Stefan Behnel
Reimer Behrends
Ben Bell
Thomas Bellman
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 1 17:10:12 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
+ properly. Patch by Stefan Behnel.
+
- Issue #5553: The Py_LOCAL_INLINE macro now results in inlining on
most platforms. Previously, it online inlined when using Microsoft
Visual C.
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Wed Sep 1 17:10:12 2010
@@ -1234,8 +1234,7 @@
const char *encoding,
const char *errors)
{
- const char *s = NULL;
- Py_ssize_t len;
+ Py_buffer buffer;
PyObject *v;
if (obj == NULL) {
@@ -1243,44 +1242,44 @@
return NULL;
}
+ /* Decoding bytes objects is the most common case and should be fast */
+ if (PyBytes_Check(obj)) {
+ if (PyBytes_GET_SIZE(obj) == 0) {
+ Py_INCREF(unicode_empty);
+ v = (PyObject *) unicode_empty;
+ }
+ else {
+ v = PyUnicode_Decode(
+ PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj),
+ encoding, errors);
+ }
+ return v;
+ }
+
if (PyUnicode_Check(obj)) {
PyErr_SetString(PyExc_TypeError,
"decoding str is not supported");
return NULL;
}
- /* Coerce object */
- if (PyBytes_Check(obj)) {
- s = PyBytes_AS_STRING(obj);
- len = PyBytes_GET_SIZE(obj);
- }
- else if (PyByteArray_Check(obj)) {
- s = PyByteArray_AS_STRING(obj);
- len = PyByteArray_GET_SIZE(obj);
- }
- else if (PyObject_AsCharBuffer(obj, &s, &len)) {
- /* Overwrite the error message with something more useful in
- case of a TypeError. */
- if (PyErr_ExceptionMatches(PyExc_TypeError))
- PyErr_Format(PyExc_TypeError,
- "coercing to str: need bytes, bytearray or char buffer, "
- "%.80s found",
- Py_TYPE(obj)->tp_name);
- goto onError;
+ /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */
+ if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) {
+ PyErr_Format(PyExc_TypeError,
+ "coercing to str: need bytes, bytearray "
+ "or buffer-like object, %.80s found",
+ Py_TYPE(obj)->tp_name);
+ return NULL;
}
- /* Convert to Unicode */
- if (len == 0) {
+ if (buffer.len == 0) {
Py_INCREF(unicode_empty);
- v = (PyObject *)unicode_empty;
+ v = (PyObject *) unicode_empty;
}
else
- v = PyUnicode_Decode(s, len, encoding, errors);
+ v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors);
+ PyBuffer_Release(&buffer);
return v;
-
- onError:
- return NULL;
}
/* Convert encoding to lower case and replace '_' with '-' in order to
From python-checkins at python.org Wed Sep 1 17:15:29 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 17:15:29 +0200 (CEST)
Subject: [Python-checkins] r84395 - python/branches/release27-maint
Message-ID: <20100901151529.1D9F7EEAC9@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 17:15:28 2010
New Revision: 84395
Log:
Blocked revisions 84394 via svnmerge
........
r84394 | antoine.pitrou | 2010-09-01 17:10:12 +0200 (mer., 01 sept. 2010) | 4 lines
Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Wed Sep 1 17:16:42 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 17:16:42 +0200 (CEST)
Subject: [Python-checkins] r84396 - in python/branches/release31-maint:
Misc/ACKS Misc/NEWS Objects/unicodeobject.c
Message-ID: <20100901151642.2C751CA71@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 17:16:41 2010
New Revision: 84396
Log:
Merged revisions 84394 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84394 | antoine.pitrou | 2010-09-01 17:10:12 +0200 (mer., 01 sept. 2010) | 4 lines
Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/ACKS
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Objects/unicodeobject.c
Modified: python/branches/release31-maint/Misc/ACKS
==============================================================================
--- python/branches/release31-maint/Misc/ACKS (original)
+++ python/branches/release31-maint/Misc/ACKS Wed Sep 1 17:16:41 2010
@@ -58,6 +58,7 @@
Robin Becker
Neal Becker
Bill Bedford
+Stefan Behnel
Reimer Behrends
Ben Bell
Thomas Bellman
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Wed Sep 1 17:16:41 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
+ properly. Patch by Stefan Behnel.
+
- Restore GIL in nis_cat in case of error.
- Issue #9712: Fix tokenize on identifiers that start with non-ascii names.
Modified: python/branches/release31-maint/Objects/unicodeobject.c
==============================================================================
--- python/branches/release31-maint/Objects/unicodeobject.c (original)
+++ python/branches/release31-maint/Objects/unicodeobject.c Wed Sep 1 17:16:41 2010
@@ -1162,8 +1162,7 @@
const char *encoding,
const char *errors)
{
- const char *s = NULL;
- Py_ssize_t len;
+ Py_buffer buffer;
PyObject *v;
if (obj == NULL) {
@@ -1171,44 +1170,44 @@
return NULL;
}
+ /* Decoding bytes objects is the most common case and should be fast */
+ if (PyBytes_Check(obj)) {
+ if (PyBytes_GET_SIZE(obj) == 0) {
+ Py_INCREF(unicode_empty);
+ v = (PyObject *) unicode_empty;
+ }
+ else {
+ v = PyUnicode_Decode(
+ PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj),
+ encoding, errors);
+ }
+ return v;
+ }
+
if (PyUnicode_Check(obj)) {
PyErr_SetString(PyExc_TypeError,
"decoding str is not supported");
return NULL;
}
- /* Coerce object */
- if (PyBytes_Check(obj)) {
- s = PyBytes_AS_STRING(obj);
- len = PyBytes_GET_SIZE(obj);
- }
- else if (PyByteArray_Check(obj)) {
- s = PyByteArray_AS_STRING(obj);
- len = PyByteArray_GET_SIZE(obj);
- }
- else if (PyObject_AsCharBuffer(obj, &s, &len)) {
- /* Overwrite the error message with something more useful in
- case of a TypeError. */
- if (PyErr_ExceptionMatches(PyExc_TypeError))
- PyErr_Format(PyExc_TypeError,
- "coercing to str: need string or buffer, "
- "%.80s found",
- Py_TYPE(obj)->tp_name);
- goto onError;
+ /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */
+ if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) {
+ PyErr_Format(PyExc_TypeError,
+ "coercing to str: need bytes, bytearray "
+ "or buffer-like object, %.80s found",
+ Py_TYPE(obj)->tp_name);
+ return NULL;
}
- /* Convert to Unicode */
- if (len == 0) {
+ if (buffer.len == 0) {
Py_INCREF(unicode_empty);
- v = (PyObject *)unicode_empty;
+ v = (PyObject *) unicode_empty;
}
else
- v = PyUnicode_Decode(s, len, encoding, errors);
+ v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors);
+ PyBuffer_Release(&buffer);
return v;
-
- onError:
- return NULL;
}
PyObject *PyUnicode_Decode(const char *s,
From python-checkins at python.org Wed Sep 1 20:54:56 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 20:54:56 +0200 (CEST)
Subject: [Python-checkins] r84397 - in python/branches/py3k:
Doc/library/sys.rst Include/unicodeobject.h Lib/site.py
Lib/test/test_site.py Misc/NEWS Misc/cheatsheet
Objects/unicodeobject.c Python/sysmodule.c
Message-ID: <20100901185456.D756DEE9C4@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 20:54:56 2010
New Revision: 84397
Log:
Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding()
are now removed, since their effect was inexistent in 3.x (the default
encoding is hardcoded to utf-8 and cannot be changed).
Modified:
python/branches/py3k/Doc/library/sys.rst
python/branches/py3k/Include/unicodeobject.h
python/branches/py3k/Lib/site.py
python/branches/py3k/Lib/test/test_site.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Misc/cheatsheet
python/branches/py3k/Objects/unicodeobject.c
python/branches/py3k/Python/sysmodule.c
Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst (original)
+++ python/branches/py3k/Doc/library/sys.rst Wed Sep 1 20:54:56 2010
@@ -712,18 +712,6 @@
:func:`setswitchinterval` instead.
-.. function:: setdefaultencoding(name)
-
- Set the current default string encoding used by the Unicode implementation. If
- *name* does not match any available encoding, :exc:`LookupError` is raised.
- This function is only intended to be used by the :mod:`site` module
- implementation and, where needed, by :mod:`sitecustomize`. Once used by the
- :mod:`site` module, it is removed from the :mod:`sys` module's namespace.
-
- .. Note that :mod:`site` is not imported if the :option:`-S` option is passed
- to the interpreter, in which case this function will remain available.
-
-
.. function:: setdlopenflags(n)
Set the flags used by the interpreter for :cfunc:`dlopen` calls, such as when
Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h (original)
+++ python/branches/py3k/Include/unicodeobject.h Wed Sep 1 20:54:56 2010
@@ -212,7 +212,6 @@
# define PyUnicode_Replace PyUnicodeUCS2_Replace
# define PyUnicode_Resize PyUnicodeUCS2_Resize
# define PyUnicode_RichCompare PyUnicodeUCS2_RichCompare
-# define PyUnicode_SetDefaultEncoding PyUnicodeUCS2_SetDefaultEncoding
# define PyUnicode_Split PyUnicodeUCS2_Split
# define PyUnicode_Splitlines PyUnicodeUCS2_Splitlines
# define PyUnicode_Tailmatch PyUnicodeUCS2_Tailmatch
@@ -295,7 +294,6 @@
# define PyUnicode_Replace PyUnicodeUCS4_Replace
# define PyUnicode_Resize PyUnicodeUCS4_Resize
# define PyUnicode_RichCompare PyUnicodeUCS4_RichCompare
-# define PyUnicode_SetDefaultEncoding PyUnicodeUCS4_SetDefaultEncoding
# define PyUnicode_Split PyUnicodeUCS4_Split
# define PyUnicode_Splitlines PyUnicodeUCS4_Splitlines
# define PyUnicode_Tailmatch PyUnicodeUCS4_Tailmatch
@@ -708,16 +706,6 @@
PyAPI_FUNC(const char*) PyUnicode_GetDefaultEncoding(void);
-/* Sets the currently active default encoding.
-
- Returns 0 on success, -1 in case of an error.
-
- */
-
-PyAPI_FUNC(int) PyUnicode_SetDefaultEncoding(
- const char *encoding /* Encoding name in standard form */
- );
-
/* --- Generic Codecs ----------------------------------------------------- */
/* Create a Unicode object by decoding the encoded string s of the
Modified: python/branches/py3k/Lib/site.py
==============================================================================
--- python/branches/py3k/Lib/site.py (original)
+++ python/branches/py3k/Lib/site.py Wed Sep 1 20:54:56 2010
@@ -460,25 +460,6 @@
encodings._cache[enc] = encodings._unknown
encodings.aliases.aliases[enc] = 'mbcs'
-def setencoding():
- """Set the string encoding used by the Unicode implementation. The
- default is 'ascii', but if you're willing to experiment, you can
- change this."""
- encoding = "ascii" # Default value set by _PyUnicode_Init()
- if 0:
- # Enable to support locale aware default string encodings.
- import locale
- loc = locale.getdefaultlocale()
- if loc[1]:
- encoding = loc[1]
- if 0:
- # Enable to switch off string to Unicode coercion and implicit
- # Unicode to string conversion.
- encoding = "undefined"
- if encoding != "ascii":
- # On Non-Unicode builds this will raise an AttributeError...
- sys.setdefaultencoding(encoding) # Needs Python Unicode build !
-
def execsitecustomize():
"""Run custom site specific code, if available."""
@@ -527,15 +508,9 @@
setcopyright()
sethelper()
aliasmbcs()
- setencoding()
execsitecustomize()
if ENABLE_USER_SITE:
execusercustomize()
- # Remove sys.setdefaultencoding() so that users cannot change the
- # encoding after initialization. The test for presence is needed when
- # this module is run as a script, because this code is executed twice.
- if hasattr(sys, "setdefaultencoding"):
- del sys.setdefaultencoding
main()
Modified: python/branches/py3k/Lib/test/test_site.py
==============================================================================
--- python/branches/py3k/Lib/test/test_site.py (original)
+++ python/branches/py3k/Lib/test/test_site.py Wed Sep 1 20:54:56 2010
@@ -29,10 +29,6 @@
class HelperFunctionsTests(unittest.TestCase):
"""Tests for helper functions.
-
- The setting of the encoding (set using sys.setdefaultencoding) used by
- the Unicode implementation is not tested.
-
"""
def setUp(self):
@@ -333,10 +329,6 @@
else:
self.fail("did not alias mbcs")
- def test_setdefaultencoding_removed(self):
- # Make sure sys.setdefaultencoding is gone
- self.assertTrue(not hasattr(sys, "setdefaultencoding"))
-
def test_sitecustomize_executed(self):
# If sitecustomize is available, it should have been imported.
if "sitecustomize" not in sys.modules:
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 1 20:54:56 2010
@@ -12,6 +12,10 @@
Core and Builtins
-----------------
+- Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding()
+ are now removed, since their effect was inexistent in 3.x (the default
+ encoding is hardcoded to utf-8 and cannot be changed).
+
- Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
Modified: python/branches/py3k/Misc/cheatsheet
==============================================================================
--- python/branches/py3k/Misc/cheatsheet (original)
+++ python/branches/py3k/Misc/cheatsheet Wed Sep 1 20:54:56 2010
@@ -1326,8 +1326,6 @@
exc_info() traceback return value to a local variable in a
function handling an exception will cause a circular
reference.
-setdefaultencoding Change default Unicode encoding - defaults to 7-bit ASCII.
-(encoding)
getrecursionlimit Retrieve maximum recursion depth.
()
setrecursionlimit Set maximum recursion depth. (Defaults to 1000.)
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Wed Sep 1 20:54:56 2010
@@ -1784,17 +1784,6 @@
return unicode_default_encoding;
}
-int PyUnicode_SetDefaultEncoding(const char *encoding)
-{
- if (strcmp(encoding, unicode_default_encoding) != 0) {
- PyErr_Format(PyExc_ValueError,
- "Can only set default encoding to %s",
- unicode_default_encoding);
- return -1;
- }
- return 0;
-}
-
/* create or adjust a UnicodeDecodeError */
static void
make_decode_exception(PyObject **exceptionObject,
Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c (original)
+++ python/branches/py3k/Python/sysmodule.c Wed Sep 1 20:54:56 2010
@@ -183,24 +183,6 @@
);
static PyObject *
-sys_setdefaultencoding(PyObject *self, PyObject *args)
-{
- char *encoding;
- if (!PyArg_ParseTuple(args, "s:setdefaultencoding", &encoding))
- return NULL;
- if (PyUnicode_SetDefaultEncoding(encoding))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setdefaultencoding_doc,
-"setdefaultencoding(encoding)\n\
-\n\
-Set the current default string encoding used by the Unicode implementation."
-);
-
-static PyObject *
sys_getfilesystemencoding(PyObject *self)
{
if (Py_FileSystemDefaultEncoding)
@@ -1030,8 +1012,6 @@
#ifdef USE_MALLOPT
{"mdebug", sys_mdebug, METH_VARARGS},
#endif
- {"setdefaultencoding", sys_setdefaultencoding, METH_VARARGS,
- setdefaultencoding_doc},
{"setfilesystemencoding", sys_setfilesystemencoding, METH_VARARGS,
setfilesystemencoding_doc},
{"setcheckinterval", sys_setcheckinterval, METH_VARARGS,
From python-checkins at python.org Wed Sep 1 20:56:56 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 20:56:56 +0200 (CEST)
Subject: [Python-checkins] r84398 - python/branches/release31-maint
Message-ID: <20100901185656.4C649EE9C4@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 20:56:56 2010
New Revision: 84398
Log:
Blocked revisions 84397 via svnmerge
........
r84397 | antoine.pitrou | 2010-09-01 20:54:56 +0200 (mer., 01 sept. 2010) | 5 lines
Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding()
are now removed, since their effect was inexistent in 3.x (the default
encoding is hardcoded to utf-8 and cannot be changed).
........
Modified:
python/branches/release31-maint/ (props changed)
From python-checkins at python.org Wed Sep 1 20:57:02 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 20:57:02 +0200 (CEST)
Subject: [Python-checkins] r84399 - python/branches/release27-maint
Message-ID: <20100901185702.898DEEEA3F@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 20:57:02 2010
New Revision: 84399
Log:
Blocked revisions 84397 via svnmerge
........
r84397 | antoine.pitrou | 2010-09-01 20:54:56 +0200 (mer., 01 sept. 2010) | 5 lines
Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding()
are now removed, since their effect was inexistent in 3.x (the default
encoding is hardcoded to utf-8 and cannot be changed).
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Wed Sep 1 21:28:49 2010
From: python-checkins at python.org (giampaolo.rodola)
Date: Wed, 1 Sep 2010 21:28:49 +0200 (CEST)
Subject: [Python-checkins] r84400 - python/branches/py3k/Modules/_ssl.c
Message-ID: <20100901192849.3A662EE985@mail.python.org>
Author: giampaolo.rodola
Date: Wed Sep 1 21:28:49 2010
New Revision: 84400
Log:
Issue #9693 - msg 115273: attempt to fix ssl module failures on certain OpenSSL versions by calling ERR_clear_error() before raising IOError
Modified:
python/branches/py3k/Modules/_ssl.c
Modified: python/branches/py3k/Modules/_ssl.c
==============================================================================
--- python/branches/py3k/Modules/_ssl.c (original)
+++ python/branches/py3k/Modules/_ssl.c Wed Sep 1 21:28:49 2010
@@ -1603,6 +1603,7 @@
PySSL_END_ALLOW_THREADS
if (r != 1) {
if (errno != 0) {
+ ERR_clear_error();
PyErr_SetFromErrno(PyExc_IOError);
}
else {
@@ -1619,6 +1620,7 @@
Py_XDECREF(certfile_bytes);
if (r != 1) {
if (errno != 0) {
+ ERR_clear_error();
PyErr_SetFromErrno(PyExc_IOError);
}
else {
@@ -1686,6 +1688,7 @@
Py_XDECREF(capath_bytes);
if (r != 1) {
if (errno != 0) {
+ ERR_clear_error();
PyErr_SetFromErrno(PyExc_IOError);
}
else {
From python-checkins at python.org Wed Sep 1 21:39:01 2010
From: python-checkins at python.org (victor.stinner)
Date: Wed, 1 Sep 2010 21:39:01 +0200 (CEST)
Subject: [Python-checkins] r84401 -
python/branches/py3k/Objects/unicodeobject.c
Message-ID: <20100901193901.D14F9EEABA@mail.python.org>
Author: victor.stinner
Date: Wed Sep 1 21:39:01 2010
New Revision: 84401
Log:
Remove unicode_default_encoding constant
Inline its value in PyUnicode_GetDefaultEncoding(). The comment is now outdated
(we will not change its value anymore).
Modified:
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Wed Sep 1 21:39:01 2010
@@ -114,15 +114,6 @@
shared as well. */
static PyUnicodeObject *unicode_latin1[256];
-/* Default encoding to use and assume when NULL is passed as encoding
- parameter; it is fixed to "utf-8". Always use the
- PyUnicode_GetDefaultEncoding() API to access this global.
-
- Don't forget to alter Py_FileSystemDefaultEncoding if you change the
- hard coded default!
-*/
-static const char unicode_default_encoding[] = "utf-8";
-
/* Fast detection of the most frequent whitespace characters */
const unsigned char _Py_ascii_whitespace[] = {
0, 0, 0, 0, 0, 0, 0, 0,
@@ -1781,7 +1772,7 @@
const char *PyUnicode_GetDefaultEncoding(void)
{
- return unicode_default_encoding;
+ return "utf-8";
}
/* create or adjust a UnicodeDecodeError */
From python-checkins at python.org Wed Sep 1 21:42:36 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 21:42:36 +0200 (CEST)
Subject: [Python-checkins] r84402 -
python/branches/release27-maint/Doc/library/bisect.rst
Message-ID: <20100901194236.35092EEA80@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 21:42:36 2010
New Revision: 84402
Log:
Clean-up bisect docs.
Modified:
python/branches/release27-maint/Doc/library/bisect.rst
Modified: python/branches/release27-maint/Doc/library/bisect.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/bisect.rst (original)
+++ python/branches/release27-maint/Doc/library/bisect.rst Wed Sep 1 21:42:36 2010
@@ -1,10 +1,10 @@
-
:mod:`bisect` --- Array bisection algorithm
===========================================
.. module:: bisect
:synopsis: Array bisection algorithms for binary searching.
.. sectionauthor:: Fred L. Drake, Jr.
+.. sectionauthor:: Raymond Hettinger
.. example based on the PyModules FAQ entry by Aaron Watters
This module provides support for maintaining a list in sorted order without
@@ -19,103 +19,111 @@
The following functions are provided:
-.. function:: bisect_left(list, item[, lo[, hi]])
-
- Locate the proper insertion point for *item* in *list* to maintain sorted order.
- The parameters *lo* and *hi* may be used to specify a subset of the list which
- should be considered; by default the entire list is used. If *item* is already
- present in *list*, the insertion point will be before (to the left of) any
- existing entries. The return value is suitable for use as the first parameter
- to ``list.insert()``. This assumes that *list* is already sorted.
+.. function:: bisect_left(a, x, lo=0, hi=len(a))
+ Locate the insertion point for *x* in *a* to maintain sorted order.
+ The parameters *lo* and *hi* may be used to specify a subset of the list
+ which should be considered; by default the entire list is used. If *x* is
+ already present in *a*, the insertion point will be before (to the left of)
+ any existing entries. The return value is suitable for use as the first
+ parameter to ``list.insert()`` assuming that *a* is already sorted.
-.. function:: bisect_right(list, item[, lo[, hi]])
-.. function:: bisect(list, item[, lo[, hi]])
+ The returned insertion point *i* partitions the array *a* into two halves so
+ that ``all(val < x for val in a[lo:i])`` for the left side and
+ ``all(val >= x for val in a[i:hi])`` for the right side.
- Similar to :func:`bisect_left`, but returns an insertion point which comes after
- (to the right of) any existing entries of *item* in *list*.
+.. function:: bisect_right(a, x, lo=0, hi=len(a))
+ bisect(a, x, lo=0, hi=len(a))
+ Similar to :func:`bisect_left`, but returns an insertion point which comes
+ after (to the right of) any existing entries of *x* in *a*.
-.. function:: insort_left(list, item[, lo[, hi]])
+ The returned insertion point *i* partitions the array *a* into two halves so
+ that ``all(val <= x for val in a[lo:i])`` for the left side and
+ ``all(val > x for val in a[i:hi])`` for the right side.
- Insert *item* in *list* in sorted order. This is equivalent to
- ``list.insert(bisect.bisect_left(list, item, lo, hi), item)``. This assumes
- that *list* is already sorted.
+.. function:: insort_left(a, x, lo=0, hi=len(a))
- Also note that while the fast search step is O(log n), the slower insertion
- step is O(n), so the overall operation is slow.
+ Insert *x* in *a* in sorted order. This is equivalent to
+ ``a.insert(bisect.bisect_left(a, x, lo, hi), x)`` assuming that *a* is
+ already sorted. Keep in mind that the O(log n) search is dominated by
+ the slow O(n) insertion step.
-.. function:: insort_right(list, item[, lo[, hi]])
+.. function:: insort_right(a, x, lo=0, hi=len(a))
insort(a, x, lo=0, hi=len(a))
- Similar to :func:`insort_left`, but inserting *item* in *list* after any
- existing entries of *item*.
+ Similar to :func:`insort_left`, but inserting *x* in *a* after any existing
+ entries of *x*.
+
+.. seealso::
+
+ `SortedCollection recipe
+ `_ that uses
+ bisect to build a full-featured collection class with straight-forward search
+ methods and support for a key-function. The keys are precomputed to save
+ unnecessary calls to the key function during searches.
- Also note that while the fast search step is O(log n), the slower insertion
- step is O(n), so the overall operation is slow.
Searching Sorted Lists
----------------------
-The above :func:`bisect` functions are useful for finding insertion points, but
-can be tricky or awkward to use for common searching tasks. The following three
+The above :func:`bisect` functions are useful for finding insertion points but
+can be tricky or awkward to use for common searching tasks. The following five
functions show how to transform them into the standard lookups for sorted
lists::
- def find(a, key):
- '''Find leftmost item exact equal to the key.
- Raise ValueError if no such item exists.
-
- '''
- i = bisect_left(a, key)
- if i < len(a) and a[i] == key:
+ def index(a, x):
+ 'Locate the leftmost value exactly equal to x'
+ i = bisect_left(a, x)
+ if i != len(a) and a[i] == x:
+ return i
+ raise ValueError
+
+ def find_lt(a, x):
+ 'Find rightmost value less than x'
+ i = bisect_left(a, x)
+ if i:
+ return a[i-1]
+ raise ValueError
+
+ def find_le(a, x):
+ 'Find rightmost value less than or equal to x'
+ i = bisect_right(a, x)
+ if i:
+ return a[i-1]
+ raise ValueError
+
+ def find_gt(a, x):
+ 'Find leftmost value greater than x'
+ i = bisect_right(a, x)
+ if i != len(a):
return a[i]
- raise ValueError('No item found with key equal to: %r' % (key,))
+ raise ValueError
- def find_le(a, key):
- '''Find largest item less-than or equal to key.
- Raise ValueError if no such item exists.
- If multiple keys are equal, return the leftmost.
-
- '''
- i = bisect_left(a, key)
- if i < len(a) and a[i] == key:
+ def find_ge(a, x):
+ 'Find leftmost item greater than or equal to x'
+ i = bisect_left(a, x)
+ if i != len(a):
return a[i]
- if i == 0:
- raise ValueError('No item found with key at or below: %r' % (key,))
- return a[i-1]
-
- def find_ge(a, key):
- '''Find smallest item greater-than or equal to key.
- Raise ValueError if no such item exists.
- If multiple keys are equal, return the leftmost.
-
- '''
- i = bisect_left(a, key)
- if i == len(a):
- raise ValueError('No item found with key at or above: %r' % (key,))
- return a[i]
+ raise ValueError
+
Other Examples
--------------
.. _bisect-example:
-The :func:`bisect` function is generally useful for categorizing numeric data.
-This example uses :func:`bisect` to look up a letter grade for an exam total
-(say) based on a set of ordered numeric breakpoints: 85 and up is an 'A', 75..84
-is a 'B', etc.
-
- >>> grades = "FEDCBA"
- >>> breakpoints = [30, 44, 66, 75, 85]
- >>> from bisect import bisect
- >>> def grade(total):
- ... return grades[bisect(breakpoints, total)]
+The :func:`bisect` function can be useful for numeric table lookups. This
+example uses :func:`bisect` to look up a letter grade for an exam score (say)
+based on a set of ordered numeric breakpoints: 90 and up is an 'A', 80 to 89 is
+a 'B', and so on::
+
+ >>> def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
+ ... i = bisect(breakpoints, score)
+ ... return grades[i]
...
- >>> grade(66)
- 'C'
- >>> map(grade, [33, 99, 77, 44, 12, 88])
- ['E', 'A', 'B', 'D', 'F', 'A']
+ >>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
+ ['F', 'A', 'C', 'C', 'B', 'A', 'A']
Unlike the :func:`sorted` function, it does not make sense for the :func:`bisect`
functions to have *key* or *reversed* arguments because that would lead to an
@@ -137,9 +145,3 @@
>>> data[bisect_left(keys, 8)]
('yellow', 8)
-.. seealso::
-
- `SortedCollection recipe
- `_ that
- encapsulates precomputed keys, allowing straight-forward insertion and
- searching using a *key* function.
From python-checkins at python.org Wed Sep 1 22:29:34 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 22:29:34 +0200 (CEST)
Subject: [Python-checkins] r84403 - in python/branches/py3k:
Doc/library/array.rst Lib/multiprocessing/managers.py
Lib/sre_compile.py Lib/test/test_array.py
Lib/test/test_file.py Lib/test/test_io.py
Lib/test/test_memoryio.py Lib/test/test_memoryview.py
Lib/test/test_struct.py Lib/wave.py Misc/NEWS Modules/arraymodule.c
Message-ID: <20100901202934.85370EEAC2@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 22:29:34 2010
New Revision: 84403
Log:
Issue #8990: array.fromstring() and array.tostring() get renamed to
frombytes() and tobytes(), respectively, to avoid confusion. Furthermore,
array.frombytes(), array.extend() as well as the array.array()
constructor now accept bytearray objects. Patch by Thomas Jollans.
Modified:
python/branches/py3k/Doc/library/array.rst
python/branches/py3k/Lib/multiprocessing/managers.py
python/branches/py3k/Lib/sre_compile.py
python/branches/py3k/Lib/test/test_array.py
python/branches/py3k/Lib/test/test_file.py
python/branches/py3k/Lib/test/test_io.py
python/branches/py3k/Lib/test/test_memoryio.py
python/branches/py3k/Lib/test/test_memoryview.py
python/branches/py3k/Lib/test/test_struct.py
python/branches/py3k/Lib/wave.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/arraymodule.c
Modified: python/branches/py3k/Doc/library/array.rst
==============================================================================
--- python/branches/py3k/Doc/library/array.rst (original)
+++ python/branches/py3k/Doc/library/array.rst Wed Sep 1 22:29:34 2010
@@ -60,7 +60,7 @@
appropriate type.
If given a list or string, the initializer is passed to the new array's
- :meth:`fromlist`, :meth:`fromstring`, or :meth:`fromunicode` method (see below)
+ :meth:`fromlist`, :meth:`frombytes`, or :meth:`fromunicode` method (see below)
to add initial items to the array. Otherwise, the iterable initializer is
passed to the :meth:`extend` method.
@@ -136,6 +136,15 @@
must be the right type to be appended to the array.
+.. method:: array.frombytes(s)
+
+ Appends items from the string, interpreting the string as an array of machine
+ values (as if it had been read from a file using the :meth:`fromfile` method).
+
+ .. versionadded:: 3.2
+ :meth:`fromstring` is renamed to :meth:`frombytes` for clarity.
+
+
.. method:: array.fromfile(f, n)
Read *n* items (as machine values) from the file object *f* and append them to
@@ -151,17 +160,16 @@
a.append(x)`` except that if there is a type error, the array is unchanged.
-.. method:: array.fromstring(s)
+.. method:: array.fromstring()
- Appends items from the string, interpreting the string as an array of machine
- values (as if it had been read from a file using the :meth:`fromfile` method).
+ Deprecated alias for :meth:`frombytes`.
.. method:: array.fromunicode(s)
Extends this array with data from the given unicode string. The array must
be a type ``'u'`` array; otherwise a :exc:`ValueError` is raised. Use
- ``array.fromstring(unicodestring.encode(enc))`` to append Unicode data to an
+ ``array.frombytes(unicodestring.encode(enc))`` to append Unicode data to an
array of some other type.
@@ -194,6 +202,16 @@
Reverse the order of the items in the array.
+.. method:: array.tobytes()
+
+ Convert the array to an array of machine values and return the bytes
+ representation (the same sequence of bytes that would be written to a file by
+ the :meth:`tofile` method.)
+
+ .. versionadded:: 3.2
+ :meth:`tostring` is renamed to :meth:`tobytes` for clarity.
+
+
.. method:: array.tofile(f)
Write all items (as machine values) to the file object *f*.
@@ -206,15 +224,13 @@
.. method:: array.tostring()
- Convert the array to an array of machine values and return the string
- representation (the same sequence of bytes that would be written to a file by
- the :meth:`tofile` method.)
+ Deprecated alias for :meth:`tobytes`.
.. method:: array.tounicode()
Convert the array to a unicode string. The array must be a type ``'u'`` array;
- otherwise a :exc:`ValueError` is raised. Use ``array.tostring().decode(enc)`` to
+ otherwise a :exc:`ValueError` is raised. Use ``array.tobytes().decode(enc)`` to
obtain a unicode string from an array of some other type.
Modified: python/branches/py3k/Lib/multiprocessing/managers.py
==============================================================================
--- python/branches/py3k/Lib/multiprocessing/managers.py (original)
+++ python/branches/py3k/Lib/multiprocessing/managers.py Wed Sep 1 22:29:34 2010
@@ -32,7 +32,7 @@
#
def reduce_array(a):
- return array.array, (a.typecode, a.tostring())
+ return array.array, (a.typecode, a.tobytes())
ForkingPickler.register(array.array, reduce_array)
view_types = [type(getattr({}, name)()) for name in ('items','keys','values')]
Modified: python/branches/py3k/Lib/sre_compile.py
==============================================================================
--- python/branches/py3k/Lib/sre_compile.py (original)
+++ python/branches/py3k/Lib/sre_compile.py Wed Sep 1 22:29:34 2010
@@ -343,7 +343,7 @@
else:
code = 'I'
# Convert block indices to byte array of 256 bytes
- mapping = array.array('b', mapping).tostring()
+ mapping = array.array('b', mapping).tobytes()
# Convert byte array to word array
mapping = array.array(code, mapping)
assert mapping.itemsize == _sre.CODESIZE
Modified: python/branches/py3k/Lib/test/test_array.py
==============================================================================
--- python/branches/py3k/Lib/test/test_array.py (original)
+++ python/branches/py3k/Lib/test/test_array.py Wed Sep 1 22:29:34 2010
@@ -11,6 +11,7 @@
import io
import math
import struct
+import warnings
import array
from array import _array_reconstructor as array_reconstructor
@@ -367,15 +368,35 @@
self.assertEqual(a, b)
def test_tofromstring(self):
+ nb_warnings = 4
+ with warnings.catch_warnings(record=True) as r:
+ warnings.filterwarnings("always",
+ message=r"(to|from)string\(\) is deprecated",
+ category=DeprecationWarning)
+ a = array.array(self.typecode, 2*self.example)
+ b = array.array(self.typecode)
+ self.assertRaises(TypeError, a.tostring, 42)
+ self.assertRaises(TypeError, b.fromstring)
+ self.assertRaises(TypeError, b.fromstring, 42)
+ b.fromstring(a.tostring())
+ self.assertEqual(a, b)
+ if a.itemsize>1:
+ self.assertRaises(ValueError, b.fromstring, "x")
+ nb_warnings += 1
+ self.assertEqual(len(r), nb_warnings)
+
+ def test_tofrombytes(self):
a = array.array(self.typecode, 2*self.example)
b = array.array(self.typecode)
- self.assertRaises(TypeError, a.tostring, 42)
- self.assertRaises(TypeError, b.fromstring)
- self.assertRaises(TypeError, b.fromstring, 42)
- b.fromstring(a.tostring())
+ self.assertRaises(TypeError, a.tobytes, 42)
+ self.assertRaises(TypeError, b.frombytes)
+ self.assertRaises(TypeError, b.frombytes, 42)
+ b.frombytes(a.tobytes())
+ c = array.array(self.typecode, bytearray(a.tobytes()))
self.assertEqual(a, b)
+ self.assertEqual(a, c)
if a.itemsize>1:
- self.assertRaises(ValueError, b.fromstring, "x")
+ self.assertRaises(ValueError, b.frombytes, b"x")
def test_repr(self):
a = array.array(self.typecode, 2*self.example)
@@ -898,8 +919,8 @@
a = array.array(self.typecode, self.example)
m = memoryview(a)
expected = m.tobytes()
- self.assertEqual(a.tostring(), expected)
- self.assertEqual(a.tostring()[0], expected[0])
+ self.assertEqual(a.tobytes(), expected)
+ self.assertEqual(a.tobytes()[0], expected[0])
# Resizing is forbidden when there are buffer exports.
# For issue 4509, we also check after each error that
# the array was not modified.
@@ -913,7 +934,7 @@
self.assertEqual(m.tobytes(), expected)
self.assertRaises(BufferError, a.fromlist, a.tolist())
self.assertEqual(m.tobytes(), expected)
- self.assertRaises(BufferError, a.fromstring, a.tostring())
+ self.assertRaises(BufferError, a.frombytes, a.tobytes())
self.assertEqual(m.tobytes(), expected)
if self.typecode == 'u':
self.assertRaises(BufferError, a.fromunicode, a.tounicode())
@@ -932,7 +953,7 @@
def test_weakref(self):
s = array.array(self.typecode, self.example)
p = weakref.proxy(s)
- self.assertEqual(p.tostring(), s.tostring())
+ self.assertEqual(p.tobytes(), s.tobytes())
s = None
self.assertRaises(ReferenceError, len, p)
@@ -1110,6 +1131,23 @@
upper = int(pow(2, a.itemsize * 8)) - 1
self.check_overflow(lower, upper)
+ def test_bytes_extend(self):
+ s = bytes(self.example)
+
+ a = array.array(self.typecode, self.example)
+ a.extend(s)
+ self.assertEqual(
+ a,
+ array.array(self.typecode, self.example+self.example)
+ )
+
+ a = array.array(self.typecode, self.example)
+ a.extend(bytearray(reversed(s)))
+ self.assertEqual(
+ a,
+ array.array(self.typecode, self.example+self.example[::-1])
+ )
+
class ByteTest(SignedNumberTest):
typecode = 'b'
@@ -1172,7 +1210,7 @@
# On alphas treating the byte swapped bit patters as
# floats/doubles results in floating point exceptions
# => compare the 8bit string values instead
- self.assertNotEqual(a.tostring(), b.tostring())
+ self.assertNotEqual(a.tobytes(), b.tobytes())
b.byteswap()
self.assertEqual(a, b)
Modified: python/branches/py3k/Lib/test/test_file.py
==============================================================================
--- python/branches/py3k/Lib/test/test_file.py (original)
+++ python/branches/py3k/Lib/test/test_file.py Wed Sep 1 22:29:34 2010
@@ -44,7 +44,7 @@
a = array('b', b'x'*10)
self.f = self.open(TESTFN, 'rb')
n = self.f.readinto(a)
- self.assertEquals(b'12', a.tostring()[:n])
+ self.assertEquals(b'12', a.tobytes()[:n])
def testReadinto_text(self):
# verify readinto refuses text files
@@ -281,7 +281,7 @@
except ValueError:
self.fail("readinto() after next() with supposedly empty "
"iteration-buffer failed anyway")
- line = buf.tostring()
+ line = buf.tobytes()
if line != testline:
self.fail("readinto() after next() with empty buffer "
"failed. Got %r, expected %r" % (line, testline))
Modified: python/branches/py3k/Lib/test/test_io.py
==============================================================================
--- python/branches/py3k/Lib/test/test_io.py (original)
+++ python/branches/py3k/Lib/test/test_io.py Wed Sep 1 22:29:34 2010
@@ -480,7 +480,7 @@
def test_array_writes(self):
a = array.array('i', range(10))
- n = len(a.tostring())
+ n = len(a.tobytes())
with self.open(support.TESTFN, "wb", 0) as f:
self.assertEqual(f.write(a), n)
with self.open(support.TESTFN, "wb") as f:
Modified: python/branches/py3k/Lib/test/test_memoryio.py
==============================================================================
--- python/branches/py3k/Lib/test/test_memoryio.py (original)
+++ python/branches/py3k/Lib/test/test_memoryio.py Wed Sep 1 22:29:34 2010
@@ -425,7 +425,7 @@
a = array.array('b', b"hello world")
memio = self.ioclass(buf)
memio.readinto(a)
- self.assertEqual(a.tostring(), b"1234567890d")
+ self.assertEqual(a.tobytes(), b"1234567890d")
memio.close()
self.assertRaises(ValueError, memio.readinto, b)
Modified: python/branches/py3k/Lib/test/test_memoryview.py
==============================================================================
--- python/branches/py3k/Lib/test/test_memoryview.py (original)
+++ python/branches/py3k/Lib/test/test_memoryview.py Wed Sep 1 22:29:34 2010
@@ -231,7 +231,7 @@
class BaseArrayMemoryTests(AbstractMemoryTests):
ro_type = None
rw_type = lambda self, b: array.array('i', list(b))
- getitem_type = lambda self, b: array.array('i', list(b)).tostring()
+ getitem_type = lambda self, b: array.array('i', list(b)).tobytes()
itemsize = array.array('i').itemsize
format = 'i'
Modified: python/branches/py3k/Lib/test/test_struct.py
==============================================================================
--- python/branches/py3k/Lib/test/test_struct.py (original)
+++ python/branches/py3k/Lib/test/test_struct.py Wed Sep 1 22:29:34 2010
@@ -430,12 +430,12 @@
# Test without offset
s.pack_into(writable_buf, 0, test_string)
- from_buf = writable_buf.tostring()[:len(test_string)]
+ from_buf = writable_buf.tobytes()[:len(test_string)]
self.assertEqual(from_buf, test_string)
# Test with offset.
s.pack_into(writable_buf, 10, test_string)
- from_buf = writable_buf.tostring()[:len(test_string)+10]
+ from_buf = writable_buf.tobytes()[:len(test_string)+10]
self.assertEqual(from_buf, test_string[:10] + test_string)
# Go beyond boundaries.
@@ -458,12 +458,12 @@
# Test without offset.
pack_into(writable_buf, 0, test_string)
- from_buf = writable_buf.tostring()[:len(test_string)]
+ from_buf = writable_buf.tobytes()[:len(test_string)]
self.assertEqual(from_buf, test_string)
# Test with offset.
pack_into(writable_buf, 10, test_string)
- from_buf = writable_buf.tostring()[:len(test_string)+10]
+ from_buf = writable_buf.tobytes()[:len(test_string)+10]
self.assertEqual(from_buf, test_string[:10] + test_string)
# Go beyond boundaries.
Modified: python/branches/py3k/Lib/wave.py
==============================================================================
--- python/branches/py3k/Lib/wave.py (original)
+++ python/branches/py3k/Lib/wave.py Wed Sep 1 22:29:34 2010
@@ -248,7 +248,7 @@
chunk = chunk.file
chunk.size_read = chunk.size_read + nitems * self._sampwidth
data.byteswap()
- data = data.tostring()
+ data = data.tobytes()
else:
data = self._data_chunk.read(nframes * self._framesize)
if self._convert and data:
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 1 22:29:34 2010
@@ -149,6 +149,11 @@
Library
-------
+- Issue #8990: array.fromstring() and array.tostring() get renamed to
+ frombytes() and tobytes(), respectively, to avoid confusion. Furthermore,
+ array.frombytes(), array.extend() as well as the array.array()
+ constructor now accept bytearray objects. Patch by Thomas Jollans.
+
- Issue #808164: Fixed socket.close to avoid references to globals, to
avoid issues when socket.close is called from a __del__ method.
Modified: python/branches/py3k/Modules/arraymodule.c
==============================================================================
--- python/branches/py3k/Modules/arraymodule.c (original)
+++ python/branches/py3k/Modules/arraymodule.c Wed Sep 1 22:29:34 2010
@@ -1175,7 +1175,7 @@
/* Forward */
-static PyObject *array_fromstring(arrayobject *self, PyObject *args);
+static PyObject *array_frombytes(arrayobject *self, PyObject *args);
static PyObject *
array_fromfile(arrayobject *self, PyObject *args)
@@ -1212,7 +1212,7 @@
if (args == NULL)
return NULL;
- res = array_fromstring(self, args);
+ res = array_frombytes(self, args);
Py_DECREF(args);
if (res == NULL)
return NULL;
@@ -1331,45 +1331,84 @@
\n\
Convert array to an ordinary list with the same items.");
-
static PyObject *
-array_fromstring(arrayobject *self, PyObject *args)
+frombytes(arrayobject *self, Py_buffer *buffer)
{
- char *str;
- Py_ssize_t n;
int itemsize = self->ob_descr->itemsize;
- if (!PyArg_ParseTuple(args, "s#:fromstring", &str, &n))
+ Py_ssize_t n;
+ if (buffer->itemsize != 1) {
+ PyBuffer_Release(buffer);
+ PyErr_SetString(PyExc_TypeError, "string/buffer of bytes required.");
return NULL;
+ }
+ n = buffer->len;
if (n % itemsize != 0) {
+ PyBuffer_Release(buffer);
PyErr_SetString(PyExc_ValueError,
"string length not a multiple of item size");
return NULL;
}
n = n / itemsize;
if (n > 0) {
- Py_ssize_t old_size = Py_SIZE(self);
+ Py_ssize_t old_size = Py_SIZE(self);
if ((n > PY_SSIZE_T_MAX - old_size) ||
((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
+ PyBuffer_Release(buffer);
return PyErr_NoMemory();
}
- if (array_resize(self, old_size + n) == -1)
+ if (array_resize(self, old_size + n) == -1) {
+ PyBuffer_Release(buffer);
return NULL;
+ }
memcpy(self->ob_item + old_size * itemsize,
- str, n * itemsize);
+ buffer->buf, n * itemsize);
}
+ PyBuffer_Release(buffer);
Py_INCREF(Py_None);
return Py_None;
}
+static PyObject *
+array_fromstring(arrayobject *self, PyObject *args)
+{
+ Py_buffer buffer;
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "fromstring() is deprecated. Use frombytes() instead.", 2) != 0)
+ return NULL;
+ if (!PyArg_ParseTuple(args, "s*:fromstring", &buffer))
+ return NULL;
+ else
+ return frombytes(self, &buffer);
+}
+
PyDoc_STRVAR(fromstring_doc,
"fromstring(string)\n\
\n\
Appends items from the string, interpreting it as an array of machine\n\
+values, as if it had been read from a file using the fromfile() method).\n\
+\n\
+This method is deprecated. Use frombytes instead.");
+
+
+static PyObject *
+array_frombytes(arrayobject *self, PyObject *args)
+{
+ Py_buffer buffer;
+ if (!PyArg_ParseTuple(args, "y*:frombytes", &buffer))
+ return NULL;
+ else
+ return frombytes(self, &buffer);
+}
+
+PyDoc_STRVAR(frombytes_doc,
+"frombytes(bytestring)\n\
+\n\
+Appends items from the string, interpreting it as an array of machine\n\
values, as if it had been read from a file using the fromfile() method).");
static PyObject *
-array_tostring(arrayobject *self, PyObject *unused)
+array_tobytes(arrayobject *self, PyObject *unused)
{
if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
return PyBytes_FromStringAndSize(self->ob_item,
@@ -1379,13 +1418,30 @@
}
}
-PyDoc_STRVAR(tostring_doc,
-"tostring() -> string\n\
+PyDoc_STRVAR(tobytes_doc,
+"tobytes() -> bytes\n\
\n\
-Convert the array to an array of machine values and return the string\n\
+Convert the array to an array of machine values and return the bytes\n\
representation.");
+static PyObject *
+array_tostring(arrayobject *self, PyObject *unused)
+{
+ if (PyErr_WarnEx(PyExc_DeprecationWarning,
+ "tostring() is deprecated. Use tobytes() instead.", 2) != 0)
+ return NULL;
+ return array_tobytes(self, unused);
+}
+
+PyDoc_STRVAR(tostring_doc,
+"tostring() -> bytes\n\
+\n\
+Convert the array to an array of machine values and return the bytes\n\
+representation.\n\
+\n\
+This method is deprecated. Use tobytes instead.");
+
static PyObject *
array_fromunicode(arrayobject *self, PyObject *args)
@@ -1420,7 +1476,7 @@
\n\
Extends this array with data from the unicode string ustr.\n\
The array must be a unicode type array; otherwise a ValueError\n\
-is raised. Use array.fromstring(ustr.decode(...)) to\n\
+is raised. Use array.frombytes(ustr.decode(...)) to\n\
append Unicode data to an array of some other type.");
@@ -1927,7 +1983,7 @@
return result;
}
- array_str = array_tostring(array, NULL);
+ array_str = array_tobytes(array, NULL);
if (array_str == NULL) {
Py_DECREF(dict);
return NULL;
@@ -1983,6 +2039,8 @@
fromlist_doc},
{"fromstring", (PyCFunction)array_fromstring, METH_VARARGS,
fromstring_doc},
+ {"frombytes", (PyCFunction)array_frombytes, METH_VARARGS,
+ frombytes_doc},
{"fromunicode", (PyCFunction)array_fromunicode, METH_VARARGS,
fromunicode_doc},
{"index", (PyCFunction)array_index, METH_O,
@@ -2005,6 +2063,8 @@
tolist_doc},
{"tostring", (PyCFunction)array_tostring, METH_NOARGS,
tostring_doc},
+ {"tobytes", (PyCFunction)array_tobytes, METH_NOARGS,
+ tobytes_doc},
{"tounicode", (PyCFunction)array_tounicode, METH_NOARGS,
tounicode_doc},
{NULL, NULL} /* sentinel */
@@ -2386,7 +2446,7 @@
Py_DECREF(a);
return NULL;
}
- v = array_fromstring((arrayobject *)a,
+ v = array_frombytes((arrayobject *)a,
t_initial);
Py_DECREF(t_initial);
if (v == NULL) {
From python-checkins at python.org Wed Sep 1 22:30:18 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 22:30:18 +0200 (CEST)
Subject: [Python-checkins] r84404 - python/branches/release31-maint
Message-ID: <20100901203018.98E57EEB21@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 22:30:18 2010
New Revision: 84404
Log:
Blocked revisions 84403 via svnmerge
........
r84403 | antoine.pitrou | 2010-09-01 22:29:34 +0200 (mer., 01 sept. 2010) | 6 lines
Issue #8990: array.fromstring() and array.tostring() get renamed to
frombytes() and tobytes(), respectively, to avoid confusion. Furthermore,
array.frombytes(), array.extend() as well as the array.array()
constructor now accept bytearray objects. Patch by Thomas Jollans.
........
Modified:
python/branches/release31-maint/ (props changed)
From python-checkins at python.org Wed Sep 1 22:31:59 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 22:31:59 +0200 (CEST)
Subject: [Python-checkins] r84405 -
python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
Message-ID: <20100901203159.EA01DEEB28@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 22:31:59 2010
New Revision: 84405
Log:
'Using Python' now called 'Python Setup'
Modified:
python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
Modified: python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
==============================================================================
--- python/branches/py3k/Doc/tools/sphinxext/indexcontent.html (original)
+++ python/branches/py3k/Doc/tools/sphinxext/indexcontent.html Wed Sep 1 22:31:59 2010
@@ -7,14 +7,14 @@
or all "What's new" documents since 2.0
Tutorial
start here
- Using Python
- how to use Python on different platforms
Library Reference
keep this under your pillow
Language Reference
describes syntax and language elements
Python HOWTOs
in-depth documents on specific topics
+ Python Setup
+ how to use Python on different platforms
Extending and Embedding
tutorial for C/C++ programmers
From python-checkins at python.org Wed Sep 1 22:55:42 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 22:55:42 +0200 (CEST)
Subject: [Python-checkins] r84406 - python/branches/py3k/Modules/_ssl.c
Message-ID: <20100901205542.1F389EEB39@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 22:55:41 2010
New Revision: 84406
Log:
Try to fix some buildbot failures on test_ssl
Modified:
python/branches/py3k/Modules/_ssl.c
Modified: python/branches/py3k/Modules/_ssl.c
==============================================================================
--- python/branches/py3k/Modules/_ssl.c (original)
+++ python/branches/py3k/Modules/_ssl.c Wed Sep 1 22:55:41 2010
@@ -1581,6 +1581,7 @@
int r;
errno = 0;
+ ERR_clear_error();
if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O|O:load_cert_chain", kwlist,
&certfile, &keyfile))
From python-checkins at python.org Wed Sep 1 23:02:50 2010
From: python-checkins at python.org (georg.brandl)
Date: Wed, 1 Sep 2010 23:02:50 +0200 (CEST)
Subject: [Python-checkins] r84407 -
python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
Message-ID: <20100901210250.6F32DEEB06@mail.python.org>
Author: georg.brandl
Date: Wed Sep 1 23:02:50 2010
New Revision: 84407
Log:
#9677: fix link.
Modified:
python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
Modified: python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
==============================================================================
--- python/branches/py3k/Doc/tools/sphinxext/indexcontent.html (original)
+++ python/branches/py3k/Doc/tools/sphinxext/indexcontent.html Wed Sep 1 23:02:50 2010
@@ -34,7 +34,7 @@
Indices and tables:
- Global Module Index
+
Global Module Index
quick access to all modules
General Index
all functions, classes, terms
From python-checkins at python.org Wed Sep 1 23:14:16 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 23:14:16 +0200 (CEST)
Subject: [Python-checkins] r84408 - in python/branches/py3k:
Lib/test/test_memoryview.py Misc/NEWS Objects/memoryobject.c
Message-ID: <20100901211416.BAC7CEE981@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 23:14:16 2010
New Revision: 84408
Log:
Issue #9737: Fix a crash when trying to delete a slice or an item from
a memoryview object.
Modified:
python/branches/py3k/Lib/test/test_memoryview.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/memoryobject.c
Modified: python/branches/py3k/Lib/test/test_memoryview.py
==============================================================================
--- python/branches/py3k/Lib/test/test_memoryview.py (original)
+++ python/branches/py3k/Lib/test/test_memoryview.py Wed Sep 1 23:14:16 2010
@@ -111,6 +111,15 @@
m = None
self.assertEquals(sys.getrefcount(b), oldrefcount)
+ def test_delitem(self):
+ for tp in self._types:
+ b = tp(self._source)
+ m = self._view(b)
+ with self.assertRaises(TypeError):
+ del m[1]
+ with self.assertRaises(TypeError):
+ del m[1:4]
+
def test_tobytes(self):
for tp in self._types:
m = self._view(tp(self._source))
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 1 23:14:16 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #9737: Fix a crash when trying to delete a slice or an item from
+ a memoryview object.
+
- Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding()
are now removed, since their effect was inexistent in 3.x (the default
encoding is hardcoded to utf-8 and cannot be changed).
Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c (original)
+++ python/branches/py3k/Objects/memoryobject.c Wed Sep 1 23:14:16 2010
@@ -631,6 +631,11 @@
"cannot modify read-only memory");
return -1;
}
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot delete memory");
+ return -1;
+ }
if (view->ndim != 1) {
PyErr_SetNone(PyExc_NotImplementedError);
return -1;
From python-checkins at python.org Wed Sep 1 23:14:46 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 23:14:46 +0200 (CEST)
Subject: [Python-checkins] r84409 -
python/branches/py3k/Objects/memoryobject.c
Message-ID: <20100901211446.91BABF6D2@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 23:14:46 2010
New Revision: 84409
Log:
Fix a compilation warning
Modified:
python/branches/py3k/Objects/memoryobject.c
Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c (original)
+++ python/branches/py3k/Objects/memoryobject.c Wed Sep 1 23:14:46 2010
@@ -179,7 +179,7 @@
int k;
Py_ssize_t elements;
char *ptr;
- void (*func)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*func)(int, Py_ssize_t *, const Py_ssize_t *);
if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
PyErr_NoMemory();
From python-checkins at python.org Wed Sep 1 23:16:10 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 23:16:10 +0200 (CEST)
Subject: [Python-checkins] r84410 - in python/branches/release31-maint:
Lib/test/test_memoryview.py Misc/NEWS Objects/memoryobject.c
Message-ID: <20100901211610.CA504EE981@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 23:16:10 2010
New Revision: 84410
Log:
Merged revisions 84408-84409 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84408 | antoine.pitrou | 2010-09-01 23:14:16 +0200 (mer., 01 sept. 2010) | 4 lines
Issue #9737: Fix a crash when trying to delete a slice or an item from
a memoryview object.
........
r84409 | antoine.pitrou | 2010-09-01 23:14:46 +0200 (mer., 01 sept. 2010) | 3 lines
Fix a compilation warning
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_memoryview.py
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Objects/memoryobject.c
Modified: python/branches/release31-maint/Lib/test/test_memoryview.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_memoryview.py (original)
+++ python/branches/release31-maint/Lib/test/test_memoryview.py Wed Sep 1 23:16:10 2010
@@ -111,6 +111,15 @@
m = None
self.assertEquals(sys.getrefcount(b), oldrefcount)
+ def test_delitem(self):
+ for tp in self._types:
+ b = tp(self._source)
+ m = self._view(b)
+ with self.assertRaises(TypeError):
+ del m[1]
+ with self.assertRaises(TypeError):
+ del m[1:4]
+
def test_tobytes(self):
for tp in self._types:
m = self._view(tp(self._source))
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Wed Sep 1 23:16:10 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #9737: Fix a crash when trying to delete a slice or an item from
+ a memoryview object.
+
- Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
Modified: python/branches/release31-maint/Objects/memoryobject.c
==============================================================================
--- python/branches/release31-maint/Objects/memoryobject.c (original)
+++ python/branches/release31-maint/Objects/memoryobject.c Wed Sep 1 23:16:10 2010
@@ -179,7 +179,7 @@
int k;
Py_ssize_t elements;
char *ptr;
- void (*func)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*func)(int, Py_ssize_t *, const Py_ssize_t *);
if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
PyErr_NoMemory();
@@ -631,6 +631,11 @@
"cannot modify read-only memory");
return -1;
}
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot delete memory");
+ return -1;
+ }
if (view->ndim != 1) {
PyErr_SetNone(PyExc_NotImplementedError);
return -1;
From python-checkins at python.org Wed Sep 1 23:17:35 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 1 Sep 2010 23:17:35 +0200 (CEST)
Subject: [Python-checkins] r84411 - in python/branches/release27-maint:
Lib/test/test_memoryview.py Misc/NEWS Objects/memoryobject.c
Message-ID: <20100901211735.1D7FEEE981@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 1 23:17:34 2010
New Revision: 84411
Log:
Merged revisions 84408-84409 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84408 | antoine.pitrou | 2010-09-01 23:14:16 +0200 (mer., 01 sept. 2010) | 4 lines
Issue #9737: Fix a crash when trying to delete a slice or an item from
a memoryview object.
........
r84409 | antoine.pitrou | 2010-09-01 23:14:46 +0200 (mer., 01 sept. 2010) | 3 lines
Fix a compilation warning
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_memoryview.py
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Objects/memoryobject.c
Modified: python/branches/release27-maint/Lib/test/test_memoryview.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_memoryview.py (original)
+++ python/branches/release27-maint/Lib/test/test_memoryview.py Wed Sep 1 23:17:34 2010
@@ -117,6 +117,15 @@
m = None
self.assertEquals(sys.getrefcount(b), oldrefcount)
+ def test_delitem(self):
+ for tp in self._types:
+ b = tp(self._source)
+ m = self._view(b)
+ with self.assertRaises(TypeError):
+ del m[1]
+ with self.assertRaises(TypeError):
+ del m[1:4]
+
def test_tobytes(self):
for tp in self._types:
m = self._view(tp(self._source))
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Wed Sep 1 23:17:34 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #9737: Fix a crash when trying to delete a slice or an item from
+ a memoryview object.
+
- Restore GIL in nis_cat in case of error.
- Issue #9688: __basicsize__ and __itemsize__ must be accessed as Py_ssize_t.
Modified: python/branches/release27-maint/Objects/memoryobject.c
==============================================================================
--- python/branches/release27-maint/Objects/memoryobject.c (original)
+++ python/branches/release27-maint/Objects/memoryobject.c Wed Sep 1 23:17:34 2010
@@ -179,7 +179,7 @@
int k;
Py_ssize_t elements;
char *ptr;
- void (*func)(int, Py_ssize_t *, Py_ssize_t *);
+ void (*func)(int, Py_ssize_t *, const Py_ssize_t *);
if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
PyErr_NoMemory();
@@ -639,6 +639,11 @@
"cannot modify read-only memory");
return -1;
}
+ if (value == NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot delete memory");
+ return -1;
+ }
if (view->ndim != 1) {
PyErr_SetNone(PyExc_NotImplementedError);
return -1;
From python-checkins at python.org Wed Sep 1 23:20:07 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 23:20:07 +0200 (CEST)
Subject: [Python-checkins] r84412 -
python/branches/release27-maint/Doc/library/heapq.rst
Message-ID: <20100901212007.33A9FEEA06@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 23:20:07 2010
New Revision: 84412
Log:
Cleanup heapq docs
Modified:
python/branches/release27-maint/Doc/library/heapq.rst
Modified: python/branches/release27-maint/Doc/library/heapq.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/heapq.rst (original)
+++ python/branches/release27-maint/Doc/library/heapq.rst Wed Sep 1 23:20:07 2010
@@ -63,45 +63,16 @@
Pop and return the smallest item from the *heap*, and also push the new *item*.
The heap size doesn't change. If the heap is empty, :exc:`IndexError` is raised.
- This is more efficient than :func:`heappop` followed by :func:`heappush`, and
- can be more appropriate when using a fixed-size heap. Note that the value
- returned may be larger than *item*! That constrains reasonable uses of this
- routine unless written as part of a conditional replacement::
-
- if item > heap[0]:
- item = heapreplace(heap, item)
-
-Example of use:
-
- >>> from heapq import heappush, heappop
- >>> heap = []
- >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
- >>> for item in data:
- ... heappush(heap, item)
- ...
- >>> ordered = []
- >>> while heap:
- ... ordered.append(heappop(heap))
- ...
- >>> print ordered
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- >>> data.sort()
- >>> print data == ordered
- True
-
-Using a heap to insert items at the correct place in a priority queue:
-
- >>> heap = []
- >>> data = [(1, 'J'), (4, 'N'), (3, 'H'), (2, 'O')]
- >>> for item in data:
- ... heappush(heap, item)
- ...
- >>> while heap:
- ... print heappop(heap)[1]
- J
- O
- H
- N
+
+ This one step operation is more efficient than a :func:`heappop` followed by
+ :func:`heappush` and can be more appropriate when using a fixed-size heap.
+ The pop/push combination always returns an element from the heap and replaces
+ it with *item*.
+
+ The value returned may be larger than the *item* added. If that isn't
+ desired, consider using :func:`heappushpop` instead. Its push/pop
+ combination returns the smaller of the two values, leaving the larger value
+ on the heap.
The module also offers three general purpose functions based on heaps.
@@ -152,6 +123,35 @@
functions.
+Basic Examples
+--------------
+
+A `heapsort `_ can be implemented by
+pushing all values onto a heap and then popping off the smallest values one at a
+time::
+
+ >>> def heapsort(iterable):
+ ... 'Equivalent to sorted(iterable)'
+ ... h = []
+ ... for value in iterable:
+ ... heappush(h, value)
+ ... return [heappop(h) for i in range(len(h))]
+ ...
+ >>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+Heap elements can be tuples. This is useful for assigning comparison values
+(such as task priorities) alongside the main record being tracked::
+
+ >>> h = []
+ >>> heappush(h, (5, 'write code'))
+ >>> heappush(h, (7, 'release product'))
+ >>> heappush(h, (1, 'write spec'))
+ >>> heappush(h, (3, 'create tests'))
+ >>> heappop(h)
+ (1, 'write spec')
+
+
Priority Queue Implementation Notes
-----------------------------------
From python-checkins at python.org Wed Sep 1 23:26:16 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 23:26:16 +0200 (CEST)
Subject: [Python-checkins] r84413 -
python/branches/release31-maint/Doc/library/heapq.rst
Message-ID: <20100901212616.3F1CFEE981@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 23:26:16 2010
New Revision: 84413
Log:
Cleanup heapq docs
Modified:
python/branches/release31-maint/Doc/library/heapq.rst
Modified: python/branches/release31-maint/Doc/library/heapq.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/heapq.rst (original)
+++ python/branches/release31-maint/Doc/library/heapq.rst Wed Sep 1 23:26:16 2010
@@ -61,45 +61,16 @@
Pop and return the smallest item from the *heap*, and also push the new *item*.
The heap size doesn't change. If the heap is empty, :exc:`IndexError` is raised.
- This is more efficient than :func:`heappop` followed by :func:`heappush`, and
- can be more appropriate when using a fixed-size heap. Note that the value
- returned may be larger than *item*! That constrains reasonable uses of this
- routine unless written as part of a conditional replacement::
-
- if item > heap[0]:
- item = heapreplace(heap, item)
-
-Example of use:
-
- >>> from heapq import heappush, heappop
- >>> heap = []
- >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
- >>> for item in data:
- ... heappush(heap, item)
- ...
- >>> ordered = []
- >>> while heap:
- ... ordered.append(heappop(heap))
- ...
- >>> ordered
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- >>> data.sort()
- >>> data == ordered
- True
-
-Using a heap to insert items at the correct place in a priority queue:
-
- >>> heap = []
- >>> data = [(1, 'J'), (4, 'N'), (3, 'H'), (2, 'O')]
- >>> for item in data:
- ... heappush(heap, item)
- ...
- >>> while heap:
- ... print(heappop(heap)[1])
- J
- O
- H
- N
+
+ This one step operation is more efficient than a :func:`heappop` followed by
+ :func:`heappush` and can be more appropriate when using a fixed-size heap.
+ The pop/push combination always returns an element from the heap and replaces
+ it with *item*.
+
+ The value returned may be larger than the *item* added. If that isn't
+ desired, consider using :func:`heappushpop` instead. Its push/pop
+ combination returns the smaller of the two values, leaving the larger value
+ on the heap.
The module also offers three general purpose functions based on heaps.
@@ -139,6 +110,35 @@
functions.
+Basic Examples
+--------------
+
+A `heapsort `_ can be implemented by
+pushing all values onto a heap and then popping off the smallest values one at a
+time::
+
+ >>> def heapsort(iterable):
+ ... 'Equivalent to sorted(iterable)'
+ ... h = []
+ ... for value in iterable:
+ ... heappush(h, value)
+ ... return [heappop(h) for i in range(len(h))]
+ ...
+ >>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+Heap elements can be tuples. This is useful for assigning comparison values
+(such as task priorities) alongside the main record being tracked::
+
+ >>> h = []
+ >>> heappush(h, (5, 'write code'))
+ >>> heappush(h, (7, 'release product'))
+ >>> heappush(h, (1, 'write spec'))
+ >>> heappush(h, (3, 'create tests'))
+ >>> heappop(h)
+ (1, 'write spec')
+
+
Priority Queue Implementation Notes
-----------------------------------
From python-checkins at python.org Wed Sep 1 23:27:32 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 1 Sep 2010 23:27:32 +0200 (CEST)
Subject: [Python-checkins] r84414 -
python/branches/py3k/Doc/library/heapq.rst
Message-ID: <20100901212732.2312BEE9B1@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 1 23:27:31 2010
New Revision: 84414
Log:
Cleanup heapq docs
Modified:
python/branches/py3k/Doc/library/heapq.rst
Modified: python/branches/py3k/Doc/library/heapq.rst
==============================================================================
--- python/branches/py3k/Doc/library/heapq.rst (original)
+++ python/branches/py3k/Doc/library/heapq.rst Wed Sep 1 23:27:31 2010
@@ -61,45 +61,16 @@
Pop and return the smallest item from the *heap*, and also push the new *item*.
The heap size doesn't change. If the heap is empty, :exc:`IndexError` is raised.
- This is more efficient than :func:`heappop` followed by :func:`heappush`, and
- can be more appropriate when using a fixed-size heap. Note that the value
- returned may be larger than *item*! That constrains reasonable uses of this
- routine unless written as part of a conditional replacement::
-
- if item > heap[0]:
- item = heapreplace(heap, item)
-
-Example of use:
-
- >>> from heapq import heappush, heappop
- >>> heap = []
- >>> data = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
- >>> for item in data:
- ... heappush(heap, item)
- ...
- >>> ordered = []
- >>> while heap:
- ... ordered.append(heappop(heap))
- ...
- >>> ordered
- [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- >>> data.sort()
- >>> data == ordered
- True
-
-Using a heap to insert items at the correct place in a priority queue:
-
- >>> heap = []
- >>> data = [(1, 'J'), (4, 'N'), (3, 'H'), (2, 'O')]
- >>> for item in data:
- ... heappush(heap, item)
- ...
- >>> while heap:
- ... print(heappop(heap)[1])
- J
- O
- H
- N
+
+ This one step operation is more efficient than a :func:`heappop` followed by
+ :func:`heappush` and can be more appropriate when using a fixed-size heap.
+ The pop/push combination always returns an element from the heap and replaces
+ it with *item*.
+
+ The value returned may be larger than the *item* added. If that isn't
+ desired, consider using :func:`heappushpop` instead. Its push/pop
+ combination returns the smaller of the two values, leaving the larger value
+ on the heap.
The module also offers three general purpose functions based on heaps.
@@ -139,6 +110,35 @@
functions.
+Basic Examples
+--------------
+
+A `heapsort `_ can be implemented by
+pushing all values onto a heap and then popping off the smallest values one at a
+time::
+
+ >>> def heapsort(iterable):
+ ... 'Equivalent to sorted(iterable)'
+ ... h = []
+ ... for value in iterable:
+ ... heappush(h, value)
+ ... return [heappop(h) for i in range(len(h))]
+ ...
+ >>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+Heap elements can be tuples. This is useful for assigning comparison values
+(such as task priorities) alongside the main record being tracked::
+
+ >>> h = []
+ >>> heappush(h, (5, 'write code'))
+ >>> heappush(h, (7, 'release product'))
+ >>> heappush(h, (1, 'write spec'))
+ >>> heappush(h, (3, 'create tests'))
+ >>> heappop(h)
+ (1, 'write spec')
+
+
Priority Queue Implementation Notes
-----------------------------------
From ncoghlan at gmail.com Wed Sep 1 23:42:34 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Thu, 2 Sep 2010 07:42:34 +1000
Subject: [Python-checkins] r84391 - in python/branches/py3k:
Include/abstract.h Misc/NEWS Objects/abstract.c Objects/memoryobject.c
In-Reply-To: <20100901125825.55BB5EE98A@mail.python.org>
References: <20100901125825.55BB5EE98A@mail.python.org>
Message-ID:
On Wed, Sep 1, 2010 at 10:58 PM, antoine.pitrou
wrote:
> Modified: python/branches/py3k/Misc/NEWS
> ==============================================================================
> --- python/branches/py3k/Misc/NEWS ? ? ?(original)
> +++ python/branches/py3k/Misc/NEWS ? ? ?Wed Sep ?1 14:58:21 2010
> @@ -354,6 +354,9 @@
> ?Build
> ?-----
>
> +- Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
> + ?_Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
> +
Minor point: the names are actually *_index_C and *_index_F. (the
patch is right, just NEWS and the checkin comment are off)
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From python-checkins at python.org Thu Sep 2 00:11:53 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 00:11:53 +0200 (CEST)
Subject: [Python-checkins] r84415 - python/branches/py3k/Doc/glossary.rst
Message-ID: <20100901221153.9D909EE985@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 00:11:53 2010
New Revision: 84415
Log:
Glossary cleanup
Modified:
python/branches/py3k/Doc/glossary.rst
Modified: python/branches/py3k/Doc/glossary.rst
==============================================================================
--- python/branches/py3k/Doc/glossary.rst (original)
+++ python/branches/py3k/Doc/glossary.rst Thu Sep 2 00:11:53 2010
@@ -140,10 +140,9 @@
For more information about descriptors' methods, see :ref:`descriptors`.
dictionary
- An associative array, where arbitrary keys are mapped to values. The use
- of :class:`dict` closely resembles that for :class:`list`, but the keys can
- be any object with a :meth:`__hash__` function, not just integers.
- Called a hash in Perl.
+ An associative array, where arbitrary keys are mapped to values. The keys
+ can be any object with :meth:`__hash__` function and :meth:`__eq__`
+ methods. Called a hash in Perl.
docstring
A string literal which appears as the first expression in a class,
@@ -192,9 +191,11 @@
:term:`abstract base class`.
floor division
- Mathematical division discarding any remainder. The floor division
- operator is ``//``. For example, the expression ``11//4`` evaluates to
- ``2`` in contrast to the ``2.75`` returned by float true division.
+ Mathematical division that rounds down to nearest integer. The floor
+ division operator is ``//``. For example, the expression ``11 // 4``
+ evaluates to ``2`` in contrast to the ``2.75`` returned by float true
+ division. Note that ``(-11) // 4`` is ``-3`` because that is ``-2.75``
+ rounded *downward*. See :pep:`238`.
function
A series of statements which returns some value to a caller. It can also
@@ -202,7 +203,7 @@
the body. See also :term:`argument` and :term:`method`.
__future__
- A pseudo module which programmers can use to enable new language features
+ A pseudo-module which programmers can use to enable new language features
which are not compatible with the current interpreter.
By importing the :mod:`__future__` module and evaluating its variables,
@@ -222,13 +223,13 @@
generator
A function which returns an iterator. It looks like a normal function
- except that values are returned to the caller using a :keyword:`yield`
- statement instead of a :keyword:`return` statement. Generator functions
- often contain one or more :keyword:`for` or :keyword:`while` loops which
- :keyword:`yield` elements back to the caller. The function execution is
- stopped at the :keyword:`yield` keyword (returning the result) and is
- resumed there when the next element is requested by calling the
- :meth:`__next__` method of the returned iterator.
+ except that it contains :keyword:`yield` statements for producing a series
+ a values usable in a for-loop or that can be retrieved one at a time with
+ the :func:`next` function. Each :keyword:`yield` temporarily suspends
+ processing, remembering the location execution state (including local
+ variables and pending try-statements). When the generator resumes, it
+ picks-up where it left-off (in contrast to functions which start fresh on
+ every invocation.
.. index:: single: generator expression
@@ -273,9 +274,7 @@
IDLE
An Integrated Development Environment for Python. IDLE is a basic editor
and interpreter environment which ships with the standard distribution of
- Python. Good for beginners, it also serves as clear example code for
- those wanting to implement a moderately sophisticated, multi-platform GUI
- application.
+ Python.
immutable
An object with a fixed value. Immutable objects include numbers, strings and
@@ -377,7 +376,8 @@
mapping
A container object (such as :class:`dict`) which supports arbitrary key
- lookups using the special method :meth:`__getitem__`.
+ lookups using the special method :meth:`__getitem__`. Mappings also
+ support :meth:`__len__`, :meth:`__iter__`, and :meth:`__contains__`.
metaclass
The class of a class. Class definitions create a class name, a class
From python-checkins at python.org Thu Sep 2 00:14:09 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:09 +0200 (CEST)
Subject: [Python-checkins] r84416 - in python/branches/import_unicode:
Include/unicodeobject.h Objects/unicodeobject.c
Message-ID: <20100901221409.A2306EE98D@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:09 2010
New Revision: 84416
Log:
Create Py_UNICODE_strdup() function
Modified:
python/branches/import_unicode/Include/unicodeobject.h
python/branches/import_unicode/Objects/unicodeobject.c
Modified: python/branches/import_unicode/Include/unicodeobject.h
==============================================================================
--- python/branches/import_unicode/Include/unicodeobject.h (original)
+++ python/branches/import_unicode/Include/unicodeobject.h Thu Sep 2 00:14:09 2010
@@ -1634,6 +1634,14 @@
const Py_UNICODE *s, Py_UNICODE c
);
+/* Create a copy of a unicode string ending with a nul character.
+ Return NULL on memory error, otherwise return a new allocated buffer:
+ use PyMem_Free() to free the buffer. */
+
+PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strdup(
+ PyObject *unicode
+ );
+
#ifdef __cplusplus
}
#endif
Modified: python/branches/import_unicode/Objects/unicodeobject.c
==============================================================================
--- python/branches/import_unicode/Objects/unicodeobject.c (original)
+++ python/branches/import_unicode/Objects/unicodeobject.c Thu Sep 2 00:14:09 2010
@@ -10018,6 +10018,22 @@
return NULL;
}
+Py_UNICODE*
+Py_UNICODE_strdup(PyObject *object)
+{
+ PyUnicodeObject *unicode = (PyUnicodeObject *)object;
+ Py_UNICODE *copy;
+ Py_ssize_t size;
+ size = PyUnicode_GET_SIZE(unicode) + 1; /* copy the nul character */
+ size *= sizeof(Py_UNICODE);
+ copy = PyMem_Malloc(size);
+ if (copy == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memcpy(copy, PyUnicode_AS_UNICODE(unicode), size);
+ return copy;
+}
#ifdef __cplusplus
}
From python-checkins at python.org Thu Sep 2 00:14:12 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:12 +0200 (CEST)
Subject: [Python-checkins] r84417 - in python/branches/import_unicode:
Include/unicodeobject.h Objects/unicodeobject.c
Message-ID: <20100901221412.C50F6EE9EE@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:12 2010
New Revision: 84417
Log:
Create Py_UNICODE_strcat() function
Modified:
python/branches/import_unicode/Include/unicodeobject.h
python/branches/import_unicode/Objects/unicodeobject.c
Modified: python/branches/import_unicode/Include/unicodeobject.h
==============================================================================
--- python/branches/import_unicode/Include/unicodeobject.h (original)
+++ python/branches/import_unicode/Include/unicodeobject.h Thu Sep 2 00:14:12 2010
@@ -1620,6 +1620,9 @@
PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcpy(
Py_UNICODE *s1, const Py_UNICODE *s2);
+PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcat(
+ Py_UNICODE *s1, const Py_UNICODE *s2);
+
PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy(
Py_UNICODE *s1, const Py_UNICODE *s2, size_t n);
Modified: python/branches/import_unicode/Objects/unicodeobject.c
==============================================================================
--- python/branches/import_unicode/Objects/unicodeobject.c (original)
+++ python/branches/import_unicode/Objects/unicodeobject.c Thu Sep 2 00:14:12 2010
@@ -9980,6 +9980,13 @@
return s1;
}
+Py_UNICODE*
+Py_UNICODE_strcat(Py_UNICODE *s1, const Py_UNICODE *s2)
+{
+ s1 += Py_UNICODE_strlen(s1);
+ return Py_UNICODE_strcpy(s1, s2);
+}
+
int
Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2)
{
From python-checkins at python.org Thu Sep 2 00:14:15 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:15 +0200 (CEST)
Subject: [Python-checkins] r84418 - in python/branches/import_unicode:
Include/unicodeobject.h Objects/unicodeobject.c
Message-ID: <20100901221415.558F7EE98D@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:15 2010
New Revision: 84418
Log:
Backport Py_UNICODE_strncmp() functio
Modified:
python/branches/import_unicode/Include/unicodeobject.h
python/branches/import_unicode/Objects/unicodeobject.c
Modified: python/branches/import_unicode/Include/unicodeobject.h
==============================================================================
--- python/branches/import_unicode/Include/unicodeobject.h (original)
+++ python/branches/import_unicode/Include/unicodeobject.h Thu Sep 2 00:14:15 2010
@@ -1629,6 +1629,12 @@
PyAPI_FUNC(int) Py_UNICODE_strcmp(
const Py_UNICODE *s1, const Py_UNICODE *s2);
+PyAPI_FUNC(int) Py_UNICODE_strncmp(
+ const Py_UNICODE *s1,
+ const Py_UNICODE *s2,
+ size_t n
+ );
+
PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strchr(
const Py_UNICODE *s, Py_UNICODE c
);
Modified: python/branches/import_unicode/Objects/unicodeobject.c
==============================================================================
--- python/branches/import_unicode/Objects/unicodeobject.c (original)
+++ python/branches/import_unicode/Objects/unicodeobject.c Thu Sep 2 00:14:15 2010
@@ -10025,6 +10025,23 @@
return NULL;
}
+int
+Py_UNICODE_strncmp(const Py_UNICODE *s1, const Py_UNICODE *s2, size_t n)
+{
+ register Py_UNICODE u1, u2;
+ for (; n != 0; n--) {
+ u1 = *s1;
+ u2 = *s2;
+ if (u1 != u2)
+ return (u1 < u2) ? -1 : +1;
+ if (u1 == '\0')
+ return 0;
+ s1++;
+ s2++;
+ }
+ return 0;
+}
+
Py_UNICODE*
Py_UNICODE_strdup(PyObject *object)
{
From python-checkins at python.org Thu Sep 2 00:14:17 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:17 +0200 (CEST)
Subject: [Python-checkins] r84419 -
python/branches/import_unicode/Python/import.c
Message-ID: <20100901221417.B27D8EEAD3@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:17 2010
New Revision: 84419
Log:
make_source_pathname() uses unicode
Modified:
python/branches/import_unicode/Python/import.c
Modified: python/branches/import_unicode/Python/import.c
==============================================================================
--- python/branches/import_unicode/Python/import.c (original)
+++ python/branches/import_unicode/Python/import.c Thu Sep 2 00:14:17 2010
@@ -853,6 +853,8 @@
/* Like strrchr(string, '/') but searches for the rightmost of either SEP
or ALTSEP, if the latter is defined.
*/
+
+/* FIXME: Remove this function and rename rightmost_sep_unicode() */
static char *
rightmost_sep(char *s)
{
@@ -870,6 +872,23 @@
return found;
}
+static Py_UNICODE *
+rightmost_sep_unicode(Py_UNICODE *s)
+{
+ Py_UNICODE *found, c;
+ for (found = NULL; (c = *s); s++) {
+ if (c == SEP
+#ifdef ALTSEP
+ || c == ALTSEP
+#endif
+ )
+ {
+ found = s;
+ }
+ }
+ return found;
+}
+
/* Given a pathname for a Python source file, fill a buffer with the
pathname for the corresponding compiled file. Return the pathname
@@ -1010,77 +1029,73 @@
3147 style, NULL is returned. buf must be at least as big as pathname;
the resulting path will always be shorter. */
-/* FIXME: use Py_UNICODE* instead of char* */
-static char *
-_make_source_pathname(char *pathname, char *buf)
+static PyObject*
+make_source_pathname(PyObject *pathobj)
{
+ Py_UNICODE buf[MAXPATHLEN + 1];
+ PyObject *cpathname;
+ Py_UNICODE *pathname;
/* __pycache__/foo..pyc -> foo.py */
- size_t i, j;
- char *left, *right, *dot0, *dot1, sep;
+ Py_UNICODE *left, *right, *dot0, *dot1, sep;
+ PyObject *cachedir = NULL;
+ Py_ssize_t len;
+
+ pathname = Py_UNICODE_strdup(pathobj);
+ if (pathname == NULL)
+ return PyErr_NoMemory();
+ cachedir = PyUnicode_FromString(CACHEDIR);
/* Look back two slashes from the end. In between these two slashes
must be the string __pycache__ or this is not a PEP 3147 style
path. It's possible for there to be only one slash.
*/
- if ((right = rightmost_sep(pathname)) == NULL)
- return NULL;
+ if ((right = rightmost_sep_unicode(pathname)) == NULL)
+ goto error;
sep = *right;
*right = '\0';
- left = rightmost_sep(pathname);
+ left = rightmost_sep_unicode(pathname);
*right = sep;
if (left == NULL)
left = pathname;
else
left++;
- if (right-left != strlen(CACHEDIR) ||
- strncmp(left, CACHEDIR, right-left) != 0)
- return NULL;
+ if (right-left != PyUnicode_GET_SIZE(cachedir) ||
+ Py_UNICODE_strncmp(left, PyUnicode_AS_UNICODE(cachedir), right-left) != 0)
+ goto error;
/* Now verify that the path component to the right of the last slash
has two dots in it.
*/
- if ((dot0 = strchr(right + 1, '.')) == NULL)
- return NULL;
- if ((dot1 = strchr(dot0 + 1, '.')) == NULL)
- return NULL;
+ if ((dot0 = Py_UNICODE_strchr(right + 1, '.')) == NULL)
+ goto error;
+ if ((dot1 = Py_UNICODE_strchr(dot0 + 1, '.')) == NULL)
+ goto error;
/* Too many dots? */
- if (strchr(dot1 + 1, '.') != NULL)
- return NULL;
+ if (Py_UNICODE_strchr(dot1 + 1, '.') != NULL)
+ goto error;
/* This is a PEP 3147 path. Start by copying everything from the
start of pathname up to and including the leftmost slash. Then
copy the file's basename, removing the magic tag and adding a .py
suffix.
*/
- strncpy(buf, pathname, (i=left-pathname));
- strncpy(buf+i, right+1, (j=dot0-right));
- strcpy(buf+i+j, "py");
- return buf;
-}
-
-static PyObject*
-make_source_pathname(PyObject *pathobj)
-{
- /* FIXME: use Py_UNICODE* instead of char* */
- char buf[MAXPATHLEN + 1];
- PyObject *pathbytes;
- char *pathname, *cpathname;
-
- pathbytes = PyUnicode_EncodeFSDefault(pathobj);
- if (pathbytes == NULL)
- return NULL;
+ len = left-pathname;
+ Py_UNICODE_strncpy(buf, pathname, len);
+ Py_UNICODE_strncpy(buf+len, right+1, dot0-right);
+ len += dot0 - right;
+ buf[len++] = 'p';
+ buf[len++] = 'y';
+ buf[len] = '\0';
- pathname = strdup(PyBytes_AsString(pathbytes));
- Py_DECREF(pathbytes);
- if (pathname == NULL)
- return PyErr_NoMemory();
+ cpathname = PyUnicode_FromUnicode(buf, len);
+ goto finally;
- cpathname = _make_source_pathname(pathname, buf);
- free(pathname);
- if (cpathname != NULL)
- return PyUnicode_DecodeFSDefault(cpathname);
- else
- return NULL;
+error:
+ cpathname = NULL;
+finally:
+ PyMem_Free(pathname);
+ Py_XDECREF(cachedir);
+ return cpathname;
}
/* Given a pathname for a Python source file, its time of last
From python-checkins at python.org Thu Sep 2 00:14:20 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:20 +0200 (CEST)
Subject: [Python-checkins] r84420 -
python/branches/import_unicode/Python/import.c
Message-ID: <20100901221420.03EF3EEA7D@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:19 2010
New Revision: 84420
Log:
make_compiled_pathname() uses unicode
Modified:
python/branches/import_unicode/Python/import.c
Modified: python/branches/import_unicode/Python/import.c
==============================================================================
--- python/branches/import_unicode/Python/import.c (original)
+++ python/branches/import_unicode/Python/import.c Thu Sep 2 00:14:19 2010
@@ -895,15 +895,42 @@
for the compiled file, or NULL if there's no space in the buffer.
Doesn't set an exception. */
-/* FIXME: use Py_UNICODE*, not char* */
-static char *
-_make_compiled_pathname(char *pathname, char *buf, size_t buflen, int debug)
+static PyObject*
+make_compiled_pathname(PyObject *pathobj, int debug)
{
/* foo.py -> __pycache__/foo..pyc */
- size_t len = strlen(pathname);
size_t i, save;
- char *pos;
+ Py_UNICODE *pos;
int sep = SEP;
+ Py_UNICODE buf[MAXPATHLEN+1];
+ size_t buflen = sizeof(buf);
+ PyObject *cpathname;
+ Py_UNICODE *pathname;
+ PyObject *cachedir = NULL;
+ PyObject *pyc_tag_unicode = NULL;
+ PyObject *suffix = NULL;
+ Py_ssize_t len;
+
+ pathname = Py_UNICODE_strdup(pathobj);
+ if (pathname == NULL)
+ return NULL;
+ cachedir = PyUnicode_FromString(CACHEDIR);
+ if (cachedir == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ pyc_tag_unicode = PyUnicode_FromString(pyc_tag);
+ if (pyc_tag_unicode == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ suffix = PyUnicode_FromString(debug ? ".pyc" : ".pyo");
+ if (suffix == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+
+ len = PyUnicode_GET_SIZE(pathobj);
/* Sanity check that the buffer has roughly enough space to hold what
will eventually be the full path to the compiled file. The 5 extra
@@ -914,35 +941,35 @@
sanity check before writing the extension to ensure we do not
overflow the buffer.
*/
- if (len + strlen(CACHEDIR) + strlen(pyc_tag) + 5 > buflen)
- return NULL;
+ if (len + PyUnicode_GET_SIZE(cachedir) + PyUnicode_GET_SIZE(pyc_tag_unicode) + 5 > buflen)
+ goto error;
/* Find the last path separator and copy everything from the start of
the source string up to and including the separator.
*/
- if ((pos = rightmost_sep(pathname)) == NULL) {
+ if ((pos = rightmost_sep_unicode(pathname)) == NULL) {
i = 0;
}
else {
sep = *pos;
i = pos - pathname + 1;
- strncpy(buf, pathname, i);
+ Py_UNICODE_strncpy(buf, pathname, i);
}
save = i;
buf[i++] = '\0';
/* Add __pycache__/ */
- strcat(buf, CACHEDIR);
- i += strlen(CACHEDIR) - 1;
+ Py_UNICODE_strcat(buf, PyUnicode_AS_UNICODE(cachedir));
+ i += PyUnicode_GET_SIZE(cachedir) - 1;
buf[i++] = sep;
buf[i++] = '\0';
/* Add the base filename, but remove the .py or .pyw extension, since
the tag name must go before the extension.
*/
- strcat(buf, pathname + save);
- if ((pos = strrchr(buf, '.')) != NULL)
+ Py_UNICODE_strcat(buf, pathname + save);
+ if ((pos = Py_UNICODE_strrchr(buf, '.')) != NULL)
*++pos = '\0';
- strcat(buf, pyc_tag);
+ Py_UNICODE_strcat(buf, PyUnicode_AS_UNICODE(pyc_tag_unicode));
/* The length test above assumes that we're only adding one character
to the end of what would normally be the extension. What if there
is no extension, or the string ends in '.' or '.p', and otherwise
@@ -992,34 +1019,22 @@
#if 0
printf("strlen(buf): %d; buflen: %d\n", (int)strlen(buf), (int)buflen);
#endif
- if (strlen(buf) + 5 > buflen)
- return NULL;
- strcat(buf, debug ? ".pyc" : ".pyo");
- assert(strlen(buf) < buflen);
- return buf;
-}
-
-static PyObject*
-make_compiled_pathname(PyObject *pathobj, int debug)
-{
- /* FIXME: use Py_UNICODE* instead of char* */
- char buf[MAXPATHLEN+1];
- PyObject *pathbytes;
- char *pathname, *cpathname;
-
- pathbytes = PyUnicode_EncodeFSDefault(pathobj);
- if (pathbytes == NULL)
- return NULL;
-
- pathname = strdup(PyBytes_AsString(pathbytes));
- Py_DECREF(pathbytes);
+ if (Py_UNICODE_strlen(buf) + 5 > buflen)
+ goto error;
+ Py_UNICODE_strcat(buf, PyUnicode_AS_UNICODE(suffix));
+ len = Py_UNICODE_strlen(buf);
+ assert(len < buflen);
+ cpathname = PyUnicode_FromUnicode(buf, len);
+ goto finally;
- cpathname = _make_compiled_pathname(pathname, buf, sizeof(buf), debug);
- free(pathname);
- if (cpathname != NULL)
- return PyUnicode_DecodeFSDefault(cpathname);
- else
- return NULL;
+error:
+ cpathname = NULL;
+finally:
+ PyMem_Free(pathname);
+ Py_XDECREF(cachedir);
+ Py_XDECREF(pyc_tag_unicode);
+ Py_XDECREF(suffix);
+ return cpathname;
}
@@ -1044,6 +1059,10 @@
if (pathname == NULL)
return PyErr_NoMemory();
cachedir = PyUnicode_FromString(CACHEDIR);
+ if (cachedir == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
/* Look back two slashes from the end. In between these two slashes
must be the string __pycache__ or this is not a PEP 3147 style
From python-checkins at python.org Thu Sep 2 00:14:22 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:22 +0200 (CEST)
Subject: [Python-checkins] r84421 -
python/branches/import_unicode/Python/import.c
Message-ID: <20100901221422.3833DEEAAC@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:22 2010
New Revision: 84421
Log:
write_compiled_module() uses PySys_FormatStderr()
Modified:
python/branches/import_unicode/Python/import.c
Modified: python/branches/import_unicode/Python/import.c
==============================================================================
--- python/branches/import_unicode/Python/import.c (original)
+++ python/branches/import_unicode/Python/import.c Thu Sep 2 00:14:22 2010
@@ -1311,9 +1311,9 @@
dirpath = rightmost_sep(cpathname);
if (dirpath == NULL) {
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# no %s path found %s\n",
- CACHEDIR, cpathname);
+ PySys_FormatStderr(
+ "# no %U path found %U\n",
+ CACHEDIR, cpathobj);
Py_DECREF(cpathbytes);
return;
}
@@ -1323,8 +1323,8 @@
if (mkdir(cpathname, dirmode) < 0 && errno != EEXIST) {
*dirpath = saved;
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# cannot create cache dir %s\n", cpathname);
+ PySys_FormatStderr(
+ "# cannot create cache directory %U\n", cpathobj);
Py_DECREF(cpathbytes);
return;
}
@@ -1333,8 +1333,8 @@
fp = open_exclusive(cpathname, mode);
if (fp == NULL) {
if (Py_VerboseFlag)
- PySys_WriteStderr(
- "# can't create %s\n", cpathname);
+ PySys_FormatStderr(
+ "# can't create %U\n", cpathobj);
Py_DECREF(cpathbytes);
return;
}
@@ -1344,7 +1344,7 @@
PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION);
if (fflush(fp) != 0 || ferror(fp)) {
if (Py_VerboseFlag)
- PySys_WriteStderr("# can't write %s\n", cpathname);
+ PySys_FormatStderr("# can't write %U\n", cpathobj);
/* Don't keep partial file */
fclose(fp);
(void) unlink(cpathname);
@@ -1358,7 +1358,7 @@
fflush(fp);
fclose(fp);
if (Py_VerboseFlag)
- PySys_WriteStderr("# wrote %s\n", cpathname);
+ PySys_FormatStderr("# wrote %U\n", cpathobj);
Py_DECREF(cpathbytes);
}
From python-checkins at python.org Thu Sep 2 00:14:24 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:24 +0200 (CEST)
Subject: [Python-checkins] r84422 -
python/branches/import_unicode/Modules/posixmodule.c
Message-ID: <20100901221424.CFA30EEA81@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:24 2010
New Revision: 84422
Log:
Remove outdated comment
Modified:
python/branches/import_unicode/Modules/posixmodule.c
Modified: python/branches/import_unicode/Modules/posixmodule.c
==============================================================================
--- python/branches/import_unicode/Modules/posixmodule.c (original)
+++ python/branches/import_unicode/Modules/posixmodule.c Thu Sep 2 00:14:24 2010
@@ -2771,8 +2771,6 @@
return NULL;
path = PyBytes_AsString(opath);
Py_BEGIN_ALLOW_THREADS
- /* PyUnicode_AS_UNICODE OK without thread lock as
- it is a simple dereference. */
res = CreateDirectoryA(path, NULL);
Py_END_ALLOW_THREADS
if (!res) {
From python-checkins at python.org Thu Sep 2 00:14:27 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:27 +0200 (CEST)
Subject: [Python-checkins] r84423 -
python/branches/import_unicode/Python/import.c
Message-ID: <20100901221427.2A43BEE9F5@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:26 2010
New Revision: 84423
Log:
write_compiled_module() uses unicode on Windows
Modified:
python/branches/import_unicode/Python/import.c
Modified: python/branches/import_unicode/Python/import.c
==============================================================================
--- python/branches/import_unicode/Python/import.c (original)
+++ python/branches/import_unicode/Python/import.c Thu Sep 2 00:14:26 2010
@@ -854,7 +854,7 @@
or ALTSEP, if the latter is defined.
*/
-/* FIXME: Remove this function and rename rightmost_sep_unicode() */
+#ifndef MS_WINDOWS
static char *
rightmost_sep(char *s)
{
@@ -871,6 +871,7 @@
}
return found;
}
+#endif
static Py_UNICODE *
rightmost_sep_unicode(Py_UNICODE *s)
@@ -1241,6 +1242,23 @@
/* Helper to open a bytecode file for writing in exclusive mode */
+#ifdef MS_WINDOWS /* since Windows uses different permissions */
+static FILE *
+open_exclusive(Py_UNICODE *filename, mode_t mode)
+{
+ int fd;
+ (void)DeleteFileW(filename);
+
+ /* hFile = CreateFileW(filename,
+ FILE_WRITE_ATTRIBUTES, 0,
+ NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL); */
+ fd = open(@@@ filename @@@, O_EXCL|O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, mode);
+ if (fd < 0)
+ return NULL;
+ return fdopen(fd, "wb");
+}
+#else
static FILE *
open_exclusive(char *filename, mode_t mode)
{
@@ -1271,6 +1289,7 @@
return fopen(filename, "wb");
#endif
}
+#endif
/* Write a compiled module to a file, placing the time of last
@@ -1283,50 +1302,66 @@
struct stat *srcstat)
{
FILE *fp;
- char *dirpath;
time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC;
mode_t dirmode = srcstat->st_mode | S_IEXEC; /* XXX Is this correct
for Windows?
2010-04-07 BAW */
+ Py_UNICODE saved;
+ Py_UNICODE *dirpath;
+ Py_UNICODE *cpathname;
+ int res;
#else
mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH;
mode_t dirmode = (srcstat->st_mode |
S_IXUSR | S_IXGRP | S_IXOTH |
S_IWUSR | S_IWGRP | S_IWOTH);
-#endif
- int saved;
- PyObject *cpathbytes;
+ char saved;
+ char *dirpath;
char *cpathname;
+ PyObject *cpathbytes;
+#endif
+ int err;
+#ifdef MS_WINDOWS
+ cpathname = PyUnicode_AS_UNICODE(cpathobj);
+ dirpath = rightmost_sep_unicode(cpathname);
+#else
cpathbytes = PyUnicode_EncodeFSDefault(cpathobj);
if (cpathbytes == NULL) {
PyErr_Clear();
return;
}
cpathname = PyBytes_AS_STRING(cpathbytes);
+ dirpath = rightmost_sep(cpathname);
+#endif
/* Ensure that the __pycache__ directory exists. */
- dirpath = rightmost_sep(cpathname);
if (dirpath == NULL) {
if (Py_VerboseFlag)
PySys_FormatStderr(
"# no %U path found %U\n",
CACHEDIR, cpathobj);
- Py_DECREF(cpathbytes);
- return;
+ goto finally;
}
saved = *dirpath;
*dirpath = '\0';
- /* XXX call os.mkdir() or maybe CreateDirectoryA() on Windows? */
- if (mkdir(cpathname, dirmode) < 0 && errno != EEXIST) {
+#ifdef MS_WINDOWS
+ res = CreateDirectoryW(cpathname, NULL); /* FIXME: use dirmode? */
+ err = !res;
+#else
+ if (mkdir(cpathname, dirmode) < 0)
+ err = (errno != EEXIST);
+ else
+ err = 0;
+#endif
+ if (err) {
*dirpath = saved;
if (Py_VerboseFlag)
PySys_FormatStderr(
"# cannot create cache directory %U\n", cpathobj);
- Py_DECREF(cpathbytes);
- return;
+ goto finally;
}
*dirpath = saved;
@@ -1335,8 +1370,7 @@
if (Py_VerboseFlag)
PySys_FormatStderr(
"# can't create %U\n", cpathobj);
- Py_DECREF(cpathbytes);
- return;
+ goto finally;
}
PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION);
/* First write a 0 for mtime */
@@ -1347,9 +1381,12 @@
PySys_FormatStderr("# can't write %U\n", cpathobj);
/* Don't keep partial file */
fclose(fp);
+#ifdef MS_WINDOWS
+ (void)DeleteFileW(cpathname);
+#else
(void) unlink(cpathname);
- Py_DECREF(cpathbytes);
- return;
+#endif
+ goto finally;
}
/* Now write the true mtime */
fseek(fp, 4L, 0);
@@ -1359,7 +1396,11 @@
fclose(fp);
if (Py_VerboseFlag)
PySys_FormatStderr("# wrote %U\n", cpathobj);
+
+finally:
+#ifndef MS_WINDOWS
Py_DECREF(cpathbytes);
+#endif
}
static void
From python-checkins at python.org Thu Sep 2 00:14:29 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 00:14:29 +0200 (CEST)
Subject: [Python-checkins] r84424 - in python/branches/import_unicode:
Include/import.h Modules/signalmodule.c Python/import.c
Python/importdl.c Python/pythonrun.c
Message-ID: <20100901221429.9D510EEAD3@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 00:14:29 2010
New Revision: 84424
Log:
Create _PyImport_FindBuiltinExtension() and _PyImport_FixupBuiltinExtension()
* Remove _PyImport_FindExtension() and _PyImport_FixupExtension()
* Rename _PyImport_FindExtensionUnicode() to _PyImport_FindExtension()
* Rename _PyImport_FixupExtensionUnicode() to_PyImport_FixupExtension()
Modified:
python/branches/import_unicode/Include/import.h
python/branches/import_unicode/Modules/signalmodule.c
python/branches/import_unicode/Python/import.c
python/branches/import_unicode/Python/importdl.c
python/branches/import_unicode/Python/pythonrun.c
Modified: python/branches/import_unicode/Include/import.h
==============================================================================
--- python/branches/import_unicode/Include/import.h (original)
+++ python/branches/import_unicode/Include/import.h Thu Sep 2 00:14:29 2010
@@ -50,10 +50,10 @@
PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr *);
PyAPI_FUNC(void) _PyImport_ReInitLock(void);
-PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *);
-PyAPI_FUNC(PyObject *)_PyImport_FindExtensionUnicode(char *, PyObject *);
-PyAPI_FUNC(int)_PyImport_FixupExtension(PyObject*, char *, char *);
-PyAPI_FUNC(int)_PyImport_FixupExtensionUnicode(PyObject*, char *, PyObject *);
+PyAPI_FUNC(PyObject *)_PyImport_FindBuiltinExtension(char *);
+PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, PyObject *);
+PyAPI_FUNC(int)_PyImport_FixupBuiltinExtension(PyObject*, char *);
+PyAPI_FUNC(int)_PyImport_FixupExtension(PyObject*, char *, PyObject *);
struct _inittab {
char *name;
Modified: python/branches/import_unicode/Modules/signalmodule.c
==============================================================================
--- python/branches/import_unicode/Modules/signalmodule.c (original)
+++ python/branches/import_unicode/Modules/signalmodule.c Thu Sep 2 00:14:29 2010
@@ -932,7 +932,7 @@
{
PyObject *m = PyInit_signal();
if (m) {
- _PyImport_FixupExtension(m, "signal", "signal");
+ _PyImport_FixupBuiltinExtension(m, "signal");
Py_DECREF(m);
}
}
Modified: python/branches/import_unicode/Python/import.c
==============================================================================
--- python/branches/import_unicode/Python/import.c (original)
+++ python/branches/import_unicode/Python/import.c Thu Sep 2 00:14:29 2010
@@ -585,7 +585,7 @@
*/
int
-_PyImport_FixupExtensionUnicode(PyObject *mod, char *name, PyObject *filename)
+_PyImport_FixupExtension(PyObject *mod, char *name, PyObject *filename)
{
PyObject *modules, *dict;
struct PyModuleDef *def;
@@ -625,32 +625,30 @@
if (def->m_base.m_copy == NULL)
return -1;
}
- PyDict_SetItem(extensions, filename, (PyObject*)def);
+ if (filename != NULL)
+ PyDict_SetItem(extensions, filename, (PyObject*)def);
+ else
+ PyDict_SetItemString(extensions, name, (PyObject*)def);
return 0;
}
int
-_PyImport_FixupExtension(PyObject *mod, char *name, char *filename)
+_PyImport_FixupBuiltinExtension(PyObject *mod, char *name)
{
- PyObject *fileobj;
- int result;
- fileobj = PyUnicode_FromString(filename);
- if (fileobj == NULL)
- return -1;
- result = _PyImport_FixupExtensionUnicode(mod, name, fileobj);
- Py_DECREF(fileobj);
- return result;
+ return _PyImport_FixupExtension(mod, name, NULL);
}
-
PyObject *
-_PyImport_FindExtensionUnicode(char *name, PyObject *filename)
+_PyImport_FindExtension(char *name, PyObject *filename)
{
PyObject *mod, *mdict;
PyModuleDef* def;
if (extensions == NULL)
return NULL;
- def = (PyModuleDef*)PyDict_GetItem(extensions, filename);
+ if (filename != NULL)
+ def = (PyModuleDef*)PyDict_GetItem(extensions, filename);
+ else
+ def = (PyModuleDef*)PyDict_GetItemString(extensions, name);
if (def == NULL)
return NULL;
if (def->m_size == -1) {
@@ -680,23 +678,22 @@
Py_DECREF(mod);
return NULL;
}
- if (Py_VerboseFlag)
- PySys_FormatStderr("import %s # previously loaded (%U)\n",
- name, filename);
+ if (Py_VerboseFlag) {
+ if (filename != NULL)
+ PySys_FormatStderr("import %s # previously loaded (%U)\n",
+ name, filename);
+ else
+ PySys_FormatStderr("import %s\n", name);
+ }
return mod;
}
PyObject *
-_PyImport_FindExtension(char *name, char *filename)
+_PyImport_FindBuiltinExtension(char *name)
{
- PyObject *fileobj, *mod;
- fileobj = PyUnicode_DecodeFSDefault(filename);
- mod = _PyImport_FindExtensionUnicode(name, fileobj);
- Py_DECREF(fileobj);
- return mod;
+ return _PyImport_FindExtension(name, NULL);
}
-
/* Get the module object corresponding to a module name.
First check the modules dictionary if there's one there,
if not, create a new one and insert it in the modules dictionary.
@@ -2446,7 +2443,7 @@
PyObject *path;
path = PyUnicode_FromString(name);
- if (_PyImport_FindExtensionUnicode(name, path) != NULL) {
+ if (_PyImport_FindExtension(name, path) != NULL) {
Py_DECREF(path);
return 1;
}
@@ -2468,7 +2465,7 @@
Py_DECREF(path);
return -1;
}
- if (_PyImport_FixupExtensionUnicode(mod, name, path) < 0) {
+ if (_PyImport_FixupExtension(mod, name, path) < 0) {
Py_DECREF(path);
return -1;
}
Modified: python/branches/import_unicode/Python/importdl.c
==============================================================================
--- python/branches/import_unicode/Python/importdl.c (original)
+++ python/branches/import_unicode/Python/importdl.c Thu Sep 2 00:14:29 2010
@@ -28,7 +28,7 @@
PyObject* (*p)(void);
struct PyModuleDef *def;
- if ((m = _PyImport_FindExtensionUnicode(name, path)) != NULL) {
+ if ((m = _PyImport_FindExtension(name, path)) != NULL) {
Py_INCREF(m);
return m;
}
@@ -83,7 +83,7 @@
Py_DECREF(path);
}
- if (_PyImport_FixupExtensionUnicode(m, name, path) < 0)
+ if (_PyImport_FixupExtension(m, name, path) < 0)
return NULL;
if (Py_VerboseFlag)
PySys_FormatStderr(
Modified: python/branches/import_unicode/Python/pythonrun.c
==============================================================================
--- python/branches/import_unicode/Python/pythonrun.c (original)
+++ python/branches/import_unicode/Python/pythonrun.c Thu Sep 2 00:14:29 2010
@@ -240,7 +240,7 @@
bimod = _PyBuiltin_Init();
if (bimod == NULL)
Py_FatalError("Py_Initialize: can't initialize builtins modules");
- _PyImport_FixupExtension(bimod, "builtins", "builtins");
+ _PyImport_FixupBuiltinExtension(bimod, "builtins");
interp->builtins = PyModule_GetDict(bimod);
if (interp->builtins == NULL)
Py_FatalError("Py_Initialize: can't initialize builtins dict");
@@ -256,7 +256,7 @@
if (interp->sysdict == NULL)
Py_FatalError("Py_Initialize: can't initialize sys dict");
Py_INCREF(interp->sysdict);
- _PyImport_FixupExtension(sysmod, "sys", "sys");
+ _PyImport_FixupBuiltinExtension(sysmod, "sys");
PySys_SetPath(Py_GetPath());
PyDict_SetItemString(interp->sysdict, "modules",
interp->modules);
@@ -557,7 +557,7 @@
interp->modules = PyDict_New();
interp->modules_reloading = PyDict_New();
- bimod = _PyImport_FindExtension("builtins", "builtins");
+ bimod = _PyImport_FindBuiltinExtension("builtins");
if (bimod != NULL) {
interp->builtins = PyModule_GetDict(bimod);
if (interp->builtins == NULL)
@@ -568,7 +568,7 @@
/* initialize builtin exceptions */
_PyExc_Init();
- sysmod = _PyImport_FindExtension("sys", "sys");
+ sysmod = _PyImport_FindBuiltinExtension("sys");
if (bimod != NULL && sysmod != NULL) {
PyObject *pstderr;
interp->sysdict = PyModule_GetDict(sysmod);
From python-checkins at python.org Thu Sep 2 00:21:36 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 00:21:36 +0200 (CEST)
Subject: [Python-checkins] r84425 -
python/branches/release31-maint/Doc/glossary.rst
Message-ID: <20100901222136.744C2EE985@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 00:21:36 2010
New Revision: 84425
Log:
Glossary cleanup
Modified:
python/branches/release31-maint/Doc/glossary.rst
Modified: python/branches/release31-maint/Doc/glossary.rst
==============================================================================
--- python/branches/release31-maint/Doc/glossary.rst (original)
+++ python/branches/release31-maint/Doc/glossary.rst Thu Sep 2 00:21:36 2010
@@ -134,10 +134,9 @@
For more information about descriptors' methods, see :ref:`descriptors`.
dictionary
- An associative array, where arbitrary keys are mapped to values. The use
- of :class:`dict` closely resembles that for :class:`list`, but the keys can
- be any object with a :meth:`__hash__` function, not just integers.
- Called a hash in Perl.
+ An associative array, where arbitrary keys are mapped to values. The keys
+ can be any object with :meth:`__hash__` function and :meth:`__eq__`
+ methods. Called a hash in Perl.
docstring
A string literal which appears as the first expression in a class,
@@ -186,9 +185,11 @@
:term:`abstract base class`.
floor division
- Mathematical division discarding any remainder. The floor division
- operator is ``//``. For example, the expression ``11//4`` evaluates to
- ``2`` in contrast to the ``2.75`` returned by float true division.
+ Mathematical division that rounds down to nearest integer. The floor
+ division operator is ``//``. For example, the expression ``11 // 4``
+ evaluates to ``2`` in contrast to the ``2.75`` returned by float true
+ division. Note that ``(-11) // 4`` is ``-3`` because that is ``-2.75``
+ rounded *downward*. See :pep:`238`.
function
A series of statements which returns some value to a caller. It can also
@@ -196,7 +197,7 @@
the body. See also :term:`argument` and :term:`method`.
__future__
- A pseudo module which programmers can use to enable new language features
+ A pseudo-module which programmers can use to enable new language features
which are not compatible with the current interpreter.
By importing the :mod:`__future__` module and evaluating its variables,
@@ -214,13 +215,13 @@
generator
A function which returns an iterator. It looks like a normal function
- except that values are returned to the caller using a :keyword:`yield`
- statement instead of a :keyword:`return` statement. Generator functions
- often contain one or more :keyword:`for` or :keyword:`while` loops which
- :keyword:`yield` elements back to the caller. The function execution is
- stopped at the :keyword:`yield` keyword (returning the result) and is
- resumed there when the next element is requested by calling the
- :meth:`__next__` method of the returned iterator.
+ except that it contains :keyword:`yield` statements for producing a series
+ a values usable in a for-loop or that can be retrieved one at a time with
+ the :func:`next` function. Each :keyword:`yield` temporarily suspends
+ processing, remembering the location execution state (including local
+ variables and pending try-statements). When the generator resumes, it
+ picks-up where it left-off (in contrast to functions which start fresh on
+ every invocation.
.. index:: single: generator expression
@@ -265,9 +266,7 @@
IDLE
An Integrated Development Environment for Python. IDLE is a basic editor
and interpreter environment which ships with the standard distribution of
- Python. Good for beginners, it also serves as clear example code for
- those wanting to implement a moderately sophisticated, multi-platform GUI
- application.
+ Python.
immutable
An object with a fixed value. Immutable objects include numbers, strings and
@@ -369,7 +368,8 @@
mapping
A container object (such as :class:`dict`) which supports arbitrary key
- lookups using the special method :meth:`__getitem__`.
+ lookups using the special method :meth:`__getitem__`. Mappings also
+ support :meth:`__len__`, :meth:`__iter__`, and :meth:`__contains__`.
metaclass
The class of a class. Class definitions create a class name, a class
From python-checkins at python.org Thu Sep 2 00:25:41 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 00:25:41 +0200 (CEST)
Subject: [Python-checkins] r84426 -
python/branches/release27-maint/Doc/glossary.rst
Message-ID: <20100901222541.6C6D2EE98D@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 00:25:41 2010
New Revision: 84426
Log:
Glossary cleanup
Modified:
python/branches/release27-maint/Doc/glossary.rst
Modified: python/branches/release27-maint/Doc/glossary.rst
==============================================================================
--- python/branches/release27-maint/Doc/glossary.rst (original)
+++ python/branches/release27-maint/Doc/glossary.rst Thu Sep 2 00:25:41 2010
@@ -143,10 +143,9 @@
For more information about descriptors' methods, see :ref:`descriptors`.
dictionary
- An associative array, where arbitrary keys are mapped to values. The use
- of :class:`dict` closely resembles that for :class:`list`, but the keys can
- be any object with a :meth:`__hash__` function, not just integers.
- Called a hash in Perl.
+ An associative array, where arbitrary keys are mapped to values. The keys
+ can be any object with :meth:`__hash__` function and :meth:`__eq__`
+ methods. Called a hash in Perl.
docstring
A string literal which appears as the first expression in a class,
@@ -193,13 +192,20 @@
implement a method named :meth:`find_module`. See :pep:`302` for
details.
+ floor division
+ Mathematical division that rounds down to nearest integer. The floor
+ division operator is ``//``. For example, the expression ``11 // 4``
+ evaluates to ``2`` in contrast to the ``2.75`` returned by float true
+ division. Note that ``(-11) // 4`` is ``-3`` because that is ``-2.75``
+ rounded *downward*. See :pep:`238`.
+
function
A series of statements which returns some value to a caller. It can also
be passed zero or more arguments which may be used in the execution of
the body. See also :term:`argument` and :term:`method`.
__future__
- A pseudo module which programmers can use to enable new language features
+ A pseudo-module which programmers can use to enable new language features
which are not compatible with the current interpreter. For example, the
expression ``11/4`` currently evaluates to ``2``. If the module in which
it is executed had enabled *true division* by executing::
@@ -224,13 +230,13 @@
generator
A function which returns an iterator. It looks like a normal function
- except that values are returned to the caller using a :keyword:`yield`
- statement instead of a :keyword:`return` statement. Generator functions
- often contain one or more :keyword:`for` or :keyword:`while` loops which
- :keyword:`yield` elements back to the caller. The function execution is
- stopped at the :keyword:`yield` keyword (returning the result) and is
- resumed there when the next element is requested by calling the
- :meth:`next` method of the returned iterator.
+ except that it contains :keyword:`yield` statements for producing a series
+ a values usable in a for-loop or that can be retrieved one at a time with
+ the :func:`next` function. Each :keyword:`yield` temporarily suspends
+ processing, remembering the location execution state (including local
+ variables and pending try-statements). When the generator resumes, it
+ picks-up where it left-off (in contrast to functions which start fresh on
+ every invocation).
.. index:: single: generator expression
@@ -275,9 +281,7 @@
IDLE
An Integrated Development Environment for Python. IDLE is a basic editor
and interpreter environment which ships with the standard distribution of
- Python. Good for beginners, it also serves as clear example code for
- those wanting to implement a moderately sophisticated, multi-platform GUI
- application.
+ Python.
immutable
An object with a fixed value. Immutable objects include numbers, strings and
@@ -389,7 +393,8 @@
mapping
A container object (such as :class:`dict`) which supports arbitrary key
- lookups using the special method :meth:`__getitem__`.
+ lookups using the special method :meth:`__getitem__`. Mappings also
+ support :meth:`__len__`, :meth:`__iter__`, and :meth:`__contains__`.
metaclass
The class of a class. Class definitions create a class name, a class
From python-checkins at python.org Thu Sep 2 00:37:17 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 00:37:17 +0200 (CEST)
Subject: [Python-checkins] r84427 - in python/branches/release27-maint/Doc:
conf.py tools/sphinxext/indexcontent.html using/index.rst
Message-ID: <20100901223717.5FBF9EEAFC@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 00:37:17 2010
New Revision: 84427
Log:
More descriptive title.
Modified:
python/branches/release27-maint/Doc/conf.py
python/branches/release27-maint/Doc/tools/sphinxext/indexcontent.html
python/branches/release27-maint/Doc/using/index.rst
Modified: python/branches/release27-maint/Doc/conf.py
==============================================================================
--- python/branches/release27-maint/Doc/conf.py (original)
+++ python/branches/release27-maint/Doc/conf.py Thu Sep 2 00:37:17 2010
@@ -125,7 +125,7 @@
('tutorial/index', 'tutorial.tex',
'Python Tutorial', _stdauthor, 'manual'),
('using/index', 'using.tex',
- 'Using Python', _stdauthor, 'manual'),
+ 'Python Setup', _stdauthor, 'manual'),
('whatsnew/' + version, 'whatsnew.tex',
'What\'s New in Python', 'A. M. Kuchling', 'howto'),
]
Modified: python/branches/release27-maint/Doc/tools/sphinxext/indexcontent.html
==============================================================================
--- python/branches/release27-maint/Doc/tools/sphinxext/indexcontent.html (original)
+++ python/branches/release27-maint/Doc/tools/sphinxext/indexcontent.html Thu Sep 2 00:37:17 2010
@@ -7,12 +7,12 @@
or all "What's new" documents since 2.0
Tutorial
start here
- Using Python
- how to use Python on different platforms
Library Reference
keep this under your pillow
Language Reference
describes syntax and language elements
+ Python Setup
+ how to use Python on different platforms
Python HOWTOs
in-depth documents on specific topics
Modified: python/branches/release27-maint/Doc/using/index.rst
==============================================================================
--- python/branches/release27-maint/Doc/using/index.rst (original)
+++ python/branches/release27-maint/Doc/using/index.rst Thu Sep 2 00:37:17 2010
@@ -1,7 +1,7 @@
.. _using-index:
################
- Using Python
+ Python Setup
################
From python-checkins at python.org Thu Sep 2 00:52:25 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 00:52:25 +0200 (CEST)
Subject: [Python-checkins] r84428 - in python/branches/release31-maint/Doc:
conf.py tools/sphinxext/indexcontent.html using/index.rst
Message-ID: <20100901225225.ED117EE981@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 00:52:25 2010
New Revision: 84428
Log:
More descriptive title.
Modified:
python/branches/release31-maint/Doc/conf.py
python/branches/release31-maint/Doc/tools/sphinxext/indexcontent.html
python/branches/release31-maint/Doc/using/index.rst
Modified: python/branches/release31-maint/Doc/conf.py
==============================================================================
--- python/branches/release31-maint/Doc/conf.py (original)
+++ python/branches/release31-maint/Doc/conf.py Thu Sep 2 00:52:25 2010
@@ -128,7 +128,7 @@
('tutorial/index', 'tutorial.tex',
'Python Tutorial', _stdauthor, 'manual'),
('using/index', 'using.tex',
- 'Using Python', _stdauthor, 'manual'),
+ 'Python Setup', _stdauthor, 'manual'),
('whatsnew/' + version, 'whatsnew.tex',
'What\'s New in Python', 'A. M. Kuchling', 'howto'),
]
Modified: python/branches/release31-maint/Doc/tools/sphinxext/indexcontent.html
==============================================================================
--- python/branches/release31-maint/Doc/tools/sphinxext/indexcontent.html (original)
+++ python/branches/release31-maint/Doc/tools/sphinxext/indexcontent.html Thu Sep 2 00:52:25 2010
@@ -7,12 +7,12 @@
or all "What's new" documents since 2.0
Tutorial
start here
- Using Python
- how to use Python on different platforms
Library Reference
keep this under your pillow
Language Reference
describes syntax and language elements
+ Python Setup
+ how to use Python on different platforms
Python HOWTOs
in-depth documents on specific topics
Modified: python/branches/release31-maint/Doc/using/index.rst
==============================================================================
--- python/branches/release31-maint/Doc/using/index.rst (original)
+++ python/branches/release31-maint/Doc/using/index.rst Thu Sep 2 00:52:25 2010
@@ -1,7 +1,7 @@
.. _using-index:
################
- Using Python
+ Python Setup
################
From python-checkins at python.org Thu Sep 2 01:43:50 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 01:43:50 +0200 (CEST)
Subject: [Python-checkins] r84429 - in python/branches/py3k:
Include/unicodeobject.h Objects/unicodeobject.c
Message-ID: <20100901234350.C1A65EEAD0@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 01:43:50 2010
New Revision: 84429
Log:
Create Py_UNICODE_strcat() function
Modified:
python/branches/py3k/Include/unicodeobject.h
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h (original)
+++ python/branches/py3k/Include/unicodeobject.h Thu Sep 2 01:43:50 2010
@@ -1573,6 +1573,9 @@
Py_UNICODE *s1,
const Py_UNICODE *s2);
+PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strcat(
+ Py_UNICODE *s1, const Py_UNICODE *s2);
+
PyAPI_FUNC(Py_UNICODE*) Py_UNICODE_strncpy(
Py_UNICODE *s1,
const Py_UNICODE *s2,
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Thu Sep 2 01:43:50 2010
@@ -9951,6 +9951,15 @@
return s1;
}
+Py_UNICODE*
+Py_UNICODE_strcat(Py_UNICODE *s1, const Py_UNICODE *s2)
+{
+ Py_UNICODE *u1 = s1;
+ u1 += Py_UNICODE_strlen(u1);
+ Py_UNICODE_strcpy(u1, s2);
+ return s1;
+}
+
int
Py_UNICODE_strcmp(const Py_UNICODE *s1, const Py_UNICODE *s2)
{
From python-checkins at python.org Thu Sep 2 01:43:53 2010
From: python-checkins at python.org (victor.stinner)
Date: Thu, 2 Sep 2010 01:43:53 +0200 (CEST)
Subject: [Python-checkins] r84430 - in python/branches/py3k:
Include/unicodeobject.h Objects/unicodeobject.c
Message-ID: <20100901234353.468A5EEAAC@mail.python.org>
Author: victor.stinner
Date: Thu Sep 2 01:43:53 2010
New Revision: 84430
Log:
Create PyUnicode_strdup() function
Modified:
python/branches/py3k/Include/unicodeobject.h
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h (original)
+++ python/branches/py3k/Include/unicodeobject.h Thu Sep 2 01:43:53 2010
@@ -220,6 +220,7 @@
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS2_AsDefaultEncodedString
# define _PyUnicode_Fini _PyUnicodeUCS2_Fini
# define _PyUnicode_Init _PyUnicodeUCS2_Init
+# define PyUnicode_strdup PyUnicodeUCS2_strdup
#else
@@ -302,7 +303,7 @@
# define _PyUnicode_AsDefaultEncodedString _PyUnicodeUCS4_AsDefaultEncodedString
# define _PyUnicode_Fini _PyUnicodeUCS4_Fini
# define _PyUnicode_Init _PyUnicodeUCS4_Init
-
+# define PyUnicode_strdup PyUnicodeUCS4_strdup
#endif
@@ -1602,6 +1603,14 @@
Py_UNICODE c
);
+/* Create a copy of a unicode string ending with a nul character. Return NULL
+ and raise a MemoryError exception on memory allocation failure, otherwise
+ return a new allocated buffer (use PyMem_Free() to free the buffer). */
+
+PyAPI_FUNC(Py_UNICODE*) PyUnicode_strdup(
+ PyObject *unicode
+ );
+
#ifdef __cplusplus
}
#endif
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Thu Sep 2 01:43:53 2010
@@ -10014,6 +10014,28 @@
return NULL;
}
+Py_UNICODE*
+PyUnicode_strdup(PyObject *object)
+{
+ PyUnicodeObject *unicode = (PyUnicodeObject *)object;
+ Py_UNICODE *copy;
+ Py_ssize_t size;
+
+ /* Ensure we won't overflow the size. */
+ if (PyUnicode_GET_SIZE(unicode) > ((PY_SSIZE_T_MAX / sizeof(Py_UNICODE)) - 1)) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ size = PyUnicode_GET_SIZE(unicode) + 1; /* copy the nul character */
+ size *= sizeof(Py_UNICODE);
+ copy = PyMem_Malloc(size);
+ if (copy == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memcpy(copy, PyUnicode_AS_UNICODE(unicode), size);
+ return copy;
+}
#ifdef __cplusplus
}
From solipsis at pitrou.net Thu Sep 2 05:02:41 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Thu, 02 Sep 2010 05:02:41 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84430): sum=0
Message-ID:
py3k results for svn r84430 (hg cset aabd2132bb90)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog-hkpsv', '-x']
From python-checkins at python.org Thu Sep 2 11:17:32 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 11:17:32 +0200 (CEST)
Subject: [Python-checkins] r84431 -
python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
Message-ID: <20100902091732.10276EE99C@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 11:17:31 2010
New Revision: 84431
Log:
Keep contents order the same between versions.
Modified:
python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
Modified: python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
==============================================================================
--- python/branches/py3k/Doc/tools/sphinxext/indexcontent.html (original)
+++ python/branches/py3k/Doc/tools/sphinxext/indexcontent.html Thu Sep 2 11:17:31 2010
@@ -11,10 +11,10 @@
keep this under your pillow
Language Reference
describes syntax and language elements
- Python HOWTOs
- in-depth documents on specific topics
Python Setup
how to use Python on different platforms
+ Python HOWTOs
+ in-depth documents on specific topics
Extending and Embedding
tutorial for C/C++ programmers
From python-checkins at python.org Thu Sep 2 11:44:29 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 11:44:29 +0200 (CEST)
Subject: [Python-checkins] r84432 - in python/branches/py3k/Lib:
collections.py functools.py
Message-ID: <20100902094429.2EAC4FAEF@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 11:44:28 2010
New Revision: 84432
Log:
Speed-up cache updates
Modified:
python/branches/py3k/Lib/collections.py
python/branches/py3k/Lib/functools.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Thu Sep 2 11:44:28 2010
@@ -161,6 +161,19 @@
def __del__(self):
self.clear() # eliminate cyclical references
+ def _move_to_end(self, key, PREV=0, NEXT=1):
+ 'Fast version of self[key]=self.pop(key). Private method for internal use.'
+ link = self.__map[key]
+ link_prev = link[PREV]
+ link_next = link[NEXT]
+ link_prev[NEXT] = link_next
+ link_next[PREV] = link_prev
+ root = self.__root
+ last = root[PREV]
+ link[PREV] = last
+ link[NEXT] = root
+ last[NEXT] = root[PREV] = link
+
################################################################################
### namedtuple
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Thu Sep 2 11:44:28 2010
@@ -139,8 +139,7 @@
try:
with lock:
result = cache[key]
- del cache[key]
- cache[key] = result # record recent use of this key
+ cache._move_to_end(key) # record recent use of this key
wrapper.hits += 1
except KeyError:
result = user_function(*args, **kwds)
From python-checkins at python.org Thu Sep 2 16:57:19 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Thu, 2 Sep 2010 16:57:19 +0200 (CEST)
Subject: [Python-checkins] r84433 - peps/trunk/pep-0007.txt
Message-ID: <20100902145719.0445AEE984@mail.python.org>
Author: daniel.stutzbach
Date: Thu Sep 2 16:57:18 2010
New Revision: 84433
Log:
Updated PEP-0007 to refer to PyAPI_FUNC instead of DL_IMPORT, which
was deprecated in Python 2.3.
Modified:
peps/trunk/pep-0007.txt
Modified: peps/trunk/pep-0007.txt
==============================================================================
--- peps/trunk/pep-0007.txt (original)
+++ peps/trunk/pep-0007.txt Thu Sep 2 16:57:18 2010
@@ -121,9 +121,9 @@
- For external functions and variables, we always have a
declaration in an appropriate header file in the "Include"
- directory, which uses the DL_IMPORT() macro, like this:
+ directory, which uses the PyAPI_FUNC() macro, like this:
- extern DL_IMPORT(PyObject *) PyObject_Repr(PyObject *);
+ PyAPI_FUNC(PyObject *) PyObject_Repr(PyObject *);
Naming conventions
From python-checkins at python.org Thu Sep 2 17:06:03 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Thu, 2 Sep 2010 17:06:03 +0200 (CEST)
Subject: [Python-checkins] r84434 - python/branches/py3k/Objects/setobject.c
Message-ID: <20100902150603.321DFEEA24@mail.python.org>
Author: daniel.stutzbach
Date: Thu Sep 2 17:06:03 2010
New Revision: 84434
Log:
Removed an extraneous semicolon
Modified:
python/branches/py3k/Objects/setobject.c
Modified: python/branches/py3k/Objects/setobject.c
==============================================================================
--- python/branches/py3k/Objects/setobject.c (original)
+++ python/branches/py3k/Objects/setobject.c Thu Sep 2 17:06:03 2010
@@ -1439,7 +1439,7 @@
while ((key = PyIter_Next(it)) != NULL) {
int rv;
setentry entry;
- long hash = PyObject_Hash(key);;
+ long hash = PyObject_Hash(key);
if (hash == -1) {
Py_DECREF(key);
From python-checkins at python.org Thu Sep 2 17:06:06 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Thu, 2 Sep 2010 17:06:06 +0200 (CEST)
Subject: [Python-checkins] r84435 - in python/branches/py3k:
Doc/library/stdtypes.rst Lib/test/test_dictviews.py Misc/NEWS
Objects/dictobject.c
Message-ID: <20100902150606.ABF1AEEA24@mail.python.org>
Author: daniel.stutzbach
Date: Thu Sep 2 17:06:06 2010
New Revision: 84435
Log:
Issue #9212: Added the missing isdisjoint method to the dict_keys and
dict_items views. The method is required by the collections.Set ABC,
which the views register as supporting.
Modified:
python/branches/py3k/Doc/library/stdtypes.rst
python/branches/py3k/Lib/test/test_dictviews.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/dictobject.c
Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst (original)
+++ python/branches/py3k/Doc/library/stdtypes.rst Thu Sep 2 17:06:06 2010
@@ -2216,6 +2216,11 @@
Return the symmetric difference (all elements either in *dictview* or
*other*, but not in both) of the dictview and the other object as a new set.
+.. method:: dictview.isdisjoint(other)
+
+ Return True if the view has no elements in common with *other*. Sets are
+ disjoint if and only if their intersection is the empty set.
+
An example of dictionary view usage::
Modified: python/branches/py3k/Lib/test/test_dictviews.py
==============================================================================
--- python/branches/py3k/Lib/test/test_dictviews.py (original)
+++ python/branches/py3k/Lib/test/test_dictviews.py Thu Sep 2 17:06:06 2010
@@ -112,6 +112,24 @@
self.assertEqual(d1.keys() ^ set(d3.keys()),
{'a', 'b', 'd', 'e'})
+ self.assertFalse(d1.keys().isdisjoint(d1.keys()))
+ self.assertFalse(d1.keys().isdisjoint(d2.keys()))
+ self.assertFalse(d1.keys().isdisjoint(list(d2.keys())))
+ self.assertFalse(d1.keys().isdisjoint(set(d2.keys())))
+ self.assertTrue(d1.keys().isdisjoint({'x', 'y', 'z'}))
+ self.assertTrue(d1.keys().isdisjoint(['x', 'y', 'z']))
+ self.assertTrue(d1.keys().isdisjoint(set(['x', 'y', 'z'])))
+ self.assertTrue(d1.keys().isdisjoint(set(['x', 'y'])))
+ self.assertTrue(d1.keys().isdisjoint(['x', 'y']))
+ self.assertTrue(d1.keys().isdisjoint({}))
+ self.assertTrue(d1.keys().isdisjoint(d3.keys()))
+
+ de = {}
+ self.assertTrue(de.keys().isdisjoint(set()))
+ self.assertTrue(de.keys().isdisjoint([]))
+ self.assertTrue(de.keys().isdisjoint(de.keys()))
+ self.assertTrue(de.keys().isdisjoint([1]))
+
def test_items_set_operations(self):
d1 = {'a': 1, 'b': 2}
d2 = {'a': 2, 'b': 2}
@@ -144,6 +162,23 @@
self.assertEqual(d1.items() ^ d3.items(),
{('a', 1), ('b', 2), ('d', 4), ('e', 5)})
+ self.assertFalse(d1.items().isdisjoint(d1.items()))
+ self.assertFalse(d1.items().isdisjoint(d2.items()))
+ self.assertFalse(d1.items().isdisjoint(list(d2.items())))
+ self.assertFalse(d1.items().isdisjoint(set(d2.items())))
+ self.assertTrue(d1.items().isdisjoint({'x', 'y', 'z'}))
+ self.assertTrue(d1.items().isdisjoint(['x', 'y', 'z']))
+ self.assertTrue(d1.items().isdisjoint(set(['x', 'y', 'z'])))
+ self.assertTrue(d1.items().isdisjoint(set(['x', 'y'])))
+ self.assertTrue(d1.items().isdisjoint({}))
+ self.assertTrue(d1.items().isdisjoint(d3.items()))
+
+ de = {}
+ self.assertTrue(de.items().isdisjoint(set()))
+ self.assertTrue(de.items().isdisjoint([]))
+ self.assertTrue(de.items().isdisjoint(de.items()))
+ self.assertTrue(de.items().isdisjoint([1]))
+
def test_main():
support.run_unittest(DictSetTest)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Thu Sep 2 17:06:06 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #9212: dict_keys and dict_items now provide the isdisjoint()
+ method, to conform to the Set ABC.
+
- Issue #9737: Fix a crash when trying to delete a slice or an item from
a memoryview object.
Modified: python/branches/py3k/Objects/dictobject.c
==============================================================================
--- python/branches/py3k/Objects/dictobject.c (original)
+++ python/branches/py3k/Objects/dictobject.c Thu Sep 2 17:06:06 2010
@@ -2807,7 +2807,63 @@
(binaryfunc)dictviews_or, /*nb_or*/
};
+static PyObject*
+dictviews_isdisjoint(PyObject *self, PyObject *other)
+{
+ PyObject *it;
+ PyObject *item = NULL;
+
+ if (self == other) {
+ if (dictview_len((dictviewobject *)self) == 0)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ }
+
+ /* Iterate over the shorter object (only if other is a set,
+ * because PySequence_Contains may be expensive otherwise): */
+ if (PyAnySet_Check(other) || PyDictViewSet_Check(other)) {
+ Py_ssize_t len_self = dictview_len((dictviewobject *)self);
+ Py_ssize_t len_other = PyObject_Size(other);
+ if (len_other == -1)
+ return NULL;
+
+ if ((len_other > len_self)) {
+ PyObject *tmp = other;
+ other = self;
+ self = tmp;
+ }
+ }
+
+ it = PyObject_GetIter(other);
+ if (it == NULL)
+ return NULL;
+
+ while ((item = PyIter_Next(it)) != NULL) {
+ int contains = PySequence_Contains(self, item);
+ Py_DECREF(item);
+ if (contains == -1) {
+ Py_DECREF(it);
+ return NULL;
+ }
+
+ if (contains) {
+ Py_DECREF(it);
+ Py_RETURN_FALSE;
+ }
+ }
+ Py_DECREF(it);
+ if (PyErr_Occurred())
+ return NULL; /* PyIter_Next raised an exception. */
+ Py_RETURN_TRUE;
+}
+
+PyDoc_STRVAR(isdisjoint_doc,
+"Return True if the view and the given iterable have a null intersection.");
+
static PyMethodDef dictkeys_methods[] = {
+ {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
+ isdisjoint_doc},
{NULL, NULL} /* sentinel */
};
@@ -2892,6 +2948,8 @@
};
static PyMethodDef dictitems_methods[] = {
+ {"isdisjoint", (PyCFunction)dictviews_isdisjoint, METH_O,
+ isdisjoint_doc},
{NULL, NULL} /* sentinel */
};
From python-checkins at python.org Thu Sep 2 17:13:35 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Thu, 2 Sep 2010 17:13:35 +0200 (CEST)
Subject: [Python-checkins] r84436 - python/branches/py3k/Misc/NEWS
Message-ID: <20100902151335.D1568EE98A@mail.python.org>
Author: daniel.stutzbach
Date: Thu Sep 2 17:13:35 2010
New Revision: 84436
Log:
Credit where credit is due
Modified:
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Thu Sep 2 17:13:35 2010
@@ -13,7 +13,7 @@
-----------------
- Issue #9212: dict_keys and dict_items now provide the isdisjoint()
- method, to conform to the Set ABC.
+ method, to conform to the Set ABC. Patch by Daniel Urban.
- Issue #9737: Fix a crash when trying to delete a slice or an item from
a memoryview object.
From python-checkins at python.org Thu Sep 2 20:44:16 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 20:44:16 +0200 (CEST)
Subject: [Python-checkins] r84437 - python/branches/py3k/Lib/collections.py
Message-ID: <20100902184416.4CCFBF80D@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 20:44:16 2010
New Revision: 84437
Log:
Make OrderedDict.popitem() a bit smarter and faster
Modified:
python/branches/py3k/Lib/collections.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Thu Sep 2 20:44:16 2010
@@ -108,25 +108,37 @@
pass
dict.clear(self)
- setdefault = MutableMapping.setdefault
- update = MutableMapping.update
- pop = MutableMapping.pop
- keys = MutableMapping.keys
- values = MutableMapping.values
- items = MutableMapping.items
- __ne__ = MutableMapping.__ne__
-
- def popitem(self, last=True):
+ def popitem(self, last=True, PREV=0, NEXT=1, KEY=2, dict_pop=dict.pop):
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
Pairs are returned in LIFO order if last is true or FIFO order if false.
'''
if not self:
raise KeyError('dictionary is empty')
- key = next(reversed(self) if last else iter(self))
- value = self.pop(key)
+ root = self.__root
+ if last: # link_prev <--> link <--> root
+ link = root[PREV]
+ link_prev = link[PREV]
+ link_prev[NEXT] = root
+ root[PREV] = link_prev
+ else: # root <--> link <--> link_next
+ link = root[NEXT]
+ link_next = link[NEXT]
+ root[NEXT] = link_next
+ link_next[PREV] = root
+ key = link[KEY]
+ del self.__map[key]
+ value = dict_pop(self, key)
return key, value
+ setdefault = MutableMapping.setdefault
+ update = MutableMapping.update
+ pop = MutableMapping.pop
+ keys = MutableMapping.keys
+ values = MutableMapping.values
+ items = MutableMapping.items
+ __ne__ = MutableMapping.__ne__
+
def __repr__(self):
'od.__repr__() <==> repr(od)'
if not self:
From python-checkins at python.org Thu Sep 2 21:48:07 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 2 Sep 2010 21:48:07 +0200 (CEST)
Subject: [Python-checkins] r84438 - in python/branches/py3k/Modules/_io:
bytesio.c stringio.c
Message-ID: <20100902194807.D0691EE984@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 2 21:48:07 2010
New Revision: 84438
Log:
BytesIO.getvalue() and StringIO.getvalue() are METH_NOARGS.
Modified:
python/branches/py3k/Modules/_io/bytesio.c
python/branches/py3k/Modules/_io/stringio.c
Modified: python/branches/py3k/Modules/_io/bytesio.c
==============================================================================
--- python/branches/py3k/Modules/_io/bytesio.c (original)
+++ python/branches/py3k/Modules/_io/bytesio.c Thu Sep 2 21:48:07 2010
@@ -818,7 +818,7 @@
{"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
{"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
{"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
- {"getvalue", (PyCFunction)bytesio_getvalue, METH_VARARGS, getval_doc},
+ {"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc},
{"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
{"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
{"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
Modified: python/branches/py3k/Modules/_io/stringio.c
==============================================================================
--- python/branches/py3k/Modules/_io/stringio.c (original)
+++ python/branches/py3k/Modules/_io/stringio.c Thu Sep 2 21:48:07 2010
@@ -827,7 +827,7 @@
static struct PyMethodDef stringio_methods[] = {
{"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc},
- {"getvalue", (PyCFunction)stringio_getvalue, METH_VARARGS, stringio_getvalue_doc},
+ {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc},
{"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc},
{"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc},
{"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc},
From python-checkins at python.org Thu Sep 2 21:56:28 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 21:56:28 +0200 (CEST)
Subject: [Python-checkins] r84439 - in python/branches/py3k/Lib:
collections.py functools.py
Message-ID: <20100902195628.429FBEE99C@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 21:56:28 2010
New Revision: 84439
Log:
Better method name. Tighten inner-loop with bound methods.
Modified:
python/branches/py3k/Lib/collections.py
python/branches/py3k/Lib/functools.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Thu Sep 2 21:56:28 2010
@@ -173,7 +173,7 @@
def __del__(self):
self.clear() # eliminate cyclical references
- def _move_to_end(self, key, PREV=0, NEXT=1):
+ def _renew(self, key, PREV=0, NEXT=1):
'Fast version of self[key]=self.pop(key). Private method for internal use.'
link = self.__map[key]
link_prev = link[PREV]
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Thu Sep 2 21:56:28 2010
@@ -128,6 +128,7 @@
def decorating_function(user_function, tuple=tuple, sorted=sorted,
len=len, KeyError=KeyError):
cache = OrderedDict() # ordered least recent to most recent
+ cache_popitem, cache_renew = cache.popitem, cache._renew
kwd_mark = object() # separate positional and keyword args
lock = Lock()
@@ -139,7 +140,7 @@
try:
with lock:
result = cache[key]
- cache._move_to_end(key) # record recent use of this key
+ cache_renew(key) # record recent use of this key
wrapper.hits += 1
except KeyError:
result = user_function(*args, **kwds)
@@ -147,7 +148,7 @@
cache[key] = result # record recent use of this key
wrapper.misses += 1
if len(cache) > maxsize:
- cache.popitem(0) # purge least recently used cache entry
+ cache_popitem(0) # purge least recently used cache entry
return result
def clear():
From python-checkins at python.org Thu Sep 2 21:58:35 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 2 Sep 2010 21:58:35 +0200 (CEST)
Subject: [Python-checkins] r84440 - python/branches/py3k/Lib/functools.py
Message-ID: <20100902195835.3CD4CEE99C@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 2 21:58:35 2010
New Revision: 84440
Log:
Readability nit.
Modified:
python/branches/py3k/Lib/functools.py
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Thu Sep 2 21:58:35 2010
@@ -128,7 +128,8 @@
def decorating_function(user_function, tuple=tuple, sorted=sorted,
len=len, KeyError=KeyError):
cache = OrderedDict() # ordered least recent to most recent
- cache_popitem, cache_renew = cache.popitem, cache._renew
+ cache_popitem = cache.popitem
+ cache_renew = cache._renew
kwd_mark = object() # separate positional and keyword args
lock = Lock()
From python-checkins at python.org Fri Sep 3 00:21:32 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 00:21:32 +0200 (CEST)
Subject: [Python-checkins] r84441 - in python/branches/release31-maint:
Modules/_io/bytesio.c Modules/_io/stringio.c
Message-ID: <20100902222132.6D282EEB02@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 00:21:32 2010
New Revision: 84441
Log:
Merged revisions 84438 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84438 | antoine.pitrou | 2010-09-02 21:48:07 +0200 (jeu., 02 sept. 2010) | 3 lines
BytesIO.getvalue() and StringIO.getvalue() are METH_NOARGS.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Modules/_io/bytesio.c
python/branches/release31-maint/Modules/_io/stringio.c
Modified: python/branches/release31-maint/Modules/_io/bytesio.c
==============================================================================
--- python/branches/release31-maint/Modules/_io/bytesio.c (original)
+++ python/branches/release31-maint/Modules/_io/bytesio.c Fri Sep 3 00:21:32 2010
@@ -704,7 +704,7 @@
{"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
{"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
{"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
- {"getvalue", (PyCFunction)bytesio_getvalue, METH_VARARGS, getval_doc},
+ {"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc},
{"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
{"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
{NULL, NULL} /* sentinel */
Modified: python/branches/release31-maint/Modules/_io/stringio.c
==============================================================================
--- python/branches/release31-maint/Modules/_io/stringio.c (original)
+++ python/branches/release31-maint/Modules/_io/stringio.c Fri Sep 3 00:21:32 2010
@@ -698,7 +698,7 @@
static struct PyMethodDef stringio_methods[] = {
{"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc},
- {"getvalue", (PyCFunction)stringio_getvalue, METH_VARARGS, stringio_getvalue_doc},
+ {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc},
{"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc},
{"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc},
{"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc},
From python-checkins at python.org Fri Sep 3 00:23:19 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 00:23:19 +0200 (CEST)
Subject: [Python-checkins] r84442 - in python/branches/release27-maint:
Modules/_io/bytesio.c Modules/_io/stringio.c
Message-ID: <20100902222319.7ACDBEEA5D@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 00:23:19 2010
New Revision: 84442
Log:
Merged revisions 84438 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84438 | antoine.pitrou | 2010-09-02 21:48:07 +0200 (jeu., 02 sept. 2010) | 3 lines
BytesIO.getvalue() and StringIO.getvalue() are METH_NOARGS.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Modules/_io/bytesio.c
python/branches/release27-maint/Modules/_io/stringio.c
Modified: python/branches/release27-maint/Modules/_io/bytesio.c
==============================================================================
--- python/branches/release27-maint/Modules/_io/bytesio.c (original)
+++ python/branches/release27-maint/Modules/_io/bytesio.c Fri Sep 3 00:23:19 2010
@@ -825,7 +825,7 @@
{"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
{"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
{"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
- {"getvalue", (PyCFunction)bytesio_getvalue, METH_VARARGS, getval_doc},
+ {"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc},
{"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
{"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
{"__getstate__", (PyCFunction)bytesio_getstate, METH_NOARGS, NULL},
Modified: python/branches/release27-maint/Modules/_io/stringio.c
==============================================================================
--- python/branches/release27-maint/Modules/_io/stringio.c (original)
+++ python/branches/release27-maint/Modules/_io/stringio.c Fri Sep 3 00:23:19 2010
@@ -809,7 +809,7 @@
static struct PyMethodDef stringio_methods[] = {
{"close", (PyCFunction)stringio_close, METH_NOARGS, stringio_close_doc},
- {"getvalue", (PyCFunction)stringio_getvalue, METH_VARARGS, stringio_getvalue_doc},
+ {"getvalue", (PyCFunction)stringio_getvalue, METH_NOARGS, stringio_getvalue_doc},
{"read", (PyCFunction)stringio_read, METH_VARARGS, stringio_read_doc},
{"readline", (PyCFunction)stringio_readline, METH_VARARGS, stringio_readline_doc},
{"tell", (PyCFunction)stringio_tell, METH_NOARGS, stringio_tell_doc},
From solipsis at pitrou.net Fri Sep 3 05:02:36 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Fri, 03 Sep 2010 05:02:36 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84440): sum=0
Message-ID:
py3k results for svn r84440 (hg cset 38425b522554)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogHYQbeb', '-x']
From python-checkins at python.org Fri Sep 3 05:55:50 2010
From: python-checkins at python.org (fred.drake)
Date: Fri, 3 Sep 2010 05:55:50 +0200 (CEST)
Subject: [Python-checkins] r84443 - in python/branches/release27-maint:
Lib/ConfigParser.py Lib/test/test_cfgparser.py Misc/NEWS
Message-ID: <20100903035550.ED98FEE99E@mail.python.org>
Author: fred.drake
Date: Fri Sep 3 05:55:50 2010
New Revision: 84443
Log:
fix output from RawConfigParser.write and ConfigParser.write for None
values (http://bugs.python.org/issue7005)
Modified:
python/branches/release27-maint/Lib/ConfigParser.py
python/branches/release27-maint/Lib/test/test_cfgparser.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/ConfigParser.py
==============================================================================
--- python/branches/release27-maint/Lib/ConfigParser.py (original)
+++ python/branches/release27-maint/Lib/ConfigParser.py Fri Sep 3 05:55:50 2010
@@ -400,7 +400,7 @@
for (key, value) in self._sections[section].items():
if key == "__name__":
continue
- if value is not None:
+ if (value is not None) or (self._optcre == self.OPTCRE):
key = " = ".join((key, str(value).replace('\n', '\n\t')))
fp.write("%s\n" % (key))
fp.write("\n")
Modified: python/branches/release27-maint/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_cfgparser.py (original)
+++ python/branches/release27-maint/Lib/test/test_cfgparser.py Fri Sep 3 05:55:50 2010
@@ -530,6 +530,33 @@
allow_no_value = True
+class Issue7005TestCase(unittest.TestCase):
+ """Test output when None is set() as a value and allow_no_value == False.
+
+ http://bugs.python.org/issue7005
+
+ """
+
+ expected_output = "[section]\noption = None\n\n"
+
+ def prepare(self, config_class):
+ # This is the default, but that's the point.
+ cp = config_class(allow_no_value=False)
+ cp.add_section("section")
+ cp.set("section", "option", None)
+ sio = StringIO.StringIO()
+ cp.write(sio)
+ return sio.getvalue()
+
+ def test_none_as_value_stringified(self):
+ output = self.prepare(ConfigParser.ConfigParser)
+ self.assertEqual(output, self.expected_output)
+
+ def test_none_as_value_stringified_raw(self):
+ output = self.prepare(ConfigParser.RawConfigParser)
+ self.assertEqual(output, self.expected_output)
+
+
class SortedTestCase(RawConfigParserTestCase):
def newconfig(self, defaults=None):
self.cf = self.config_class(defaults=defaults, dict_type=SortedDict)
@@ -563,6 +590,7 @@
SafeConfigParserTestCase,
SafeConfigParserTestCaseNoValue,
SortedTestCase,
+ Issue7005TestCase,
)
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Fri Sep 3 05:55:50 2010
@@ -36,6 +36,9 @@
Library
-------
+- Issue #7005: Fixed output of None values for RawConfigParser.write and
+ ConfigParser.write.
+
- Issue #808164: Fixed socket.close to avoid references to globals, to
avoid issues when socket.close is called from a __del__ method.
From python-checkins at python.org Fri Sep 3 06:22:36 2010
From: python-checkins at python.org (fred.drake)
Date: Fri, 3 Sep 2010 06:22:36 +0200 (CEST)
Subject: [Python-checkins] r84444 - in python/branches/py3k:
Lib/configparser.py Lib/test/test_cfgparser.py Misc/NEWS
Message-ID: <20100903042236.B6B5BEE99E@mail.python.org>
Author: fred.drake
Date: Fri Sep 3 06:22:36 2010
New Revision: 84444
Log:
fix output from RawConfigParser.write and ConfigParser.write for None
values (http://bugs.python.org/issue7005)
(merged r84443 from the release27-mmaint branch, with changes to reflect
changes in Python 3)
Modified:
python/branches/py3k/Lib/configparser.py
python/branches/py3k/Lib/test/test_cfgparser.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/configparser.py
==============================================================================
--- python/branches/py3k/Lib/configparser.py (original)
+++ python/branches/py3k/Lib/configparser.py Fri Sep 3 06:22:36 2010
@@ -637,7 +637,7 @@
for key, value in section_items:
if key == "__name__":
continue
- if value is not None:
+ if (value is not None) or (self._optcre == self.OPTCRE):
value = delimiter + str(value).replace('\n', '\n\t')
else:
value = ""
Modified: python/branches/py3k/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cfgparser.py (original)
+++ python/branches/py3k/Lib/test/test_cfgparser.py Fri Sep 3 06:22:36 2010
@@ -755,6 +755,34 @@
with self.assertRaises(UnicodeDecodeError):
cf.read(tricky, encoding='ascii')
+
+class Issue7005TestCase(unittest.TestCase):
+ """Test output when None is set() as a value and allow_no_value == False.
+
+ http://bugs.python.org/issue7005
+
+ """
+
+ expected_output = "[section]\noption = None\n\n"
+
+ def prepare(self, config_class):
+ # This is the default, but that's the point.
+ cp = config_class(allow_no_value=False)
+ cp.add_section("section")
+ cp.set("section", "option", None)
+ sio = io.StringIO()
+ cp.write(sio)
+ return sio.getvalue()
+
+ def test_none_as_value_stringified(self):
+ output = self.prepare(configparser.ConfigParser)
+ self.assertEqual(output, self.expected_output)
+
+ def test_none_as_value_stringified_raw(self):
+ output = self.prepare(configparser.RawConfigParser)
+ self.assertEqual(output, self.expected_output)
+
+
class SortedTestCase(RawConfigParserTestCase):
dict_type = SortedDict
@@ -811,6 +839,7 @@
SafeConfigParserTestCaseNoValue,
SafeConfigParserTestCaseTrickyFile,
SortedTestCase,
+ Issue7005TestCase,
StrictTestCase,
CompatibleTestCase,
)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 3 06:22:36 2010
@@ -155,6 +155,9 @@
Library
-------
+- Issue #7005: Fixed output of None values for RawConfigParser.write and
+ ConfigParser.write.
+
- Issue #8990: array.fromstring() and array.tostring() get renamed to
frombytes() and tobytes(), respectively, to avoid confusion. Furthermore,
array.frombytes(), array.extend() as well as the array.array()
From python-checkins at python.org Fri Sep 3 11:06:07 2010
From: python-checkins at python.org (vinay.sajip)
Date: Fri, 3 Sep 2010 11:06:07 +0200 (CEST)
Subject: [Python-checkins] r84445 -
python/branches/release27-maint/Lib/logging/handlers.py
Message-ID: <20100903090607.E5FFBEE9A3@mail.python.org>
Author: vinay.sajip
Date: Fri Sep 3 11:06:07 2010
New Revision: 84445
Log:
Issue #7077: Backported fix from py3k.
Modified:
python/branches/release27-maint/Lib/logging/handlers.py
Modified: python/branches/release27-maint/Lib/logging/handlers.py
==============================================================================
--- python/branches/release27-maint/Lib/logging/handlers.py (original)
+++ python/branches/release27-maint/Lib/logging/handlers.py Fri Sep 3 11:06:07 2010
@@ -786,20 +786,19 @@
The record is formatted, and then sent to the syslog server. If
exception information is present, it is NOT sent to the server.
"""
- msg = self.format(record)
+ msg = self.format(record) + '\000'
"""
We need to convert record level to lowercase, maybe this will
change in the future.
"""
- msg = self.log_format_string % (
- self.encodePriority(self.facility,
- self.mapPriority(record.levelname)),
- msg)
- # Treat unicode messages as required by RFC 5424
- if _unicode and type(msg) is unicode:
+ prio = '<%d>' % self.encodePriority(self.facility,
+ self.mapPriority(record.levelname))
+ # Message is a string. Convert to bytes as required by RFC 5424
+ if type(msg) is unicode:
msg = msg.encode('utf-8')
if codecs:
msg = codecs.BOM_UTF8 + msg
+ msg = prio + msg
try:
if self.unixsocket:
try:
From python-checkins at python.org Fri Sep 3 11:26:14 2010
From: python-checkins at python.org (armin.rigo)
Date: Fri, 3 Sep 2010 11:26:14 +0200 (CEST)
Subject: [Python-checkins] r84446 -
python/branches/release27-maint/Lib/test/crashers/gc_has_finalizer.py
Message-ID: <20100903092614.52612EEA53@mail.python.org>
Author: armin.rigo
Date: Fri Sep 3 11:26:14 2010
New Revision: 84446
Log:
An example that shows that _PyInstance_Lookup() does not fulfill
its documented purpose.
Added:
python/branches/release27-maint/Lib/test/crashers/gc_has_finalizer.py (contents, props changed)
Added: python/branches/release27-maint/Lib/test/crashers/gc_has_finalizer.py
==============================================================================
--- (empty file)
+++ python/branches/release27-maint/Lib/test/crashers/gc_has_finalizer.py Fri Sep 3 11:26:14 2010
@@ -0,0 +1,36 @@
+"""
+The gc module can still invoke arbitrary Python code and crash.
+This is an attack against _PyInstance_Lookup(), which is documented
+as follows:
+
+ The point of this routine is that it never calls arbitrary Python
+ code, so is always "safe": all it does is dict lookups.
+
+But of course dict lookups can call arbitrary Python code.
+The following code causes mutation of the object graph during
+the call to has_finalizer() in gcmodule.c, and that might
+segfault.
+"""
+
+import gc
+
+
+class A:
+ def __hash__(self):
+ return hash("__del__")
+ def __eq__(self, other):
+ del self.other
+ return False
+
+a = A()
+b = A()
+
+a.__dict__[b] = 'A'
+
+a.other = b
+b.other = a
+
+gc.collect()
+del a, b
+
+gc.collect()
From python-checkins at python.org Fri Sep 3 12:00:51 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Fri, 3 Sep 2010 12:00:51 +0200 (CEST)
Subject: [Python-checkins] r84447 - in python/branches/py3k:
Lib/test/test_set.py Objects/setobject.c
Message-ID: <20100903100051.16CA7EEA4D@mail.python.org>
Author: raymond.hettinger
Date: Fri Sep 3 12:00:50 2010
New Revision: 84447
Log:
Issue 8420: Fix obscure set crashers.
Modified:
python/branches/py3k/Lib/test/test_set.py
python/branches/py3k/Objects/setobject.c
Modified: python/branches/py3k/Lib/test/test_set.py
==============================================================================
--- python/branches/py3k/Lib/test/test_set.py (original)
+++ python/branches/py3k/Lib/test/test_set.py Fri Sep 3 12:00:50 2010
@@ -1660,6 +1660,39 @@
self.assertRaises(TypeError, getattr(set('january'), methname), N(data))
self.assertRaises(ZeroDivisionError, getattr(set('january'), methname), E(data))
+class bad_eq:
+ def __eq__(self, other):
+ if be_bad:
+ set2.clear()
+ raise ZeroDivisionError
+ return self is other
+ def __hash__(self):
+ return 0
+
+class bad_dict_clear:
+ def __eq__(self, other):
+ if be_bad:
+ dict2.clear()
+ return self is other
+ def __hash__(self):
+ return 0
+
+class Test_Weird_Bugs(unittest.TestCase):
+ def test_8420_set_merge(self):
+ # This used to segfault
+ global be_bad, set2, dict2
+ be_bad = False
+ set1 = {bad_eq()}
+ set2 = {bad_eq() for i in range(75)}
+ be_bad = True
+ self.assertRaises(ZeroDivisionError, set1.update, set2)
+
+ be_bad = False
+ set1 = {bad_dict_clear()}
+ dict2 = {bad_dict_clear(): None}
+ be_bad = True
+ set1.symmetric_difference_update(dict2)
+
# Application tests (based on David Eppstein's graph recipes ====================================
def powerset(U):
@@ -1804,6 +1837,7 @@
TestIdentities,
TestVariousIteratorArgs,
TestGraphs,
+ Test_Weird_Bugs,
)
support.run_unittest(*test_classes)
Modified: python/branches/py3k/Objects/setobject.c
==============================================================================
--- python/branches/py3k/Objects/setobject.c (original)
+++ python/branches/py3k/Objects/setobject.c Fri Sep 3 12:00:50 2010
@@ -364,12 +364,13 @@
set_add_entry(register PySetObject *so, setentry *entry)
{
register Py_ssize_t n_used;
+ PyObject *key = entry->key;
assert(so->fill <= so->mask); /* at least one empty slot */
n_used = so->used;
- Py_INCREF(entry->key);
- if (set_insert_key(so, entry->key, (long) entry->hash) == -1) {
- Py_DECREF(entry->key);
+ Py_INCREF(key);
+ if (set_insert_key(so, key, (long) entry->hash) == -1) {
+ Py_DECREF(key);
return -1;
}
if (!(so->used > n_used && so->fill*3 >= (so->mask+1)*2))
@@ -637,6 +638,7 @@
set_merge(PySetObject *so, PyObject *otherset)
{
PySetObject *other;
+ PyObject *key;
register Py_ssize_t i;
register setentry *entry;
@@ -657,11 +659,12 @@
}
for (i = 0; i <= other->mask; i++) {
entry = &other->table[i];
- if (entry->key != NULL &&
- entry->key != dummy) {
- Py_INCREF(entry->key);
- if (set_insert_key(so, entry->key, (long) entry->hash) == -1) {
- Py_DECREF(entry->key);
+ key = entry->key;
+ if (key != NULL &&
+ key != dummy) {
+ Py_INCREF(key);
+ if (set_insert_key(so, key, (long) entry->hash) == -1) {
+ Py_DECREF(key);
return -1;
}
}
@@ -1642,15 +1645,22 @@
while (_PyDict_Next(other, &pos, &key, &value, &hash)) {
setentry an_entry;
+ Py_INCREF(key);
an_entry.hash = hash;
an_entry.key = key;
+
rv = set_discard_entry(so, &an_entry);
- if (rv == -1)
+ if (rv == -1) {
+ Py_DECREF(key);
return NULL;
+ }
if (rv == DISCARD_NOTFOUND) {
- if (set_add_entry(so, &an_entry) == -1)
+ if (set_add_entry(so, &an_entry) == -1) {
+ Py_DECREF(key);
return NULL;
+ }
}
+ Py_DECREF(key);
}
Py_RETURN_NONE;
}
From python-checkins at python.org Fri Sep 3 12:52:56 2010
From: python-checkins at python.org (georg.brandl)
Date: Fri, 3 Sep 2010 12:52:56 +0200 (CEST)
Subject: [Python-checkins] r84448 - python/branches/py3k/Objects/setobject.c
Message-ID: <20100903105256.0DED3EE9D0@mail.python.org>
Author: georg.brandl
Date: Fri Sep 3 12:52:55 2010
New Revision: 84448
Log:
Reindent.
Modified:
python/branches/py3k/Objects/setobject.c
Modified: python/branches/py3k/Objects/setobject.c
==============================================================================
--- python/branches/py3k/Objects/setobject.c (original)
+++ python/branches/py3k/Objects/setobject.c Fri Sep 3 12:52:55 2010
@@ -1650,7 +1650,7 @@
an_entry.key = key;
rv = set_discard_entry(so, &an_entry);
- if (rv == -1) {
+ if (rv == -1) {
Py_DECREF(key);
return NULL;
}
@@ -1660,7 +1660,7 @@
return NULL;
}
}
- Py_DECREF(key);
+ Py_DECREF(key);
}
Py_RETURN_NONE;
}
From python-checkins at python.org Fri Sep 3 13:11:43 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Fri, 3 Sep 2010 13:11:43 +0200 (CEST)
Subject: [Python-checkins] r84449 -
python/branches/py3k/Lib/test/test_socket.py
Message-ID: <20100903111143.E58B7EEA16@mail.python.org>
Author: daniel.stutzbach
Date: Fri Sep 3 13:11:43 2010
New Revision: 84449
Log:
fromfd exists on Windows now
Modified:
python/branches/py3k/Lib/test/test_socket.py
Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py (original)
+++ python/branches/py3k/Lib/test/test_socket.py Fri Sep 3 13:11:43 2010
@@ -708,8 +708,6 @@
def testFromFd(self):
# Testing fromfd()
- if not hasattr(socket, "fromfd"):
- return # On Windows, this doesn't exist
fd = self.cli_conn.fileno()
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
msg = sock.recv(1024)
From python-checkins at python.org Fri Sep 3 14:38:33 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Fri, 3 Sep 2010 14:38:33 +0200 (CEST)
Subject: [Python-checkins] r84450 - in python/branches/py3k: Misc/NEWS
Modules/socketmodule.c
Message-ID: <20100903123833.4A192FBD4@mail.python.org>
Author: daniel.stutzbach
Date: Fri Sep 3 14:38:33 2010
New Revision: 84450
Log:
Fix Issue9753: socket.dup() does not always work right on Windows
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/socketmodule.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 3 14:38:33 2010
@@ -155,6 +155,9 @@
Library
-------
+- Issue #9753: Fixed socket.dup, which did not always work correctly
+ on Windows.
+
- Issue #7005: Fixed output of None values for RawConfigParser.write and
ConfigParser.write.
Modified: python/branches/py3k/Modules/socketmodule.c
==============================================================================
--- python/branches/py3k/Modules/socketmodule.c (original)
+++ python/branches/py3k/Modules/socketmodule.c Fri Sep 3 14:38:33 2010
@@ -351,16 +351,13 @@
static SOCKET
dup_socket(SOCKET handle)
{
- HANDLE newhandle;
+ WSAPROTOCOL_INFO info;
- if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)handle,
- GetCurrentProcess(), &newhandle,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- WSASetLastError(GetLastError());
+ if (WSADuplicateSocket(handle, GetCurrentProcessId(), &info))
return INVALID_SOCKET;
- }
- return (SOCKET)newhandle;
+
+ return WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
+ FROM_PROTOCOL_INFO, &info, 0, 0);
}
#define SOCKETCLOSE closesocket
#else
From python-checkins at python.org Fri Sep 3 14:42:06 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Fri, 3 Sep 2010 14:42:06 +0200 (CEST)
Subject: [Python-checkins] r84451 - in python/branches/release31-maint:
Misc/NEWS Modules/socketmodule.c
Message-ID: <20100903124206.7F34DEE99A@mail.python.org>
Author: daniel.stutzbach
Date: Fri Sep 3 14:42:06 2010
New Revision: 84451
Log:
Merged revisions 84450 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84450 | daniel.stutzbach | 2010-09-03 07:38:33 -0500 (Fri, 03 Sep 2010) | 1 line
Fix Issue9753: socket.dup() does not always work right on Windows
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Modules/socketmodule.c
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Fri Sep 3 14:42:06 2010
@@ -105,6 +105,9 @@
Library
-------
+- Issue #9753: Fixed socket.dup, which did not always work correctly
+ on Windows.
+
- Issue #1868: Eliminate subtle timing issues in thread-local objects by
getting rid of the cached copy of thread-local attribute dictionary.
Modified: python/branches/release31-maint/Modules/socketmodule.c
==============================================================================
--- python/branches/release31-maint/Modules/socketmodule.c (original)
+++ python/branches/release31-maint/Modules/socketmodule.c Fri Sep 3 14:42:06 2010
@@ -351,16 +351,13 @@
static SOCKET
dup_socket(SOCKET handle)
{
- HANDLE newhandle;
+ WSAPROTOCOL_INFO info;
- if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)handle,
- GetCurrentProcess(), &newhandle,
- 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- WSASetLastError(GetLastError());
+ if (WSADuplicateSocket(handle, GetCurrentProcessId(), &info))
return INVALID_SOCKET;
- }
- return (SOCKET)newhandle;
+
+ return WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
+ FROM_PROTOCOL_INFO, &info, 0, 0);
}
#define SOCKETCLOSE closesocket
#else
From python-checkins at python.org Fri Sep 3 18:12:14 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 18:12:14 +0200 (CEST)
Subject: [Python-checkins] r84452 - python/branches/py3k/Misc/NEWS
Message-ID: <20100903161214.94BF8FC5E@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 18:12:14 2010
New Revision: 84452
Log:
Fix NEWS entry.
Modified:
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 3 18:12:14 2010
@@ -378,8 +378,9 @@
Build
-----
-- Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
- _Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
+- Issue #3101: Helper functions _add_one_to_index_C() and
+ _add_one_to_index_F() become _Py_add_one_to_index_C() and
+ _Py_add_one_to_index_F(), respectively.
- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
S?bastien Sabl?.
From python-checkins at python.org Fri Sep 3 18:14:15 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 18:14:15 +0200 (CEST)
Subject: [Python-checkins] r84453 - in python/branches/release31-maint:
Misc/NEWS
Message-ID: <20100903161415.16FE9FC5E@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 18:14:14 2010
New Revision: 84453
Log:
Merged revisions 84452 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84452 | antoine.pitrou | 2010-09-03 18:12:14 +0200 (ven., 03 sept. 2010) | 3 lines
Fix NEWS entry.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/NEWS
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Fri Sep 3 18:14:14 2010
@@ -523,8 +523,9 @@
Build
-----
-- Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
- _Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
+- Issue #3101: Helper functions _add_one_to_index_C() and
+ _add_one_to_index_F() become _Py_add_one_to_index_C() and
+ _Py_add_one_to_index_F(), respectively.
- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
S?bastien Sabl?.
From python-checkins at python.org Fri Sep 3 18:15:18 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 18:15:18 +0200 (CEST)
Subject: [Python-checkins] r84454 - in python/branches/release27-maint:
Misc/NEWS
Message-ID: <20100903161518.1FD12FC5E@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 18:15:17 2010
New Revision: 84454
Log:
Merged revisions 84452 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84452 | antoine.pitrou | 2010-09-03 18:12:14 +0200 (ven., 03 sept. 2010) | 3 lines
Fix NEWS entry.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Fri Sep 3 18:15:17 2010
@@ -266,8 +266,9 @@
Build
-----
-- Issue #3101: Helper functions _add_one_to_C() and _add_one_to_F() become
- _Py_add_one_to_C() and _Py_add_one_to_F(), respectively.
+- Issue #3101: Helper functions _add_one_to_index_C() and
+ _add_one_to_index_F() become _Py_add_one_to_index_C() and
+ _Py_add_one_to_index_F(), respectively.
- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
S?bastien Sabl?.
From python-checkins at python.org Fri Sep 3 18:18:00 2010
From: python-checkins at python.org (victor.stinner)
Date: Fri, 3 Sep 2010 18:18:00 +0200 (CEST)
Subject: [Python-checkins] r84455 - in python/branches/py3k:
Include/unicodeobject.h Objects/unicodeobject.c
Message-ID: <20100903161800.69160EE98F@mail.python.org>
Author: victor.stinner
Date: Fri Sep 3 18:18:00 2010
New Revision: 84455
Log:
Rename PyUnicode_strdup() to PyUnicode_AsUnicodeCopy()
Modified:
python/branches/py3k/Include/unicodeobject.h
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h (original)
+++ python/branches/py3k/Include/unicodeobject.h Fri Sep 3 18:18:00 2010
@@ -1607,7 +1607,7 @@
and raise a MemoryError exception on memory allocation failure, otherwise
return a new allocated buffer (use PyMem_Free() to free the buffer). */
-PyAPI_FUNC(Py_UNICODE*) PyUnicode_strdup(
+PyAPI_FUNC(Py_UNICODE*) PyUnicode_AsUnicodeCopy(
PyObject *unicode
);
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Fri Sep 3 18:18:00 2010
@@ -10015,7 +10015,7 @@
}
Py_UNICODE*
-PyUnicode_strdup(PyObject *object)
+PyUnicode_AsUnicodeCopy(PyObject *object)
{
PyUnicodeObject *unicode = (PyUnicodeObject *)object;
Py_UNICODE *copy;
From python-checkins at python.org Fri Sep 3 18:23:29 2010
From: python-checkins at python.org (victor.stinner)
Date: Fri, 3 Sep 2010 18:23:29 +0200 (CEST)
Subject: [Python-checkins] r84456 -
python/branches/py3k/Doc/c-api/unicode.rst
Message-ID: <20100903162329.A386CEE9BC@mail.python.org>
Author: victor.stinner
Date: Fri Sep 3 18:23:29 2010
New Revision: 84456
Log:
Document PyUnicode_AsUnicodeCopy()
Modified:
python/branches/py3k/Doc/c-api/unicode.rst
Modified: python/branches/py3k/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/unicode.rst (original)
+++ python/branches/py3k/Doc/c-api/unicode.rst Fri Sep 3 18:23:29 2010
@@ -335,6 +335,14 @@
buffer, *NULL* if *unicode* is not a Unicode object.
+.. cfunction:: Py_UNICODE* PyUnicode_AsUnicodeCopy(PyObject *unicode)
+
+ Create a copy of a unicode string ending with a nul character. Return *NULL*
+ and raise a :exc:`MemoryError` exception on memory allocation failure,
+ otherwise return a new allocated buffer (use :cfunc:`PyMem_Free` to free the
+ buffer).
+
+
.. cfunction:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
Return the length of the Unicode object.
From python-checkins at python.org Fri Sep 3 19:07:56 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 19:07:56 +0200 (CEST)
Subject: [Python-checkins] r84457 - peps/trunk/pep-3151.txt
Message-ID: <20100903170756.32392EE9F6@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 19:07:56 2010
New Revision: 84457
Log:
Add "Error" at the end of class names.
Propose two new intermediate classes (ConnectionError and FileSystemError)
Add a small diagram.
Modified:
peps/trunk/pep-3151.txt
Modified: peps/trunk/pep-3151.txt
==============================================================================
--- peps/trunk/pep-3151.txt (original)
+++ peps/trunk/pep-3151.txt Fri Sep 3 19:07:56 2010
@@ -154,7 +154,7 @@
try:
os.remove(filename)
- except FileNotFound:
+ except FileNotFoundError:
pass
@@ -330,44 +330,76 @@
The following tentative list of subclasses, along with a description and
the list of errnos mapped to them, is submitted to discussion:
-* ``FileAlreadyExists``: trying to create a file or directory which already
- exists (EEXIST)
+* ``FileAlreadyExistsError``: trying to create a file or directory which
+ already exists (EEXIST)
-* ``FileNotFound``: for all circumstances where a file and directory is
+* ``FileNotFoundError``: for all circumstances where a file and directory is
requested but doesn't exist (ENOENT)
-* ``IsADirectory``: file-level operation (open(), os.remove()...) requested
- on a directory (EISDIR)
+* ``IsADirectoryError``: file-level operation (open(), os.remove()...)
+ requested on a directory (EISDIR)
-* ``NotADirectory``: directory-level operation requested on something else
- (ENOTDIR)
+* ``NotADirectoryError``: directory-level operation requested on something
+ else (ENOTDIR)
-* ``PermissionDenied``: trying to run an operation without the adequate access
- rights - for example filesystem permissions (EACCESS, optionally EPERM)
+* ``PermissionError``: trying to run an operation without the adequate access
+ rights - for example filesystem permissions (EACCESS, EPERM)
* ``BlockingIOError``: an operation would block on an object (e.g. socket) set
for non-blocking operation (EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS);
this is the existing ``io.BlockingIOError`` with an extended role
-* ``BadFileDescriptor``: operation on an invalid file descriptor (EBADF);
+* ``FileDescriptorError``: operation on an invalid file descriptor (EBADF);
the default error message could point out that most causes are that
an existing file descriptor has been closed
-* ``ConnectionAborted``: connection attempt aborted by peer (ECONNABORTED)
+* ``ConnectionAbortedError``: connection attempt aborted by peer (ECONNABORTED)
-* ``ConnectionRefused``: connection reset by peer (ECONNREFUSED)
+* ``ConnectionRefusedError``: connection reset by peer (ECONNREFUSED)
-* ``ConnectionReset``: connection reset by peer (ECONNRESET)
+* ``ConnectionResetError``: connection reset by peer (ECONNRESET)
-* ``TimeoutError``: connection timed out (ECONNTIMEOUT); this could be re-cast
+* ``TimeoutError``: connection timed out (ECONNTIMEOUT); this can be re-cast
as a generic timeout exception, useful for other types of timeout (for
example in Lock.acquire())
-This list assumes `Step 1`_ is accepted in full; the exception classes
-described above would all derive from the now unified exception type
-IOError. It will need reworking if a partial version of step 1 is accepted
-instead (again, see appendix A for the current distribution of errnos
-and exception types).
+In addition, the following exception class are proposed for inclusion:
+
+* ``ConnectionError``: a base class for ``ConnectionAbortedError``,
+ ``ConnectionRefusedError`` and ``ConnectionResetError``
+
+* ``FileSystemError``: a base class for ``FileAlreadyExistsError``,
+ ``FileNotFoundError``, ``IsADirectoryError`` and ``NotADirectoryError``
+
+The following drawing tries to sum up the proposed additions, along with
+the corresponding errno values (where applicable). The root of the
+sub-hierarchy (IOError, assuming `Step 1`_ is accepted in full) is not
+shown::
+
+ +-- BlockingIOError EAGAIN, EALREADY, EWOULDBLOCK, EINPROGRESS
+ +-- ConnectionError
+ +-- ConnectionAbortedError ECONNABORTED
+ +-- ConnectionRefusedError ECONNREFUSED
+ +-- ConnectionResetError ECONNRESET
+ +-- FileDescriptorError EBADF
+ +-- FileSystemError
+ +-- FileAlreadyExistsError EEXIST
+ +-- FileNotFoundError ENOENT
+ +-- IsADirectoryError EISDIR
+ +-- NotADirectoryError ENOTDIR
+ +-- PermissionError EACCESS, EPERM
+ +-- TimeoutError ECONNTIMEOUT
+
+Naming
+------
+
+Various naming controversies can arise. One of them is whether all
+exception class names should end in "``Error``". In favour is consistency
+with the rest of the exception hiearchy, against is concision (especially
+with long names such as ``FileAlreadyExistsError``).
+
+Another cosmetic issue is whether ``FileSystemError`` should be spelled
+``FilesystemError`` instead.
Exception attributes
--------------------
From python-checkins at python.org Fri Sep 3 20:30:30 2010
From: python-checkins at python.org (barry.warsaw)
Date: Fri, 3 Sep 2010 20:30:30 +0200 (CEST)
Subject: [Python-checkins] r84458 - in python/branches/py3k:
Lib/distutils/tests/test_build_ext.py Makefile.pre.in
Python/dynload_shlib.c configure configure.in pyconfig.h.in
Message-ID: <20100903183030.B71ACEEA93@mail.python.org>
Author: barry.warsaw
Date: Fri Sep 3 20:30:30 2010
New Revision: 84458
Log:
PEP 3149 is accepted.
http://mail.python.org/pipermail/python-dev/2010-September/103408.html
Modified:
python/branches/py3k/Lib/distutils/tests/test_build_ext.py
python/branches/py3k/Makefile.pre.in
python/branches/py3k/Python/dynload_shlib.c
python/branches/py3k/configure
python/branches/py3k/configure.in
python/branches/py3k/pyconfig.h.in
Modified: python/branches/py3k/Lib/distutils/tests/test_build_ext.py
==============================================================================
--- python/branches/py3k/Lib/distutils/tests/test_build_ext.py (original)
+++ python/branches/py3k/Lib/distutils/tests/test_build_ext.py Fri Sep 3 20:30:30 2010
@@ -323,8 +323,8 @@
finally:
os.chdir(old_wd)
self.assertTrue(os.path.exists(so_file))
- self.assertEquals(os.path.splitext(so_file)[-1],
- sysconfig.get_config_var('SO'))
+ so_ext = sysconfig.get_config_var('SO')
+ self.assertTrue(so_file.endswith(so_ext))
so_dir = os.path.dirname(so_file)
self.assertEquals(so_dir, other_tmp_dir)
@@ -333,8 +333,7 @@
cmd.run()
so_file = cmd.get_outputs()[0]
self.assertTrue(os.path.exists(so_file))
- self.assertEquals(os.path.splitext(so_file)[-1],
- sysconfig.get_config_var('SO'))
+ self.assertTrue(so_file.endswith(so_ext))
so_dir = os.path.dirname(so_file)
self.assertEquals(so_dir, cmd.build_lib)
Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in (original)
+++ python/branches/py3k/Makefile.pre.in Fri Sep 3 20:30:30 2010
@@ -35,6 +35,7 @@
AR= @AR@
RANLIB= @RANLIB@
SVNVERSION= @SVNVERSION@
+SOABI= @SOABI@
GNULD= @GNULD@
@@ -559,6 +560,11 @@
Modules/python.o: $(srcdir)/Modules/python.c
$(MAINCC) -c $(PY_CORE_CFLAGS) -o $@ $(srcdir)/Modules/python.c
+Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile
+ $(CC) -c $(PY_CORE_CFLAGS) \
+ -DSOABI='"$(SOABI)"' \
+ -o $@ $(srcdir)/Python/dynload_shlib.c
+
$(IO_OBJS): $(IO_H)
# Use a stamp file to prevent make -j invoking pgen twice
Modified: python/branches/py3k/Python/dynload_shlib.c
==============================================================================
--- python/branches/py3k/Python/dynload_shlib.c (original)
+++ python/branches/py3k/Python/dynload_shlib.c Fri Sep 3 20:30:30 2010
@@ -30,27 +30,34 @@
#define LEAD_UNDERSCORE ""
#endif
+/* The .so extension module ABI tag, supplied by the Makefile via
+ Makefile.pre.in and configure. This is used to discriminate between
+ incompatible .so files so that extensions for different Python builds can
+ live in the same directory. E.g. foomodule.cpython-32.so
+*/
const struct filedescr _PyImport_DynLoadFiletab[] = {
#ifdef __CYGWIN__
{".dll", "rb", C_EXTENSION},
{"module.dll", "rb", C_EXTENSION},
-#else
+#else /* !__CYGWIN__ */
#if defined(PYOS_OS2) && defined(PYCC_GCC)
{".pyd", "rb", C_EXTENSION},
{".dll", "rb", C_EXTENSION},
-#else
+#else /* !(defined(PYOS_OS2) && defined(PYCC_GCC)) */
#ifdef __VMS
{".exe", "rb", C_EXTENSION},
{".EXE", "rb", C_EXTENSION},
{"module.exe", "rb", C_EXTENSION},
{"MODULE.EXE", "rb", C_EXTENSION},
-#else
+#else /* !__VMS */
+ {"." SOABI ".so", "rb", C_EXTENSION},
{".so", "rb", C_EXTENSION},
+ {"module." SOABI ".so", "rb", C_EXTENSION},
{"module.so", "rb", C_EXTENSION},
-#endif
-#endif
-#endif
+#endif /* __VMS */
+#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
+#endif /* __CYGWIN__ */
{0, 0}
};
Modified: python/branches/py3k/configure
==============================================================================
--- python/branches/py3k/configure (original)
+++ python/branches/py3k/configure Fri Sep 3 20:30:30 2010
@@ -1,14 +1,14 @@
#! /bin/sh
-# From configure.in Revision: 83986 .
+# From configure.in Revision: 84379 .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.65 for python 3.2.
+# Generated by GNU Autoconf 2.67 for python 3.2.
#
# Report bugs to .
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -320,7 +320,7 @@
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
@@ -360,19 +360,19 @@
fi # as_fn_arith
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
- $as_echo "$as_me: error: $1" >&2
+ $as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
@@ -534,7 +534,7 @@
exec 6>&1
# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
@@ -598,6 +598,7 @@
ac_subst_vars='LTLIBOBJS
SRCDIRS
THREADHEADERS
+SOABI
LIBC
LIBM
HAVE_GETHOSTBYNAME
@@ -825,8 +826,9 @@
fi
case $ac_option in
- *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *) ac_optarg=yes ;;
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
@@ -871,7 +873,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
+ as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -897,7 +899,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid feature name: $ac_useropt"
+ as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1101,7 +1103,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
+ as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1117,7 +1119,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error "invalid package name: $ac_useropt"
+ as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1147,8 +1149,8 @@
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
- -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
;;
*=*)
@@ -1156,7 +1158,7 @@
# Reject names that are not valid shell variable names.
case $ac_envvar in #(
'' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
esac
eval $ac_envvar=\$ac_optarg
export $ac_envvar ;;
@@ -1174,13 +1176,13 @@
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error "missing argument to $ac_option"
+ as_fn_error $? "missing argument to $ac_option"
fi
if test -n "$ac_unrecognized_opts"; then
case $enable_option_checking in
no) ;;
- fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
*) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
fi
@@ -1203,7 +1205,7 @@
[\\/$]* | ?:[\\/]* ) continue;;
NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
esac
- as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done
# There might be people who depend on the old broken behavior: `$host'
@@ -1217,8 +1219,8 @@
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
+ $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1233,9 +1235,9 @@
ac_pwd=`pwd` && test -n "$ac_pwd" &&
ac_ls_di=`ls -di .` &&
ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error "working directory cannot be determined"
+ as_fn_error $? "working directory cannot be determined"
test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error "pwd does not report name of working directory"
+ as_fn_error $? "pwd does not report name of working directory"
# Find the source files, if location was not specified.
@@ -1274,11 +1276,11 @@
fi
if test ! -r "$srcdir/$ac_unique_file"; then
test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1318,7 +1320,7 @@
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
+ -q, --quiet, --silent do not print \`checking ...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
@@ -1503,9 +1505,9 @@
if $ac_init_version; then
cat <<\_ACEOF
python configure 3.2
-generated by GNU Autoconf 2.65
+generated by GNU Autoconf 2.67
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1575,7 +1577,7 @@
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } >/dev/null && {
+ test $ac_status = 0; } > conftest.i && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then :
@@ -1599,10 +1601,10 @@
ac_fn_c_check_header_mongrel ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ if eval "test \"\${$3+set}\"" = set; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
@@ -1638,7 +1640,7 @@
else
ac_header_preproc=no
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }
@@ -1661,17 +1663,15 @@
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( cat <<\_ASBOX
-## -------------------------------------- ##
+( $as_echo "## -------------------------------------- ##
## Report this to http://bugs.python.org/ ##
-## -------------------------------------- ##
-_ASBOX
+## -------------------------------------- ##"
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
eval "$3=\$ac_header_compiler"
@@ -1735,7 +1735,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1812,7 +1812,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
@@ -1866,7 +1866,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
$as_echo_n "checking for uint$2_t... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
@@ -1896,8 +1896,7 @@
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- eval as_val=\$$3
- if test "x$as_val" = x""no; then :
+ if eval test \"x\$"$3"\" = x"no"; then :
else
break
@@ -1920,7 +1919,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
$as_echo_n "checking for int$2_t... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
@@ -1931,11 +1930,11 @@
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
+ enum { N = $2 / 2 - 1 };
int
main ()
{
-static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 };
- 0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
test_array [0] = 0
;
@@ -1946,11 +1945,11 @@
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
+ enum { N = $2 / 2 - 1 };
int
main ()
{
-static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 };
- ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
< ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
test_array [0] = 0
@@ -1971,8 +1970,7 @@
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- eval as_val=\$$3
- if test "x$as_val" = x""no; then :
+ if eval test \"x\$"$3"\" = x"no"; then :
else
break
@@ -2172,7 +2170,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2240,7 +2238,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
$as_echo_n "checking for $2.$3... " >&6; }
-if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$4+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2288,15 +2286,18 @@
} # ac_fn_c_check_member
-# ac_fn_c_check_decl LINENO SYMBOL VAR
-# ------------------------------------
-# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
ac_fn_c_check_decl ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
-$as_echo_n "checking whether $2 is declared... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ as_decl_name=`echo $2|sed 's/ *(.*//'`
+ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval "test \"\${$3+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2305,8 +2306,12 @@
int
main ()
{
-#ifndef $2
- (void) $2;
+#ifndef $as_decl_name
+#ifdef __cplusplus
+ (void) $as_decl_use;
+#else
+ (void) $as_decl_name;
+#endif
#endif
;
@@ -2331,7 +2336,7 @@
running configure, to aid debugging if configure makes a mistake.
It was created by python $as_me 3.2, which was
-generated by GNU Autoconf 2.65. Invocation command line was
+generated by GNU Autoconf 2.67. Invocation command line was
$ $0 $@
@@ -2441,11 +2446,9 @@
{
echo
- cat <<\_ASBOX
-## ---------------- ##
+ $as_echo "## ---------------- ##
## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
echo
# The following way of writing the cache mishandles newlines in values,
(
@@ -2479,11 +2482,9 @@
)
echo
- cat <<\_ASBOX
-## ----------------- ##
+ $as_echo "## ----------------- ##
## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
echo
for ac_var in $ac_subst_vars
do
@@ -2496,11 +2497,9 @@
echo
if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------------- ##
+ $as_echo "## ------------------- ##
## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
echo
for ac_var in $ac_subst_files
do
@@ -2514,11 +2513,9 @@
fi
if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
+ $as_echo "## ----------- ##
## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
echo
cat confdefs.h
echo
@@ -2573,7 +2570,12 @@
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
- ac_site_file1=$CONFIG_SITE
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
elif test "x$prefix" != xNONE; then
ac_site_file1=$prefix/share/config.site
ac_site_file2=$prefix/etc/config.site
@@ -2588,7 +2590,11 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
done
@@ -2664,7 +2670,7 @@
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
@@ -2698,6 +2704,7 @@
VERSION=3.2
+# Version number or Python's own shared library file.
SOVERSION=1.0
@@ -2764,7 +2771,7 @@
UNIVERSALSDK=$enableval
if test ! -d "${UNIVERSALSDK}"
then
- as_fn_error "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5
+ as_fn_error $? "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5
fi
;;
esac
@@ -3156,7 +3163,7 @@
# If the user switches compilers, we can't believe the cache
if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
then
- as_fn_error "cached CC is different -- throw away $cache_file
+ as_fn_error $? "cached CC is different -- throw away $cache_file
(it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5
fi
@@ -3466,8 +3473,8 @@
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5 ; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -3581,9 +3588,8 @@
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5 ; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -3625,8 +3631,8 @@
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -3683,9 +3689,9 @@
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run C compiled programs.
+as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
fi
fi
@@ -3736,8 +3742,8 @@
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
@@ -4190,7 +4196,7 @@
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
@@ -4206,11 +4212,11 @@
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
break
fi
@@ -4249,7 +4255,7 @@
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
@@ -4265,18 +4271,18 @@
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
ac_ext=c
@@ -4337,7 +4343,7 @@
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_GREP"; then
- as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_GREP=$GREP
@@ -4403,7 +4409,7 @@
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_EGREP"; then
- as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_EGREP=$EGREP
@@ -4535,8 +4541,7 @@
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
@@ -5140,16 +5145,22 @@
esac
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- for ac_t in install-sh install.sh shtool; do
- if test -f "$ac_dir/$ac_t"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/$ac_t -c"
- break 2
- fi
- done
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
done
if test -z "$ac_aux_dir"; then
- as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
fi
# These three variables are undocumented and unsupported,
@@ -5264,6 +5275,9 @@
esac
fi
+# For calculating the .so ABI tag.
+SOABI_QUALIFIERS=""
+
# Check for --with-pydebug
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-pydebug" >&5
$as_echo_n "checking for --with-pydebug... " >&6; }
@@ -5279,6 +5293,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; };
Py_DEBUG='true'
+ SOABI_QUALIFIERS="${SOABI_QUALIFIERS}d"
else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }; Py_DEBUG='false'
fi
@@ -5482,7 +5497,7 @@
ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc"
else
- as_fn_error "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5
+ as_fn_error $? "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5
fi
@@ -6059,8 +6074,7 @@
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
@@ -6074,7 +6088,7 @@
as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval "test \"\${$as_ac_Header+set}\"" = set; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -6101,8 +6115,7 @@
eval ac_res=\$$as_ac_Header
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
_ACEOF
@@ -6622,9 +6635,8 @@
if test "$ac_cv_type_int" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (int)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (int)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_int=0
fi
@@ -6656,9 +6668,8 @@
if test "$ac_cv_type_long" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (long)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (long)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_long=0
fi
@@ -6690,9 +6701,8 @@
if test "$ac_cv_type_void_p" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (void *)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (void *)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_void_p=0
fi
@@ -6724,9 +6734,8 @@
if test "$ac_cv_type_short" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (short)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (short)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_short=0
fi
@@ -6758,9 +6767,8 @@
if test "$ac_cv_type_float" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (float)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (float)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_float=0
fi
@@ -6792,9 +6800,8 @@
if test "$ac_cv_type_double" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (double)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (double)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_double=0
fi
@@ -6826,9 +6833,8 @@
if test "$ac_cv_type_fpos_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (fpos_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (fpos_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_fpos_t=0
fi
@@ -6860,9 +6866,8 @@
if test "$ac_cv_type_size_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (size_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (size_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_size_t=0
fi
@@ -6894,9 +6899,8 @@
if test "$ac_cv_type_pid_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (pid_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (pid_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_pid_t=0
fi
@@ -6955,9 +6959,8 @@
if test "$ac_cv_type_long_long" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (long long)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (long long)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_long_long=0
fi
@@ -7017,9 +7020,8 @@
if test "$ac_cv_type_long_double" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (long double)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (long double)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_long_double=0
fi
@@ -7080,9 +7082,8 @@
if test "$ac_cv_type__Bool" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (_Bool)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (_Bool)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof__Bool=0
fi
@@ -7126,9 +7127,8 @@
if test "$ac_cv_type_uintptr_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (uintptr_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (uintptr_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_uintptr_t=0
fi
@@ -7168,9 +7168,8 @@
if test "$ac_cv_type_off_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (off_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (off_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_off_t=0
fi
@@ -7231,9 +7230,8 @@
if test "$ac_cv_type_time_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (time_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (time_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_time_t=0
fi
@@ -7304,9 +7302,8 @@
if test "$ac_cv_type_pthread_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (pthread_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (pthread_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_pthread_t=0
fi
@@ -7393,7 +7390,7 @@
MACOSX_DEFAULT_ARCH="ppc"
;;
*)
- as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5
+ as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
;;
esac
else
@@ -7405,7 +7402,7 @@
MACOSX_DEFAULT_ARCH="ppc64"
;;
*)
- as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5
+ as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
;;
esac
@@ -7431,7 +7428,7 @@
$as_echo "yes" >&6; }
if test $enable_shared = "yes"
then
- as_fn_error "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5
+ as_fn_error $? "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
@@ -7461,36 +7458,6 @@
-# SO is the extension of shared libraries `(including the dot!)
-# -- usually .so, .sl on HP-UX, .dll on Cygwin
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SO" >&5
-$as_echo_n "checking SO... " >&6; }
-if test -z "$SO"
-then
- case $ac_sys_system in
- hp*|HP*)
- case `uname -m` in
- ia64) SO=.so;;
- *) SO=.sl;;
- esac
- ;;
- CYGWIN*) SO=.dll;;
- *) SO=.so;;
- esac
-else
- # this might also be a termcap variable, see #610332
- echo
- echo '====================================================================='
- echo '+ +'
- echo '+ WARNING: You have set SO in your environment. +'
- echo '+ Do you really mean to change the extension for shared libraries? +'
- echo '+ Continuing in 10 seconds to let you to ponder. +'
- echo '+ +'
- echo '====================================================================='
- sleep 10
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SO" >&5
-$as_echo "$SO" >&6; }
cat >>confdefs.h <<_ACEOF
@@ -8239,12 +8206,12 @@
withval=$with_dbmliborder;
if test x$with_dbmliborder = xyes
then
-as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
+as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
else
for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do
if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb
then
- as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
+ as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
fi
done
fi
@@ -9210,7 +9177,9 @@
if test -z "$with_pymalloc"
-then with_pymalloc="yes"
+then
+ with_pymalloc="yes"
+ SOABI_QUALIFIERS="${SOABI_QUALIFIERS}m"
fi
if test "$with_pymalloc" != "no"
then
@@ -9241,7 +9210,7 @@
$as_echo "#define WITH_VALGRIND 1" >>confdefs.h
else
- as_fn_error "Valgrind support requested but headers not available" "$LINENO" 5
+ as_fn_error $? "Valgrind support requested but headers not available" "$LINENO" 5
fi
@@ -9358,8 +9327,7 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -10293,8 +10261,7 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -10303,25 +10270,44 @@
done
-for ac_func in dup2 getcwd strdup
-do :
- as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2"
+if test "x$ac_cv_func_dup2" = x""yes; then :
+ $as_echo "#define HAVE_DUP2 1" >>confdefs.h
else
case " $LIBOBJS " in
- *" $ac_func.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+ *" dup2.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS dup2.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd"
+if test "x$ac_cv_func_getcwd" = x""yes; then :
+ $as_echo "#define HAVE_GETCWD 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" getcwd.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getcwd.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup"
+if test "x$ac_cv_func_strdup" = x""yes; then :
+ $as_echo "#define HAVE_STRDUP 1" >>confdefs.h
+
+else
+ case " $LIBOBJS " in
+ *" strdup.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strdup.$ac_objext"
;;
esac
fi
-done
for ac_func in getpgrp
@@ -11530,7 +11516,7 @@
then LIBM=$withval
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5
$as_echo "set LIBM=\"$withval\"" >&6; }
-else as_fn_error "proper usage is --with-libm=STRING" "$LINENO" 5
+else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5
@@ -11554,7 +11540,7 @@
then LIBC=$withval
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5
$as_echo "set LIBC=\"$withval\"" >&6; }
-else as_fn_error "proper usage is --with-libc=STRING" "$LINENO" 5
+else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5
@@ -11850,8 +11836,7 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -11863,8 +11848,7 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
- if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -12032,7 +12016,7 @@
15|30)
;;
*)
- as_fn_error "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;;
+ as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5
$as_echo "$enable_big_digits" >&6; }
@@ -12083,9 +12067,8 @@
if test "$ac_cv_type_wchar_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "cannot compute sizeof (wchar_t)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (wchar_t)
+See \`config.log' for more details" "$LINENO" 5 ; }
else
ac_cv_sizeof_wchar_t=0
fi
@@ -12187,7 +12170,7 @@
else
case "$have_ucs4_tcl" in
- yes) unicode_size="4" ;;
+ yes) unicode_size="4";;
*) unicode_size="2" ;;
esac
@@ -12196,8 +12179,11 @@
case "$unicode_size" in
- 4) $as_echo "#define Py_UNICODE_SIZE 4" >>confdefs.h
- ;;
+ 4)
+ $as_echo "#define Py_UNICODE_SIZE 4" >>confdefs.h
+
+ SOABI_QUALIFIERS="${SOABI_QUALIFIERS}u"
+ ;;
*) $as_echo "#define Py_UNICODE_SIZE 2" >>confdefs.h
;;
esac
@@ -12451,11 +12437,64 @@
;; #(
*)
- as_fn_error "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
esac
+# ABI version string for Python extension modules. This appears between the
+# periods in shared library file names, e.g. foo..so. It is calculated
+# from the following attributes which affect the ABI of this Python build (in
+# this order):
+#
+# * The Python implementation (always 'cpython-' for us)
+# * The major and minor version numbers
+# * --with-pydebug (adds a 'd')
+# * --with-pymalloc (adds a 'm')
+# * --with-wide-unicode (adds a 'u')
+#
+# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc,
+# would get a shared library ABI version tag of 'cpython-32udm' and shared
+# libraries would be named 'foo.cpython-32udm.so'.
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5
+$as_echo_n "checking SOABI... " >&6; }
+SOABI='cpython-'`echo $VERSION | tr -d .`${SOABI_QUALIFIERS}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SOABI" >&5
+$as_echo "$SOABI" >&6; }
+
+# SO is the extension of shared libraries `(including the dot!)
+# -- usually .so, .sl on HP-UX, .dll on Cygwin
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SO" >&5
+$as_echo_n "checking SO... " >&6; }
+if test -z "$SO"
+then
+ case $ac_sys_system in
+ hp*|HP*)
+ case `uname -m` in
+ ia64) SO=.so;;
+ *) SO=.sl;;
+ esac
+ ;;
+ CYGWIN*) SO=.dll;;
+ Linux*) SO=.${SOABI}.so;;
+ *) SO=.so;;
+ esac
+else
+ # this might also be a termcap variable, see #610332
+ echo
+ echo '====================================================================='
+ echo '+ +'
+ echo '+ WARNING: You have set SO in your environment. +'
+ echo '+ Do you really mean to change the extension for shared libraries? +'
+ echo '+ Continuing in 10 seconds to let you to ponder. +'
+ echo '+ +'
+ echo '====================================================================='
+ sleep 10
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SO" >&5
+$as_echo "$SO" >&6; }
+
# Check whether right shifting a negative integer extends the sign bit
# or fills with zeros (like the Cray J90, according to Tim Peters).
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether right shift extends the sign bit" >&5
@@ -12649,7 +12688,7 @@
have_readline=no
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
if test $have_readline = yes
then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -12823,7 +12862,7 @@
have_readline=no
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
if test $have_readline = yes
then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13633,7 +13672,7 @@
case $ac_sys_system in
- OSF*) as_fn_error "OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606" "$LINENO" 5 ;;
+ OSF*) as_fn_error $? "OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606" "$LINENO" 5 ;;
esac
@@ -13743,6 +13782,7 @@
ac_libobjs=
ac_ltlibobjs=
+U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -13905,19 +13945,19 @@
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
- as_status=$?; test $as_status -eq 0 && as_status=1
- if test "$3"; then
- as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
- $as_echo "$as_me: error: $1" >&2
+ $as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
@@ -14113,7 +14153,7 @@
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
@@ -14167,7 +14207,7 @@
# values after options handling.
ac_log="
This file was extended by python $as_me 3.2, which was
-generated by GNU Autoconf 2.65. Invocation command line was
+generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -14191,8 +14231,8 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
# Files that config.status was made for.
-config_files="`echo $ac_config_files`"
-config_headers="`echo $ac_config_headers`"
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
_ACEOF
@@ -14229,10 +14269,10 @@
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
python config.status 3.2
-configured by $0, generated by GNU Autoconf 2.65,
+configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -14248,11 +14288,16 @@
while test $# != 0
do
case $1 in
- --*=*)
+ --*=?*)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
*)
ac_option=$1
ac_optarg=$2
@@ -14274,6 +14319,7 @@
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
esac
as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
@@ -14286,7 +14332,7 @@
ac_need_defaults=false;;
--he | --h)
# Conflict between --help and --header
- as_fn_error "ambiguous option: \`$1'
+ as_fn_error $? "ambiguous option: \`$1'
Try \`$0 --help' for more information.";;
--help | --hel | -h )
$as_echo "$ac_cs_usage"; exit ;;
@@ -14295,7 +14341,7 @@
ac_cs_silent=: ;;
# This is an error.
- -*) as_fn_error "unrecognized option: \`$1'
+ -*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
@@ -14353,7 +14399,7 @@
"Modules/Setup.config") CONFIG_FILES="$CONFIG_FILES Modules/Setup.config" ;;
"Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;;
- *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
esac
done
@@ -14390,7 +14436,7 @@
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
@@ -14407,7 +14453,7 @@
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\r'
+ ac_cs_awk_cr='\\r'
else
ac_cs_awk_cr=$ac_cr
fi
@@ -14421,18 +14467,18 @@
echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
echo "_ACEOF"
} >conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
. ./conf$$subs.sh ||
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
if test $ac_delim_n = $ac_delim_num; then
break
elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
@@ -14521,20 +14567,28 @@
else
cat
fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
- || as_fn_error "could not setup config files machinery" "$LINENO" 5
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[ ]*\):*/\1/
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
s/^[^=]*=[ ]*$//
}'
fi
@@ -14562,7 +14616,7 @@
if test -z "$ac_t"; then
break
elif $ac_last_try; then
- as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+ as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
@@ -14647,7 +14701,7 @@
_ACAWK
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error "could not setup config headers machinery" "$LINENO" 5
+ as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
fi # test -n "$CONFIG_HEADERS"
@@ -14660,7 +14714,7 @@
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -14688,7 +14742,7 @@
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
@@ -14715,7 +14769,7 @@
case $ac_tag in
*:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
@@ -14846,22 +14900,22 @@
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&5
+which seems to be undefined. Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined." >&2;}
+which seems to be undefined. Please make sure it is defined" >&2;}
rm -f "$tmp/stdin"
case $ac_file in
-) cat "$tmp/out" && rm -f "$tmp/out";;
*) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
esac \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
;;
:H)
#
@@ -14872,19 +14926,19 @@
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
} >"$tmp/config.h" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
$as_echo "$as_me: $ac_file is unchanged" >&6;}
else
rm -f "$ac_file"
mv "$tmp/config.h" "$ac_file" \
- || as_fn_error "could not create $ac_file" "$LINENO" 5
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
fi
else
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error "could not create -" "$LINENO" 5
+ || as_fn_error $? "could not create -" "$LINENO" 5
fi
;;
@@ -14899,7 +14953,7 @@
ac_clean_files=$ac_clean_files_save
test $ac_write_fail = 0 ||
- as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
# configure is writing to config.log, and then calls config.status.
@@ -14920,7 +14974,7 @@
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit $?
+ $ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in (original)
+++ python/branches/py3k/configure.in Fri Sep 3 20:30:30 2010
@@ -12,7 +12,7 @@
[],
[m4_fatal([Autoconf version $1 is required for Python], 63)])
])
-version_required(2.65)
+AC_PREREQ(2.65)
AC_REVISION($Revision$)
AC_INIT(python, PYTHON_VERSION, http://bugs.python.org/)
@@ -52,6 +52,7 @@
AC_SUBST(VERSION)
VERSION=PYTHON_VERSION
+# Version number or Python's own shared library file.
AC_SUBST(SOVERSION)
SOVERSION=1.0
@@ -817,6 +818,9 @@
esac
fi
+# For calculating the .so ABI tag.
+SOABI_QUALIFIERS=""
+
# Check for --with-pydebug
AC_MSG_CHECKING(for --with-pydebug)
AC_ARG_WITH(pydebug,
@@ -828,6 +832,7 @@
[Define if you want to build an interpreter with many run-time checks.])
AC_MSG_RESULT(yes);
Py_DEBUG='true'
+ SOABI_QUALIFIERS="${SOABI_QUALIFIERS}d"
else AC_MSG_RESULT(no); Py_DEBUG='false'
fi],
[AC_MSG_RESULT(no)])
@@ -1649,34 +1654,6 @@
AC_SUBST(BLDSHARED)
AC_SUBST(CCSHARED)
AC_SUBST(LINKFORSHARED)
-# SO is the extension of shared libraries `(including the dot!)
-# -- usually .so, .sl on HP-UX, .dll on Cygwin
-AC_MSG_CHECKING(SO)
-if test -z "$SO"
-then
- case $ac_sys_system in
- hp*|HP*)
- case `uname -m` in
- ia64) SO=.so;;
- *) SO=.sl;;
- esac
- ;;
- CYGWIN*) SO=.dll;;
- *) SO=.so;;
- esac
-else
- # this might also be a termcap variable, see #610332
- echo
- echo '====================================================================='
- echo '+ +'
- echo '+ WARNING: You have set SO in your environment. +'
- echo '+ Do you really mean to change the extension for shared libraries? +'
- echo '+ Continuing in 10 seconds to let you to ponder. +'
- echo '+ +'
- echo '====================================================================='
- sleep 10
-fi
-AC_MSG_RESULT($SO)
AC_DEFINE_UNQUOTED(SHLIB_EXT, "$SO", [Define this to be extension of shared libraries (including the dot!).])
# LDSHARED is the ld *command* used to create shared library
@@ -2487,7 +2464,9 @@
AS_HELP_STRING([--with(out)-pymalloc], [disable/enable specialized mallocs]))
if test -z "$with_pymalloc"
-then with_pymalloc="yes"
+then
+ with_pymalloc="yes"
+ SOABI_QUALIFIERS="${SOABI_QUALIFIERS}m"
fi
if test "$with_pymalloc" != "no"
then
@@ -3595,7 +3574,7 @@
],
[
case "$have_ucs4_tcl" in
- yes) unicode_size="4" ;;
+ yes) unicode_size="4";;
*) unicode_size="2" ;;
esac
])
@@ -3603,7 +3582,10 @@
AH_TEMPLATE(Py_UNICODE_SIZE,
[Define as the size of the unicode type.])
case "$unicode_size" in
- 4) AC_DEFINE(Py_UNICODE_SIZE, 4) ;;
+ 4)
+ AC_DEFINE(Py_UNICODE_SIZE, 4)
+ SOABI_QUALIFIERS="${SOABI_QUALIFIERS}u"
+ ;;
*) AC_DEFINE(Py_UNICODE_SIZE, 2) ;;
esac
@@ -3636,6 +3618,55 @@
# check for endianness
AC_C_BIGENDIAN
+# ABI version string for Python extension modules. This appears between the
+# periods in shared library file names, e.g. foo..so. It is calculated
+# from the following attributes which affect the ABI of this Python build (in
+# this order):
+#
+# * The Python implementation (always 'cpython-' for us)
+# * The major and minor version numbers
+# * --with-pydebug (adds a 'd')
+# * --with-pymalloc (adds a 'm')
+# * --with-wide-unicode (adds a 'u')
+#
+# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc,
+# would get a shared library ABI version tag of 'cpython-32udm' and shared
+# libraries would be named 'foo.cpython-32udm.so'.
+AC_SUBST(SOABI)
+AC_MSG_CHECKING(SOABI)
+SOABI='cpython-'`echo $VERSION | tr -d .`${SOABI_QUALIFIERS}
+AC_MSG_RESULT($SOABI)
+
+# SO is the extension of shared libraries `(including the dot!)
+# -- usually .so, .sl on HP-UX, .dll on Cygwin
+AC_MSG_CHECKING(SO)
+if test -z "$SO"
+then
+ case $ac_sys_system in
+ hp*|HP*)
+ case `uname -m` in
+ ia64) SO=.so;;
+ *) SO=.sl;;
+ esac
+ ;;
+ CYGWIN*) SO=.dll;;
+ Linux*) SO=.${SOABI}.so;;
+ *) SO=.so;;
+ esac
+else
+ # this might also be a termcap variable, see #610332
+ echo
+ echo '====================================================================='
+ echo '+ +'
+ echo '+ WARNING: You have set SO in your environment. +'
+ echo '+ Do you really mean to change the extension for shared libraries? +'
+ echo '+ Continuing in 10 seconds to let you to ponder. +'
+ echo '+ +'
+ echo '====================================================================='
+ sleep 10
+fi
+AC_MSG_RESULT($SO)
+
# Check whether right shifting a negative integer extends the sign bit
# or fills with zeros (like the Cray J90, according to Tim Peters).
AC_MSG_CHECKING(whether right shift extends the sign bit)
Modified: python/branches/py3k/pyconfig.h.in
==============================================================================
--- python/branches/py3k/pyconfig.h.in (original)
+++ python/branches/py3k/pyconfig.h.in Fri Sep 3 20:30:30 2010
@@ -1040,7 +1040,7 @@
/* Define to 1 if your declares `struct tm'. */
#undef TM_IN_SYS_TIME
-/* Define to 0 if you don't want to use computed gotos in ceval.c. */
+/* Define if you want to use computed gotos in ceval.c. */
#undef USE_COMPUTED_GOTOS
/* Define if the compiler supports the inline keyword */
From python-checkins at python.org Fri Sep 3 20:31:07 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Fri, 3 Sep 2010 20:31:07 +0200 (CEST)
Subject: [Python-checkins] r84459 -
python/branches/py3k/Doc/c-api/unicode.rst
Message-ID: <20100903183107.B0CF7EEA4D@mail.python.org>
Author: daniel.stutzbach
Date: Fri Sep 3 20:31:07 2010
New Revision: 84459
Log:
Doc fix: unicode() is now str()
Modified:
python/branches/py3k/Doc/c-api/unicode.rst
Modified: python/branches/py3k/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/unicode.rst (original)
+++ python/branches/py3k/Doc/c-api/unicode.rst Fri Sep 3 20:31:07 2010
@@ -470,7 +470,7 @@
Many of the following APIs take two arguments encoding and errors. These
parameters encoding and errors have the same semantics as the ones of the
-built-in :func:`unicode` Unicode object constructor.
+built-in :func:`str` string object constructor.
Setting encoding to *NULL* causes the default encoding to be used
which is ASCII. The file system calls should use
From python-checkins at python.org Fri Sep 3 20:31:47 2010
From: python-checkins at python.org (barry.warsaw)
Date: Fri, 3 Sep 2010 20:31:47 +0200 (CEST)
Subject: [Python-checkins] r84460 - peps/trunk/pep-3149.txt
Message-ID: <20100903183147.A0AC6EEA1C@mail.python.org>
Author: barry.warsaw
Date: Fri Sep 3 20:31:47 2010
New Revision: 84460
Log:
PEP 3149 has been accepted.
Modified:
peps/trunk/pep-3149.txt
Modified: peps/trunk/pep-3149.txt
==============================================================================
--- peps/trunk/pep-3149.txt (original)
+++ peps/trunk/pep-3149.txt Fri Sep 3 20:31:47 2010
@@ -3,13 +3,13 @@
Version: $Revision$
Last-Modified: $Date$
Author: Barry Warsaw
-Status: Draft
+Status: Final
Type: Standards Track
Content-Type: text/x-rst
Created: 2010-07-09
Python-Version: 3.2
Post-History: 2010-07-14, 2010-07-22
-Resolution: TBD
+Resolution: http://mail.python.org/pipermail/python-dev/2010-September/103408.html
Abstract
From python-checkins at python.org Fri Sep 3 20:32:23 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 20:32:23 +0200 (CEST)
Subject: [Python-checkins] r84461 - peps/trunk/pep-3151.txt
Message-ID: <20100903183223.51915FCB4@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 20:32:23 2010
New Revision: 84461
Log:
Replaced `FileAlreadyExistsError` with the shorter `FileExistsError`
(thanks Georg)
Modified:
peps/trunk/pep-3151.txt
Modified: peps/trunk/pep-3151.txt
==============================================================================
--- peps/trunk/pep-3151.txt (original)
+++ peps/trunk/pep-3151.txt Fri Sep 3 20:32:23 2010
@@ -330,8 +330,8 @@
The following tentative list of subclasses, along with a description and
the list of errnos mapped to them, is submitted to discussion:
-* ``FileAlreadyExistsError``: trying to create a file or directory which
- already exists (EEXIST)
+* ``FileExistsError``: trying to create a file or directory which already
+ exists (EEXIST)
* ``FileNotFoundError``: for all circumstances where a file and directory is
requested but doesn't exist (ENOENT)
@@ -368,7 +368,7 @@
* ``ConnectionError``: a base class for ``ConnectionAbortedError``,
``ConnectionRefusedError`` and ``ConnectionResetError``
-* ``FileSystemError``: a base class for ``FileAlreadyExistsError``,
+* ``FileSystemError``: a base class for ``FileExistsError``,
``FileNotFoundError``, ``IsADirectoryError`` and ``NotADirectoryError``
The following drawing tries to sum up the proposed additions, along with
@@ -383,7 +383,7 @@
+-- ConnectionResetError ECONNRESET
+-- FileDescriptorError EBADF
+-- FileSystemError
- +-- FileAlreadyExistsError EEXIST
+ +-- FileExistsError EEXIST
+-- FileNotFoundError ENOENT
+-- IsADirectoryError EISDIR
+-- NotADirectoryError ENOTDIR
@@ -396,7 +396,7 @@
Various naming controversies can arise. One of them is whether all
exception class names should end in "``Error``". In favour is consistency
with the rest of the exception hiearchy, against is concision (especially
-with long names such as ``FileAlreadyExistsError``).
+with long names such as ``ConnectionAbortedError``).
Another cosmetic issue is whether ``FileSystemError`` should be spelled
``FilesystemError`` instead.
From python-checkins at python.org Fri Sep 3 20:36:11 2010
From: python-checkins at python.org (barry.warsaw)
Date: Fri, 3 Sep 2010 20:36:11 +0200 (CEST)
Subject: [Python-checkins] r84462 - python/branches/py3k/Misc/NEWS
Message-ID: <20100903183611.93861EEAC2@mail.python.org>
Author: barry.warsaw
Date: Fri Sep 3 20:36:11 2010
New Revision: 84462
Log:
NEWS for PEP 3149, and clean up a few other entries.
Modified:
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 3 20:36:11 2010
@@ -36,8 +36,8 @@
- Issue #9684: Added a definition for SIZEOF_WCHAR_T to PC/pyconfig.h,
to match the pyconfig.h generated by configure on other systems.
-- Issue #9666: Only catch AttributeError in hasattr(). All other exceptions that
- occur during attribute lookup are now propagated to the caller.
+- Issue #9666: Only catch AttributeError in hasattr(). All other exceptions
+ that occur during attribute lookup are now propagated to the caller.
- Issue #8622: Add PYTHONFSENCODING environment variable to override the
filesystem encoding.
@@ -190,9 +190,9 @@
- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing
error handling when accepting a new connection.
-- Issue #9601: ftplib now provides a workaround for non-compliant
- implementations such as IIS shipped with Windows server 2003 returning invalid
- response codes for MKD and PWD commands.
+- Issue #9601: ftplib now provides a workaround for non-compliant
+ implementations such as IIS shipped with Windows server 2003 returning
+ invalid response codes for MKD and PWD commands.
- Issue #658749: asyncore's connect() method now correctly interprets winsock
errors.
@@ -215,8 +215,8 @@
- Issue #3488: Provide convenient shorthand functions ``gzip.compress``
and ``gzip.decompress``. Original patch by Anand B. Pillai.
-- Issue #8807: poplib.POP3_SSL class now accepts a context parameter, which is a
- ssl.SSLContext object allowing bundling SSL configuration options,
+- Issue #8807: poplib.POP3_SSL class now accepts a context parameter, which is
+ a ssl.SSLContext object allowing bundling SSL configuration options,
certificates and private keys into a single (potentially long-lived)
structure.
@@ -378,6 +378,8 @@
Build
-----
+- Issue #9193: PEP 3149 is accepted.
+
- Issue #3101: Helper functions _add_one_to_index_C() and
_add_one_to_index_F() become _Py_add_one_to_index_C() and
_Py_add_one_to_index_F(), respectively.
From python-checkins at python.org Fri Sep 3 20:37:34 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Fri, 3 Sep 2010 20:37:34 +0200 (CEST)
Subject: [Python-checkins] r84463 - in python/branches/release31-maint:
Doc/c-api/unicode.rst
Message-ID: <20100903183734.8F1AEF0B1@mail.python.org>
Author: daniel.stutzbach
Date: Fri Sep 3 20:37:34 2010
New Revision: 84463
Log:
Merged revisions 84459 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84459 | daniel.stutzbach | 2010-09-03 13:31:07 -0500 (Fri, 03 Sep 2010) | 1 line
Doc fix: unicode() is now str()
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/c-api/unicode.rst
Modified: python/branches/release31-maint/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/release31-maint/Doc/c-api/unicode.rst (original)
+++ python/branches/release31-maint/Doc/c-api/unicode.rst Fri Sep 3 20:37:34 2010
@@ -420,7 +420,7 @@
Many of the following APIs take two arguments encoding and errors. These
parameters encoding and errors have the same semantics as the ones of the
-built-in :func:`unicode` Unicode object constructor.
+built-in :func:`str` string object constructor.
Setting encoding to *NULL* causes the default encoding to be used
which is ASCII. The file system calls should use
From python-checkins at python.org Fri Sep 3 20:38:18 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 20:38:18 +0200 (CEST)
Subject: [Python-checkins] r84464 - in python/branches/py3k: Lib/ssl.py
Modules/_ssl.c
Message-ID: <20100903183818.050C0EEAAA@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 20:38:17 2010
New Revision: 84464
Log:
Issue #3805: clean up implementation of the _read method in _ssl.c.
Modified:
python/branches/py3k/Lib/ssl.py
python/branches/py3k/Modules/_ssl.c
Modified: python/branches/py3k/Lib/ssl.py
==============================================================================
--- python/branches/py3k/Lib/ssl.py (original)
+++ python/branches/py3k/Lib/ssl.py Fri Sep 3 20:38:17 2010
@@ -199,14 +199,14 @@
self._checkClosed()
try:
- if buffer:
- v = self._sslobj.read(buffer, len)
+ if buffer is not None:
+ v = self._sslobj.read(len, buffer)
else:
v = self._sslobj.read(len or 1024)
return v
except SSLError as x:
if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
- if buffer:
+ if buffer is not None:
return 0
else:
return b''
Modified: python/branches/py3k/Modules/_ssl.c
==============================================================================
--- python/branches/py3k/Modules/_ssl.c (original)
+++ python/branches/py3k/Modules/_ssl.c Fri Sep 3 20:38:17 2010
@@ -1156,11 +1156,9 @@
{
PyObject *dest = NULL;
Py_buffer buf;
- int buf_passed = 0;
- int count = -1;
char *mem;
- /* XXX this should use Py_ssize_t */
- int len = 1024;
+ int len, count;
+ int buf_passed = 0;
int sockstate;
int err;
int nonblocking;
@@ -1174,26 +1172,28 @@
}
Py_INCREF(sock);
- if (!PyArg_ParseTuple(args, "|Oi:read", &dest, &count))
+ buf.obj = NULL;
+ buf.buf = NULL;
+ if (!PyArg_ParseTuple(args, "i|w*:read", &len, &buf))
goto error;
- if ((dest == NULL) || (dest == Py_None)) {
- if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
- goto error;
- mem = PyByteArray_AS_STRING(dest);
- } else if (PyLong_Check(dest)) {
- len = PyLong_AS_LONG(dest);
- if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
+ if ((buf.buf == NULL) && (buf.obj == NULL)) {
+ dest = PyBytes_FromStringAndSize(NULL, len);
+ if (dest == NULL)
goto error;
- mem = PyByteArray_AS_STRING(dest);
- } else {
- if (PyObject_GetBuffer(dest, &buf, PyBUF_CONTIG) < 0)
- goto error;
- mem = buf.buf;
- len = buf.len;
- if ((count > 0) && (count <= len))
- len = count;
+ mem = PyBytes_AS_STRING(dest);
+ }
+ else {
buf_passed = 1;
+ mem = buf.buf;
+ if (len <= 0 || len > buf.len) {
+ len = (int) buf.len;
+ if (buf.len != len) {
+ PyErr_SetString(PyExc_OverflowError,
+ "maximum length can't fit in a C 'int'");
+ goto error;
+ }
+ }
}
/* just in case the blocking state of the socket has been changed */
@@ -1254,23 +1254,24 @@
PySSL_SetError(self, count, __FILE__, __LINE__);
goto error;
}
- done:
+
+done:
Py_DECREF(sock);
if (!buf_passed) {
- PyObject *res = PyBytes_FromStringAndSize(mem, count);
- Py_DECREF(dest);
- return res;
- } else {
+ _PyBytes_Resize(&dest, count);
+ return dest;
+ }
+ else {
PyBuffer_Release(&buf);
return PyLong_FromLong(count);
}
- error:
+
+error:
Py_DECREF(sock);
- if (!buf_passed) {
+ if (!buf_passed)
Py_XDECREF(dest);
- } else {
+ else
PyBuffer_Release(&buf);
- }
return NULL;
}
From python-checkins at python.org Fri Sep 3 20:39:47 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 3 Sep 2010 20:39:47 +0200 (CEST)
Subject: [Python-checkins] r84465 - in python/branches/release31-maint:
Lib/ssl.py Modules/_ssl.c
Message-ID: <20100903183947.5838FEEA90@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 3 20:39:47 2010
New Revision: 84465
Log:
Merged revisions 84464 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84464 | antoine.pitrou | 2010-09-03 20:38:17 +0200 (ven., 03 sept. 2010) | 3 lines
Issue #3805: clean up implementation of the _read method in _ssl.c.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/ssl.py
python/branches/release31-maint/Modules/_ssl.c
Modified: python/branches/release31-maint/Lib/ssl.py
==============================================================================
--- python/branches/release31-maint/Lib/ssl.py (original)
+++ python/branches/release31-maint/Lib/ssl.py Fri Sep 3 20:39:47 2010
@@ -162,14 +162,14 @@
self._checkClosed()
try:
- if buffer:
- v = self._sslobj.read(buffer, len)
+ if buffer is not None:
+ v = self._sslobj.read(len, buffer)
else:
v = self._sslobj.read(len or 1024)
return v
except SSLError as x:
if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs:
- if buffer:
+ if buffer is not None:
return 0
else:
return b''
Modified: python/branches/release31-maint/Modules/_ssl.c
==============================================================================
--- python/branches/release31-maint/Modules/_ssl.c (original)
+++ python/branches/release31-maint/Modules/_ssl.c Fri Sep 3 20:39:47 2010
@@ -1277,11 +1277,9 @@
{
PyObject *dest = NULL;
Py_buffer buf;
- int buf_passed = 0;
- int count = -1;
char *mem;
- /* XXX this should use Py_ssize_t */
- int len = 1024;
+ int len, count;
+ int buf_passed = 0;
int sockstate;
int err;
int nonblocking;
@@ -1295,26 +1293,28 @@
}
Py_INCREF(sock);
- if (!PyArg_ParseTuple(args, "|Oi:read", &dest, &count))
+ buf.obj = NULL;
+ buf.buf = NULL;
+ if (!PyArg_ParseTuple(args, "i|w*:read", &len, &buf))
goto error;
- if ((dest == NULL) || (dest == Py_None)) {
- if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
- goto error;
- mem = PyByteArray_AS_STRING(dest);
- } else if (PyLong_Check(dest)) {
- len = PyLong_AS_LONG(dest);
- if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
- goto error;
- mem = PyByteArray_AS_STRING(dest);
- } else {
- if (PyObject_GetBuffer(dest, &buf, PyBUF_CONTIG) < 0)
+ if ((buf.buf == NULL) && (buf.obj == NULL)) {
+ dest = PyBytes_FromStringAndSize(NULL, len);
+ if (dest == NULL)
goto error;
- mem = buf.buf;
- len = buf.len;
- if ((count > 0) && (count <= len))
- len = count;
+ mem = PyBytes_AS_STRING(dest);
+ }
+ else {
buf_passed = 1;
+ mem = buf.buf;
+ if (len <= 0 || len > buf.len) {
+ len = (int) buf.len;
+ if (buf.len != len) {
+ PyErr_SetString(PyExc_OverflowError,
+ "maximum length can't fit in a C 'int'");
+ goto error;
+ }
+ }
}
/* just in case the blocking state of the socket has been changed */
@@ -1375,23 +1375,24 @@
PySSL_SetError(self, count, __FILE__, __LINE__);
goto error;
}
- done:
+
+done:
Py_DECREF(sock);
if (!buf_passed) {
- PyObject *res = PyBytes_FromStringAndSize(mem, count);
- Py_DECREF(dest);
- return res;
- } else {
+ _PyBytes_Resize(&dest, count);
+ return dest;
+ }
+ else {
PyBuffer_Release(&buf);
return PyLong_FromLong(count);
}
- error:
+
+error:
Py_DECREF(sock);
- if (!buf_passed) {
+ if (!buf_passed)
Py_XDECREF(dest);
- } else {
+ else
PyBuffer_Release(&buf);
- }
return NULL;
}
From python-checkins at python.org Fri Sep 3 21:08:36 2010
From: python-checkins at python.org (florent.xicluna)
Date: Fri, 3 Sep 2010 21:08:36 +0200 (CEST)
Subject: [Python-checkins] r84466 - peps/trunk/pep-0001.txt
Message-ID: <20100903190836.7F6B9EEA15@mail.python.org>
Author: florent.xicluna
Date: Fri Sep 3 21:08:36 2010
New Revision: 84466
Log:
Remove reference to python-3000 mailing list in PEP1
Modified:
peps/trunk/pep-0001.txt
Modified: peps/trunk/pep-0001.txt
==============================================================================
--- peps/trunk/pep-0001.txt (original)
+++ peps/trunk/pep-0001.txt Fri Sep 3 21:08:36 2010
@@ -439,7 +439,7 @@
properly.
* Send email back to the PEP author with next steps (post to
- python-list & -dev/-3000).
+ python-list & -dev).
Updates to existing PEPs also come in to peps at python.org. Many PEP
authors are not SVN committers yet, so we do the commits for them.
From python-checkins at python.org Fri Sep 3 21:52:04 2010
From: python-checkins at python.org (florent.xicluna)
Date: Fri, 3 Sep 2010 21:52:04 +0200 (CEST)
Subject: [Python-checkins] r84467 - in python/branches/py3k/Lib: keyword.py
pdb.py platform.py turtle.py
Message-ID: <20100903195204.36E17F682@mail.python.org>
Author: florent.xicluna
Date: Fri Sep 3 21:52:03 2010
New Revision: 84467
Log:
Use a context manager for some file objects.
Modified:
python/branches/py3k/Lib/keyword.py
python/branches/py3k/Lib/pdb.py
python/branches/py3k/Lib/platform.py
python/branches/py3k/Lib/turtle.py
Modified: python/branches/py3k/Lib/keyword.py
==============================================================================
--- python/branches/py3k/Lib/keyword.py (original)
+++ python/branches/py3k/Lib/keyword.py Fri Sep 3 21:52:03 2010
@@ -61,21 +61,19 @@
else: optfile = "Lib/keyword.py"
# scan the source file for keywords
- fp = open(iptfile)
- strprog = re.compile('"([^"]+)"')
- lines = []
- for line in fp:
- if '{1, "' in line:
- match = strprog.search(line)
- if match:
- lines.append(" '" + match.group(1) + "',\n")
- fp.close()
+ with open(iptfile) as fp:
+ strprog = re.compile('"([^"]+)"')
+ lines = []
+ for line in fp:
+ if '{1, "' in line:
+ match = strprog.search(line)
+ if match:
+ lines.append(" '" + match.group(1) + "',\n")
lines.sort()
# load the output skeleton from the target
- fp = open(optfile)
- format = fp.readlines()
- fp.close()
+ with open(optfile) as fp:
+ format = fp.readlines()
# insert the lines of keywords
try:
Modified: python/branches/py3k/Lib/pdb.py
==============================================================================
--- python/branches/py3k/Lib/pdb.py (original)
+++ python/branches/py3k/Lib/pdb.py Fri Sep 3 21:52:03 2010
@@ -155,21 +155,15 @@
if 'HOME' in os.environ:
envHome = os.environ['HOME']
try:
- rcFile = open(os.path.join(envHome, ".pdbrc"))
+ with open(os.path.join(envHome, ".pdbrc")) as rcFile:
+ self.rcLines.extend(rcFile)
except IOError:
pass
- else:
- for line in rcFile.readlines():
- self.rcLines.append(line)
- rcFile.close()
try:
- rcFile = open(".pdbrc")
+ with open(".pdbrc") as rcFile:
+ self.rcLines.extend(rcFile)
except IOError:
pass
- else:
- for line in rcFile.readlines():
- self.rcLines.append(line)
- rcFile.close()
self.commands = {} # associates a command list to breakpoint numbers
self.commands_doprompt = {} # for each bp num, tells if the prompt
Modified: python/branches/py3k/Lib/platform.py
==============================================================================
--- python/branches/py3k/Lib/platform.py (original)
+++ python/branches/py3k/Lib/platform.py Fri Sep 3 21:52:03 2010
@@ -200,9 +200,8 @@
"""
if os.path.exists('/var/adm/inst-log/info'):
# SuSE Linux stores distribution information in that file
- info = open('/var/adm/inst-log/info').readlines()
distname = 'SuSE'
- for line in info:
+ for line in open('/var/adm/inst-log/info'):
tv = line.split()
if len(tv) == 2:
tag,value = tv
@@ -217,8 +216,7 @@
if os.path.exists('/etc/.installed'):
# Caldera OpenLinux has some infos in that file (thanks to Colin Kong)
- info = open('/etc/.installed').readlines()
- for line in info:
+ for line in open('/etc/.installed'):
pkg = line.split('-')
if len(pkg) >= 2 and pkg[0] == 'OpenLinux':
# XXX does Caldera support non Intel platforms ? If yes,
@@ -327,9 +325,8 @@
return _dist_try_harder(distname,version,id)
# Read the first line
- f = open('/etc/'+file, 'r')
- firstline = f.readline()
- f.close()
+ with open('/etc/'+file, 'r') as f:
+ firstline = f.readline()
_distname, _version, _id = _parse_release_file(firstline)
if _distname and full_distribution_name:
Modified: python/branches/py3k/Lib/turtle.py
==============================================================================
--- python/branches/py3k/Lib/turtle.py (original)
+++ python/branches/py3k/Lib/turtle.py Fri Sep 3 21:52:03 2010
@@ -169,9 +169,8 @@
def config_dict(filename):
"""Convert content of config-file into dictionary."""
- f = open(filename, "r")
- cfglines = f.readlines()
- f.close()
+ with open(filename, "r") as f:
+ cfglines = f.readlines()
cfgdict = {}
for line in cfglines:
line = line.strip()
From python-checkins at python.org Fri Sep 3 21:54:03 2010
From: python-checkins at python.org (florent.xicluna)
Date: Fri, 3 Sep 2010 21:54:03 +0200 (CEST)
Subject: [Python-checkins] r84468 - python/branches/py3k/Lib/tokenize.py
Message-ID: <20100903195403.06379F0B1@mail.python.org>
Author: florent.xicluna
Date: Fri Sep 3 21:54:02 2010
New Revision: 84468
Log:
Remove unused import, fix typo and rewrap docstrings.
Modified:
python/branches/py3k/Lib/tokenize.py
Modified: python/branches/py3k/Lib/tokenize.py
==============================================================================
--- python/branches/py3k/Lib/tokenize.py (original)
+++ python/branches/py3k/Lib/tokenize.py Fri Sep 3 21:54:02 2010
@@ -1,12 +1,12 @@
"""Tokenization help for Python programs.
-tokenize(readline) is a generator that breaks a stream of
-bytes into Python tokens. It decodes the bytes according to
-PEP-0263 for determining source file encoding.
-
-It accepts a readline-like method which is called
-repeatedly to get the next line of input (or b"" for EOF). It generates
-5-tuples with these members:
+tokenize(readline) is a generator that breaks a stream of bytes into
+Python tokens. It decodes the bytes according to PEP-0263 for
+determining source file encoding.
+
+It accepts a readline-like method which is called repeatedly to get the
+next line of input (or b"" for EOF). It generates 5-tuples with these
+members:
the token type (see token.py)
the token (a string)
@@ -16,14 +16,16 @@
It is designed to match the working of the Python tokenizer exactly, except
that it produces COMMENT tokens for comments and gives type OP for all
-operators. Aditionally, all token lists start with an ENCODING token
-which tells you which encoding was used to decode the bytes stream."""
+operators. Additionally, all token lists start with an ENCODING token
+which tells you which encoding was used to decode the bytes stream.
+"""
__author__ = 'Ka-Ping Yee '
__credits__ = ('GvR, ESR, Tim Peters, Thomas Wouters, Fred Drake, '
'Skip Montanaro, Raymond Hettinger, Trent Nelson, '
'Michael Foord')
-import re, string, sys
+import re
+import sys
from token import *
from codecs import lookup, BOM_UTF8
cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
@@ -298,17 +300,16 @@
def detect_encoding(readline):
"""
The detect_encoding() function is used to detect the encoding that should
- be used to decode a Python source file. It requires one argment, readline,
+ be used to decode a Python source file. It requires one argment, readline,
in the same way as the tokenize() generator.
It will call readline a maximum of twice, and return the encoding used
- (as a string) and a list of any lines (left as bytes) it has read
- in.
+ (as a string) and a list of any lines (left as bytes) it has read in.
It detects the encoding from the presence of a utf-8 bom or an encoding
- cookie as specified in pep-0263. If both a bom and a cookie are present, but
- disagree, a SyntaxError will be raised. If the encoding cookie is an invalid
- charset, raise a SyntaxError. Note that if a utf-8 bom is found,
+ cookie as specified in pep-0263. If both a bom and a cookie are present,
+ but disagree, a SyntaxError will be raised. If the encoding cookie is an
+ invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found,
'utf-8-sig' is returned.
If no encoding is specified, then the default of 'utf-8' will be returned.
@@ -372,7 +373,7 @@
"""
The tokenize() generator requires one argment, readline, which
must be a callable object which provides the same interface as the
- readline() method of built-in file objects. Each call to the function
+ readline() method of built-in file objects. Each call to the function
should return one line of input as bytes. Alternately, readline
can be a callable function terminating with StopIteration:
readline = open(myfile, 'rb').__next__ # Example of alternate readline
@@ -381,7 +382,7 @@
token string; a 2-tuple (srow, scol) of ints specifying the row and
column where the token begins in the source; a 2-tuple (erow, ecol) of
ints specifying the row and column where the token ends in the source;
- and the line on which the token was found. The line passed is the
+ and the line on which the token was found. The line passed is the
logical line; continuation lines are included.
The first token sequence will always be an ENCODING token
From python-checkins at python.org Fri Sep 3 21:55:26 2010
From: python-checkins at python.org (florent.xicluna)
Date: Fri, 3 Sep 2010 21:55:26 +0200 (CEST)
Subject: [Python-checkins] r84469 -
python/branches/py3k/Lib/importlib/_bootstrap.py
Message-ID: <20100903195526.44830EEA30@mail.python.org>
Author: florent.xicluna
Date: Fri Sep 3 21:55:26 2010
New Revision: 84469
Log:
Remove redundant context manager.
Modified:
python/branches/py3k/Lib/importlib/_bootstrap.py
Modified: python/branches/py3k/Lib/importlib/_bootstrap.py
==============================================================================
--- python/branches/py3k/Lib/importlib/_bootstrap.py (original)
+++ python/branches/py3k/Lib/importlib/_bootstrap.py Fri Sep 3 21:55:26 2010
@@ -80,20 +80,6 @@
return _path_join(_os.getcwd(), path)
-class _closing:
-
- """Simple replacement for contextlib.closing."""
-
- def __init__(self, obj):
- self.obj = obj
-
- def __enter__(self):
- return self.obj
-
- def __exit__(self, *args):
- self.obj.close()
-
-
def _wrap(new, old):
"""Simple substitute for functools.wraps."""
for replace in ['__module__', '__name__', '__doc__']:
@@ -468,7 +454,7 @@
def get_data(self, path):
"""Return the data from path as raw bytes."""
- with _closing(_io.FileIO(path, 'r')) as file:
+ with _io.FileIO(path, 'r') as file:
return file.read()
From python-checkins at python.org Fri Sep 3 22:00:37 2010
From: python-checkins at python.org (florent.xicluna)
Date: Fri, 3 Sep 2010 22:00:37 +0200 (CEST)
Subject: [Python-checkins] r84470 -
python/branches/py3k/Lib/test/test_bytes.py
Message-ID: <20100903200037.38A7FF4A9@mail.python.org>
Author: florent.xicluna
Date: Fri Sep 3 22:00:37 2010
New Revision: 84470
Log:
Strengthen BytesWarning tests.
Modified:
python/branches/py3k/Lib/test/test_bytes.py
Modified: python/branches/py3k/Lib/test/test_bytes.py
==============================================================================
--- python/branches/py3k/Lib/test/test_bytes.py (original)
+++ python/branches/py3k/Lib/test/test_bytes.py Fri Sep 3 22:00:37 2010
@@ -9,15 +9,28 @@
import re
import sys
import copy
-import operator
+import functools
import pickle
import tempfile
import unittest
-import warnings
import test.support
import test.string_tests
import test.buffer_tests
+
+if sys.flags.bytes_warning:
+ def check_bytes_warnings(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kw):
+ with test.support.check_warnings(('', BytesWarning)):
+ return func(*args, **kw)
+ return wrapper
+else:
+ # no-op
+ def check_bytes_warnings(func):
+ return func
+
+
class Indexable:
def __init__(self, value=0):
self.value = value
@@ -121,20 +134,19 @@
self.assertFalse(b3 < b2)
self.assertFalse(b3 <= b2)
+ @check_bytes_warnings
def test_compare_to_str(self):
- with test.support.check_warnings():
- warnings.simplefilter('ignore', BytesWarning)
- # Byte comparisons with unicode should always fail!
- # Test this for all expected byte orders and Unicode character
- # sizes.
- self.assertEqual(self.type2test(b"\0a\0b\0c") == "abc", False)
- self.assertEqual(self.type2test(b"\0\0\0a\0\0\0b\0\0\0c") == "abc",
- False)
- self.assertEqual(self.type2test(b"a\0b\0c\0") == "abc", False)
- self.assertEqual(self.type2test(b"a\0\0\0b\0\0\0c\0\0\0") == "abc",
- False)
- self.assertEqual(self.type2test() == str(), False)
- self.assertEqual(self.type2test() != str(), True)
+ # Byte comparisons with unicode should always fail!
+ # Test this for all expected byte orders and Unicode character
+ # sizes.
+ self.assertEqual(self.type2test(b"\0a\0b\0c") == "abc", False)
+ self.assertEqual(self.type2test(b"\0\0\0a\0\0\0b\0\0\0c") == "abc",
+ False)
+ self.assertEqual(self.type2test(b"a\0b\0c\0") == "abc", False)
+ self.assertEqual(self.type2test(b"a\0\0\0b\0\0\0c\0\0\0") == "abc",
+ False)
+ self.assertEqual(self.type2test() == str(), False)
+ self.assertEqual(self.type2test() != str(), True)
def test_reversed(self):
input = list(map(ord, "Hello"))
@@ -823,17 +835,16 @@
# Test various combinations of bytes and bytearray
#
+ @check_bytes_warnings
def test_repr_str(self):
- with test.support.check_warnings():
- warnings.simplefilter('ignore', BytesWarning)
- for f in str, repr:
- self.assertEqual(f(bytearray()), "bytearray(b'')")
- self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
- self.assertEqual(f(bytearray([0, 1, 254, 255])),
- "bytearray(b'\\x00\\x01\\xfe\\xff')")
- self.assertEqual(f(b"abc"), "b'abc'")
- self.assertEqual(f(b"'"), '''b"'"''') # '''
- self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
+ for f in str, repr:
+ self.assertEqual(f(bytearray()), "bytearray(b'')")
+ self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
+ self.assertEqual(f(bytearray([0, 1, 254, 255])),
+ "bytearray(b'\\x00\\x01\\xfe\\xff')")
+ self.assertEqual(f(b"abc"), "b'abc'")
+ self.assertEqual(f(b"'"), '''b"'"''') # '''
+ self.assertEqual(f(b"'\""), r"""b'\'"'""") # '
def test_compare_bytes_to_bytearray(self):
self.assertEqual(b"abc" == bytes(b"abc"), True)
@@ -876,15 +887,14 @@
b = bytearray(buf)
self.assertEqual(b, bytearray(sample))
+ @check_bytes_warnings
def test_to_str(self):
- with test.support.check_warnings():
- warnings.simplefilter('ignore', BytesWarning)
- self.assertEqual(str(b''), "b''")
- self.assertEqual(str(b'x'), "b'x'")
- self.assertEqual(str(b'\x80'), "b'\\x80'")
- self.assertEqual(str(bytearray(b'')), "bytearray(b'')")
- self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')")
- self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')")
+ self.assertEqual(str(b''), "b''")
+ self.assertEqual(str(b'x'), "b'x'")
+ self.assertEqual(str(b'\x80'), "b'\\x80'")
+ self.assertEqual(str(bytearray(b'')), "bytearray(b'')")
+ self.assertEqual(str(bytearray(b'x')), "bytearray(b'x')")
+ self.assertEqual(str(bytearray(b'\x80')), "bytearray(b'\\x80')")
def test_literal(self):
tests = [
@@ -930,19 +940,18 @@
def test_compare(self):
if sys.flags.bytes_warning:
- with test.support.check_warnings():
- warnings.simplefilter('error', BytesWarning)
- with self.assertRaises(BytesWarning):
- b'' == ''
- with self.assertRaises(BytesWarning):
- b'' != ''
- with self.assertRaises(BytesWarning):
- bytearray(b'') == ''
- with self.assertRaises(BytesWarning):
- bytearray(b'') != ''
+ def bytes_warning():
+ return test.support.check_warnings(('', BytesWarning))
+ with bytes_warning():
+ b'' == ''
+ with bytes_warning():
+ b'' != ''
+ with bytes_warning():
+ bytearray(b'') == ''
+ with bytes_warning():
+ bytearray(b'') != ''
else:
- # self.skipTest("BytesWarning is needed for this test: use -bb option")
- pass
+ self.skipTest("BytesWarning is needed for this test: use -bb option")
# Optimizations:
# __iter__? (optimization)
From python-checkins at python.org Fri Sep 3 22:23:40 2010
From: python-checkins at python.org (florent.xicluna)
Date: Fri, 3 Sep 2010 22:23:40 +0200 (CEST)
Subject: [Python-checkins] r84471 -
python/branches/py3k/Doc/reference/simple_stmts.rst
Message-ID: <20100903202340.8324AF1F2@mail.python.org>
Author: florent.xicluna
Date: Fri Sep 3 22:23:40 2010
New Revision: 84471
Log:
Typo
Modified:
python/branches/py3k/Doc/reference/simple_stmts.rst
Modified: python/branches/py3k/Doc/reference/simple_stmts.rst
==============================================================================
--- python/branches/py3k/Doc/reference/simple_stmts.rst (original)
+++ python/branches/py3k/Doc/reference/simple_stmts.rst Fri Sep 3 22:23:40 2010
@@ -823,7 +823,7 @@
exists. Two dots means up one package level. Three dots is up two levels, etc.
So if you execute ``from . import mod`` from a module in the ``pkg`` package
then you will end up importing ``pkg.mod``. If you execute ``from ..subpkg2
-imprt mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``.
+import mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``.
The specification for relative imports is contained within :pep:`328`.
:func:`importlib.import_module` is provided to support applications that
From python-checkins at python.org Sat Sep 4 00:03:11 2010
From: python-checkins at python.org (eric.araujo)
Date: Sat, 4 Sep 2010 00:03:11 +0200 (CEST)
Subject: [Python-checkins] r84472 -
python/branches/py3k/Modules/_heapqmodule.c
Message-ID: <20100903220311.162C9F7F4@mail.python.org>
Author: eric.araujo
Date: Sat Sep 4 00:03:10 2010
New Revision: 84472
Log:
Fix invalid bytes for UTF-8
Modified:
python/branches/py3k/Modules/_heapqmodule.c
Modified: python/branches/py3k/Modules/_heapqmodule.c
==============================================================================
--- python/branches/py3k/Modules/_heapqmodule.c (original)
+++ python/branches/py3k/Modules/_heapqmodule.c Sat Sep 4 00:03:10 2010
@@ -2,7 +2,7 @@
C implementation derived directly from heapq.py in Py2.3
which was written by Kevin O'Connor, augmented by Tim Peters,
-annotated by Fran?ois Pinard, and converted to C by Raymond Hettinger.
+annotated by Fran??ois Pinard, and converted to C by Raymond Hettinger.
*/
From python-checkins at python.org Sat Sep 4 00:05:17 2010
From: python-checkins at python.org (eric.araujo)
Date: Sat, 4 Sep 2010 00:05:17 +0200 (CEST)
Subject: [Python-checkins] r84473 - in python/branches/release31-maint:
Modules/_heapqmodule.c
Message-ID: <20100903220517.5B4A1F269@mail.python.org>
Author: eric.araujo
Date: Sat Sep 4 00:05:17 2010
New Revision: 84473
Log:
Merged revisions 84472 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84472 | eric.araujo | 2010-09-04 00:03:10 +0200 (sam., 04 sept. 2010) | 2 lines
Fix invalid bytes for UTF-8
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Modules/_heapqmodule.c
Modified: python/branches/release31-maint/Modules/_heapqmodule.c
==============================================================================
--- python/branches/release31-maint/Modules/_heapqmodule.c (original)
+++ python/branches/release31-maint/Modules/_heapqmodule.c Sat Sep 4 00:05:17 2010
@@ -2,7 +2,7 @@
C implementation derived directly from heapq.py in Py2.3
which was written by Kevin O'Connor, augmented by Tim Peters,
-annotated by Fran?ois Pinard, and converted to C by Raymond Hettinger.
+annotated by Fran??ois Pinard, and converted to C by Raymond Hettinger.
*/
From python-checkins at python.org Sat Sep 4 00:06:31 2010
From: python-checkins at python.org (eric.araujo)
Date: Sat, 4 Sep 2010 00:06:31 +0200 (CEST)
Subject: [Python-checkins] r84474 - in python/branches/release27-maint:
Modules/_heapqmodule.c
Message-ID: <20100903220631.3BF18F46E@mail.python.org>
Author: eric.araujo
Date: Sat Sep 4 00:06:31 2010
New Revision: 84474
Log:
Merged revisions 84472 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84472 | eric.araujo | 2010-09-04 00:03:10 +0200 (sam., 04 sept. 2010) | 2 lines
Fix invalid bytes for UTF-8
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Modules/_heapqmodule.c
Modified: python/branches/release27-maint/Modules/_heapqmodule.c
==============================================================================
--- python/branches/release27-maint/Modules/_heapqmodule.c (original)
+++ python/branches/release27-maint/Modules/_heapqmodule.c Sat Sep 4 00:06:31 2010
@@ -2,7 +2,7 @@
C implementation derived directly from heapq.py in Py2.3
which was written by Kevin O'Connor, augmented by Tim Peters,
-annotated by Fran?ois Pinard, and converted to C by Raymond Hettinger.
+annotated by Fran??ois Pinard, and converted to C by Raymond Hettinger.
*/
From python-checkins at python.org Sat Sep 4 00:13:42 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 4 Sep 2010 00:13:42 +0200 (CEST)
Subject: [Python-checkins] r84475 -
python/branches/py3k/Doc/c-api/unicode.rst
Message-ID: <20100903221342.A1D8DC621@mail.python.org>
Author: victor.stinner
Date: Sat Sep 4 00:13:42 2010
New Revision: 84475
Log:
Add versionadded tag to PyUnicode_AsUnicodeCopy's doc
Modified:
python/branches/py3k/Doc/c-api/unicode.rst
Modified: python/branches/py3k/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/unicode.rst (original)
+++ python/branches/py3k/Doc/c-api/unicode.rst Sat Sep 4 00:13:42 2010
@@ -342,6 +342,8 @@
otherwise return a new allocated buffer (use :cfunc:`PyMem_Free` to free the
buffer).
+ .. versionadded:: 3.2
+
.. cfunction:: Py_ssize_t PyUnicode_GetSize(PyObject *unicode)
From python-checkins at python.org Sat Sep 4 00:14:52 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:14:52 +0200 (CEST)
Subject: [Python-checkins] r84476 - python/branches/py3k/Makefile.pre.in
Message-ID: <20100903221452.DB294EAD1@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:14:52 2010
New Revision: 84476
Log:
Use tabs consistently.
Modified:
python/branches/py3k/Makefile.pre.in
Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in (original)
+++ python/branches/py3k/Makefile.pre.in Sat Sep 4 00:14:52 2010
@@ -35,9 +35,9 @@
AR= @AR@
RANLIB= @RANLIB@
SVNVERSION= @SVNVERSION@
-SOABI= @SOABI@
+SOABI= @SOABI@
-GNULD= @GNULD@
+GNULD= @GNULD@
# Shell used by make (some versions default to the login shell, which is bad)
SHELL= /bin/sh
From python-checkins at python.org Sat Sep 4 00:19:08 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:19:08 +0200 (CEST)
Subject: [Python-checkins] r84477 - python/branches/py3k/configure.in
Message-ID: <20100903221908.0B0F3F569@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:19:07 2010
New Revision: 84477
Log:
Fix typos and use tabs consistently.
Modified:
python/branches/py3k/configure.in
Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in (original)
+++ python/branches/py3k/configure.in Sat Sep 4 00:19:07 2010
@@ -52,7 +52,7 @@
AC_SUBST(VERSION)
VERSION=PYTHON_VERSION
-# Version number or Python's own shared library file.
+# Version number of Python's own shared library file.
AC_SUBST(SOVERSION)
SOVERSION=1.0
@@ -3630,8 +3630,8 @@
# * --with-wide-unicode (adds a 'u')
#
# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc,
-# would get a shared library ABI version tag of 'cpython-32udm' and shared
-# libraries would be named 'foo.cpython-32udm.so'.
+# would get a shared library ABI version tag of 'cpython-32dmu' and shared
+# libraries would be named 'foo.cpython-32dmu.so'.
AC_SUBST(SOABI)
AC_MSG_CHECKING(SOABI)
SOABI='cpython-'`echo $VERSION | tr -d .`${SOABI_QUALIFIERS}
@@ -3650,19 +3650,19 @@
esac
;;
CYGWIN*) SO=.dll;;
- Linux*) SO=.${SOABI}.so;;
+ Linux*) SO=.${SOABI}.so;;
*) SO=.so;;
esac
else
# this might also be a termcap variable, see #610332
- echo
- echo '====================================================================='
- echo '+ +'
+ echo
+ echo '====================================================================='
+ echo '+ +'
echo '+ WARNING: You have set SO in your environment. +'
- echo '+ Do you really mean to change the extension for shared libraries? +'
- echo '+ Continuing in 10 seconds to let you to ponder. +'
- echo '+ +'
- echo '====================================================================='
+ echo '+ Do you really mean to change the extension for shared libraries? +'
+ echo '+ Continuing in 10 seconds to let you to ponder. +'
+ echo '+ +'
+ echo '====================================================================='
sleep 10
fi
AC_MSG_RESULT($SO)
From python-checkins at python.org Sat Sep 4 00:20:58 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:20:58 +0200 (CEST)
Subject: [Python-checkins] r84478 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100903222058.EA688C4CE@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:20:58 2010
New Revision: 84478
Log:
Make PEP section a bit less ugly and at least list implemented PEPs.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sat Sep 4 00:20:58 2010
@@ -51,8 +51,13 @@
This article explains the new features in Python 3.2, compared to 3.1.
-PEP XXX: Stub
-=============
+PEPs
+====
+
+Implemented PEPs:
+
+* :pep:`3147`
+* :pep:`3149`
Other Language Changes
From python-checkins at python.org Sat Sep 4 00:29:08 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:29:08 +0200 (CEST)
Subject: [Python-checkins] r84479 - python/branches/py3k/pyconfig.h.in
Message-ID: <20100903222908.99C1BEBC8@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:29:08 2010
New Revision: 84479
Log:
Revert unintended change from r84458.
Modified:
python/branches/py3k/pyconfig.h.in
Modified: python/branches/py3k/pyconfig.h.in
==============================================================================
--- python/branches/py3k/pyconfig.h.in (original)
+++ python/branches/py3k/pyconfig.h.in Sat Sep 4 00:29:08 2010
@@ -1040,7 +1040,8 @@
/* Define to 1 if your declares `struct tm'. */
#undef TM_IN_SYS_TIME
-/* Define if you want to use computed gotos in ceval.c. */
+/* Define to 0 if you don't want to use computed gotos in ceval.c.
+ (The default is to use them if HAVE_COMPUTED_GOTOS is defined.) */
#undef USE_COMPUTED_GOTOS
/* Define if the compiler supports the inline keyword */
From python-checkins at python.org Sat Sep 4 00:33:27 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:33:27 +0200 (CEST)
Subject: [Python-checkins] r84480 - in python/branches/py3k/Doc: conf.py
tools/sphinxext/indexcontent.html using/index.rst
Message-ID: <20100903223327.3B5D8F513@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:33:27 2010
New Revision: 84480
Log:
More inclusive title.
Modified:
python/branches/py3k/Doc/conf.py
python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
python/branches/py3k/Doc/using/index.rst
Modified: python/branches/py3k/Doc/conf.py
==============================================================================
--- python/branches/py3k/Doc/conf.py (original)
+++ python/branches/py3k/Doc/conf.py Sat Sep 4 00:33:27 2010
@@ -131,7 +131,7 @@
('tutorial/index', 'tutorial.tex',
'Python Tutorial', _stdauthor, 'manual'),
('using/index', 'using.tex',
- 'Python Setup', _stdauthor, 'manual'),
+ 'Python Setup and Usage', _stdauthor, 'manual'),
('whatsnew/' + version, 'whatsnew.tex',
'What\'s New in Python', 'A. M. Kuchling', 'howto'),
]
Modified: python/branches/py3k/Doc/tools/sphinxext/indexcontent.html
==============================================================================
--- python/branches/py3k/Doc/tools/sphinxext/indexcontent.html (original)
+++ python/branches/py3k/Doc/tools/sphinxext/indexcontent.html Sat Sep 4 00:33:27 2010
@@ -11,7 +11,7 @@
keep this under your pillow
Language Reference
describes syntax and language elements
- Python Setup
+
Python Setup and Usage
how to use Python on different platforms
Python HOWTOs
in-depth documents on specific topics
Modified: python/branches/py3k/Doc/using/index.rst
==============================================================================
--- python/branches/py3k/Doc/using/index.rst (original)
+++ python/branches/py3k/Doc/using/index.rst Sat Sep 4 00:33:27 2010
@@ -1,8 +1,8 @@
.. _using-index:
-################
- Python Setup
-################
+##########################
+ Python Setup and Usage
+##########################
This part of the documentation is devoted to general information on the setup
From python-checkins at python.org Sat Sep 4 00:36:23 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:36:23 +0200 (CEST)
Subject: [Python-checkins] r84481 - python/branches/py3k/Doc/library/json.rst
Message-ID: <20100903223623.19ABDEB74@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:36:22 2010
New Revision: 84481
Log:
#9767: doctest run over json docs.
Modified:
python/branches/py3k/Doc/library/json.rst
Modified: python/branches/py3k/Doc/library/json.rst
==============================================================================
--- python/branches/py3k/Doc/library/json.rst (original)
+++ python/branches/py3k/Doc/library/json.rst Sat Sep 4 00:36:22 2010
@@ -82,12 +82,12 @@
... return [obj.real, obj.imag]
... return json.JSONEncoder.default(self, obj)
...
- >>> dumps(2 + 1j, cls=ComplexEncoder)
+ >>> json.dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
- ['[', '2.0', ', ', '1.0', ']']
+ ['[2.0', ', 1.0', ']']
.. highlight:: none
@@ -373,7 +373,7 @@
pass
else:
return list(iterable)
- return JSONEncoder.default(self, o)
+ return json.JSONEncoder.default(self, o)
.. method:: encode(o)
@@ -381,7 +381,7 @@
Return a JSON string representation of a Python data structure, *o*. For
example::
- >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
+ >>> json.JSONEncoder().encode({"foo": ["bar", "baz"]})
'{"foo": ["bar", "baz"]}'
@@ -390,5 +390,5 @@
Encode the given object, *o*, and yield each string representation as
available. For example::
- for chunk in JSONEncoder().iterencode(bigobject):
+ for chunk in json.JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)
From python-checkins at python.org Sat Sep 4 00:40:02 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:40:02 +0200 (CEST)
Subject: [Python-checkins] r84482 -
python/branches/py3k/Doc/reference/compound_stmts.rst
Message-ID: <20100903224002.8D0FEDA87@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:40:02 2010
New Revision: 84482
Log:
#9760: clarify what context expression is.
Modified:
python/branches/py3k/Doc/reference/compound_stmts.rst
Modified: python/branches/py3k/Doc/reference/compound_stmts.rst
==============================================================================
--- python/branches/py3k/Doc/reference/compound_stmts.rst (original)
+++ python/branches/py3k/Doc/reference/compound_stmts.rst Sat Sep 4 00:40:02 2010
@@ -350,7 +350,8 @@
The execution of the :keyword:`with` statement with one "item" proceeds as follows:
-#. The context expression is evaluated to obtain a context manager.
+#. The context expression (the expression given in the :token:`with_item`) is
+ evaluated to obtain a context manager.
#. The context manager's :meth:`__exit__` is loaded for later use.
From python-checkins at python.org Sat Sep 4 00:43:08 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Sat, 4 Sep 2010 00:43:08 +0200 (CEST)
Subject: [Python-checkins] r84483 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100903224308.BFC8ADA87@mail.python.org>
Author: amaury.forgeotdarc
Date: Sat Sep 4 00:43:08 2010
New Revision: 84483
Log:
Add an entry in whatsnew about the PyCObject -> PyCapsule move.
(It seems that I am the first SWIG user to try python 3.2...)
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sat Sep 4 00:43:08 2010
@@ -282,3 +282,7 @@
* "t#" format has been removed: use "s#" or "s*" instead
* "w" and "w#" formats has been removed: use "w*" instead
+* The :ctype:`PyCObject` type, deprecated in 3.1, has been removed. To wrap
+ opaque C pointers in Python objects, the :ctype:`PyCapsule` API should be
+ used instead; the new type has a well defined interface for passing typing
+ safety information and a less complicated signature for calling a destructor.
From python-checkins at python.org Sat Sep 4 00:49:27 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 4 Sep 2010 00:49:27 +0200 (CEST)
Subject: [Python-checkins] r84484 -
python/branches/py3k/Doc/library/multiprocessing.rst
Message-ID: <20100903224927.F256BF513@mail.python.org>
Author: georg.brandl
Date: Sat Sep 4 00:49:27 2010
New Revision: 84484
Log:
Fix missing word.
Modified:
python/branches/py3k/Doc/library/multiprocessing.rst
Modified: python/branches/py3k/Doc/library/multiprocessing.rst
==============================================================================
--- python/branches/py3k/Doc/library/multiprocessing.rst (original)
+++ python/branches/py3k/Doc/library/multiprocessing.rst Sat Sep 4 00:49:27 2010
@@ -2221,8 +2221,8 @@
.. literalinclude:: ../includes/mp_synchronize.py
-An showing how to use queues to feed tasks to a collection of worker process and
-collect the results:
+An example showing how to use queues to feed tasks to a collection of worker
+process and collect the results:
.. literalinclude:: ../includes/mp_workers.py
From python-checkins at python.org Sat Sep 4 01:47:32 2010
From: python-checkins at python.org (florent.xicluna)
Date: Sat, 4 Sep 2010 01:47:32 +0200 (CEST)
Subject: [Python-checkins] r84485 - in python/branches/py3k:
Modules/_sqlite/cache.c Modules/_sqlite/cache.h
Modules/_sqlite/connection.c Modules/_sqlite/connection.h
Modules/_sqlite/cursor.h Modules/_sqlite/module.c
Modules/_sqlite/module.h Modules/_sqlite/prepare_protocol.c
Modules/_sqlite/prepare_protocol.h Modules/_sqlite/row.c
Modules/_sqlite/row.h Modules/_sqlite/sqlitecompat.h
Modules/_sqlite/statement.c Modules/_sqlite/statement.h
Modules/_sqlite/util.c Modules/_sqlite/util.h
Modules/unicodedata.c PC/_msi.c
Message-ID: <20100903234732.532F9D2A5@mail.python.org>
Author: florent.xicluna
Date: Sat Sep 4 01:47:32 2010
New Revision: 84485
Log:
Welcome in the UTF-8 world.
Modified:
python/branches/py3k/Modules/_sqlite/cache.c
python/branches/py3k/Modules/_sqlite/cache.h
python/branches/py3k/Modules/_sqlite/connection.c
python/branches/py3k/Modules/_sqlite/connection.h
python/branches/py3k/Modules/_sqlite/cursor.h
python/branches/py3k/Modules/_sqlite/module.c
python/branches/py3k/Modules/_sqlite/module.h
python/branches/py3k/Modules/_sqlite/prepare_protocol.c
python/branches/py3k/Modules/_sqlite/prepare_protocol.h
python/branches/py3k/Modules/_sqlite/row.c
python/branches/py3k/Modules/_sqlite/row.h
python/branches/py3k/Modules/_sqlite/sqlitecompat.h
python/branches/py3k/Modules/_sqlite/statement.c
python/branches/py3k/Modules/_sqlite/statement.h
python/branches/py3k/Modules/_sqlite/util.c
python/branches/py3k/Modules/_sqlite/util.h
python/branches/py3k/Modules/unicodedata.c
python/branches/py3k/PC/_msi.c
Modified: python/branches/py3k/Modules/_sqlite/cache.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/cache.c (original)
+++ python/branches/py3k/Modules/_sqlite/cache.c Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* cache .c - a LRU cache
*
- * Copyright (C) 2004-2010 Gerhard H?ring
+ * Copyright (C) 2004-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/cache.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/cache.h (original)
+++ python/branches/py3k/Modules/_sqlite/cache.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* cache.h - definitions for the LRU cache
*
- * Copyright (C) 2004-2010 Gerhard H?ring
+ * Copyright (C) 2004-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/connection.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/connection.c (original)
+++ python/branches/py3k/Modules/_sqlite/connection.c Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* connection.c - the connection type
*
- * Copyright (C) 2004-2010 Gerhard H?ring
+ * Copyright (C) 2004-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/connection.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/connection.h (original)
+++ python/branches/py3k/Modules/_sqlite/connection.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* connection.h - definitions for the connection type
*
- * Copyright (C) 2004-2010 Gerhard H?ring
+ * Copyright (C) 2004-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/cursor.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/cursor.h (original)
+++ python/branches/py3k/Modules/_sqlite/cursor.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* cursor.h - definitions for the cursor type
*
- * Copyright (C) 2004-2010 Gerhard H?ring
+ * Copyright (C) 2004-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/module.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/module.c (original)
+++ python/branches/py3k/Modules/_sqlite/module.c Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* module.c - the module itself
*
- * Copyright (C) 2004-2010 Gerhard H?ring
+ * Copyright (C) 2004-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/module.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/module.h (original)
+++ python/branches/py3k/Modules/_sqlite/module.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* module.h - definitions for the module
*
- * Copyright (C) 2004-2010 Gerhard H?ring
+ * Copyright (C) 2004-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/prepare_protocol.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/prepare_protocol.c (original)
+++ python/branches/py3k/Modules/_sqlite/prepare_protocol.c Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* prepare_protocol.c - the protocol for preparing values for SQLite
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/prepare_protocol.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/prepare_protocol.h (original)
+++ python/branches/py3k/Modules/_sqlite/prepare_protocol.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* prepare_protocol.h - the protocol for preparing values for SQLite
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/row.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/row.c (original)
+++ python/branches/py3k/Modules/_sqlite/row.c Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* row.c - an enhanced tuple for database rows
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/row.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/row.h (original)
+++ python/branches/py3k/Modules/_sqlite/row.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* row.h - an enhanced tuple for database rows
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/sqlitecompat.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/sqlitecompat.h (original)
+++ python/branches/py3k/Modules/_sqlite/sqlitecompat.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* sqlitecompat.h - compatibility macros
*
- * Copyright (C) 2006-2010 Gerhard H?ring
+ * Copyright (C) 2006-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/statement.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/statement.c (original)
+++ python/branches/py3k/Modules/_sqlite/statement.c Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* statement.c - the statement type
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/statement.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/statement.h (original)
+++ python/branches/py3k/Modules/_sqlite/statement.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* statement.h - definitions for the statement type
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/util.c
==============================================================================
--- python/branches/py3k/Modules/_sqlite/util.c (original)
+++ python/branches/py3k/Modules/_sqlite/util.c Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* util.c - various utility functions
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/_sqlite/util.h
==============================================================================
--- python/branches/py3k/Modules/_sqlite/util.h (original)
+++ python/branches/py3k/Modules/_sqlite/util.h Sat Sep 4 01:47:32 2010
@@ -1,6 +1,6 @@
/* util.h - various utility functions
*
- * Copyright (C) 2005-2010 Gerhard H?ring
+ * Copyright (C) 2005-2010 Gerhard H??ring
*
* This file is part of pysqlite.
*
Modified: python/branches/py3k/Modules/unicodedata.c
==============================================================================
--- python/branches/py3k/Modules/unicodedata.c (original)
+++ python/branches/py3k/Modules/unicodedata.c Sat Sep 4 01:47:32 2010
@@ -6,7 +6,7 @@
Written by Marc-Andre Lemburg (mal at lemburg.com).
Modified for Python 2.0 by Fredrik Lundh (fredrik at pythonware.com)
- Modified by Martin v. L?wis (martin at v.loewis.de)
+ Modified by Martin v. L??wis (martin at v.loewis.de)
Copyright (c) Corporation for National Research Initiatives.
Modified: python/branches/py3k/PC/_msi.c
==============================================================================
--- python/branches/py3k/PC/_msi.c (original)
+++ python/branches/py3k/PC/_msi.c Sat Sep 4 01:47:32 2010
@@ -1,5 +1,5 @@
/* Helper library for MSI creation with Python.
- * Copyright (C) 2005 Martin v. L?wis
+ * Copyright (C) 2005 Martin v. L??wis
* Licensed to PSF under a contributor agreement.
*/
From python-checkins at python.org Sat Sep 4 01:56:06 2010
From: python-checkins at python.org (florent.xicluna)
Date: Sat, 4 Sep 2010 01:56:06 +0200 (CEST)
Subject: [Python-checkins] r84485 - svn:log
Message-ID: <20100903235606.A70E1EFB5@mail.python.org>
Author: florent.xicluna
Revision: 84485
Property Name: svn:log
Action: modified
Property diff:
--- old property value
+++ new property value
@@ -1 +1 @@
-Welcome in the UTF-8 world.
\ No newline at end of file
+Welcome to the UTF-8 world.
From solipsis at pitrou.net Sat Sep 4 05:01:29 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Sat, 04 Sep 2010 05:01:29 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84485): sum=0
Message-ID:
py3k results for svn r84485 (hg cset 1fbac42d64e5)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogrxB6b0', '-x']
From python-checkins at python.org Sat Sep 4 06:35:35 2010
From: python-checkins at python.org (fred.drake)
Date: Sat, 4 Sep 2010 06:35:35 +0200 (CEST)
Subject: [Python-checkins] r84486 - in python/branches/py3k:
Doc/library/configparser.rst Lib/configparser.py
Lib/test/test_cfgparser.py Misc/NEWS
Message-ID: <20100904043535.2AEE5EB74@mail.python.org>
Author: fred.drake
Date: Sat Sep 4 06:35:34 2010
New Revision: 84486
Log:
add consistent support for the vars and default arguments on all
configuration parser classes
(http://bugs.python.org/issue9421)
Modified:
python/branches/py3k/Doc/library/configparser.rst
python/branches/py3k/Lib/configparser.py
python/branches/py3k/Lib/test/test_cfgparser.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/configparser.rst
==============================================================================
--- python/branches/py3k/Doc/library/configparser.rst (original)
+++ python/branches/py3k/Doc/library/configparser.rst Sat Sep 4 06:35:34 2010
@@ -135,7 +135,7 @@
*empty_lines_in_values* were added.
-.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), strict=False, empty_lines_in_values=True)
+.. class:: SafeConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True)
Derived class of :class:`ConfigParser` that implements a sane variant of the
magical interpolation feature. This implementation is more predictable as it
@@ -155,7 +155,7 @@
*empty_lines_in_values* were added.
-.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=('#', ';'), strict=False, empty_lines_in_values=True)
+.. class:: ConfigParser(defaults=None, dict_type=collections.OrderedDict, allow_no_value=False, delimiters=('=', ':'), comment_prefixes=_COMPATIBLE, strict=False, empty_lines_in_values=True)
Derived class of :class:`RawConfigParser` that implements the magical
interpolation feature and adds optional arguments to the :meth:`get` and
@@ -366,39 +366,44 @@
Load configuration from a dictionary. Keys are section names, values are
dictionaries with keys and values that should be present in the section. If
the used dictionary type preserves order, sections and their keys will be
- added in order.
+ added in order. Values are automatically converted to strings.
Optional argument *source* specifies a context-specific name of the
dictionary passed. If not given, ```` is used.
.. versionadded:: 3.2
+.. method:: RawConfigParser.get(section, option, [vars, default])
-.. method:: RawConfigParser.get(section, option)
-
- Get an *option* value for the named *section*.
+ Get an *option* value for the named *section*. If *vars* is provided, it
+ must be a dictionary. The *option* is looked up in *vars* (if provided),
+ *section*, and in *DEFAULTSECT* in that order. If the key is not found and
+ *default* is provided, it is used as a fallback value. ``None`` can be
+ provided as a *default* value.
-.. method:: RawConfigParser.getint(section, option)
+.. method:: RawConfigParser.getint(section, option, [vars, default])
- A convenience method which coerces the *option* in the specified *section* to an
- integer.
+ A convenience method which coerces the *option* in the specified *section* to
+ an integer. See :meth:`get` for explanation of *vars* and *default*.
-.. method:: RawConfigParser.getfloat(section, option)
+.. method:: RawConfigParser.getfloat(section, option, [vars, default])
- A convenience method which coerces the *option* in the specified *section* to a
- floating point number.
+ A convenience method which coerces the *option* in the specified *section* to
+ a floating point number. See :meth:`get` for explanation of *vars* and
+ *default*.
-.. method:: RawConfigParser.getboolean(section, option)
+.. method:: RawConfigParser.getboolean(section, option, [vars, default])
- A convenience method which coerces the *option* in the specified *section* to a
- Boolean value. Note that the accepted values for the option are ``"1"``,
- ``"yes"``, ``"true"``, and ``"on"``, which cause this method to return ``True``,
- and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which cause it to return
- ``False``. These string values are checked in a case-insensitive manner. Any
- other value will cause it to raise :exc:`ValueError`.
+ A convenience method which coerces the *option* in the specified *section*
+ to a Boolean value. Note that the accepted values for the option are
+ ``"1"``, ``"yes"``, ``"true"``, and ``"on"``, which cause this method to
+ return ``True``, and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which
+ cause it to return ``False``. These string values are checked in
+ a case-insensitive manner. Any other value will cause it to raise
+ :exc:`ValueError`. See :meth:`get` for explanation of *vars* and *default*.
.. method:: RawConfigParser.items(section)
@@ -475,17 +480,44 @@
for the interpolation.
-.. method:: ConfigParser.get(section, option, raw=False, vars=None)
+.. method:: ConfigParser.get(section, option, raw=False, [vars, default])
Get an *option* value for the named *section*. If *vars* is provided, it
must be a dictionary. The *option* is looked up in *vars* (if provided),
- *section*, and in *defaults* in that order.
+ *section*, and in *DEFAULTSECT* in that order. If the key is not found and
+ *default* is provided, it is used as a fallback value. ``None`` can be
+ provided as a *default* value.
All the ``'%'`` interpolations are expanded in the return values, unless the
*raw* argument is true. Values for interpolation keys are looked up in the
same manner as the option.
+.. method:: ConfigParser.getint(section, option, raw=False, [vars, default])
+
+ A convenience method which coerces the *option* in the specified *section* to
+ an integer. See :meth:`get` for explanation of *raw*, *vars* and *default*.
+
+
+.. method:: ConfigParser.getfloat(section, option, raw=False, [vars, default])
+
+ A convenience method which coerces the *option* in the specified *section* to
+ a floating point number. See :meth:`get` for explanation of *raw*, *vars*
+ and *default*.
+
+
+.. method:: ConfigParser.getboolean(section, option, raw=False, [vars, default])
+
+ A convenience method which coerces the *option* in the specified *section*
+ to a Boolean value. Note that the accepted values for the option are
+ ``"1"``, ``"yes"``, ``"true"``, and ``"on"``, which cause this method to
+ return ``True``, and ``"0"``, ``"no"``, ``"false"``, and ``"off"``, which
+ cause it to return ``False``. These string values are checked in
+ a case-insensitive manner. Any other value will cause it to raise
+ :exc:`ValueError`. See :meth:`get` for explanation of *raw*, *vars* and
+ *default*.
+
+
.. method:: ConfigParser.items(section, raw=False, vars=None)
Return a list of ``(name, value)`` pairs for each option in the given
Modified: python/branches/py3k/Lib/configparser.py
==============================================================================
--- python/branches/py3k/Lib/configparser.py (original)
+++ python/branches/py3k/Lib/configparser.py Sat Sep 4 06:35:34 2010
@@ -24,9 +24,9 @@
methods:
- __init__(defaults=None, dict_type=_default_dict,
- delimiters=('=', ':'), comment_prefixes=('#', ';'),
- strict=False, empty_lines_in_values=True, allow_no_value=False):
+ __init__(defaults=None, dict_type=_default_dict, allow_no_value=False,
+ delimiters=('=', ':'), comment_prefixes=_COMPATIBLE,
+ strict=False, empty_lines_in_values=True):
Create the parser. When `defaults' is given, it is initialized into the
dictionary or intrinsic defaults. The keys must be strings, the values
must be appropriate for %()s string interpolation. Note that `__name__'
@@ -82,22 +82,24 @@
Read configuration from a dictionary. Keys are section names,
values are dictionaries with keys and values that should be present
in the section. If the used dictionary type preserves order, sections
- and their keys will be added in order.
+ and their keys will be added in order. Values are automatically
+ converted to strings.
- get(section, option, raw=False, vars=None)
+ get(section, option, raw=False, vars=None, default=_UNSET)
Return a string value for the named option. All % interpolations are
expanded in the return values, based on the defaults passed into the
constructor and the DEFAULT section. Additional substitutions may be
provided using the `vars' argument, which must be a dictionary whose
- contents override any pre-existing defaults.
+ contents override any pre-existing defaults. If `option' is a key in
+ `vars', the value from `vars' is used.
- getint(section, options)
+ getint(section, options, raw=False, vars=None, default=_UNSET)
Like get(), but convert value to an integer.
- getfloat(section, options)
+ getfloat(section, options, raw=False, vars=None, default=_UNSET)
Like get(), but convert value to a float.
- getboolean(section, options)
+ getboolean(section, options, raw=False, vars=None, default=_UNSET)
Like get(), but convert value to a boolean (currently case
insensitively defined as 0, false, no, off for False, and 1, true,
yes, on for True). Returns False or True.
@@ -353,6 +355,17 @@
self.args = (filename, lineno, line)
+# Used in parsers to denote selecting a backwards-compatible inline comment
+# character behavior (; and # are comments at the start of a line, but ; only
+# inline)
+_COMPATIBLE = object()
+
+# Used in parser getters to indicate the default behaviour when a specific
+# option is not found it to raise an exception. Created to enable `None' as
+# a valid fallback value.
+_UNSET = object()
+
+
class RawConfigParser:
"""ConfigParser that does not do interpolation."""
@@ -389,9 +402,9 @@
OPTCRE_NV = re.compile(_OPT_NV_TMPL.format(delim="=|:"), re.VERBOSE)
# Compiled regular expression for matching leading whitespace in a line
NONSPACECRE = re.compile(r"\S")
- # Select backwards-compatible inline comment character behavior
- # (; and # are comments at the start of a line, but ; only inline)
- _COMPATIBLE = object()
+ # Possible boolean values in the configuration.
+ BOOLEAN_STATES = {'1': True, 'yes': True, 'true': True, 'on': True,
+ '0': False, 'no': False, 'false': False, 'off': False}
def __init__(self, defaults=None, dict_type=_default_dict,
allow_no_value=False, *, delimiters=('=', ':'),
@@ -414,7 +427,7 @@
else:
self._optcre = re.compile(self._OPT_TMPL.format(delim=d),
re.VERBOSE)
- if comment_prefixes is self._COMPATIBLE:
+ if comment_prefixes is _COMPATIBLE:
self._startonly_comment_prefixes = ('#',)
self._comment_prefixes = (';',)
else:
@@ -528,6 +541,8 @@
elements_added.add(section)
for key, value in keys.items():
key = self.optionxform(key)
+ if value is not None:
+ value = str(value)
if self._strict and (section, key) in elements_added:
raise DuplicateOptionError(section, key, source)
elements_added.add((section, key))
@@ -542,21 +557,29 @@
)
self.read_file(fp, source=filename)
- def get(self, section, option):
- opt = self.optionxform(option)
- if section not in self._sections:
- if section != DEFAULTSECT:
- raise NoSectionError(section)
- if opt in self._defaults:
- return self._defaults[opt]
+ def get(self, section, option, vars=None, default=_UNSET):
+ """Get an option value for a given section.
+
+ If `vars' is provided, it must be a dictionary. The option is looked up
+ in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
+ If the key is not found and `default' is provided, it is used as
+ a fallback value. `None' can be provided as a `default' value.
+ """
+ try:
+ d = self._unify_values(section, vars)
+ except NoSectionError:
+ if default is _UNSET:
+ raise
else:
+ return default
+ option = self.optionxform(option)
+ try:
+ return d[option]
+ except KeyError:
+ if default is _UNSET:
raise NoOptionError(option, section)
- elif opt in self._sections[section]:
- return self._sections[section][opt]
- elif opt in self._defaults:
- return self._defaults[opt]
- else:
- raise NoOptionError(option, section)
+ else:
+ return default
def items(self, section):
try:
@@ -571,23 +594,35 @@
del d["__name__"]
return d.items()
- def _get(self, section, conv, option):
- return conv(self.get(section, option))
+ def _get(self, section, conv, option, *args, **kwargs):
+ return conv(self.get(section, option, *args, **kwargs))
- def getint(self, section, option):
- return self._get(section, int, option)
+ def getint(self, section, option, vars=None, default=_UNSET):
+ try:
+ return self._get(section, int, option, vars)
+ except (NoSectionError, NoOptionError):
+ if default is _UNSET:
+ raise
+ else:
+ return default
- def getfloat(self, section, option):
- return self._get(section, float, option)
+ def getfloat(self, section, option, vars=None, default=_UNSET):
+ try:
+ return self._get(section, float, option, vars)
+ except (NoSectionError, NoOptionError):
+ if default is _UNSET:
+ raise
+ else:
+ return default
- _boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
- '0': False, 'no': False, 'false': False, 'off': False}
-
- def getboolean(self, section, option):
- v = self.get(section, option)
- if v.lower() not in self._boolean_states:
- raise ValueError('Not a boolean: %s' % v)
- return self._boolean_states[v.lower()]
+ def getboolean(self, section, option, vars=None, default=_UNSET):
+ try:
+ return self._get(section, self._convert_to_boolean, option, vars)
+ except (NoSectionError, NoOptionError):
+ if default is _UNSET:
+ raise
+ else:
+ return default
def optionxform(self, optionstr):
return optionstr.lower()
@@ -797,15 +832,43 @@
exc.append(lineno, repr(line))
return exc
+ def _unify_values(self, section, vars):
+ """Create a copy of the DEFAULTSECT with values from a specific
+ `section' and the `vars' dictionary. If provided, values in `vars'
+ take precendence.
+ """
+ d = self._defaults.copy()
+ try:
+ d.update(self._sections[section])
+ except KeyError:
+ if section != DEFAULTSECT:
+ raise NoSectionError(section)
+ # Update with the entry specific variables
+ if vars:
+ for key, value in vars.items():
+ if value is not None:
+ value = str(value)
+ d[self.optionxform(key)] = value
+ return d
+
+ def _convert_to_boolean(self, value):
+ """Return a boolean value translating from other types if necessary.
+ """
+ if value.lower() not in self.BOOLEAN_STATES:
+ raise ValueError('Not a boolean: %s' % value)
+ return self.BOOLEAN_STATES[value.lower()]
+
class ConfigParser(RawConfigParser):
"""ConfigParser implementing interpolation."""
- def get(self, section, option, raw=False, vars=None):
+ def get(self, section, option, raw=False, vars=None, default=_UNSET):
"""Get an option value for a given section.
If `vars' is provided, it must be a dictionary. The option is looked up
- in `vars' (if provided), `section', and in `defaults' in that order.
+ in `vars' (if provided), `section', and in `DEFAULTSECT' in that order.
+ If the key is not found and `default' is provided, it is used as
+ a fallback value. `None' can be provided as a `default' value.
All % interpolations are expanded in the return values, unless the
optional argument `raw' is true. Values for interpolation keys are
@@ -813,27 +876,56 @@
The section DEFAULT is special.
"""
- d = self._defaults.copy()
try:
- d.update(self._sections[section])
- except KeyError:
- if section != DEFAULTSECT:
- raise NoSectionError(section)
- # Update with the entry specific variables
- if vars:
- for key, value in vars.items():
- d[self.optionxform(key)] = value
+ d = self._unify_values(section, vars)
+ except NoSectionError:
+ if default is _UNSET:
+ raise
+ else:
+ return default
option = self.optionxform(option)
try:
value = d[option]
except KeyError:
- raise NoOptionError(option, section)
+ if default is _UNSET:
+ raise NoOptionError(option, section)
+ else:
+ return default
if raw or value is None:
return value
else:
return self._interpolate(section, option, value, d)
+ def getint(self, section, option, raw=False, vars=None, default=_UNSET):
+ try:
+ return self._get(section, int, option, raw, vars)
+ except (NoSectionError, NoOptionError):
+ if default is _UNSET:
+ raise
+ else:
+ return default
+
+ def getfloat(self, section, option, raw=False, vars=None, default=_UNSET):
+ try:
+ return self._get(section, float, option, raw, vars)
+ except (NoSectionError, NoOptionError):
+ if default is _UNSET:
+ raise
+ else:
+ return default
+
+ def getboolean(self, section, option, raw=False, vars=None,
+ default=_UNSET):
+ try:
+ return self._get(section, self._convert_to_boolean, option, raw,
+ vars)
+ except (NoSectionError, NoOptionError):
+ if default is _UNSET:
+ raise
+ else:
+ return default
+
def items(self, section, raw=False, vars=None):
"""Return a list of (name, value) tuples for each option in a section.
Modified: python/branches/py3k/Lib/test/test_cfgparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cfgparser.py (original)
+++ python/branches/py3k/Lib/test/test_cfgparser.py Sat Sep 4 06:35:34 2010
@@ -62,9 +62,10 @@
'Spaces',
'Spacey Bar',
'Spacey Bar From The Beginning',
+ 'Types',
]
if self.allow_no_value:
- E.append(r'NoValue')
+ E.append('NoValue')
E.sort()
eq = self.assertEqual
eq(L, E)
@@ -80,9 +81,43 @@
eq(cf.get('Commented Bar', 'baz'), 'qwe')
eq(cf.get('Spaces', 'key with spaces'), 'value')
eq(cf.get('Spaces', 'another with spaces'), 'splat!')
+ eq(cf.getint('Types', 'int'), 42)
+ eq(cf.get('Types', 'int'), "42")
+ self.assertAlmostEqual(cf.getfloat('Types', 'float'), 0.44)
+ eq(cf.get('Types', 'float'), "0.44")
+ eq(cf.getboolean('Types', 'boolean'), False)
if self.allow_no_value:
eq(cf.get('NoValue', 'option-without-value'), None)
+ # test vars= and default=
+ eq(cf.get('Foo Bar', 'foo', default='baz'), 'bar')
+ eq(cf.get('Foo Bar', 'foo', vars={'foo': 'baz'}), 'baz')
+ with self.assertRaises(configparser.NoSectionError):
+ cf.get('No Such Foo Bar', 'foo')
+ with self.assertRaises(configparser.NoOptionError):
+ cf.get('Foo Bar', 'no-such-foo')
+ eq(cf.get('No Such Foo Bar', 'foo', default='baz'), 'baz')
+ eq(cf.get('Foo Bar', 'no-such-foo', default='baz'), 'baz')
+ eq(cf.get('Spacey Bar', 'foo', default=None), 'bar')
+ eq(cf.get('No Such Spacey Bar', 'foo', default=None), None)
+ eq(cf.getint('Types', 'int', default=18), 42)
+ eq(cf.getint('Types', 'no-such-int', default=18), 18)
+ eq(cf.getint('Types', 'no-such-int', default="18"), "18") # sic!
+ self.assertAlmostEqual(cf.getfloat('Types', 'float',
+ default=0.0), 0.44)
+ self.assertAlmostEqual(cf.getfloat('Types', 'no-such-float',
+ default=0.0), 0.0)
+ eq(cf.getfloat('Types', 'no-such-float', default="0.0"), "0.0") # sic!
+ eq(cf.getboolean('Types', 'boolean', default=True), False)
+ eq(cf.getboolean('Types', 'no-such-boolean', default="yes"),
+ "yes") # sic!
+ eq(cf.getboolean('Types', 'no-such-boolean', default=True), True)
+ eq(cf.getboolean('No Such Types', 'boolean', default=True), True)
+ if self.allow_no_value:
+ eq(cf.get('NoValue', 'option-without-value', default=False), None)
+ eq(cf.get('NoValue', 'no-such-option-without-value',
+ default=False), False)
+
self.assertNotIn('__name__', cf.options("Foo Bar"),
'__name__ "option" should not be exposed by the API!')
@@ -127,6 +162,10 @@
[Spaces]
key with spaces {0[1]} value
another with spaces {0[0]} splat!
+[Types]
+int {0[1]} 42
+float {0[0]} 0.44
+boolean {0[0]} NO
""".format(self.delimiters, self.comment_prefixes)
if self.allow_no_value:
config_string += (
@@ -194,7 +233,12 @@
"Spaces": {
"key with spaces": "value",
"another with spaces": "splat!",
- }
+ },
+ "Types": {
+ "int": 42,
+ "float": 0.44,
+ "boolean": False,
+ },
}
if self.allow_no_value:
config.update({
@@ -732,8 +776,11 @@
'no values here',
'tricky interpolation',
'more interpolation'])
- #self.assertEqual(cf.getint('DEFAULT', 'go', vars={'interpolate': '-1'}),
- # -1)
+ self.assertEqual(cf.getint('DEFAULT', 'go',
+ vars={'interpolate': '-1'}), -1)
+ with self.assertRaises(ValueError):
+ # no interpolation will happen
+ cf.getint('DEFAULT', 'go', raw=True, vars={'interpolate': '-1'})
self.assertEqual(len(cf.get('strange', 'other').split('\n')), 4)
self.assertEqual(len(cf.get('corruption', 'value').split('\n')), 10)
longname = 'yeah, sections can be indented as well'
@@ -808,7 +855,7 @@
class CompatibleTestCase(CfgParserTestCaseClass):
config_class = configparser.RawConfigParser
- comment_prefixes = configparser.RawConfigParser._COMPATIBLE
+ comment_prefixes = configparser._COMPATIBLE
def test_comment_handling(self):
config_string = textwrap.dedent("""\
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 06:35:34 2010
@@ -158,6 +158,9 @@
- Issue #9753: Fixed socket.dup, which did not always work correctly
on Windows.
+- Issue #9421: Made the get methods consistently accept the vars
+ and default arguments on all parser classes.
+
- Issue #7005: Fixed output of None values for RawConfigParser.write and
ConfigParser.write.
From python-checkins at python.org Sat Sep 4 16:38:09 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sat, 4 Sep 2010 16:38:09 +0200 (CEST)
Subject: [Python-checkins] r84487 - in python/branches/py3k: Misc/NEWS
Tools/msi/msi.py
Message-ID: <20100904143809.8AA4BDFFD@mail.python.org>
Author: martin.v.loewis
Date: Sat Sep 4 16:38:09 2010
New Revision: 84487
Log:
Issue #1303434: Include PDBs in release.
Patch by James Lee and Daniel Stutzbach.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Tools/msi/msi.py
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 16:38:09 2010
@@ -381,6 +381,8 @@
Build
-----
+- Issue #1303434: Generate ZIP file containing all PDBs.
+
- Issue #9193: PEP 3149 is accepted.
- Issue #3101: Helper functions _add_one_to_index_C() and
Modified: python/branches/py3k/Tools/msi/msi.py
==============================================================================
--- python/branches/py3k/Tools/msi/msi.py (original)
+++ python/branches/py3k/Tools/msi/msi.py Sat Sep 4 16:38:09 2010
@@ -1,7 +1,7 @@
# Python MSI Generator
# (C) 2003 Martin v. Loewis
# See "FOO" in comments refers to MSDN sections with the title FOO.
-import msilib, schema, sequence, os, glob, time, re, shutil
+import msilib, schema, sequence, os, glob, time, re, shutil, zipfile
from msilib import Feature, CAB, Directory, Dialog, Binary, add_data
import uisample
from win32com.client import constants
@@ -31,6 +31,8 @@
MSVCR = "90"
# Name of certificate in default store to sign MSI with
certname = None
+# Make a zip file containing the PDB files for this build?
+pdbzip = True
try:
from config import *
@@ -1316,6 +1318,16 @@
])
db.Commit()
+def build_pdbzip():
+ pdbexclude = ['kill_python.pdb', 'make_buildinfo.pdb',
+ 'make_versioninfo.pdb']
+ path = "python-%s%s-pdb.zip" % (full_current_version, msilib.arch_ext)
+ pdbzip = zipfile.ZipFile(path, 'w')
+ for f in glob.glob1(os.path.join(srcdir, PCBUILD), "*.pdb"):
+ if f not in pdbexclude and not f.endswith('_d.pdb'):
+ pdbzip.write(os.path.join(srcdir, PCBUILD, f), f)
+ pdbzip.close()
+
db,msiname = build_database()
try:
add_features(db)
@@ -1398,3 +1410,6 @@
# the certificate subject, e.g. "Python Software Foundation"
if certname:
os.system('signtool sign /n "%s" /t http://timestamp.verisign.com/scripts/timestamp.dll %s' % (certname, msiname))
+
+if pdbzip:
+ build_pdbzip()
From python-checkins at python.org Sat Sep 4 18:28:04 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 18:28:04 +0200 (CEST)
Subject: [Python-checkins] r84488 - python/branches/py3k/setup.py
Message-ID: <20100904162804.4FDE1F7C1@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 18:28:00 2010
New Revision: 84488
Log:
Workaround PEP 3149 build problems.
Modified:
python/branches/py3k/setup.py
Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py (original)
+++ python/branches/py3k/setup.py Sat Sep 4 18:28:00 2010
@@ -152,7 +152,13 @@
def build_extensions(self):
# Detect which modules should be compiled
- missing = self.detect_modules()
+ old_so = self.compiler.shared_lib_extension
+ # Workaround PEP 3149 stuff
+ self.compiler.shared_lib_extension = os.environ.get("SO", ".so")
+ try:
+ missing = self.detect_modules()
+ finally:
+ self.compiler.shared_lib_extension = old_so
# Remove modules that are present on the disabled list
extensions = [ext for ext in self.extensions
From python-checkins at python.org Sat Sep 4 19:21:57 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:21:57 +0200 (CEST)
Subject: [Python-checkins] r84489 - in python/branches/py3k: Misc/NEWS
Modules/posixmodule.c
Message-ID: <20100904172157.47801F9B5@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:21:57 2010
New Revision: 84489
Log:
Issue #7736: Release the GIL around calls to opendir() and closedir()
in the posix module. Patch by Marcin Bachry.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/posixmodule.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 19:21:57 2010
@@ -93,6 +93,9 @@
Extensions
----------
+- Issue #7736: Release the GIL around calls to opendir() and closedir()
+ in the posix module. Patch by Marcin Bachry.
+
- Issue #4835: make PyLong_FromSocket_t() and PyLong_AsSocket_t() private
to the socket module, and fix the width of socket descriptors to be
correctly detected under 64-bit Windows.
Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Sat Sep 4 19:21:57 2010
@@ -2580,11 +2580,16 @@
oname = PyBytes_FromString(".");
}
name = PyBytes_AsString(oname);
- if ((dirp = opendir(name)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ dirp = opendir(name);
+ Py_END_ALLOW_THREADS
+ if (dirp == NULL) {
return posix_error_with_allocated_filename(oname);
}
if ((d = PyList_New(0)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
Py_DECREF(oname);
return NULL;
}
@@ -2597,7 +2602,9 @@
if (errno == 0) {
break;
} else {
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
Py_DECREF(d);
return posix_error_with_allocated_filename(oname);
}
@@ -2621,7 +2628,9 @@
}
Py_DECREF(v);
}
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
Py_DECREF(oname);
return d;
From python-checkins at python.org Sat Sep 4 19:26:02 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:26:02 +0200 (CEST)
Subject: [Python-checkins] r84490 - in python/branches/release31-maint:
Misc/NEWS Modules/posixmodule.c
Message-ID: <20100904172602.1F30AF6FF@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:26:01 2010
New Revision: 84490
Log:
Merged revisions 84489 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84489 | antoine.pitrou | 2010-09-04 19:21:57 +0200 (sam., 04 sept. 2010) | 4 lines
Issue #7736: Release the GIL around calls to opendir() and closedir()
in the posix module. Patch by Marcin Bachry.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Modules/posixmodule.c
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Sat Sep 4 19:26:01 2010
@@ -474,6 +474,9 @@
Extension Modules
-----------------
+- Issue #7736: Release the GIL around calls to opendir() and closedir()
+ in the posix module. Patch by Marcin Bachry.
+
- Issue #4835: make PyLong_FromSocket_t() and PyLong_AsSocket_t() private
to the socket module, and fix the width of socket descriptors to be
correctly detected under 64-bit Windows.
Modified: python/branches/release31-maint/Modules/posixmodule.c
==============================================================================
--- python/branches/release31-maint/Modules/posixmodule.c (original)
+++ python/branches/release31-maint/Modules/posixmodule.c Sat Sep 4 19:26:01 2010
@@ -2493,11 +2493,16 @@
if (!PyArg_ParseTuple(args, "O&:listdir", PyUnicode_FSConverter, &oname))
return NULL;
name = bytes2str(oname, 1);
- if ((dirp = opendir(name)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ dirp = opendir(name);
+ Py_END_ALLOW_THREADS
+ if (dirp == NULL) {
return posix_error_with_allocated_filename(oname);
}
if ((d = PyList_New(0)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
release_bytes(oname);
return NULL;
}
@@ -2510,7 +2515,9 @@
if (errno == 0) {
break;
} else {
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
Py_DECREF(d);
return posix_error_with_allocated_filename(oname);
}
@@ -2550,7 +2557,9 @@
}
Py_DECREF(v);
}
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
release_bytes(oname);
return d;
From python-checkins at python.org Sat Sep 4 19:27:10 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:27:10 +0200 (CEST)
Subject: [Python-checkins] r84491 - in python/branches/release27-maint:
Misc/NEWS Modules/posixmodule.c
Message-ID: <20100904172710.5D36FF6FF@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:27:10 2010
New Revision: 84491
Log:
Merged revisions 84489 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84489 | antoine.pitrou | 2010-09-04 19:21:57 +0200 (sam., 04 sept. 2010) | 4 lines
Issue #7736: Release the GIL around calls to opendir() and closedir()
in the posix module. Patch by Marcin Bachry.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Modules/posixmodule.c
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Sat Sep 4 19:27:10 2010
@@ -225,6 +225,9 @@
Extension Modules
-----------------
+- Issue #7736: Release the GIL around calls to opendir() and closedir()
+ in the posix module. Patch by Marcin Bachry.
+
- As a result of issue #2521, the _weakref module is now compiled into the
interpreter by default.
Modified: python/branches/release27-maint/Modules/posixmodule.c
==============================================================================
--- python/branches/release27-maint/Modules/posixmodule.c (original)
+++ python/branches/release27-maint/Modules/posixmodule.c Sat Sep 4 19:27:10 2010
@@ -2333,11 +2333,16 @@
}
if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
return NULL;
- if ((dirp = opendir(name)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
+ dirp = opendir(name);
+ Py_END_ALLOW_THREADS
+ if (dirp == NULL) {
return posix_error_with_allocated_filename(name);
}
if ((d = PyList_New(0)) == NULL) {
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
PyMem_Free(name);
return NULL;
}
@@ -2350,7 +2355,9 @@
if (errno == 0) {
break;
} else {
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
Py_DECREF(d);
return posix_error_with_allocated_filename(name);
}
@@ -2391,7 +2398,9 @@
}
Py_DECREF(v);
}
+ Py_BEGIN_ALLOW_THREADS
closedir(dirp);
+ Py_END_ALLOW_THREADS
PyMem_Free(name);
return d;
From python-checkins at python.org Sat Sep 4 19:32:06 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:32:06 +0200 (CEST)
Subject: [Python-checkins] r84492 -
python/branches/py3k/Lib/test/test_posix.py
Message-ID: <20100904173206.D9F14FB7F@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:32:06 2010
New Revision: 84492
Log:
Issue #9581: Fix non-working PosixGroupsTester test case
(it only runs as root, which is why nobody bothered about the failure)
Modified:
python/branches/py3k/Lib/test/test_posix.py
Modified: python/branches/py3k/Lib/test/test_posix.py
==============================================================================
--- python/branches/py3k/Lib/test/test_posix.py (original)
+++ python/branches/py3k/Lib/test/test_posix.py Sat Sep 4 19:32:06 2010
@@ -409,13 +409,7 @@
def test_initgroups(self):
# find missing group
- groups = sorted(self.saved_groups)
- for g1,g2 in zip(groups[:-1], groups[1:]):
- g = g1 + 1
- if g < g2:
- break
- else:
- g = g2 + 1
+ g = max(self.saved_groups) + 1
name = pwd.getpwuid(posix.getuid()).pw_name
posix.initgroups(name, g)
self.assertIn(g, posix.getgroups())
@@ -423,7 +417,7 @@
@unittest.skipUnless(hasattr(posix, 'setgroups'),
"test needs posix.setgroups()")
def test_setgroups(self):
- for groups in [[0], range(16)]:
+ for groups in [[0], list(range(16))]:
posix.setgroups(groups)
self.assertListEqual(groups, posix.getgroups())
From python-checkins at python.org Sat Sep 4 19:33:06 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:33:06 +0200 (CEST)
Subject: [Python-checkins] r84493 - in python/branches/release31-maint:
Lib/test/test_posix.py
Message-ID: <20100904173306.A1B82F4CB@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:33:06 2010
New Revision: 84493
Log:
Merged revisions 84492 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84492 | antoine.pitrou | 2010-09-04 19:32:06 +0200 (sam., 04 sept. 2010) | 4 lines
Issue #9581: Fix non-working PosixGroupsTester test case
(it only runs as root, which is why nobody bothered about the failure)
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_posix.py
Modified: python/branches/release31-maint/Lib/test/test_posix.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_posix.py (original)
+++ python/branches/release31-maint/Lib/test/test_posix.py Sat Sep 4 19:33:06 2010
@@ -310,13 +310,7 @@
def test_initgroups(self):
# find missing group
- groups = sorted(self.saved_groups)
- for g1,g2 in zip(groups[:-1], groups[1:]):
- g = g1 + 1
- if g < g2:
- break
- else:
- g = g2 + 1
+ g = max(self.saved_groups) + 1
name = pwd.getpwuid(posix.getuid()).pw_name
posix.initgroups(name, g)
self.assertIn(g, posix.getgroups())
@@ -324,7 +318,7 @@
@unittest.skipUnless(hasattr(posix, 'setgroups'),
"test needs posix.setgroups()")
def test_setgroups(self):
- for groups in [[0], range(16)]:
+ for groups in [[0], list(range(16))]:
posix.setgroups(groups)
self.assertListEqual(groups, posix.getgroups())
From python-checkins at python.org Sat Sep 4 19:34:12 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:34:12 +0200 (CEST)
Subject: [Python-checkins] r84494 - in python/branches/release27-maint:
Lib/test/test_posix.py
Message-ID: <20100904173412.EFEF5F4CB@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:34:12 2010
New Revision: 84494
Log:
Merged revisions 84492 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84492 | antoine.pitrou | 2010-09-04 19:32:06 +0200 (sam., 04 sept. 2010) | 4 lines
Issue #9581: Fix non-working PosixGroupsTester test case
(it only runs as root, which is why nobody bothered about the failure)
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_posix.py
Modified: python/branches/release27-maint/Lib/test/test_posix.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_posix.py (original)
+++ python/branches/release27-maint/Lib/test/test_posix.py Sat Sep 4 19:34:12 2010
@@ -400,13 +400,7 @@
def test_initgroups(self):
# find missing group
- groups = sorted(self.saved_groups)
- for g1,g2 in zip(groups[:-1], groups[1:]):
- g = g1 + 1
- if g < g2:
- break
- else:
- g = g2 + 1
+ g = max(self.saved_groups) + 1
name = pwd.getpwuid(posix.getuid()).pw_name
posix.initgroups(name, g)
self.assertIn(g, posix.getgroups())
From python-checkins at python.org Sat Sep 4 19:40:21 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:40:21 +0200 (CEST)
Subject: [Python-checkins] r84495 - in python/branches/py3k: Lib/copy.py
Lib/test/test_copy.py Misc/NEWS
Message-ID: <20100904174021.9D7FFF8F0@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:40:21 2010
New Revision: 84495
Log:
Issue #1100562: Fix deep-copying of objects derived from the list and dict types.
Patch by Michele Orr? and Bj?rn Lindqvist.
Modified:
python/branches/py3k/Lib/copy.py
python/branches/py3k/Lib/test/test_copy.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/copy.py
==============================================================================
--- python/branches/py3k/Lib/copy.py (original)
+++ python/branches/py3k/Lib/copy.py Sat Sep 4 19:40:21 2010
@@ -283,17 +283,7 @@
args = deepcopy(args, memo)
y = callable(*args)
memo[id(x)] = y
- if listiter is not None:
- for item in listiter:
- if deep:
- item = deepcopy(item, memo)
- y.append(item)
- if dictiter is not None:
- for key, value in dictiter:
- if deep:
- key = deepcopy(key, memo)
- value = deepcopy(value, memo)
- y[key] = value
+
if state:
if deep:
state = deepcopy(state, memo)
@@ -309,6 +299,18 @@
if slotstate is not None:
for key, value in slotstate.items():
setattr(y, key, value)
+
+ if listiter is not None:
+ for item in listiter:
+ if deep:
+ item = deepcopy(item, memo)
+ y.append(item)
+ if dictiter is not None:
+ for key, value in dictiter:
+ if deep:
+ key = deepcopy(key, memo)
+ value = deepcopy(value, memo)
+ y[key] = value
return y
del d
@@ -370,6 +372,16 @@
print(map(reprlib.repr, l1))
print(map(reprlib.repr, l2))
print(map(reprlib.repr, l3))
+ class odict(dict):
+ def __init__(self, d = {}):
+ self.a = 99
+ dict.__init__(self, d)
+ def __setitem__(self, k, i):
+ dict.__setitem__(self, k, i)
+ self.a
+ o = odict({"A" : "B"})
+ x = deepcopy(o)
+ print(o, x)
if __name__ == '__main__':
_test()
Modified: python/branches/py3k/Lib/test/test_copy.py
==============================================================================
--- python/branches/py3k/Lib/test/test_copy.py (original)
+++ python/branches/py3k/Lib/test/test_copy.py Sat Sep 4 19:40:21 2010
@@ -532,6 +532,26 @@
self.assertEqual(x.foo, y.foo)
self.assertTrue(x.foo is not y.foo)
+ def test_deepcopy_dict_subclass(self):
+ class C(dict):
+ def __init__(self, d=None):
+ if not d:
+ d = {}
+ self._keys = list(d.keys())
+ super().__init__(d)
+ def __setitem__(self, key, item):
+ super().__setitem__(key, item)
+ if key not in self._keys:
+ self._keys.append(key)
+ x = C(d={'foo':0})
+ y = copy.deepcopy(x)
+ self.assertEqual(x, y)
+ self.assertEqual(x._keys, y._keys)
+ self.assertTrue(x is not y)
+ x['bar'] = 1
+ self.assertNotEqual(x, y)
+ self.assertNotEqual(x._keys, y._keys)
+
def test_copy_list_subclass(self):
class C(list):
pass
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 19:40:21 2010
@@ -158,6 +158,9 @@
Library
-------
+- Issue #1100562: Fix deep-copying of objects derived from the list and
+ dict types. Patch by Michele Orr? and Bj?rn Lindqvist.
+
- Issue #9753: Fixed socket.dup, which did not always work correctly
on Windows.
From python-checkins at python.org Sat Sep 4 19:40:51 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:40:51 +0200 (CEST)
Subject: [Python-checkins] r84496 - python/branches/py3k/Misc/ACKS
Message-ID: <20100904174051.84A38FAEF@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:40:51 2010
New Revision: 84496
Log:
Fix Bj?rn's name in ACKS.
Modified:
python/branches/py3k/Misc/ACKS
Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS (original)
+++ python/branches/py3k/Misc/ACKS Sat Sep 4 19:40:51 2010
@@ -494,7 +494,7 @@
Martin Ligr
Grant Limberg
Christopher Lindblad
-Bjorn Lindqvist
+Bj?rn Lindqvist
Per Lindqvist
Eric Lindvall
Gregor Lingl
From python-checkins at python.org Sat Sep 4 19:46:44 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:46:44 +0200 (CEST)
Subject: [Python-checkins] r84497 - python/branches/py3k/Lib/copy.py
Message-ID: <20100904174644.F191DF924@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:46:44 2010
New Revision: 84497
Log:
Fix running the copy module from the command-line (however use{ful,less} it may be).
Modified:
python/branches/py3k/Lib/copy.py
Modified: python/branches/py3k/Lib/copy.py
==============================================================================
--- python/branches/py3k/Lib/copy.py (original)
+++ python/branches/py3k/Lib/copy.py Sat Sep 4 19:46:44 2010
@@ -51,6 +51,7 @@
import types
import weakref
from copyreg import dispatch_table
+import builtins
class Error(Exception):
pass
@@ -109,7 +110,7 @@
if t is not None:
d[t] = _copy_immutable
for name in ("complex", "unicode"):
- t = globals()['__builtins__'].get(name)
+ t = getattr(builtins, name, None)
if t is not None:
d[t] = _copy_immutable
From python-checkins at python.org Sat Sep 4 19:49:13 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:49:13 +0200 (CEST)
Subject: [Python-checkins] r84498 - in python/branches/release31-maint:
Lib/copy.py Lib/test/test_copy.py Misc/ACKS Misc/NEWS
Message-ID: <20100904174913.BC84EFA84@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:49:13 2010
New Revision: 84498
Log:
Merged revisions 84495-84497 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84495 | antoine.pitrou | 2010-09-04 19:40:21 +0200 (sam., 04 sept. 2010) | 4 lines
Issue #1100562: Fix deep-copying of objects derived from the list and dict types.
Patch by Michele Orr? and Bj?rn Lindqvist.
........
r84496 | antoine.pitrou | 2010-09-04 19:40:51 +0200 (sam., 04 sept. 2010) | 3 lines
Fix Bj?rn's name in ACKS.
........
r84497 | antoine.pitrou | 2010-09-04 19:46:44 +0200 (sam., 04 sept. 2010) | 3 lines
Fix running the copy module from the command-line (however use{ful,less} it may be).
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/copy.py
python/branches/release31-maint/Lib/test/test_copy.py
python/branches/release31-maint/Misc/ACKS
python/branches/release31-maint/Misc/NEWS
Modified: python/branches/release31-maint/Lib/copy.py
==============================================================================
--- python/branches/release31-maint/Lib/copy.py (original)
+++ python/branches/release31-maint/Lib/copy.py Sat Sep 4 19:49:13 2010
@@ -51,6 +51,7 @@
import types
import weakref
from copyreg import dispatch_table
+import builtins
class Error(Exception):
pass
@@ -109,7 +110,7 @@
if t is not None:
d[t] = _copy_immutable
for name in ("complex", "unicode"):
- t = globals()['__builtins__'].get(name)
+ t = getattr(builtins, name, None)
if t is not None:
d[t] = _copy_immutable
@@ -279,17 +280,7 @@
args = deepcopy(args, memo)
y = callable(*args)
memo[id(x)] = y
- if listiter is not None:
- for item in listiter:
- if deep:
- item = deepcopy(item, memo)
- y.append(item)
- if dictiter is not None:
- for key, value in dictiter:
- if deep:
- key = deepcopy(key, memo)
- value = deepcopy(value, memo)
- y[key] = value
+
if state:
if deep:
state = deepcopy(state, memo)
@@ -305,6 +296,18 @@
if slotstate is not None:
for key, value in slotstate.items():
setattr(y, key, value)
+
+ if listiter is not None:
+ for item in listiter:
+ if deep:
+ item = deepcopy(item, memo)
+ y.append(item)
+ if dictiter is not None:
+ for key, value in dictiter:
+ if deep:
+ key = deepcopy(key, memo)
+ value = deepcopy(value, memo)
+ y[key] = value
return y
del d
@@ -366,6 +369,16 @@
print(map(reprlib.repr, l1))
print(map(reprlib.repr, l2))
print(map(reprlib.repr, l3))
+ class odict(dict):
+ def __init__(self, d = {}):
+ self.a = 99
+ dict.__init__(self, d)
+ def __setitem__(self, k, i):
+ dict.__setitem__(self, k, i)
+ self.a
+ o = odict({"A" : "B"})
+ x = deepcopy(o)
+ print(o, x)
if __name__ == '__main__':
_test()
Modified: python/branches/release31-maint/Lib/test/test_copy.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_copy.py (original)
+++ python/branches/release31-maint/Lib/test/test_copy.py Sat Sep 4 19:49:13 2010
@@ -532,6 +532,26 @@
self.assertEqual(x.foo, y.foo)
self.assertTrue(x.foo is not y.foo)
+ def test_deepcopy_dict_subclass(self):
+ class C(dict):
+ def __init__(self, d=None):
+ if not d:
+ d = {}
+ self._keys = list(d.keys())
+ super().__init__(d)
+ def __setitem__(self, key, item):
+ super().__setitem__(key, item)
+ if key not in self._keys:
+ self._keys.append(key)
+ x = C(d={'foo':0})
+ y = copy.deepcopy(x)
+ self.assertEqual(x, y)
+ self.assertEqual(x._keys, y._keys)
+ self.assertTrue(x is not y)
+ x['bar'] = 1
+ self.assertNotEqual(x, y)
+ self.assertNotEqual(x._keys, y._keys)
+
def test_copy_list_subclass(self):
class C(list):
pass
Modified: python/branches/release31-maint/Misc/ACKS
==============================================================================
--- python/branches/release31-maint/Misc/ACKS (original)
+++ python/branches/release31-maint/Misc/ACKS Sat Sep 4 19:49:13 2010
@@ -469,7 +469,7 @@
Martin Ligr
Grant Limberg
Christopher Lindblad
-Bjorn Lindqvist
+Bj?rn Lindqvist
Per Lindqvist
Eric Lindvall
Gregor Lingl
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Sat Sep 4 19:49:13 2010
@@ -105,6 +105,9 @@
Library
-------
+- Issue #1100562: Fix deep-copying of objects derived from the list and
+ dict types. Patch by Michele Orr? and Bj?rn Lindqvist.
+
- Issue #9753: Fixed socket.dup, which did not always work correctly
on Windows.
From python-checkins at python.org Sat Sep 4 19:52:26 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 19:52:26 +0200 (CEST)
Subject: [Python-checkins] r84499 - in python/branches/release27-maint:
Lib/copy.py Lib/test/test_copy.py Misc/ACKS Misc/NEWS
Message-ID: <20100904175226.630F1E381@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 19:52:26 2010
New Revision: 84499
Log:
Merged revisions 84495-84496 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84495 | antoine.pitrou | 2010-09-04 19:40:21 +0200 (sam., 04 sept. 2010) | 4 lines
Issue #1100562: Fix deep-copying of objects derived from the list and dict types.
Patch by Michele Orr? and Bj?rn Lindqvist.
........
r84496 | antoine.pitrou | 2010-09-04 19:40:51 +0200 (sam., 04 sept. 2010) | 3 lines
Fix Bj?rn's name in ACKS.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/copy.py
python/branches/release27-maint/Lib/test/test_copy.py
python/branches/release27-maint/Misc/ACKS
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/copy.py
==============================================================================
--- python/branches/release27-maint/Lib/copy.py (original)
+++ python/branches/release27-maint/Lib/copy.py Sat Sep 4 19:52:26 2010
@@ -328,17 +328,7 @@
args = deepcopy(args, memo)
y = callable(*args)
memo[id(x)] = y
- if listiter is not None:
- for item in listiter:
- if deep:
- item = deepcopy(item, memo)
- y.append(item)
- if dictiter is not None:
- for key, value in dictiter:
- if deep:
- key = deepcopy(key, memo)
- value = deepcopy(value, memo)
- y[key] = value
+
if state:
if deep:
state = deepcopy(state, memo)
@@ -354,6 +344,18 @@
if slotstate is not None:
for key, value in slotstate.iteritems():
setattr(y, key, value)
+
+ if listiter is not None:
+ for item in listiter:
+ if deep:
+ item = deepcopy(item, memo)
+ y.append(item)
+ if dictiter is not None:
+ for key, value in dictiter:
+ if deep:
+ key = deepcopy(key, memo)
+ value = deepcopy(value, memo)
+ y[key] = value
return y
del d
@@ -416,6 +418,16 @@
print map(repr.repr, l1)
print map(repr.repr, l2)
print map(repr.repr, l3)
+ class odict(dict):
+ def __init__(self, d = {}):
+ self.a = 99
+ dict.__init__(self, d)
+ def __setitem__(self, k, i):
+ dict.__setitem__(self, k, i)
+ self.a
+ o = odict({"A" : "B"})
+ x = deepcopy(o)
+ print(o, x)
if __name__ == '__main__':
_test()
Modified: python/branches/release27-maint/Lib/test/test_copy.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_copy.py (original)
+++ python/branches/release27-maint/Lib/test/test_copy.py Sat Sep 4 19:52:26 2010
@@ -526,6 +526,26 @@
self.assertEqual(x.foo, y.foo)
self.assertTrue(x.foo is not y.foo)
+ def test_deepcopy_dict_subclass(self):
+ class C(dict):
+ def __init__(self, d=None):
+ if not d:
+ d = {}
+ self._keys = list(d.keys())
+ dict.__init__(self, d)
+ def __setitem__(self, key, item):
+ dict.__setitem__(self, key, item)
+ if key not in self._keys:
+ self._keys.append(key)
+ x = C(d={'foo':0})
+ y = copy.deepcopy(x)
+ self.assertEqual(x, y)
+ self.assertEqual(x._keys, y._keys)
+ self.assertTrue(x is not y)
+ x['bar'] = 1
+ self.assertNotEqual(x, y)
+ self.assertNotEqual(x._keys, y._keys)
+
def test_copy_list_subclass(self):
class C(list):
pass
Modified: python/branches/release27-maint/Misc/ACKS
==============================================================================
--- python/branches/release27-maint/Misc/ACKS (original)
+++ python/branches/release27-maint/Misc/ACKS Sat Sep 4 19:52:26 2010
@@ -472,7 +472,7 @@
Shawn Ligocki
Martin Ligr
Christopher Lindblad
-Bjorn Lindqvist
+Bj?rn Lindqvist
Per Lindqvist
Eric Lindvall
Gregor Lingl
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Sat Sep 4 19:52:26 2010
@@ -36,6 +36,9 @@
Library
-------
+- Issue #1100562: Fix deep-copying of objects derived from the list and
+ dict types. Patch by Michele Orr? and Bj?rn Lindqvist.
+
- Issue #7005: Fixed output of None values for RawConfigParser.write and
ConfigParser.write.
From python-checkins at python.org Sat Sep 4 20:24:04 2010
From: python-checkins at python.org (brett.cannon)
Date: Sat, 4 Sep 2010 20:24:04 +0200 (CEST)
Subject: [Python-checkins] r84500 - in python/branches/py3k: Lib/warnings.py
Misc/NEWS Python/_warnings.c
Message-ID: <20100904182404.A352DF4A9@mail.python.org>
Author: brett.cannon
Date: Sat Sep 4 20:24:04 2010
New Revision: 84500
Log:
_warnings exposed two variables with the name 'default_action' and
'once_registry'. This is bad as the warnings module had variables named
'defaultaction' and 'onceregistry' which are what people should be looking at
(technically those variables shouldn't be mucked with as they are undocumented,
but we all know better than to believe that isn't happening). So the variables
from _warnings have been renamed to come off as private and to avoid confusion
over what variable should be used.
Closes issue #9766. Thanks to Antoine Pitrou for the discovery.
Modified:
python/branches/py3k/Lib/warnings.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Python/_warnings.c
Modified: python/branches/py3k/Lib/warnings.py
==============================================================================
--- python/branches/py3k/Lib/warnings.py (original)
+++ python/branches/py3k/Lib/warnings.py Sat Sep 4 20:24:04 2010
@@ -357,10 +357,10 @@
# If either if the compiled regexs are None, match anything.
_warnings_defaults = False
try:
- from _warnings import (filters, default_action, once_registry,
+ from _warnings import (filters, _defaultaction, _onceregistry,
warn, warn_explicit)
- defaultaction = default_action
- onceregistry = once_registry
+ defaultaction = _defaultaction
+ onceregistry = _onceregistry
_warnings_defaults = True
except ImportError:
filters = []
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 20:24:04 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #9766: Rename poorly named variables exposed by _warnings to prevent
+ confusion with the proper variables names from 'warnings' itself.
+
- Issue #9212: dict_keys and dict_items now provide the isdisjoint()
method, to conform to the Set ABC. Patch by Daniel Urban.
Modified: python/branches/py3k/Python/_warnings.c
==============================================================================
--- python/branches/py3k/Python/_warnings.c (original)
+++ python/branches/py3k/Python/_warnings.c Sat Sep 4 20:24:04 2010
@@ -945,13 +945,13 @@
if (_once_registry == NULL)
return NULL;
Py_INCREF(_once_registry);
- if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)
+ if (PyModule_AddObject(m, "_onceregistry", _once_registry) < 0)
return NULL;
_default_action = PyUnicode_FromString("default");
if (_default_action == NULL)
return NULL;
- if (PyModule_AddObject(m, "default_action", _default_action) < 0)
+ if (PyModule_AddObject(m, "_defaultaction", _default_action) < 0)
return NULL;
return m;
}
From python-checkins at python.org Sat Sep 4 20:43:53 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 20:43:53 +0200 (CEST)
Subject: [Python-checkins] r84501 - in python/branches/py3k:
Doc/library/dis.rst Include/opcode.h Lib/opcode.py Misc/ACKS
Misc/NEWS Python/ceval.c Python/compile.c Python/import.c
Python/opcode_targets.h
Message-ID: <20100904184353.308B6F943@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 20:43:52 2010
New Revision: 84501
Log:
Issue #9225: Remove the ROT_FOUR and DUP_TOPX opcode, the latter replaced
by the new (and simpler) DUP_TOP_TWO. Performance isn't changed, but
our bytecode is a bit simplified. Patch by Demur Rumed.
Modified:
python/branches/py3k/Doc/library/dis.rst
python/branches/py3k/Include/opcode.h
python/branches/py3k/Lib/opcode.py
python/branches/py3k/Misc/ACKS
python/branches/py3k/Misc/NEWS
python/branches/py3k/Python/ceval.c
python/branches/py3k/Python/compile.c
python/branches/py3k/Python/import.c
python/branches/py3k/Python/opcode_targets.h
Modified: python/branches/py3k/Doc/library/dis.rst
==============================================================================
--- python/branches/py3k/Doc/library/dis.rst (original)
+++ python/branches/py3k/Doc/library/dis.rst Sat Sep 4 20:43:52 2010
@@ -184,15 +184,15 @@
three.
-.. opcode:: ROT_FOUR
+.. opcode:: DUP_TOP
- Lifts second, third and forth stack item one position up, moves top down to
- position four.
+ Duplicates the reference on top of the stack.
-.. opcode:: DUP_TOP
+.. opcode:: DUP_TOP_TWO
- Duplicates the reference on top of the stack.
+ Duplicates the two references on top of the stack, leaving them in the
+ same order.
**Unary operations**
@@ -531,12 +531,6 @@
are put onto the stack right-to-left.
-.. opcode:: DUP_TOPX (count)
-
- Duplicate *count* items, keeping them in the same order. Due to implementation
- limits, *count* should be between 1 and 5 inclusive.
-
-
.. opcode:: STORE_ATTR (namei)
Implements ``TOS.name = TOS1``, where *namei* is the index of name in
Modified: python/branches/py3k/Include/opcode.h
==============================================================================
--- python/branches/py3k/Include/opcode.h (original)
+++ python/branches/py3k/Include/opcode.h Sat Sep 4 20:43:52 2010
@@ -12,7 +12,7 @@
#define ROT_TWO 2
#define ROT_THREE 3
#define DUP_TOP 4
-#define ROT_FOUR 5
+#define DUP_TOP_TWO 5
#define NOP 9
#define UNARY_POSITIVE 10
@@ -83,7 +83,7 @@
#define DELETE_ATTR 96 /* "" */
#define STORE_GLOBAL 97 /* "" */
#define DELETE_GLOBAL 98 /* "" */
-#define DUP_TOPX 99 /* number of items to duplicate */
+
#define LOAD_CONST 100 /* Index in const list */
#define LOAD_NAME 101 /* Index in name list */
#define BUILD_TUPLE 102 /* Number of tuple items */
Modified: python/branches/py3k/Lib/opcode.py
==============================================================================
--- python/branches/py3k/Lib/opcode.py (original)
+++ python/branches/py3k/Lib/opcode.py Sat Sep 4 20:43:52 2010
@@ -48,7 +48,7 @@
def_op('ROT_TWO', 2)
def_op('ROT_THREE', 3)
def_op('DUP_TOP', 4)
-def_op('ROT_FOUR', 5)
+def_op('DUP_TOP_TWO', 5)
def_op('NOP', 9)
def_op('UNARY_POSITIVE', 10)
@@ -116,7 +116,6 @@
name_op('DELETE_ATTR', 96) # ""
name_op('STORE_GLOBAL', 97) # ""
name_op('DELETE_GLOBAL', 98) # ""
-def_op('DUP_TOPX', 99) # number of items to duplicate
def_op('LOAD_CONST', 100) # Index in const list
hasconst.append(100)
name_op('LOAD_NAME', 101) # Index in name list
Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS (original)
+++ python/branches/py3k/Misc/ACKS Sat Sep 4 20:43:52 2010
@@ -700,6 +700,7 @@
Clinton Roy
Paul Rubin
Sam Ruby
+Demur Rumed
Audun S. Runde
Rauli Ruohonen
Jeff Rush
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 20:43:52 2010
@@ -12,6 +12,10 @@
Core and Builtins
-----------------
+- Issue #9225: Remove the ROT_FOUR and DUP_TOPX opcode, the latter replaced
+ by the new (and simpler) DUP_TOP_TWO. Performance isn't changed, but
+ our bytecode is a bit simplified. Patch by Demur Rumed.
+
- Issue #9766: Rename poorly named variables exposed by _warnings to prevent
confusion with the proper variables names from 'warnings' itself.
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Sat Sep 4 20:43:52 2010
@@ -1420,50 +1420,21 @@
SET_THIRD(v);
FAST_DISPATCH();
- TARGET(ROT_FOUR)
- u = TOP();
- v = SECOND();
- w = THIRD();
- x = FOURTH();
- SET_TOP(v);
- SET_SECOND(w);
- SET_THIRD(x);
- SET_FOURTH(u);
- FAST_DISPATCH();
-
TARGET(DUP_TOP)
v = TOP();
Py_INCREF(v);
PUSH(v);
FAST_DISPATCH();
- TARGET(DUP_TOPX)
- if (oparg == 2) {
- x = TOP();
- Py_INCREF(x);
- w = SECOND();
- Py_INCREF(w);
- STACKADJ(2);
- SET_TOP(x);
- SET_SECOND(w);
- FAST_DISPATCH();
- } else if (oparg == 3) {
- x = TOP();
- Py_INCREF(x);
- w = SECOND();
- Py_INCREF(w);
- v = THIRD();
- Py_INCREF(v);
- STACKADJ(3);
- SET_TOP(x);
- SET_SECOND(w);
- SET_THIRD(v);
- FAST_DISPATCH();
- }
- Py_FatalError("invalid argument to DUP_TOPX"
- " (bytecode corruption?)");
- /* Never returns, so don't bother to set why. */
- break;
+ TARGET(DUP_TOP_TWO)
+ x = TOP();
+ Py_INCREF(x);
+ w = SECOND();
+ Py_INCREF(w);
+ STACKADJ(2);
+ SET_TOP(x);
+ SET_SECOND(w);
+ FAST_DISPATCH();
TARGET(UNARY_POSITIVE)
v = TOP();
Modified: python/branches/py3k/Python/compile.c
==============================================================================
--- python/branches/py3k/Python/compile.c (original)
+++ python/branches/py3k/Python/compile.c Sat Sep 4 20:43:52 2010
@@ -680,8 +680,8 @@
return 0;
case DUP_TOP:
return 1;
- case ROT_FOUR:
- return 0;
+ case DUP_TOP_TWO:
+ return 2;
case UNARY_POSITIVE:
case UNARY_NEGATIVE:
@@ -782,8 +782,6 @@
return -1;
case DELETE_GLOBAL:
return 0;
- case DUP_TOPX:
- return oparg;
case LOAD_CONST:
return 1;
case LOAD_NAME:
@@ -3404,7 +3402,7 @@
return 0;
}
if (ctx == AugLoad) {
- ADDOP_I(c, DUP_TOPX, 2);
+ ADDOP(c, DUP_TOP_TWO);
}
else if (ctx == AugStore) {
ADDOP(c, ROT_THREE);
Modified: python/branches/py3k/Python/import.c
==============================================================================
--- python/branches/py3k/Python/import.c (original)
+++ python/branches/py3k/Python/import.c Sat Sep 4 20:43:52 2010
@@ -101,12 +101,14 @@
introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
Python 3.2a0: 3160 (add SETUP_WITH)
tag: cpython-32
+ Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
+ tag: cpython-32
*/
/* If you change MAGIC, you must change TAG and you must insert the old value
into _PyMagicNumberTags below.
*/
-#define MAGIC (3160 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (3170 | ((long)'\r'<<16) | ((long)'\n'<<24))
#define TAG "cpython-32"
#define CACHEDIR "__pycache__"
/* Current magic word and string tag as globals. */
Modified: python/branches/py3k/Python/opcode_targets.h
==============================================================================
--- python/branches/py3k/Python/opcode_targets.h (original)
+++ python/branches/py3k/Python/opcode_targets.h Sat Sep 4 20:43:52 2010
@@ -4,7 +4,7 @@
&&TARGET_ROT_TWO,
&&TARGET_ROT_THREE,
&&TARGET_DUP_TOP,
- &&TARGET_ROT_FOUR,
+ &&TARGET_DUP_TOP_TWO,
&&_unknown_opcode,
&&_unknown_opcode,
&&_unknown_opcode,
@@ -98,7 +98,7 @@
&&TARGET_DELETE_ATTR,
&&TARGET_STORE_GLOBAL,
&&TARGET_DELETE_GLOBAL,
- &&TARGET_DUP_TOPX,
+ &&_unknown_opcode,
&&TARGET_LOAD_CONST,
&&TARGET_LOAD_NAME,
&&TARGET_BUILD_TUPLE,
From python-checkins at python.org Sat Sep 4 20:45:37 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 20:45:37 +0200 (CEST)
Subject: [Python-checkins] r84502 - python/branches/py3k/Modules/_pickle.c
Message-ID: <20100904184537.33570FA6F@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 20:45:37 2010
New Revision: 84502
Log:
Fix typos in error messages (thanks Arfrever).
Modified:
python/branches/py3k/Modules/_pickle.c
Modified: python/branches/py3k/Modules/_pickle.c
==============================================================================
--- python/branches/py3k/Modules/_pickle.c (original)
+++ python/branches/py3k/Modules/_pickle.c Sat Sep 4 20:45:37 2010
@@ -497,7 +497,7 @@
/* XXX: Should bytearray be supported too? */
if (!PyBytes_Check(data)) {
PyErr_SetString(PyExc_ValueError,
- "read() from the underlying stream did not"
+ "read() from the underlying stream did not "
"return bytes");
Py_DECREF(data);
return -1;
@@ -530,7 +530,7 @@
/* XXX: Should bytearray be supported too? */
if (!PyBytes_Check(data)) {
PyErr_SetString(PyExc_ValueError,
- "readline() from the underlying stream did not"
+ "readline() from the underlying stream did not "
"return bytes");
return -1;
}
From python-checkins at python.org Sat Sep 4 20:46:56 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 20:46:56 +0200 (CEST)
Subject: [Python-checkins] r84503 - in python/branches/release31-maint:
Modules/_pickle.c
Message-ID: <20100904184656.C7AB1FA9F@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 20:46:56 2010
New Revision: 84503
Log:
Merged revisions 84502 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84502 | antoine.pitrou | 2010-09-04 20:45:37 +0200 (sam., 04 sept. 2010) | 3 lines
Fix typos in error messages (thanks Arfrever).
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Modules/_pickle.c
Modified: python/branches/release31-maint/Modules/_pickle.c
==============================================================================
--- python/branches/release31-maint/Modules/_pickle.c (original)
+++ python/branches/release31-maint/Modules/_pickle.c Sat Sep 4 20:46:56 2010
@@ -497,7 +497,7 @@
/* XXX: Should bytearray be supported too? */
if (!PyBytes_Check(data)) {
PyErr_SetString(PyExc_ValueError,
- "read() from the underlying stream did not"
+ "read() from the underlying stream did not "
"return bytes");
Py_DECREF(data);
return -1;
@@ -530,7 +530,7 @@
/* XXX: Should bytearray be supported too? */
if (!PyBytes_Check(data)) {
PyErr_SetString(PyExc_ValueError,
- "readline() from the underlying stream did not"
+ "readline() from the underlying stream did not "
"return bytes");
return -1;
}
From python-checkins at python.org Sat Sep 4 20:50:35 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 20:50:35 +0200 (CEST)
Subject: [Python-checkins] r84504 -
python/branches/py3k/Lib/test/test_socket.py
Message-ID: <20100904185035.67729F99B@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 20:50:35 2010
New Revision: 84504
Log:
Issue #9777: test_idna requires the "network" resource
Modified:
python/branches/py3k/Lib/test/test_socket.py
Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py (original)
+++ python/branches/py3k/Lib/test/test_socket.py Sat Sep 4 20:50:35 2010
@@ -642,6 +642,7 @@
self.assertRaises(socket.error, socket.getnameinfo, ('mail.python.org',0), 0)
def test_idna(self):
+ support.requires('network')
# these should all be successful
socket.gethostbyname('?????????.python.org')
socket.gethostbyname_ex('?????????.python.org')
From python-checkins at python.org Sat Sep 4 22:16:54 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 22:16:54 +0200 (CEST)
Subject: [Python-checkins] r84505 - in python/branches/py3k:
Lib/json/decoder.py Lib/json/scanner.py
Lib/json/tests/test_decode.py Misc/NEWS Modules/_json.c
Message-ID: <20100904201654.2F7AEF924@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 22:16:53 2010
New Revision: 84505
Log:
Issue #7451: Improve decoding performance of JSON objects, and reduce
the memory consumption of said decoded objects when they use the same
strings as keys.
Modified:
python/branches/py3k/Lib/json/decoder.py
python/branches/py3k/Lib/json/scanner.py
python/branches/py3k/Lib/json/tests/test_decode.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/_json.c
Modified: python/branches/py3k/Lib/json/decoder.py
==============================================================================
--- python/branches/py3k/Lib/json/decoder.py (original)
+++ python/branches/py3k/Lib/json/decoder.py Sat Sep 4 22:16:53 2010
@@ -147,10 +147,14 @@
def JSONObject(s_and_end, strict, scan_once, object_hook, object_pairs_hook,
- _w=WHITESPACE.match, _ws=WHITESPACE_STR):
+ memo=None, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
s, end = s_and_end
pairs = []
pairs_append = pairs.append
+ # Backwards compatibility
+ if memo is None:
+ memo = {}
+ memo_get = memo.setdefault
# Use a slice to prevent IndexError from being raised, the following
# check will raise a more specific ValueError if the string is empty
nextchar = s[end:end + 1]
@@ -167,6 +171,7 @@
end += 1
while True:
key, end = scanstring(s, end, strict)
+ key = memo_get(key, key)
# To skip some function call overhead we optimize the fast paths where
# the JSON key separator is ": " or just ":".
if s[end:end + 1] != ':':
@@ -214,7 +219,7 @@
pairs = object_hook(pairs)
return pairs, end
-def JSONArray(s_and_end, scan_once, context, _w=WHITESPACE.match):
+def JSONArray(s_and_end, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
s, end = s_and_end
values = []
nextchar = s[end:end + 1]
@@ -314,6 +319,7 @@
self.parse_object = JSONObject
self.parse_array = JSONArray
self.parse_string = scanstring
+ self.memo = {}
self.scan_once = make_scanner(self)
Modified: python/branches/py3k/Lib/json/scanner.py
==============================================================================
--- python/branches/py3k/Lib/json/scanner.py (original)
+++ python/branches/py3k/Lib/json/scanner.py Sat Sep 4 22:16:53 2010
@@ -22,6 +22,8 @@
parse_int = context.parse_int
parse_constant = context.parse_constant
object_hook = context.object_hook
+ object_pairs_hook = context.object_pairs_hook
+ memo = context.memo
def _scan_once(string, idx):
try:
@@ -33,7 +35,7 @@
return parse_string(string, idx + 1, strict)
elif nextchar == '{':
return parse_object((string, idx + 1), strict,
- _scan_once, object_hook, object_pairs_hook)
+ _scan_once, object_hook, object_pairs_hook, memo)
elif nextchar == '[':
return parse_array((string, idx + 1), _scan_once)
elif nextchar == 'n' and string[idx:idx + 4] == 'null':
@@ -60,6 +62,12 @@
else:
raise StopIteration
+ def scan_once(string, idx):
+ try:
+ return _scan_once(string, idx)
+ finally:
+ memo.clear()
+
return _scan_once
make_scanner = c_make_scanner or py_make_scanner
Modified: python/branches/py3k/Lib/json/tests/test_decode.py
==============================================================================
--- python/branches/py3k/Lib/json/tests/test_decode.py (original)
+++ python/branches/py3k/Lib/json/tests/test_decode.py Sat Sep 4 22:16:53 2010
@@ -1,10 +1,25 @@
import decimal
from unittest import TestCase
from io import StringIO
+from contextlib import contextmanager
import json
+import json.decoder
+import json.scanner
from collections import OrderedDict
+
+ at contextmanager
+def use_python_scanner():
+ py_scanner = json.scanner.py_make_scanner
+ old_scanner = json.decoder.make_scanner
+ json.decoder.make_scanner = py_scanner
+ try:
+ yield
+ finally:
+ json.decoder.make_scanner = old_scanner
+
+
class TestDecode(TestCase):
def test_decimal(self):
rval = json.loads('1.1', parse_float=decimal.Decimal)
@@ -39,3 +54,16 @@
# exercise the uncommon cases. The array cases are already covered.
rval = json.loads('{ "key" : "value" , "k":"v" }')
self.assertEquals(rval, {"key":"value", "k":"v"})
+
+ def check_keys_reuse(self, source, loads):
+ rval = loads(source)
+ (a, b), (c, d) = sorted(rval[0]), sorted(rval[1])
+ self.assertIs(a, c)
+ self.assertIs(b, d)
+
+ def test_keys_reuse(self):
+ s = '[{"a_key": 1, "b_\xe9": 2}, {"a_key": 3, "b_\xe9": 4}]'
+ self.check_keys_reuse(s, json.loads)
+ # Disabled: the pure Python version of json simply doesn't work
+ with use_python_scanner():
+ self.check_keys_reuse(s, json.decoder.JSONDecoder().decode)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 22:16:53 2010
@@ -165,6 +165,10 @@
Library
-------
+- Issue #7451: Improve decoding performance of JSON objects, and reduce
+ the memory consumption of said decoded objects when they use the same
+ strings as keys.
+
- Issue #1100562: Fix deep-copying of objects derived from the list and
dict types. Patch by Michele Orr? and Bj?rn Lindqvist.
Modified: python/branches/py3k/Modules/_json.c
==============================================================================
--- python/branches/py3k/Modules/_json.c (original)
+++ python/branches/py3k/Modules/_json.c Sat Sep 4 22:16:53 2010
@@ -36,6 +36,7 @@
PyObject *parse_float;
PyObject *parse_int;
PyObject *parse_constant;
+ PyObject *memo;
} PyScannerObject;
static PyMemberDef scanner_members[] = {
@@ -305,6 +306,21 @@
return tpl;
}
+#define APPEND_OLD_CHUNK \
+ if (chunk != NULL) { \
+ if (chunks == NULL) { \
+ chunks = PyList_New(0); \
+ if (chunks == NULL) { \
+ goto bail; \
+ } \
+ } \
+ if (PyList_Append(chunks, chunk)) { \
+ Py_DECREF(chunk); \
+ goto bail; \
+ } \
+ Py_CLEAR(chunk); \
+ }
+
static PyObject *
scanstring_unicode(PyObject *pystr, Py_ssize_t end, int strict, Py_ssize_t *next_end_ptr)
{
@@ -316,15 +332,14 @@
Return value is a new PyUnicode
*/
- PyObject *rval;
+ PyObject *rval = NULL;
Py_ssize_t len = PyUnicode_GET_SIZE(pystr);
Py_ssize_t begin = end - 1;
Py_ssize_t next = begin;
const Py_UNICODE *buf = PyUnicode_AS_UNICODE(pystr);
- PyObject *chunks = PyList_New(0);
- if (chunks == NULL) {
- goto bail;
- }
+ PyObject *chunks = NULL;
+ PyObject *chunk = NULL;
+
if (end < 0 || len <= end) {
PyErr_SetString(PyExc_ValueError, "end is out of bounds");
goto bail;
@@ -332,7 +347,6 @@
while (1) {
/* Find the end of the string or the next escape */
Py_UNICODE c = 0;
- PyObject *chunk = NULL;
for (next = end; next < len; next++) {
c = buf[next];
if (c == '"' || c == '\\') {
@@ -349,15 +363,11 @@
}
/* Pick up this chunk if it's not zero length */
if (next != end) {
+ APPEND_OLD_CHUNK
chunk = PyUnicode_FromUnicode(&buf[end], next - end);
if (chunk == NULL) {
goto bail;
}
- if (PyList_Append(chunks, chunk)) {
- Py_DECREF(chunk);
- goto bail;
- }
- Py_DECREF(chunk);
}
next++;
if (c == '"') {
@@ -459,27 +469,34 @@
}
#endif
}
+ APPEND_OLD_CHUNK
chunk = PyUnicode_FromUnicode(&c, 1);
if (chunk == NULL) {
goto bail;
}
- if (PyList_Append(chunks, chunk)) {
- Py_DECREF(chunk);
+ }
+
+ if (chunks == NULL) {
+ if (chunk != NULL)
+ rval = chunk;
+ else
+ rval = PyUnicode_FromStringAndSize("", 0);
+ }
+ else {
+ APPEND_OLD_CHUNK
+ rval = join_list_unicode(chunks);
+ if (rval == NULL) {
goto bail;
}
- Py_DECREF(chunk);
+ Py_CLEAR(chunks);
}
- rval = join_list_unicode(chunks);
- if (rval == NULL) {
- goto bail;
- }
- Py_DECREF(chunks);
*next_end_ptr = end;
return rval;
bail:
*next_end_ptr = -1;
Py_XDECREF(chunks);
+ Py_XDECREF(chunk);
return NULL;
}
@@ -578,6 +595,7 @@
Py_CLEAR(s->parse_float);
Py_CLEAR(s->parse_int);
Py_CLEAR(s->parse_constant);
+ Py_CLEAR(s->memo);
return 0;
}
@@ -593,10 +611,16 @@
Py_UNICODE *str = PyUnicode_AS_UNICODE(pystr);
Py_ssize_t end_idx = PyUnicode_GET_SIZE(pystr) - 1;
PyObject *val = NULL;
- PyObject *rval = PyList_New(0);
+ PyObject *rval = NULL;
PyObject *key = NULL;
int strict = PyObject_IsTrue(s->strict);
+ int has_pairs_hook = (s->object_pairs_hook != Py_None);
Py_ssize_t next_idx;
+
+ if (has_pairs_hook)
+ rval = PyList_New(0);
+ else
+ rval = PyDict_New();
if (rval == NULL)
return NULL;
@@ -606,6 +630,8 @@
/* only loop if the object is non-empty */
if (idx <= end_idx && str[idx] != '}') {
while (idx <= end_idx) {
+ PyObject *memokey;
+
/* read key */
if (str[idx] != '"') {
raise_errmsg("Expecting property name", pystr, idx);
@@ -614,6 +640,16 @@
key = scanstring_unicode(pystr, idx + 1, strict, &next_idx);
if (key == NULL)
goto bail;
+ memokey = PyDict_GetItem(s->memo, key);
+ if (memokey != NULL) {
+ Py_INCREF(memokey);
+ Py_DECREF(key);
+ key = memokey;
+ }
+ else {
+ if (PyDict_SetItem(s->memo, key, key) < 0)
+ goto bail;
+ }
idx = next_idx;
/* skip whitespace between key and : delimiter, read :, skip whitespace */
@@ -630,19 +666,24 @@
if (val == NULL)
goto bail;
- {
- PyObject *tuple = PyTuple_Pack(2, key, val);
- if (tuple == NULL)
+ if (has_pairs_hook) {
+ PyObject *item = PyTuple_Pack(2, key, val);
+ if (item == NULL)
goto bail;
- if (PyList_Append(rval, tuple) == -1) {
- Py_DECREF(tuple);
+ Py_CLEAR(key);
+ Py_CLEAR(val);
+ if (PyList_Append(rval, item) == -1) {
+ Py_DECREF(item);
goto bail;
}
- Py_DECREF(tuple);
+ Py_DECREF(item);
+ }
+ else {
+ if (PyDict_SetItem(rval, key, val) < 0)
+ goto bail;
+ Py_CLEAR(key);
+ Py_CLEAR(val);
}
-
- Py_CLEAR(key);
- Py_CLEAR(val);
idx = next_idx;
/* skip whitespace before } or , */
@@ -672,36 +713,23 @@
*next_idx_ptr = idx + 1;
- if (s->object_pairs_hook != Py_None) {
+ if (has_pairs_hook) {
val = PyObject_CallFunctionObjArgs(s->object_pairs_hook, rval, NULL);
- if (val == NULL)
- goto bail;
Py_DECREF(rval);
return val;
}
- val = PyDict_New();
- if (val == NULL)
- goto bail;
- if (PyDict_MergeFromSeq2(val, rval, 1) == -1)
- goto bail;
- Py_DECREF(rval);
- rval = val;
-
/* if object_hook is not None: rval = object_hook(rval) */
if (s->object_hook != Py_None) {
val = PyObject_CallFunctionObjArgs(s->object_hook, rval, NULL);
- if (val == NULL)
- goto bail;
Py_DECREF(rval);
- rval = val;
- val = NULL;
+ return val;
}
return rval;
bail:
Py_XDECREF(key);
Py_XDECREF(val);
- Py_DECREF(rval);
+ Py_XDECREF(rval);
return NULL;
}
@@ -988,6 +1016,9 @@
Py_TYPE(pystr)->tp_name);
return NULL;
}
+ PyDict_Clear(s->memo);
+ if (rval == NULL)
+ return NULL;
return _build_rval_index_tuple(rval, next_idx);
}
@@ -1021,6 +1052,12 @@
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:make_scanner", kwlist, &ctx))
return -1;
+ if (s->memo == NULL) {
+ s->memo = PyDict_New();
+ if (s->memo == NULL)
+ goto bail;
+ }
+
/* All of these will fail "gracefully" so we don't need to verify them */
s->strict = PyObject_GetAttrString(ctx, "strict");
if (s->strict == NULL)
From python-checkins at python.org Sat Sep 4 22:53:30 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 22:53:30 +0200 (CEST)
Subject: [Python-checkins] r84506 - in python/branches/py3k:
Lib/test/test_fileio.py Misc/NEWS PC/msvcrtmodule.c
Message-ID: <20100904205330.0C9E3FB04@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 22:53:29 2010
New Revision: 84506
Log:
Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file
descriptor is provided. Patch by Pascal Chambon.
Modified:
python/branches/py3k/Lib/test/test_fileio.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/PC/msvcrtmodule.c
Modified: python/branches/py3k/Lib/test/test_fileio.py
==============================================================================
--- python/branches/py3k/Lib/test/test_fileio.py (original)
+++ python/branches/py3k/Lib/test/test_fileio.py Sat Sep 4 22:53:29 2010
@@ -309,6 +309,9 @@
def testInvalidFd(self):
self.assertRaises(ValueError, _FileIO, -10)
self.assertRaises(OSError, _FileIO, make_bad_fd())
+ if sys.platform == 'win32':
+ import msvcrt
+ self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd())
def testBadModeArgument(self):
# verify that we get a sensible error message for bad mode argument
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 4 22:53:29 2010
@@ -100,6 +100,9 @@
Extensions
----------
+- Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file
+ descriptor is provided. Patch by Pascal Chambon.
+
- Issue #7736: Release the GIL around calls to opendir() and closedir()
in the posix module. Patch by Marcin Bachry.
Modified: python/branches/py3k/PC/msvcrtmodule.c
==============================================================================
--- python/branches/py3k/PC/msvcrtmodule.c (original)
+++ python/branches/py3k/PC/msvcrtmodule.c Sat Sep 4 22:53:29 2010
@@ -143,6 +143,9 @@
if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
return NULL;
+ if (!_PyVerify_fd(fd))
+ return PyErr_SetFromErrno(PyExc_IOError);
+
handle = _get_osfhandle(fd);
if (handle == -1)
return PyErr_SetFromErrno(PyExc_IOError);
From python-checkins at python.org Sat Sep 4 23:02:41 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 23:02:41 +0200 (CEST)
Subject: [Python-checkins] r84507 - in python/branches/release31-maint:
Lib/test/test_fileio.py Misc/NEWS PC/msvcrtmodule.c
Message-ID: <20100904210241.72D3FF794@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 23:02:41 2010
New Revision: 84507
Log:
Merged revisions 84506 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84506 | antoine.pitrou | 2010-09-04 22:53:29 +0200 (sam., 04 sept. 2010) | 5 lines
Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file
descriptor is provided. Patch by Pascal Chambon.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_fileio.py
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/PC/msvcrtmodule.c
Modified: python/branches/release31-maint/Lib/test/test_fileio.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_fileio.py (original)
+++ python/branches/release31-maint/Lib/test/test_fileio.py Sat Sep 4 23:02:41 2010
@@ -313,6 +313,9 @@
def testInvalidFd(self):
self.assertRaises(ValueError, _FileIO, -10)
self.assertRaises(OSError, _FileIO, make_bad_fd())
+ if sys.platform == 'win32':
+ import msvcrt
+ self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd())
def testBadModeArgument(self):
# verify that we get a sensible error message for bad mode argument
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Sat Sep 4 23:02:41 2010
@@ -477,6 +477,9 @@
Extension Modules
-----------------
+- Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file
+ descriptor is provided. Patch by Pascal Chambon.
+
- Issue #7736: Release the GIL around calls to opendir() and closedir()
in the posix module. Patch by Marcin Bachry.
Modified: python/branches/release31-maint/PC/msvcrtmodule.c
==============================================================================
--- python/branches/release31-maint/PC/msvcrtmodule.c (original)
+++ python/branches/release31-maint/PC/msvcrtmodule.c Sat Sep 4 23:02:41 2010
@@ -143,6 +143,9 @@
if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
return NULL;
+ if (!_PyVerify_fd(fd))
+ return PyErr_SetFromErrno(PyExc_IOError);
+
handle = _get_osfhandle(fd);
if (handle == -1)
return PyErr_SetFromErrno(PyExc_IOError);
From python-checkins at python.org Sat Sep 4 23:24:42 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 4 Sep 2010 23:24:42 +0200 (CEST)
Subject: [Python-checkins] r84508 - in python/branches/release27-maint:
Lib/test/test_fileio.py Misc/NEWS PC/msvcrtmodule.c
Message-ID: <20100904212442.3F72DF99B@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 4 23:24:42 2010
New Revision: 84508
Log:
Merged revisions 84506 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84506 | antoine.pitrou | 2010-09-04 22:53:29 +0200 (sam., 04 sept. 2010) | 5 lines
Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file
descriptor is provided. Patch by Pascal Chambon.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_fileio.py
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/PC/msvcrtmodule.c
Modified: python/branches/release27-maint/Lib/test/test_fileio.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_fileio.py (original)
+++ python/branches/release27-maint/Lib/test/test_fileio.py Sat Sep 4 23:24:42 2010
@@ -312,6 +312,9 @@
def testInvalidFd(self):
self.assertRaises(ValueError, _FileIO, -10)
self.assertRaises(OSError, _FileIO, make_bad_fd())
+ if sys.platform == 'win32':
+ import msvcrt
+ self.assertRaises(IOError, msvcrt.get_osfhandle, make_bad_fd())
def testBadModeArgument(self):
# verify that we get a sensible error message for bad mode argument
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Sat Sep 4 23:24:42 2010
@@ -228,6 +228,9 @@
Extension Modules
-----------------
+- Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file
+ descriptor is provided. Patch by Pascal Chambon.
+
- Issue #7736: Release the GIL around calls to opendir() and closedir()
in the posix module. Patch by Marcin Bachry.
Modified: python/branches/release27-maint/PC/msvcrtmodule.c
==============================================================================
--- python/branches/release27-maint/PC/msvcrtmodule.c (original)
+++ python/branches/release27-maint/PC/msvcrtmodule.c Sat Sep 4 23:24:42 2010
@@ -141,6 +141,9 @@
if (!PyArg_ParseTuple(args,"i:get_osfhandle", &fd))
return NULL;
+ if (!_PyVerify_fd(fd))
+ return PyErr_SetFromErrno(PyExc_IOError);
+
handle = _get_osfhandle(fd);
if (handle == -1)
return PyErr_SetFromErrno(PyExc_IOError);
From python-checkins at python.org Sun Sep 5 00:12:46 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sun, 5 Sep 2010 00:12:46 +0200 (CEST)
Subject: [Python-checkins] r84509 - python/branches/py3k/Tools/msi/msilib.py
Message-ID: <20100904221246.6EF5FFA4B@mail.python.org>
Author: martin.v.loewis
Date: Sun Sep 5 00:12:46 2010
New Revision: 84509
Log:
Drop cabarc artifact.
Modified:
python/branches/py3k/Tools/msi/msilib.py
Modified: python/branches/py3k/Tools/msi/msilib.py
==============================================================================
--- python/branches/py3k/Tools/msi/msilib.py (original)
+++ python/branches/py3k/Tools/msi/msilib.py Sun Sep 5 00:12:46 2010
@@ -381,7 +381,6 @@
add_data(db, "Media",
[(1, self.index, None, "#"+self.name, None, None)])
add_stream(db, self.name, self.name+".cab")
- os.unlink(self.name+".txt")
os.unlink(self.name+".cab")
db.Commit()
From python-checkins at python.org Sun Sep 5 00:46:06 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 00:46:06 +0200 (CEST)
Subject: [Python-checkins] r84510 - in python/branches/py3k:
Doc/library/functools.rst Doc/whatsnew/3.2.rst
Lib/functools.py Lib/re.py Lib/test/test_functools.py
Message-ID: <20100904224606.6CC40FA4B@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 00:46:06 2010
New Revision: 84510
Log:
Adopt more descriptive attribute names as suggested on python-dev.
Modified:
python/branches/py3k/Doc/library/functools.rst
python/branches/py3k/Doc/whatsnew/3.2.rst
python/branches/py3k/Lib/functools.py
python/branches/py3k/Lib/re.py
python/branches/py3k/Lib/test/test_functools.py
Modified: python/branches/py3k/Doc/library/functools.rst
==============================================================================
--- python/branches/py3k/Doc/library/functools.rst (original)
+++ python/branches/py3k/Doc/library/functools.rst Sun Sep 5 00:46:06 2010
@@ -47,12 +47,12 @@
results, the positional and keyword arguments to the function must be
hashable.
- The wrapped function is instrumented with two attributes, :attr:`hits`
- and :attr:`misses` which count the number of successful or unsuccessful
+ The wrapped function is instrumented with two attributes, :attr:`cache_hits`
+ and :attr:`cache_misses` which count the number of successful or unsuccessful
cache lookups. These statistics are helpful for tuning the *maxsize*
parameter and for measuring the cache's effectiveness.
- The wrapped function also has a :attr:`clear` attribute which can be
+ The wrapped function also has a :attr:`cache_clear` attribute which can be
called (with no arguments) to clear the cache.
The original underlying function is accessible through the
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 00:46:06 2010
@@ -85,17 +85,17 @@
return c.fetchone()[0]
To help with choosing an effective cache size, the wrapped function is
- instrumented with two attributes *hits* and *misses*::
+ instrumented with two attributes *cache_hits* and *cache_misses*::
>>> for name in user_requests:
... get_phone_number(name)
- >>> print(get_phone_number.hits, get_phone_number.misses)
+ >>> print(get_phone_number.cache_hits, get_phone_number.cache_misses)
4805 980
If the phonelist table gets updated, the outdated contents of the cache can be
cleared with::
- >>> get_phone_number.clear()
+ >>> get_phone_number.cache_clear()
(Contributed by Raymond Hettinger)
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Sun Sep 5 00:46:06 2010
@@ -142,23 +142,23 @@
with lock:
result = cache[key]
cache_renew(key) # record recent use of this key
- wrapper.hits += 1
+ wrapper.cache_hits += 1
except KeyError:
result = user_function(*args, **kwds)
with lock:
cache[key] = result # record recent use of this key
- wrapper.misses += 1
+ wrapper.cache_misses += 1
if len(cache) > maxsize:
cache_popitem(0) # purge least recently used cache entry
return result
- def clear():
+ def cache_clear():
"""Clear the cache and cache statistics"""
with lock:
cache.clear()
- wrapper.hits = wrapper.misses = 0
+ wrapper.cache_hits = wrapper.cache_misses = 0
- wrapper.hits = wrapper.misses = 0
- wrapper.clear = clear
+ wrapper.cache_hits = wrapper.cache_misses = 0
+ wrapper.cache_clear = cache_clear
return wrapper
return decorating_function
Modified: python/branches/py3k/Lib/re.py
==============================================================================
--- python/branches/py3k/Lib/re.py (original)
+++ python/branches/py3k/Lib/re.py Sun Sep 5 00:46:06 2010
@@ -207,8 +207,8 @@
def purge():
"Clear the regular expression caches"
- _compile_typed.clear()
- _compile_repl.clear()
+ _compile_typed.cache_clear()
+ _compile_repl.cache_clear()
def template(pattern, flags=0):
"Compile a template pattern, returning a pattern object"
Modified: python/branches/py3k/Lib/test/test_functools.py
==============================================================================
--- python/branches/py3k/Lib/test/test_functools.py (original)
+++ python/branches/py3k/Lib/test/test_functools.py Sun Sep 5 00:46:06 2010
@@ -508,21 +508,21 @@
actual = f(x, y)
expected = orig(x, y)
self.assertEquals(actual, expected)
- self.assert_(f.hits > f.misses)
- self.assertEquals(f.hits + f.misses, 1000)
+ self.assert_(f.cache_hits > f.cache_misses)
+ self.assertEquals(f.cache_hits + f.cache_misses, 1000)
- f.clear() # test clearing
- self.assertEqual(f.hits, 0)
- self.assertEqual(f.misses, 0)
+ f.cache_clear() # test clearing
+ self.assertEqual(f.cache_hits, 0)
+ self.assertEqual(f.cache_misses, 0)
f(x, y)
- self.assertEqual(f.hits, 0)
- self.assertEqual(f.misses, 1)
+ self.assertEqual(f.cache_hits, 0)
+ self.assertEqual(f.cache_misses, 1)
# Test bypassing the cache
self.assertIs(f.__wrapped__, orig)
f.__wrapped__(x, y)
- self.assertEqual(f.hits, 0)
- self.assertEqual(f.misses, 1)
+ self.assertEqual(f.cache_hits, 0)
+ self.assertEqual(f.cache_misses, 1)
# test size zero (which means "never-cache")
@functools.lru_cache(0)
From python-checkins at python.org Sun Sep 5 01:53:24 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 01:53:24 +0200 (CEST)
Subject: [Python-checkins] r84511 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100904235324.D465BFCB4@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 01:53:24 2010
New Revision: 84511
Log:
Update whatsnew for Pep3147.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 01:53:24 2010
@@ -51,12 +51,65 @@
This article explains the new features in Python 3.2, compared to 3.1.
+PEP 3147: PYC Repository Directories
+=====================================
+
+Python's scheme for caching bytecode in *.pyc* files did not work well in
+environments with multiple python interpreters. If one interpreter encountered
+a cached file created by another interpreter, it would recompile the source and
+overwrite the cached file, thus losing the benefits of caching.
+
+The issue of "pyc fights" has become more pronounced as it has become
+common-place for Linux distributions to ship with multiple versions of Python.
+These conflicts also arise with CPython alternatives such as Unladen Swallow.
+
+To solve this problem, Python's import machinery has been extended to use
+distinct filenames for each interpreter. Instead of Python3.2 and Python3.3 and
+UnladenSwallow each competing for a file called "mymodule.pyc", they will now
+look for "mymodule.cpython-32.pyc", "mymodule.cpython-33.pyc", and
+"mymodule.unladen10.pyc". And to keep prevent all of these new files from
+cluttering source directories, the *pyc* files are now collected in a
+"__pycache__" directory stored under the package directory.
+
+Aside from the filenames and target directories, the new scheme has a few
+aspects that are visible to the programmer:
+
+* Imported modules now have a :attr:`__cached__` attribute which stores the
+ name of the actual file that was imported::
+
+ >>> import collections
+ >>> collections.__cached__
+ 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
+
+* The tag that is unique to each interpreter is accessible from the :mod:`imp`
+ module::
+
+ >>> import imp
+ >>> imp.get_tag()
+ 'cpython-32'
+
+* Scripts that try to deduce source filename from the imported file now need to
+ be smarter. It is no longer sufficient to simply strip the "c" from a ".pyc"
+ filename. Instead, use the new functions in the :mod:`imp` module:
+
+ >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')
+ 'c:/py32/lib/collections.py'
+ >>> imp.cache_from_source('c:/py32/lib/collections.py')
+ 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
+
+* The :mod:`py_compile` and :mod:`compileall` modules have been updated to
+ reflect the new naming convention and target directory.
+
+.. seealso::
+
+ :pep:`3147` - PYC Repository Directories
+ PEP written by Barry Warsaw.
+
PEPs
====
Implemented PEPs:
-* :pep:`3147`
* :pep:`3149`
From python-checkins at python.org Sun Sep 5 02:09:07 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 5 Sep 2010 02:09:07 +0200 (CEST)
Subject: [Python-checkins] r84512 - in python/branches/py3k: configure
configure.in pyconfig.h.in
Message-ID: <20100905000907.ED500EB74@mail.python.org>
Author: benjamin.peterson
Date: Sun Sep 5 02:09:07 2010
New Revision: 84512
Log:
run autoreconf
Modified:
python/branches/py3k/configure
python/branches/py3k/configure.in
python/branches/py3k/pyconfig.h.in
Modified: python/branches/py3k/configure
==============================================================================
--- python/branches/py3k/configure (original)
+++ python/branches/py3k/configure Sun Sep 5 02:09:07 2010
@@ -1,14 +1,14 @@
#! /bin/sh
-# From configure.in Revision: 84379 .
+# From configure.in Revision: 84477 .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for python 3.2.
+# Generated by GNU Autoconf 2.65 for python 3.2.
#
# Report bugs to .
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
-# Foundation, Inc.
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
#
#
# This configure script is free software; the Free Software Foundation
@@ -320,7 +320,7 @@
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
} # as_fn_mkdir_p
@@ -360,19 +360,19 @@
fi # as_fn_arith
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
+# script with status $?, using 1 if that was 0.
as_fn_error ()
{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
fi
- $as_echo "$as_me: error: $2" >&2
+ $as_echo "$as_me: error: $1" >&2
as_fn_exit $as_status
} # as_fn_error
@@ -534,7 +534,7 @@
exec 6>&1
# Name of the host.
-# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
@@ -826,9 +826,8 @@
fi
case $ac_option in
- *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
- *=) ac_optarg= ;;
- *) ac_optarg=yes ;;
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
@@ -873,7 +872,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
+ as_fn_error "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -899,7 +898,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid feature name: $ac_useropt"
+ as_fn_error "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1103,7 +1102,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
+ as_fn_error "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1119,7 +1118,7 @@
ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
- as_fn_error $? "invalid package name: $ac_useropt"
+ as_fn_error "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
@@ -1149,8 +1148,8 @@
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
- -*) as_fn_error $? "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information"
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
;;
*=*)
@@ -1158,7 +1157,7 @@
# Reject names that are not valid shell variable names.
case $ac_envvar in #(
'' | [0-9]* | *[!_$as_cr_alnum]* )
- as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
esac
eval $ac_envvar=\$ac_optarg
export $ac_envvar ;;
@@ -1176,13 +1175,13 @@
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- as_fn_error $? "missing argument to $ac_option"
+ as_fn_error "missing argument to $ac_option"
fi
if test -n "$ac_unrecognized_opts"; then
case $enable_option_checking in
no) ;;
- fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
*) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
fi
@@ -1205,7 +1204,7 @@
[\\/$]* | ?:[\\/]* ) continue;;
NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
esac
- as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
done
# There might be people who depend on the old broken behavior: `$host'
@@ -1219,8 +1218,8 @@
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used" >&2
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -1235,9 +1234,9 @@
ac_pwd=`pwd` && test -n "$ac_pwd" &&
ac_ls_di=`ls -di .` &&
ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
- as_fn_error $? "working directory cannot be determined"
+ as_fn_error "working directory cannot be determined"
test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
- as_fn_error $? "pwd does not report name of working directory"
+ as_fn_error "pwd does not report name of working directory"
# Find the source files, if location was not specified.
@@ -1276,11 +1275,11 @@
fi
if test ! -r "$srcdir/$ac_unique_file"; then
test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
- as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
- cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1320,7 +1319,7 @@
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking ...' messages
+ -q, --quiet, --silent do not print \`checking...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
@@ -1505,9 +1504,9 @@
if $ac_init_version; then
cat <<\_ACEOF
python configure 3.2
-generated by GNU Autoconf 2.67
+generated by GNU Autoconf 2.65
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2009 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
@@ -1577,7 +1576,7 @@
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } > conftest.i && {
+ test $ac_status = 0; } >/dev/null && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then :
@@ -1601,10 +1600,10 @@
ac_fn_c_check_header_mongrel ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if eval "test \"\${$3+set}\"" = set; then :
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
@@ -1640,7 +1639,7 @@
else
ac_header_preproc=no
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }
@@ -1663,15 +1662,17 @@
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## -------------------------------------- ##
+( cat <<\_ASBOX
+## -------------------------------------- ##
## Report this to http://bugs.python.org/ ##
-## -------------------------------------- ##"
+## -------------------------------------- ##
+_ASBOX
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
eval "$3=\$ac_header_compiler"
@@ -1735,7 +1736,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -1812,7 +1813,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
@@ -1866,7 +1867,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
$as_echo_n "checking for uint$2_t... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
@@ -1896,7 +1897,8 @@
esac
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if eval test \"x\$"$3"\" = x"no"; then :
+ eval as_val=\$$3
+ if test "x$as_val" = x""no; then :
else
break
@@ -1919,7 +1921,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
$as_echo_n "checking for int$2_t... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
@@ -1930,11 +1932,11 @@
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
- enum { N = $2 / 2 - 1 };
int
main ()
{
-static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 };
+ 0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
test_array [0] = 0
;
@@ -1945,11 +1947,11 @@
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
- enum { N = $2 / 2 - 1 };
int
main ()
{
-static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+static int test_array [1 - 2 * !(enum { N = $2 / 2 - 1 };
+ ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
< ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
test_array [0] = 0
@@ -1970,7 +1972,8 @@
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- if eval test \"x\$"$3"\" = x"no"; then :
+ eval as_val=\$$3
+ if test "x$as_val" = x""no; then :
else
break
@@ -2170,7 +2173,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2238,7 +2241,7 @@
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
$as_echo_n "checking for $2.$3... " >&6; }
-if eval "test \"\${$4+set}\"" = set; then :
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2286,18 +2289,15 @@
} # ac_fn_c_check_member
-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
-# ---------------------------------------------
-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
-# accordingly.
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
ac_fn_c_check_decl ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- as_decl_name=`echo $2|sed 's/ *(.*//'`
- as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
-$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
-if eval "test \"\${$3+set}\"" = set; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2306,12 +2306,8 @@
int
main ()
{
-#ifndef $as_decl_name
-#ifdef __cplusplus
- (void) $as_decl_use;
-#else
- (void) $as_decl_name;
-#endif
+#ifndef $2
+ (void) $2;
#endif
;
@@ -2336,7 +2332,7 @@
running configure, to aid debugging if configure makes a mistake.
It was created by python $as_me 3.2, which was
-generated by GNU Autoconf 2.67. Invocation command line was
+generated by GNU Autoconf 2.65. Invocation command line was
$ $0 $@
@@ -2446,9 +2442,11 @@
{
echo
- $as_echo "## ---------------- ##
+ cat <<\_ASBOX
+## ---------------- ##
## Cache variables. ##
-## ---------------- ##"
+## ---------------- ##
+_ASBOX
echo
# The following way of writing the cache mishandles newlines in values,
(
@@ -2482,9 +2480,11 @@
)
echo
- $as_echo "## ----------------- ##
+ cat <<\_ASBOX
+## ----------------- ##
## Output variables. ##
-## ----------------- ##"
+## ----------------- ##
+_ASBOX
echo
for ac_var in $ac_subst_vars
do
@@ -2497,9 +2497,11 @@
echo
if test -n "$ac_subst_files"; then
- $as_echo "## ------------------- ##
+ cat <<\_ASBOX
+## ------------------- ##
## File substitutions. ##
-## ------------------- ##"
+## ------------------- ##
+_ASBOX
echo
for ac_var in $ac_subst_files
do
@@ -2513,9 +2515,11 @@
fi
if test -s confdefs.h; then
- $as_echo "## ----------- ##
+ cat <<\_ASBOX
+## ----------- ##
## confdefs.h. ##
-## ----------- ##"
+## ----------- ##
+_ASBOX
echo
cat confdefs.h
echo
@@ -2570,12 +2574,7 @@
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
- # We do not want a PATH search for config.site.
- case $CONFIG_SITE in #((
- -*) ac_site_file1=./$CONFIG_SITE;;
- */*) ac_site_file1=$CONFIG_SITE;;
- *) ac_site_file1=./$CONFIG_SITE;;
- esac
+ ac_site_file1=$CONFIG_SITE
elif test "x$prefix" != xNONE; then
ac_site_file1=$prefix/share/config.site
ac_site_file2=$prefix/etc/config.site
@@ -2590,11 +2589,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file" \
- || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5 ; }
+ . "$ac_site_file"
fi
done
@@ -2670,7 +2665,7 @@
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
@@ -2704,7 +2699,7 @@
VERSION=3.2
-# Version number or Python's own shared library file.
+# Version number of Python's own shared library file.
SOVERSION=1.0
@@ -2771,7 +2766,7 @@
UNIVERSALSDK=$enableval
if test ! -d "${UNIVERSALSDK}"
then
- as_fn_error $? "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5
+ as_fn_error "--enable-universalsdk specifies non-existing SDK: ${UNIVERSALSDK}" "$LINENO" 5
fi
;;
esac
@@ -3163,7 +3158,7 @@
# If the user switches compilers, we can't believe the cache
if test ! -z "$ac_cv_prog_CC" -a ! -z "$CC" -a "$CC" != "$ac_cv_prog_CC"
then
- as_fn_error $? "cached CC is different -- throw away $cache_file
+ as_fn_error "cached CC is different -- throw away $cache_file
(it is also a good idea to do 'make clean' before compiling)" "$LINENO" 5
fi
@@ -3473,8 +3468,8 @@
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5 ; }
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -3588,8 +3583,9 @@
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -3631,8 +3627,8 @@
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5 ; }
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -3689,9 +3685,9 @@
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
+as_fn_error "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details." "$LINENO" 5; }
fi
fi
fi
@@ -3742,8 +3738,8 @@
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5 ; }
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
@@ -4196,7 +4192,7 @@
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
@@ -4212,11 +4208,11 @@
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
break
fi
@@ -4255,7 +4251,7 @@
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
@@ -4271,18 +4267,18 @@
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
fi
ac_ext=c
@@ -4343,7 +4339,7 @@
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_GREP"; then
- as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_GREP=$GREP
@@ -4409,7 +4405,7 @@
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_EGREP"; then
- as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_EGREP=$EGREP
@@ -4541,7 +4537,8 @@
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
@@ -4803,7 +4800,8 @@
esac
if test "$ac_cv_c_inline" != no ; then
- $as_echo "#define USE_INLINE 1" >>confdefs.h
+
+$as_echo "#define USE_INLINE 1" >>confdefs.h
fi
@@ -5145,22 +5143,16 @@
esac
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
done
if test -z "$ac_aux_dir"; then
- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
fi
# These three variables are undocumented and unsupported,
@@ -5497,7 +5489,7 @@
ARCH_RUN_32BIT="/usr/bin/arch -i386 -ppc"
else
- as_fn_error $? "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5
+ as_fn_error "proper usage is --with-universal-arch=32-bit|64-bit|all|intel|3-way" "$LINENO" 5
fi
@@ -6074,7 +6066,8 @@
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
@@ -6088,7 +6081,7 @@
as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
-if eval "test \"\${$as_ac_Header+set}\"" = set; then :
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -6115,7 +6108,8 @@
eval ac_res=\$$as_ac_Header
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
_ACEOF
@@ -6635,8 +6629,9 @@
if test "$ac_cv_type_int" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (int)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_int=0
fi
@@ -6668,8 +6663,9 @@
if test "$ac_cv_type_long" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (long)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_long=0
fi
@@ -6701,8 +6697,9 @@
if test "$ac_cv_type_void_p" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (void *)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (void *)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_void_p=0
fi
@@ -6734,8 +6731,9 @@
if test "$ac_cv_type_short" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (short)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (short)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_short=0
fi
@@ -6767,8 +6765,9 @@
if test "$ac_cv_type_float" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (float)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (float)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_float=0
fi
@@ -6800,8 +6799,9 @@
if test "$ac_cv_type_double" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (double)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (double)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_double=0
fi
@@ -6833,8 +6833,9 @@
if test "$ac_cv_type_fpos_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (fpos_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (fpos_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_fpos_t=0
fi
@@ -6866,8 +6867,9 @@
if test "$ac_cv_type_size_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (size_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (size_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_size_t=0
fi
@@ -6899,8 +6901,9 @@
if test "$ac_cv_type_pid_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (pid_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (pid_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_pid_t=0
fi
@@ -6959,8 +6962,9 @@
if test "$ac_cv_type_long_long" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (long long)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_long_long=0
fi
@@ -7020,8 +7024,9 @@
if test "$ac_cv_type_long_double" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (long double)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long double)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_long_double=0
fi
@@ -7082,8 +7087,9 @@
if test "$ac_cv_type__Bool" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (_Bool)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (_Bool)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof__Bool=0
fi
@@ -7127,8 +7133,9 @@
if test "$ac_cv_type_uintptr_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (uintptr_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (uintptr_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_uintptr_t=0
fi
@@ -7168,8 +7175,9 @@
if test "$ac_cv_type_off_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (off_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (off_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_off_t=0
fi
@@ -7230,8 +7238,9 @@
if test "$ac_cv_type_time_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (time_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (time_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_time_t=0
fi
@@ -7302,8 +7311,9 @@
if test "$ac_cv_type_pthread_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (pthread_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (pthread_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_pthread_t=0
fi
@@ -7390,7 +7400,7 @@
MACOSX_DEFAULT_ARCH="ppc"
;;
*)
- as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
+ as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5
;;
esac
else
@@ -7402,7 +7412,7 @@
MACOSX_DEFAULT_ARCH="ppc64"
;;
*)
- as_fn_error $? "Unexpected output of 'arch' on OSX" "$LINENO" 5
+ as_fn_error "Unexpected output of 'arch' on OSX" "$LINENO" 5
;;
esac
@@ -7428,7 +7438,7 @@
$as_echo "yes" >&6; }
if test $enable_shared = "yes"
then
- as_fn_error $? "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5
+ as_fn_error "Specifying both --enable-shared and --enable-framework is not supported, use only --enable-framework instead" "$LINENO" 5
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
@@ -8206,12 +8216,12 @@
withval=$with_dbmliborder;
if test x$with_dbmliborder = xyes
then
-as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
+as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
else
for db in `echo $with_dbmliborder | sed 's/:/ /g'`; do
if test x$db != xndbm && test x$db != xgdbm && test x$db != xbdb
then
- as_fn_error $? "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
+ as_fn_error "proper usage is --with-dbmliborder=db1:db2:..." "$LINENO" 5
fi
done
fi
@@ -9210,7 +9220,7 @@
$as_echo "#define WITH_VALGRIND 1" >>confdefs.h
else
- as_fn_error $? "Valgrind support requested but headers not available" "$LINENO" 5
+ as_fn_error "Valgrind support requested but headers not available" "$LINENO" 5
fi
@@ -9327,7 +9337,8 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -10261,7 +10272,8 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -10270,44 +10282,25 @@
done
-ac_fn_c_check_func "$LINENO" "dup2" "ac_cv_func_dup2"
-if test "x$ac_cv_func_dup2" = x""yes; then :
- $as_echo "#define HAVE_DUP2 1" >>confdefs.h
-
-else
- case " $LIBOBJS " in
- *" dup2.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS dup2.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd"
-if test "x$ac_cv_func_getcwd" = x""yes; then :
- $as_echo "#define HAVE_GETCWD 1" >>confdefs.h
-
-else
- case " $LIBOBJS " in
- *" getcwd.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS getcwd.$ac_objext"
- ;;
-esac
-
-fi
-
-ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup"
-if test "x$ac_cv_func_strdup" = x""yes; then :
- $as_echo "#define HAVE_STRDUP 1" >>confdefs.h
+for ac_func in dup2 getcwd strdup
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
else
case " $LIBOBJS " in
- *" strdup.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strdup.$ac_objext"
+ *" $ac_func.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
;;
esac
fi
+done
for ac_func in getpgrp
@@ -11516,7 +11509,7 @@
then LIBM=$withval
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBM=\"$withval\"" >&5
$as_echo "set LIBM=\"$withval\"" >&6; }
-else as_fn_error $? "proper usage is --with-libm=STRING" "$LINENO" 5
+else as_fn_error "proper usage is --with-libm=STRING" "$LINENO" 5
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBM=\"$LIBM\"" >&5
@@ -11540,7 +11533,7 @@
then LIBC=$withval
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: set LIBC=\"$withval\"" >&5
$as_echo "set LIBC=\"$withval\"" >&6; }
-else as_fn_error $? "proper usage is --with-libc=STRING" "$LINENO" 5
+else as_fn_error "proper usage is --with-libc=STRING" "$LINENO" 5
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: default LIBC=\"$LIBC\"" >&5
@@ -11836,7 +11829,8 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -11848,7 +11842,8 @@
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
@@ -12016,7 +12011,7 @@
15|30)
;;
*)
- as_fn_error $? "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;;
+ as_fn_error "bad value $enable_big_digits for --enable-big-digits; value should be 15 or 30" "$LINENO" 5 ;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_big_digits" >&5
$as_echo "$enable_big_digits" >&6; }
@@ -12067,8 +12062,9 @@
if test "$ac_cv_type_wchar_t" = yes; then
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (wchar_t)
-See \`config.log' for more details" "$LINENO" 5 ; }
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (wchar_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
else
ac_cv_sizeof_wchar_t=0
fi
@@ -12437,8 +12433,8 @@
;; #(
*)
- as_fn_error $? "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ as_fn_error "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
esac
@@ -12454,8 +12450,8 @@
# * --with-wide-unicode (adds a 'u')
#
# Thus for example, Python 3.2 built with wide unicode, pydebug, and pymalloc,
-# would get a shared library ABI version tag of 'cpython-32udm' and shared
-# libraries would be named 'foo.cpython-32udm.so'.
+# would get a shared library ABI version tag of 'cpython-32dmu' and shared
+# libraries would be named 'foo.cpython-32dmu.so'.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SOABI" >&5
$as_echo_n "checking SOABI... " >&6; }
@@ -12477,19 +12473,19 @@
esac
;;
CYGWIN*) SO=.dll;;
- Linux*) SO=.${SOABI}.so;;
+ Linux*) SO=.${SOABI}.so;;
*) SO=.so;;
esac
else
# this might also be a termcap variable, see #610332
- echo
- echo '====================================================================='
- echo '+ +'
+ echo
+ echo '====================================================================='
+ echo '+ +'
echo '+ WARNING: You have set SO in your environment. +'
- echo '+ Do you really mean to change the extension for shared libraries? +'
- echo '+ Continuing in 10 seconds to let you to ponder. +'
- echo '+ +'
- echo '====================================================================='
+ echo '+ Do you really mean to change the extension for shared libraries? +'
+ echo '+ Continuing in 10 seconds to let you to ponder. +'
+ echo '+ +'
+ echo '====================================================================='
sleep 10
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SO" >&5
@@ -12688,7 +12684,7 @@
have_readline=no
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
if test $have_readline = yes
then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -12862,7 +12858,7 @@
have_readline=no
fi
-rm -f conftest.err conftest.i conftest.$ac_ext
+rm -f conftest.err conftest.$ac_ext
if test $have_readline = yes
then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13672,7 +13668,7 @@
case $ac_sys_system in
- OSF*) as_fn_error $? "OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606" "$LINENO" 5 ;;
+ OSF*) as_fn_error "OSF* systems are deprecated unless somebody volunteers. Check http://bugs.python.org/issue8606" "$LINENO" 5 ;;
esac
@@ -13782,7 +13778,6 @@
ac_libobjs=
ac_ltlibobjs=
-U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
@@ -13945,19 +13940,19 @@
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-# as_fn_error STATUS ERROR [LINENO LOG_FD]
-# ----------------------------------------
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with STATUS, using 1 if that was 0.
+# script with status $?, using 1 if that was 0.
as_fn_error ()
{
- as_status=$1; test $as_status -eq 0 && as_status=1
- if test "$4"; then
- as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
fi
- $as_echo "$as_me: error: $2" >&2
+ $as_echo "$as_me: error: $1" >&2
as_fn_exit $as_status
} # as_fn_error
@@ -14153,7 +14148,7 @@
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
- } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
} # as_fn_mkdir_p
@@ -14207,7 +14202,7 @@
# values after options handling.
ac_log="
This file was extended by python $as_me 3.2, which was
-generated by GNU Autoconf 2.67. Invocation command line was
+generated by GNU Autoconf 2.65. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -14269,10 +14264,10 @@
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
python config.status 3.2
-configured by $0, generated by GNU Autoconf 2.67,
+configured by $0, generated by GNU Autoconf 2.65,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2010 Free Software Foundation, Inc.
+Copyright (C) 2009 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
@@ -14288,16 +14283,11 @@
while test $# != 0
do
case $1 in
- --*=?*)
+ --*=*)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
- --*=)
- ac_option=`expr "X$1" : 'X\([^=]*\)='`
- ac_optarg=
- ac_shift=:
- ;;
*)
ac_option=$1
ac_optarg=$2
@@ -14319,7 +14309,6 @@
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
- '') as_fn_error $? "missing file argument" ;;
esac
as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
@@ -14332,7 +14321,7 @@
ac_need_defaults=false;;
--he | --h)
# Conflict between --help and --header
- as_fn_error $? "ambiguous option: \`$1'
+ as_fn_error "ambiguous option: \`$1'
Try \`$0 --help' for more information.";;
--help | --hel | -h )
$as_echo "$ac_cs_usage"; exit ;;
@@ -14341,7 +14330,7 @@
ac_cs_silent=: ;;
# This is an error.
- -*) as_fn_error $? "unrecognized option: \`$1'
+ -*) as_fn_error "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
@@ -14399,7 +14388,7 @@
"Modules/Setup.config") CONFIG_FILES="$CONFIG_FILES Modules/Setup.config" ;;
"Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;;
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
@@ -14436,7 +14425,7 @@
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
-} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
@@ -14453,7 +14442,7 @@
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
- ac_cs_awk_cr='\\r'
+ ac_cs_awk_cr='\r'
else
ac_cs_awk_cr=$ac_cr
fi
@@ -14467,18 +14456,18 @@
echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
echo "_ACEOF"
} >conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
. ./conf$$subs.sh ||
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
if test $ac_delim_n = $ac_delim_num; then
break
elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
@@ -14567,28 +14556,20 @@
else
cat
fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
- || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
_ACEOF
-# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
-# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
-h
-s///
-s/^/:/
-s/[ ]*$/:/
-s/:\$(srcdir):/:/g
-s/:\${srcdir}:/:/g
-s/:@srcdir@:/:/g
-s/^:*//
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
s/:*$//
-x
-s/\(=[ ]*\).*/\1/
-G
-s/\n//
s/^[^=]*=[ ]*$//
}'
fi
@@ -14616,7 +14597,7 @@
if test -z "$ac_t"; then
break
elif $ac_last_try; then
- as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
@@ -14701,7 +14682,7 @@
_ACAWK
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
- as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+ as_fn_error "could not setup config headers machinery" "$LINENO" 5
fi # test -n "$CONFIG_HEADERS"
@@ -14714,7 +14695,7 @@
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -14742,7 +14723,7 @@
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
@@ -14769,7 +14750,7 @@
case $ac_tag in
*:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
@@ -14900,22 +14881,22 @@
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&5
+which seems to be undefined. Please make sure it is defined." >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined. Please make sure it is defined" >&2;}
+which seems to be undefined. Please make sure it is defined." >&2;}
rm -f "$tmp/stdin"
case $ac_file in
-) cat "$tmp/out" && rm -f "$tmp/out";;
*) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
esac \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
;;
:H)
#
@@ -14926,19 +14907,19 @@
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
} >"$tmp/config.h" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
$as_echo "$as_me: $ac_file is unchanged" >&6;}
else
rm -f "$ac_file"
mv "$tmp/config.h" "$ac_file" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
fi
else
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
- || as_fn_error $? "could not create -" "$LINENO" 5
+ || as_fn_error "could not create -" "$LINENO" 5
fi
;;
@@ -14953,7 +14934,7 @@
ac_clean_files=$ac_clean_files_save
test $ac_write_fail = 0 ||
- as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
# configure is writing to config.log, and then calls config.status.
@@ -14974,7 +14955,7 @@
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
- $ac_cs_success || as_fn_exit 1
+ $ac_cs_success || as_fn_exit $?
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in (original)
+++ python/branches/py3k/configure.in Sun Sep 5 02:09:07 2010
@@ -663,7 +663,7 @@
AC_C_INLINE
if test "$ac_cv_c_inline" != no ; then
- AC_DEFINE(USE_INLINE,1)
+ AC_DEFINE(USE_INLINE, 1, [Define to use the C99 inline keyword.])
AC_SUBST(USE_INLINE)
fi
Modified: python/branches/py3k/pyconfig.h.in
==============================================================================
--- python/branches/py3k/pyconfig.h.in (original)
+++ python/branches/py3k/pyconfig.h.in Sun Sep 5 02:09:07 2010
@@ -1040,11 +1040,10 @@
/* Define to 1 if your declares `struct tm'. */
#undef TM_IN_SYS_TIME
-/* Define to 0 if you don't want to use computed gotos in ceval.c.
- (The default is to use them if HAVE_COMPUTED_GOTOS is defined.) */
+/* Define if you want to use computed gotos in ceval.c. */
#undef USE_COMPUTED_GOTOS
-/* Define if the compiler supports the inline keyword */
+/* Define to use the C99 inline keyword. */
#undef USE_INLINE
/* Enable extensions on AIX 3, Interix. */
@@ -1200,6 +1199,12 @@
/* Define to `int' if doesn't define. */
#undef gid_t
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
/* Define to the type of a signed integer type of width exactly 32 bits if
such a type exists and the standard includes do not define it. */
#undef int32_t
From python-checkins at python.org Sun Sep 5 02:27:25 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 02:27:25 +0200 (CEST)
Subject: [Python-checkins] r84513 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905002725.6F458FBF2@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 02:27:25 2010
New Revision: 84513
Log:
Update whatsnew for Pep3149.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 02:27:25 2010
@@ -105,12 +105,35 @@
:pep:`3147` - PYC Repository Directories
PEP written by Barry Warsaw.
-PEPs
-====
+PEP 3149 ABI Version Tagged .so Files
+=====================================
-Implemented PEPs:
+The PYC repository directory allows multiple bytecode cache files to be
+co-located. This PEP implements a similar mechanism for shared object files by
+giving them a common directory and distinct names for each version.
+
+The common directory is "pyshared" and the file names are made distinct by
+identifying the Python implementation (such as CPython, PyPy, Jython, etc.), the
+major and minor version numbers, and optional build flags (such as "d" for
+debug, "m" for pymalloc, "u" for wide-unicode). For an arbtrary package, "foo",
+you may see these files when the distribution package is installed::
+
+ /usr/share/pyshared/foo.cpython-32m.so
+ /usr/share/pyshared/foo.cpython-33md.so
+
+In Python itself, the tags are accessible from functions in the :mod:`sysconfig`
+module::
+
+ >>> import sysconfig
+ >>> sysconfig.get_config_var('SOABI') # find the version tag
+ 'cpython-32mu'
+ >>> sysconfig.get_config_var('SO') # find the full filename extension
+ 'cpython-32mu.so'
-* :pep:`3149`
+.. seealso::
+
+ :pep:`3149` - ABI Version Tagged .so Files
+ PEP written by Barry Warsaw.
Other Language Changes
From python-checkins at python.org Sun Sep 5 02:36:26 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 02:36:26 +0200 (CEST)
Subject: [Python-checkins] r84514 - python/branches/py3k/Misc/NEWS
Message-ID: <20100905003626.EBC2AFCB4@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 02:36:26 2010
New Revision: 84514
Log:
Typo
Modified:
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 5 02:36:26 2010
@@ -1,4 +1,4 @@
-+++++++++++
+?+++++++++++
Python News
+++++++++++
@@ -33,7 +33,7 @@
properly. Patch by Stefan Behnel.
- Issue #5553: The Py_LOCAL_INLINE macro now results in inlining on
- most platforms. Previously, it online inlined when using Microsoft
+ most platforms. Previously, it inlined when using Microsoft
Visual C.
- Issue #9712: Fix tokenize on identifiers that start with non-ascii names.
From python-checkins at python.org Sun Sep 5 03:00:19 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 03:00:19 +0200 (CEST)
Subject: [Python-checkins] r84515 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905010019.E7ED3EE9F0@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 03:00:19 2010
New Revision: 84515
Log:
More updates to whatsnew
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 03:00:19 2010
@@ -141,7 +141,22 @@
Some smaller changes made to the core Python language are:
-* Stub
+* The :func:`hasattr` function used to catch and suppress any Exception.
+ Now, it only catches :exc:`AttributeError`. Under the hood, :func:`hasattr`
+ works by calling :func:`getattr` and throwing away the results. This is
+ necessary because dynamic attribute creation is possible using
+ :meth:`__getattribute__` or :meth:`__getattr`. If :func:`hasattr` were to
+ just scan instance and class dictionaries it would miss the dynmaic methods
+ and make it difficult to implement proxy objects.
+
+ (Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.)
+
+* The :func:`str` of a float or complex number is now the same as it
+ :func:`repr`. Previously, the :func:`str` form was shorter but that just
+ caused confusion and is no longer needed now that we the shortest possible
+ :func:`repr` is displayed by default.
+
+ (Proposed and implemented by Mark Dickinson; :issue:`9337`).
New, Improved, and Deprecated Modules
@@ -342,8 +357,19 @@
Changes to Python's build process and to the C API include:
-* Stub
+* The C functions that access the Unicode Database now accept and
+ return characters from the full Unicode range, even on narrow unicode builds
+ (Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL, and others). A visible difference
+ in Python is that :cfunc:`unicodedata.numeric` now returns the correct value for
+ large code points, and :func:`repr` may consider more characters as printable.
+
+ (Reported by Bupjoe Lee and fixed by Amaury Forgeot D'Arc; :issue:`5127`.)
+
+* Computed gotos are now enabled by default on supported
+ compilers (which are detected by the configure script). They can still
+ be disable selectively by specifying ``--without-computed-gotos``.
+ (:issue:`9203`)
Porting to Python 3.2
=====================
From solipsis at pitrou.net Sun Sep 5 05:01:30 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Sun, 05 Sep 2010 05:01:30 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84515): sum=0
Message-ID:
py3k results for svn r84515 (hg cset 4f9044e31b9e)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogYZi0P_', '-x']
From python-checkins at python.org Sun Sep 5 07:26:10 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 07:26:10 +0200 (CEST)
Subject: [Python-checkins] r84516 -
python/branches/py3k/Modules/_heapqmodule.c
Message-ID: <20100905052610.D4808F6E5@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 07:26:10 2010
New Revision: 84516
Log:
Inline cmp_lt().
Modified:
python/branches/py3k/Modules/_heapqmodule.c
Modified: python/branches/py3k/Modules/_heapqmodule.c
==============================================================================
--- python/branches/py3k/Modules/_heapqmodule.c (original)
+++ python/branches/py3k/Modules/_heapqmodule.c Sun Sep 5 07:26:10 2010
@@ -9,12 +9,6 @@
#include "Python.h"
static int
-cmp_lt(PyObject *x, PyObject *y)
-{
- return PyObject_RichCompareBool(x, y, Py_LT);
-}
-
-static int
_siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
{
PyObject *newitem, *parent;
@@ -34,7 +28,7 @@
while (pos > startpos){
parentpos = (pos - 1) >> 1;
parent = PyList_GET_ITEM(heap, parentpos);
- cmp = cmp_lt(newitem, parent);
+ cmp = PyObject_RichCompareBool(newitem, parent, Py_LT);
if (cmp == -1) {
Py_DECREF(newitem);
return -1;
@@ -74,9 +68,10 @@
/* Set childpos to index of smaller child. */
rightpos = childpos + 1;
if (rightpos < endpos) {
- cmp = cmp_lt(
+ cmp = PyObject_RichCompareBool(
PyList_GET_ITEM(heap, childpos),
- PyList_GET_ITEM(heap, rightpos));
+ PyList_GET_ITEM(heap, rightpos),
+ Py_LT);
if (cmp == -1) {
Py_DECREF(newitem);
return -1;
@@ -219,7 +214,7 @@
return item;
}
- cmp = cmp_lt(PyList_GET_ITEM(heap, 0), item);
+ cmp = PyObject_RichCompareBool(PyList_GET_ITEM(heap, 0), item, Py_LT);
if (cmp == -1)
return NULL;
if (cmp == 0) {
@@ -318,7 +313,7 @@
else
goto sortit;
}
- cmp = cmp_lt(sol, elem);
+ cmp = PyObject_RichCompareBool(sol, elem, Py_LT);
if (cmp == -1) {
Py_DECREF(elem);
goto fail;
@@ -373,7 +368,7 @@
while (pos > startpos){
parentpos = (pos - 1) >> 1;
parent = PyList_GET_ITEM(heap, parentpos);
- cmp = cmp_lt(parent, newitem);
+ cmp = PyObject_RichCompareBool(parent, newitem, Py_LT);
if (cmp == -1) {
Py_DECREF(newitem);
return -1;
@@ -413,9 +408,10 @@
/* Set childpos to index of smaller child. */
rightpos = childpos + 1;
if (rightpos < endpos) {
- cmp = cmp_lt(
+ cmp = PyObject_RichCompareBool(
PyList_GET_ITEM(heap, rightpos),
- PyList_GET_ITEM(heap, childpos));
+ PyList_GET_ITEM(heap, childpos),
+ Py_LT);
if (cmp == -1) {
Py_DECREF(newitem);
return -1;
@@ -488,7 +484,7 @@
else
goto sortit;
}
- cmp = cmp_lt(elem, los);
+ cmp = PyObject_RichCompareBool(elem, los, Py_LT);
if (cmp == -1) {
Py_DECREF(elem);
goto fail;
From python-checkins at python.org Sun Sep 5 07:56:44 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 07:56:44 +0200 (CEST)
Subject: [Python-checkins] r84517 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905055644.9FED0F7BF@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 07:56:44 2010
New Revision: 84517
Log:
Add an example
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 07:56:44 2010
@@ -154,7 +154,12 @@
* The :func:`str` of a float or complex number is now the same as it
:func:`repr`. Previously, the :func:`str` form was shorter but that just
caused confusion and is no longer needed now that we the shortest possible
- :func:`repr` is displayed by default.
+ :func:`repr` is displayed by default::
+
+ >>> repr(math.pi)
+ '3.141592653589793'
+ >>> str(math.pi)
+ '3.141592653589793'
(Proposed and implemented by Mark Dickinson; :issue:`9337`).
From python-checkins at python.org Sun Sep 5 07:57:35 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 07:57:35 +0200 (CEST)
Subject: [Python-checkins] r84518 - in python/branches/py3k:
Lib/functools.py Misc/NEWS
Message-ID: <20100905055735.DFC28F7BF@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 07:57:35 2010
New Revision: 84518
Log:
Clean-up functools.total_ordering().
Modified:
python/branches/py3k/Lib/functools.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Sun Sep 5 07:57:35 2010
@@ -65,7 +65,6 @@
return partial(update_wrapper, wrapped=wrapped,
assigned=assigned, updated=updated)
-_object_defaults = {object.__lt__, object.__le__, object.__gt__, object.__ge__}
def total_ordering(cls):
"""Class decorator that fills in missing ordering methods"""
convert = {
@@ -82,9 +81,8 @@
('__gt__', lambda self, other: not other >= self),
('__lt__', lambda self, other: not self >= other)]
}
- roots = set(dir(cls)) & set(convert)
- # Remove default comparison operations defined on object.
- roots -= {meth for meth in roots if getattr(cls, meth) in _object_defaults}
+ # Find comparisons not inherited from object.
+ roots = [op for op in convert if getattr(cls, op) is not getattr(object, op)]
if not roots:
raise ValueError('must define at least one ordering operation: < > <= >=')
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 5 07:57:35 2010
@@ -222,7 +222,7 @@
- Issue #9501: Fixed logging regressions in cleanup code.
-- Fix functools.total_ordering() to actually work.
+- Fix functools.total_ordering() to skip methods inherited from object().
- Issue #9572: Importlib should not raise an exception if a directory it
thought it needed to create was done concurrently by another process.
From python-checkins at python.org Sun Sep 5 08:13:48 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 08:13:48 +0200 (CEST)
Subject: [Python-checkins] r84519 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905061348.1EDECFB89@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 08:13:47 2010
New Revision: 84519
Log:
More updates to whatsnew.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 08:13:47 2010
@@ -163,6 +163,19 @@
(Proposed and implemented by Mark Dickinson; :issue:`9337`).
+* The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
+ pointing to the original callable function. This allows wrapped functions to
+ be introspected. It also copies :attr:`__annotations__` if defined. And now
+ it also gracefully skips over missing attributes such as :attr:`__doc__` which
+ might not be defined for the wrapped callable.
+
+ (By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
+ :issue:`8814`.)
+
+* The :mod:`abc` module now supports :func:`abstractclassmethod` and
+ :func:`staticmethod`.
+
+ (:issue:`5867`)
New, Improved, and Deprecated Modules
=====================================
@@ -286,11 +299,6 @@
(Contributed by Georg Brandl; :issue:`5675`.)
-* Parameters passed to :func:`socket.getaddrinfo()` function can now be
- specified as single keyword arguments.
-
- (Contributed by Giampaolo Rodol?; :issue:`8866`.)
-
* :class:`~poplib.POP3_SSL` class now accepts a *context* parameter, which is a
:class:`ssl.SSLContext` object allowing bundling SSL configuration options,
certificates and private keys into a single (potentially long-lived)
From python-checkins at python.org Sun Sep 5 10:28:41 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 10:28:41 +0200 (CEST)
Subject: [Python-checkins] r84520 -
python/branches/py3k/Lib/pydoc_data/topics.py
Message-ID: <20100905082841.7FB94FB89@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 10:28:41 2010
New Revision: 84520
Log:
Update pydoc topics.
Modified:
python/branches/py3k/Lib/pydoc_data/topics.py
Modified: python/branches/py3k/Lib/pydoc_data/topics.py
==============================================================================
--- python/branches/py3k/Lib/pydoc_data/topics.py (original)
+++ python/branches/py3k/Lib/pydoc_data/topics.py Sun Sep 5 10:28:41 2010
@@ -1,4 +1,4 @@
-# Autogenerated by Sphinx on Sat Jul 31 10:22:58 2010
+# Autogenerated by Sphinx on Sun Sep 5 10:24:54 2010
topics = {'assert': '\nThe ``assert`` statement\n************************\n\nAssert statements are a convenient way to insert debugging assertions\ninto a program:\n\n assert_stmt ::= "assert" expression ["," expression]\n\nThe simple form, ``assert expression``, is equivalent to\n\n if __debug__:\n if not expression: raise AssertionError\n\nThe extended form, ``assert expression1, expression2``, is equivalent\nto\n\n if __debug__:\n if not expression1: raise AssertionError(expression2)\n\nThese equivalences assume that ``__debug__`` and ``AssertionError``\nrefer to the built-in variables with those names. In the current\nimplementation, the built-in variable ``__debug__`` is ``True`` under\nnormal circumstances, ``False`` when optimization is requested\n(command line option -O). The current code generator emits no code\nfor an assert statement when optimization is requested at compile\ntime. Note that it is unnecessary to include the source code for the\nexpression that failed in the error message; it will be displayed as\npart of the stack trace.\n\nAssignments to ``__debug__`` are illegal. The value for the built-in\nvariable is determined when the interpreter starts.\n',
'assignment': '\nAssignment statements\n*********************\n\nAssignment statements are used to (re)bind names to values and to\nmodify attributes or items of mutable objects:\n\n assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)\n target_list ::= target ("," target)* [","]\n target ::= identifier\n | "(" target_list ")"\n | "[" target_list "]"\n | attributeref\n | subscription\n | slicing\n | "*" target\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn assignment statement evaluates the expression list (remember that\nthis can be a single expression or a comma-separated list, the latter\nyielding a tuple) and assigns the single resulting object to each of\nthe target lists, from left to right.\n\nAssignment is defined recursively depending on the form of the target\n(list). When a target is part of a mutable object (an attribute\nreference, subscription or slicing), the mutable object must\nultimately perform the assignment and decide about its validity, and\nmay raise an exception if the assignment is unacceptable. The rules\nobserved by various types and the exceptions raised are given with the\ndefinition of the object types (see section *The standard type\nhierarchy*).\n\nAssignment of an object to a target list, optionally enclosed in\nparentheses or square brackets, is recursively defined as follows.\n\n* If the target list is a single target: The object is assigned to\n that target.\n\n* If the target list is a comma-separated list of targets: The object\n must be an iterable with the same number of items as there are\n targets in the target list, and the items are assigned, from left to\n right, to the corresponding targets. (This rule is relaxed as of\n Python 1.5; in earlier versions, the object had to be a tuple.\n Since strings are sequences, an assignment like ``a, b = "xy"`` is\n now legal as long as the string has the right length.)\n\n * If the target list contains one target prefixed with an asterisk,\n called a "starred" target: The object must be a sequence with at\n least as many items as there are targets in the target list, minus\n one. The first items of the sequence are assigned, from left to\n right, to the targets before the starred target. The final items\n of the sequence are assigned to the targets after the starred\n target. A list of the remaining items in the sequence is then\n assigned to the starred target (the list can be empty).\n\n * Else: The object must be a sequence with the same number of items\n as there are targets in the target list, and the items are\n assigned, from left to right, to the corresponding targets.\n\nAssignment of an object to a single target is recursively defined as\nfollows.\n\n* If the target is an identifier (name):\n\n * If the name does not occur in a ``global`` or ``nonlocal``\n statement in the current code block: the name is bound to the\n object in the current local namespace.\n\n * Otherwise: the name is bound to the object in the global namespace\n or the outer namespace determined by ``nonlocal``, respectively.\n\n The name is rebound if it was already bound. This may cause the\n reference count for the object previously bound to the name to reach\n zero, causing the object to be deallocated and its destructor (if it\n has one) to be called.\n\n* If the target is a target list enclosed in parentheses or in square\n brackets: The object must be an iterable with the same number of\n items as there are targets in the target list, and its items are\n assigned, from left to right, to the corresponding targets.\n\n* If the target is an attribute reference: The primary expression in\n the reference is evaluated. It should yield an object with\n assignable attributes; if this is not the case, ``TypeError`` is\n raised. That object is then asked to assign the assigned object to\n the given attribute; if it cannot perform the assignment, it raises\n an exception (usually but not necessarily ``AttributeError``).\n\n Note: If the object is a class instance and the attribute reference\n occurs on both sides of the assignment operator, the RHS expression,\n ``a.x`` can access either an instance attribute or (if no instance\n attribute exists) a class attribute. The LHS target ``a.x`` is\n always set as an instance attribute, creating it if necessary.\n Thus, the two occurrences of ``a.x`` do not necessarily refer to the\n same attribute: if the RHS expression refers to a class attribute,\n the LHS creates a new instance attribute as the target of the\n assignment:\n\n class Cls:\n x = 3 # class variable\n inst = Cls()\n inst.x = inst.x + 1 # writes inst.x as 4 leaving Cls.x as 3\n\n This description does not necessarily apply to descriptor\n attributes, such as properties created with ``property()``.\n\n* If the target is a subscription: The primary expression in the\n reference is evaluated. It should yield either a mutable sequence\n object (such as a list) or a mapping object (such as a dictionary).\n Next, the subscript expression is evaluated.\n\n If the primary is a mutable sequence object (such as a list), the\n subscript must yield an integer. If it is negative, the sequence\'s\n length is added to it. The resulting value must be a nonnegative\n integer less than the sequence\'s length, and the sequence is asked\n to assign the assigned object to its item with that index. If the\n index is out of range, ``IndexError`` is raised (assignment to a\n subscripted sequence cannot add new items to a list).\n\n If the primary is a mapping object (such as a dictionary), the\n subscript must have a type compatible with the mapping\'s key type,\n and the mapping is then asked to create a key/datum pair which maps\n the subscript to the assigned object. This can either replace an\n existing key/value pair with the same key value, or insert a new\n key/value pair (if no key with the same value existed).\n\n For user-defined objects, the ``__setitem__()`` method is called\n with appropriate arguments.\n\n* If the target is a slicing: The primary expression in the reference\n is evaluated. It should yield a mutable sequence object (such as a\n list). The assigned object should be a sequence object of the same\n type. Next, the lower and upper bound expressions are evaluated,\n insofar they are present; defaults are zero and the sequence\'s\n length. The bounds should evaluate to integers. If either bound is\n negative, the sequence\'s length is added to it. The resulting\n bounds are clipped to lie between zero and the sequence\'s length,\n inclusive. Finally, the sequence object is asked to replace the\n slice with the items of the assigned sequence. The length of the\n slice may be different from the length of the assigned sequence,\n thus changing the length of the target sequence, if the object\n allows it.\n\n**CPython implementation detail:** In the current implementation, the\nsyntax for targets is taken to be the same as for expressions, and\ninvalid syntax is rejected during the code generation phase, causing\nless detailed error messages.\n\nWARNING: Although the definition of assignment implies that overlaps\nbetween the left-hand side and the right-hand side are \'safe\' (for\nexample ``a, b = b, a`` swaps two variables), overlaps *within* the\ncollection of assigned-to variables are not safe! For instance, the\nfollowing program prints ``[0, 2]``:\n\n x = [0, 1]\n i = 0\n i, x[i] = 1, 2\n print(x)\n\nSee also:\n\n **PEP 3132** - Extended Iterable Unpacking\n The specification for the ``*target`` feature.\n\n\nAugmented assignment statements\n===============================\n\nAugmented assignment is the combination, in a single statement, of a\nbinary operation and an assignment statement:\n\n augmented_assignment_stmt ::= augtarget augop (expression_list | yield_expression)\n augtarget ::= identifier | attributeref | subscription | slicing\n augop ::= "+=" | "-=" | "*=" | "/=" | "//=" | "%=" | "**="\n | ">>=" | "<<=" | "&=" | "^=" | "|="\n\n(See section *Primaries* for the syntax definitions for the last three\nsymbols.)\n\nAn augmented assignment evaluates the target (which, unlike normal\nassignment statements, cannot be an unpacking) and the expression\nlist, performs the binary operation specific to the type of assignment\non the two operands, and assigns the result to the original target.\nThe target is only evaluated once.\n\nAn augmented assignment expression like ``x += 1`` can be rewritten as\n``x = x + 1`` to achieve a similar, but not exactly equal effect. In\nthe augmented version, ``x`` is only evaluated once. Also, when\npossible, the actual operation is performed *in-place*, meaning that\nrather than creating a new object and assigning that to the target,\nthe old object is modified instead.\n\nWith the exception of assigning to tuples and multiple targets in a\nsingle statement, the assignment done by augmented assignment\nstatements is handled the same way as normal assignments. Similarly,\nwith the exception of the possible *in-place* behavior, the binary\noperation performed by augmented assignment is the same as the normal\nbinary operations.\n\nFor targets which are attribute references, the same *caveat about\nclass and instance attributes* applies as for regular assignments.\n',
'atom-identifiers': '\nIdentifiers (Names)\n*******************\n\nAn identifier occurring as an atom is a name. See section\n*Identifiers and keywords* for lexical definition and section *Naming\nand binding* for documentation of naming and binding.\n\nWhen the name is bound to an object, evaluation of the atom yields\nthat object. When a name is not bound, an attempt to evaluate it\nraises a ``NameError`` exception.\n\n**Private name mangling:** When an identifier that textually occurs in\na class definition begins with two or more underscore characters and\ndoes not end in two or more underscores, it is considered a *private\nname* of that class. Private names are transformed to a longer form\nbefore code is generated for them. The transformation inserts the\nclass name in front of the name, with leading underscores removed, and\na single underscore inserted in front of the class name. For example,\nthe identifier ``__spam`` occurring in a class named ``Ham`` will be\ntransformed to ``_Ham__spam``. This transformation is independent of\nthe syntactical context in which the identifier is used. If the\ntransformed name is extremely long (longer than 255 characters),\nimplementation defined truncation may happen. If the class name\nconsists only of underscores, no transformation is done.\n',
@@ -16,9 +16,9 @@
'break': '\nThe ``break`` statement\n***********************\n\n break_stmt ::= "break"\n\n``break`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition\nwithin that loop.\n\nIt terminates the nearest enclosing loop, skipping the optional\n``else`` clause if the loop has one.\n\nIf a ``for`` loop is terminated by ``break``, the loop control target\nkeeps its current value.\n\nWhen ``break`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the loop.\n',
'callable-types': '\nEmulating callable objects\n**************************\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n',
'calls': '\nCalls\n*****\n\nA call calls a callable object (e.g., a function) with a possibly\nempty series of arguments:\n\n call ::= primary "(" [argument_list [","] | comprehension] ")"\n argument_list ::= positional_arguments ["," keyword_arguments]\n ["," "*" expression] ["," keyword_arguments]\n ["," "**" expression]\n | keyword_arguments ["," "*" expression]\n ["," keyword_arguments] ["," "**" expression]\n | "*" expression ["," keyword_arguments] ["," "**" expression]\n | "**" expression\n positional_arguments ::= expression ("," expression)*\n keyword_arguments ::= keyword_item ("," keyword_item)*\n keyword_item ::= identifier "=" expression\n\nA trailing comma may be present after the positional and keyword\narguments but does not affect the semantics.\n\nThe primary must evaluate to a callable object (user-defined\nfunctions, built-in functions, methods of built-in objects, class\nobjects, methods of class instances, and all objects having a\n``__call__()`` method are callable). All argument expressions are\nevaluated before the call is attempted. Please refer to section\n*Function definitions* for the syntax of formal parameter lists.\n\nIf keyword arguments are present, they are first converted to\npositional arguments, as follows. First, a list of unfilled slots is\ncreated for the formal parameters. If there are N positional\narguments, they are placed in the first N slots. Next, for each\nkeyword argument, the identifier is used to determine the\ncorresponding slot (if the identifier is the same as the first formal\nparameter name, the first slot is used, and so on). If the slot is\nalready filled, a ``TypeError`` exception is raised. Otherwise, the\nvalue of the argument is placed in the slot, filling it (even if the\nexpression is ``None``, it fills the slot). When all arguments have\nbeen processed, the slots that are still unfilled are filled with the\ncorresponding default value from the function definition. (Default\nvalues are calculated, once, when the function is defined; thus, a\nmutable object such as a list or dictionary used as default value will\nbe shared by all calls that don\'t specify an argument value for the\ncorresponding slot; this should usually be avoided.) If there are any\nunfilled slots for which no default value is specified, a\n``TypeError`` exception is raised. Otherwise, the list of filled\nslots is used as the argument list for the call.\n\n**CPython implementation detail:** An implementation may provide\nbuilt-in functions whose positional parameters do not have names, even\nif they are \'named\' for the purpose of documentation, and which\ntherefore cannot be supplied by keyword. In CPython, this is the case\nfor functions implemented in C that use ``PyArg_ParseTuple()`` to\nparse their arguments.\n\nIf there are more positional arguments than there are formal parameter\nslots, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``*identifier`` is present; in this case, that formal\nparameter receives a tuple containing the excess positional arguments\n(or an empty tuple if there were no excess positional arguments).\n\nIf any keyword argument does not correspond to a formal parameter\nname, a ``TypeError`` exception is raised, unless a formal parameter\nusing the syntax ``**identifier`` is present; in this case, that\nformal parameter receives a dictionary containing the excess keyword\narguments (using the keywords as keys and the argument values as\ncorresponding values), or a (new) empty dictionary if there were no\nexcess keyword arguments.\n\nIf the syntax ``*expression`` appears in the function call,\n``expression`` must evaluate to a sequence. Elements from this\nsequence are treated as if they were additional positional arguments;\nif there are positional arguments *x1*,..., *xN*, and ``expression``\nevaluates to a sequence *y1*, ..., *yM*, this is equivalent to a call\nwith M+N positional arguments *x1*, ..., *xN*, *y1*, ..., *yM*.\n\nA consequence of this is that although the ``*expression`` syntax may\nappear *after* some keyword arguments, it is processed *before* the\nkeyword arguments (and the ``**expression`` argument, if any -- see\nbelow). So:\n\n >>> def f(a, b):\n ... print(a, b)\n ...\n >>> f(b=1, *(2,))\n 2 1\n >>> f(a=1, *(2,))\n Traceback (most recent call last):\n File "", line 1, in ?\n TypeError: f() got multiple values for keyword argument \'a\'\n >>> f(1, *(2,))\n 1 2\n\nIt is unusual for both keyword arguments and the ``*expression``\nsyntax to be used in the same call, so in practice this confusion does\nnot arise.\n\nIf the syntax ``**expression`` appears in the function call,\n``expression`` must evaluate to a mapping, the contents of which are\ntreated as additional keyword arguments. In the case of a keyword\nappearing in both ``expression`` and as an explicit keyword argument,\na ``TypeError`` exception is raised.\n\nFormal parameters using the syntax ``*identifier`` or ``**identifier``\ncannot be used as positional argument slots or as keyword argument\nnames.\n\nA call always returns some value, possibly ``None``, unless it raises\nan exception. How this value is computed depends on the type of the\ncallable object.\n\nIf it is---\n\na user-defined function:\n The code block for the function is executed, passing it the\n argument list. The first thing the code block will do is bind the\n formal parameters to the arguments; this is described in section\n *Function definitions*. When the code block executes a ``return``\n statement, this specifies the return value of the function call.\n\na built-in function or method:\n The result is up to the interpreter; see *Built-in Functions* for\n the descriptions of built-in functions and methods.\n\na class object:\n A new instance of that class is returned.\n\na class instance method:\n The corresponding user-defined function is called, with an argument\n list that is one longer than the argument list of the call: the\n instance becomes the first argument.\n\na class instance:\n The class must define a ``__call__()`` method; the effect is then\n the same as if that method was called.\n',
- 'class': '\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by instances. Instance variables can\nbe set in a method with ``self.name = value``. Both class and\ninstance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n',
+ 'class': '\nClass definitions\n*****************\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [argument_list [","] ] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated; as with functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with ``self.name = value``. Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way. Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results. *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n **PEP 3116** - Metaclasses in Python 3 **PEP 3129** - Class\n Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n',
'comparisons': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes. You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n are identical to themselves, ``x is x`` but are not equal to\n themselves, ``x != x``. Additionally, comparing any value to a\n not-a-number value will return ``False``. For example, both ``3 <\n float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``[1,2,x] <= [1,2,y]`` has the\n same value as ``x <= y``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, ``min()``, ``max()``, and ``sorted()`` produce\n undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison. Most\nnumeric types can be compared with one another, but comparisons of\n``float`` and ``Decimal`` are not supported to avoid the inevitable\nconfusion arising from representation issues such as ``float(\'1.1\')``\nbeing inexactly represented and therefore not exactly equal to\n``Decimal(\'1.1\')`` which is. When cross-type comparison is not\nsupported, the comparison method returns ``NotImplemented``. This can\ncreate the illusion of non-transitivity between supported cross-type\ncomparisons and unsupported comparisons. For example, ``Decimal(2) ==\n2`` and *2 == float(2)`* but ``Decimal(2) != float(2)``.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [4]\n',
- 'compound': '\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements, while the ``with`` statement\nallows the execution of initialization and finalization code around a\nblock of code. Function and class definitions are also syntactically\ncompound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print()`` calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting\nof: ``exc_type``, the exception class; ``exc_value``, the exception\ninstance; ``exc_traceback``, a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. ``sys.exc_info()`` values are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)*\n [, "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [expression_list] ")"\n classname ::= identifier\n\nA class definition is an executable statement. It first evaluates the\ninheritance list, if present. Each item in the inheritance list\nshould evaluate to a class object or class type which allows\nsubclassing. The class\'s suite is then executed in a new execution\nframe (see section *Naming and binding*), using a newly created local\nnamespace and the original global namespace. (Usually, the suite\ncontains only function definitions.) When the class\'s suite finishes\nexecution, its execution frame is discarded but its local namespace is\nsaved. [4] A class object is then created using the inheritance list\nfor the base classes and the saved local namespace for the attribute\ndictionary. The class name is bound to this class object in the\noriginal local namespace.\n\nClasses can also be decorated; as with functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass variables; they are shared by instances. Instance variables can\nbe set in a method with ``self.name = value``. Both class and\ninstance variables are accessible through the notation\n"``self.name``", and an instance variable hides a class variable with\nthe same name when accessed in this way. Class variables can be used\nas defaults for instance variables, but using mutable values there can\nlead to unexpected results. Descriptors can be used to create\ninstance variables with different implementation details.\n\nSee also:\n\n **PEP 3129** - Class Decorators\n\nClass definitions, like function definitions, may be wrapped by one or\nmore *decorator* expressions. The evaluation rules for the decorator\nexpressions are the same as for functions. The result must be a class\nobject, which is then bound to the class name.\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n',
+ 'compound': '\nCompound statements\n*******************\n\nCompound statements contain (groups of) other statements; they affect\nor control the execution of those other statements in some way. In\ngeneral, compound statements span multiple lines, although in simple\nincarnations a whole compound statement may be contained in one line.\n\nThe ``if``, ``while`` and ``for`` statements implement traditional\ncontrol flow constructs. ``try`` specifies exception handlers and/or\ncleanup code for a group of statements, while the ``with`` statement\nallows the execution of initialization and finalization code around a\nblock of code. Function and class definitions are also syntactically\ncompound statements.\n\nCompound statements consist of one or more \'clauses.\' A clause\nconsists of a header and a \'suite.\' The clause headers of a\nparticular compound statement are all at the same indentation level.\nEach clause header begins with a uniquely identifying keyword and ends\nwith a colon. A suite is a group of statements controlled by a\nclause. A suite can be one or more semicolon-separated simple\nstatements on the same line as the header, following the header\'s\ncolon, or it can be one or more indented statements on subsequent\nlines. Only the latter form of suite can contain nested compound\nstatements; the following is illegal, mostly because it wouldn\'t be\nclear to which ``if`` clause a following ``else`` clause would belong:\n\n if test1: if test2: print(x)\n\nAlso note that the semicolon binds tighter than the colon in this\ncontext, so that in the following example, either all or none of the\n``print()`` calls are executed:\n\n if x < y < z: print(x); print(y); print(z)\n\nSummarizing:\n\n compound_stmt ::= if_stmt\n | while_stmt\n | for_stmt\n | try_stmt\n | with_stmt\n | funcdef\n | classdef\n suite ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT\n statement ::= stmt_list NEWLINE | compound_stmt\n stmt_list ::= simple_stmt (";" simple_stmt)* [";"]\n\nNote that statements always end in a ``NEWLINE`` possibly followed by\na ``DEDENT``. Also note that optional continuation clauses always\nbegin with a keyword that cannot start a statement, thus there are no\nambiguities (the \'dangling ``else``\' problem is solved in Python by\nrequiring nested ``if`` statements to be indented).\n\nThe formatting of the grammar rules in the following sections places\neach clause on a separate line for clarity.\n\n\nThe ``if`` statement\n====================\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n\n\nThe ``while`` statement\n=======================\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n\n\nThe ``for`` statement\n=====================\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments (see *Assignment statements*), and then the suite is\nexecuted. When the items are exhausted (which is immediately when the\nsequence is empty or an iterator raises a ``StopIteration``\nexception), the suite in the ``else`` clause, if present, is executed,\nand the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nNames in the target list are not deleted when the loop is finished,\nbut if the sequence is empty, it will not have been assigned to at all\nby the loop. Hint: the built-in function ``range()`` returns an\niterator of integers suitable to emulate the effect of Pascal\'s ``for\ni := a to b do``; e.g., ``list(range(3))`` returns the list ``[0, 1,\n2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An\n internal counter is used to keep track of which item is used next,\n and this is incremented on each iteration. When this counter has\n reached the length of the sequence the loop terminates. This means\n that if the suite deletes the current (or a previous) item from the\n sequence, the next item will be skipped (since it gets the index of\n the current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n\n\nThe ``try`` statement\n=====================\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting\nof: ``exc_type``, the exception class; ``exc_value``, the exception\ninstance; ``exc_traceback``, a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. ``sys.exc_info()`` values are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n\n\nThe ``with`` statement\n======================\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nFunction definitions\n====================\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)*\n [, "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n\n\nClass definitions\n=================\n\nA class definition defines a class object (see section *The standard\ntype hierarchy*):\n\n classdef ::= [decorators] "class" classname [inheritance] ":" suite\n inheritance ::= "(" [argument_list [","] ] ")"\n classname ::= identifier\n\nA class definition is an executable statement. The inheritance list\nusually gives a list of base classes (see *Customizing class creation*\nfor more advanced uses), so each item in the list should evaluate to a\nclass object which allows subclassing.\n\nThe class\'s suite is then executed in a new execution frame (see\n*Naming and binding*), using a newly created local namespace and the\noriginal global namespace. (Usually, the suite contains mostly\nfunction definitions.) When the class\'s suite finishes execution, its\nexecution frame is discarded but its local namespace is saved. [4] A\nclass object is then created using the inheritance list for the base\nclasses and the saved local namespace for the attribute dictionary.\nThe class name is bound to this class object in the original local\nnamespace.\n\nClass creation can be customized heavily using *metaclasses*.\n\nClasses can also be decorated; as with functions,\n\n @f1(arg)\n @f2\n class Foo: pass\n\nis equivalent to\n\n class Foo: pass\n Foo = f1(arg)(f2(Foo))\n\n**Programmer\'s note:** Variables defined in the class definition are\nclass attributes; they are shared by instances. Instance attributes\ncan be set in a method with ``self.name = value``. Both class and\ninstance attributes are accessible through the notation\n"``self.name``", and an instance attribute hides a class attribute\nwith the same name when accessed in this way. Class attributes can be\nused as defaults for instance attributes, but using mutable values\nthere can lead to unexpected results. *Descriptors* can be used to\ncreate instance variables with different implementation details.\n\nSee also:\n\n **PEP 3116** - Metaclasses in Python 3 **PEP 3129** - Class\n Decorators\n\n-[ Footnotes ]-\n\n[1] The exception is propagated to the invocation stack only if there\n is no ``finally`` clause that negates the exception.\n\n[2] Currently, control "flows off the end" except in the case of an\n exception or the execution of a ``return``, ``continue``, or\n ``break`` statement.\n\n[3] A string literal appearing as the first statement in the function\n body is transformed into the function\'s ``__doc__`` attribute and\n therefore the function\'s *docstring*.\n\n[4] A string literal appearing as the first statement in the class\n body is transformed into the namespace\'s ``__doc__`` item and\n therefore the class\'s *docstring*.\n',
'context-managers': '\nWith Statement Context Managers\n*******************************\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n',
'continue': '\nThe ``continue`` statement\n**************************\n\n continue_stmt ::= "continue"\n\n``continue`` may only occur syntactically nested in a ``for`` or\n``while`` loop, but not nested in a function or class definition or\n``finally`` clause within that loop. It continues with the next cycle\nof the nearest enclosing loop.\n\nWhen ``continue`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nstarting the next loop cycle.\n',
'conversions': '\nArithmetic conversions\n**********************\n\nWhen a description of an arithmetic operator below uses the phrase\n"the numeric arguments are converted to a common type," this means\nthat the operator implementation for built-in types works that way:\n\n* If either argument is a complex number, the other is converted to\n complex;\n\n* otherwise, if either argument is a floating point number, the other\n is converted to floating point;\n\n* otherwise, both must be integers and no conversion is necessary.\n\nSome additional rules apply for certain operators (e.g., a string left\nargument to the \'%\' operator). Extensions must define their own\nconversion behavior.\n',
@@ -36,16 +36,17 @@
'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s" | "a"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either\neither a number or a keyword. If it\'s a number, it refers to a\npositional argument, and if it\'s a keyword, it refers to a named\nkeyword argument. If the numerical arg_names in a format string are\n0, 1, 2, ... in sequence, they can all be omitted (not just some) and\nthe numbers 0, 1, 2, ... will be automatically inserted in that order.\nThe *arg_name* can be followed by any number of index or attribute\nexpressions. An expression of the form ``\'.name\'`` selects the named\nattribute using ``getattr()``, while an expression of the form\n``\'[index]\'`` does an index lookup using ``__getitem__()``.\n\nChanged in version 3.1: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nThree conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, ``\'!r\'`` which calls ``repr()`` and ``\'!a\'``\nwhich calls ``ascii()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n "More {!a}" # Calls ascii() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'}\' (which\nsignifies the end of the field). The presence of a fill character is\nsignaled by the *next* character, which must be one of the alignment\noptions. If the second character of *format_spec* is not a valid\nalignment option, then it is assumed that both the fill character and\nthe alignment option are absent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 3.1: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nIf the *width* field is preceded by a zero (``\'0\'``) character, this\nenables zero-padding. This is equivalent to an *alignment* type of\n``\'=\'`` and a *fill* character of ``\'0\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``, but converts ``nan`` to |\n | | ``NAN`` and ``inf`` to ``INF``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Postive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | Similar to ``\'g\'``, except with at least one digit past |\n | | the decimal point and a default precision of 12. This is |\n | | intended to match ``str()``, except you can add the other |\n | | format modifiers. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 3.1+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point:\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19\n >>> total = 22\n >>> \'Correct answers: {:.2%}.\'.format(points/total)\n \'Correct answers: 86.36%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{align}{fill}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print(\'{0:{width}{base}}\'.format(num, base=base, width=width), end=\' \')\n ... print()\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n',
'function': '\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n funcdef ::= [decorators] "def" funcname "(" [parameter_list] ")" ["->" expression] ":" suite\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" [parameter] ("," defparameter)*\n [, "**" parameter]\n | "**" parameter\n | defparameter [","] )\n parameter ::= identifier [":" expression]\n defparameter ::= parameter ["=" expression]\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more parameters have the form *parameter* ``=``\n*expression*, the function is said to have "default parameter values."\nFor a parameter with a default value, the corresponding argument may\nbe omitted from a call, in which case the parameter\'s default value is\nsubstituted. If a parameter has a default value, all following\nparameters up until the "``*``" must also have a default value ---\nthis is a syntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that that same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary. Parameters after "``*``" or "``*identifier``" are\nkeyword-only parameters and may only be passed used keyword arguments.\n\nParameters may have annotations of the form "``: expression``"\nfollowing the parameter name. Any parameter may have an annotation\neven those of the form ``*identifier`` or ``**identifier``. Functions\nmay have "return" annotation of the form "``-> expression``" after the\nparameter list. These annotations can be any valid Python expression\nand are evaluated when the function definition is executed.\nAnnotations may be evaluated in a different order than they appear in\nthe source code. The presence of annotations does not change the\nsemantics of a function. The annotation values are available as\nvalues of a dictionary keyed by the parameters\' names in the\n``__annotations__`` attribute of the function object.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements and annotations.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n',
'global': '\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in a string\nor code object supplied to the built-in ``exec()`` function does not\naffect the code block *containing* the function call, and code\ncontained in such a string is unaffected by ``global`` statements in\nthe code containing the function call. The same applies to the\n``eval()`` and ``compile()`` functions.\n',
- 'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n',
- 'identifiers': '\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters ``A`` through ``Z``, the underscore ``_`` and, except for the\nfirst character, the digits ``0`` through ``9``.\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n``unicodedata`` module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= id_start id_continue*\n id_start ::= \n id_continue ::= \n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\nAll identifiers are converted into the normal form NFC while parsing;\ncomparison of identifiers is based on NFC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library);\n applications should not expect to define additional names using\n this convention. The set of names of this class defined by Python\n may be extended in future versions. See section *Special method\n names*.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n',
+ 'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n',
+ 'identifiers': '\nIdentifiers and keywords\n************************\n\nIdentifiers (also referred to as *names*) are described by the\nfollowing lexical definitions.\n\nThe syntax of identifiers in Python is based on the Unicode standard\nannex UAX-31, with elaboration and changes as defined below; see also\n**PEP 3131** for further details.\n\nWithin the ASCII range (U+0001..U+007F), the valid characters for\nidentifiers are the same as in Python 2.x: the uppercase and lowercase\nletters ``A`` through ``Z``, the underscore ``_`` and, except for the\nfirst character, the digits ``0`` through ``9``.\n\nPython 3.0 introduces additional characters from outside the ASCII\nrange (see **PEP 3131**). For these characters, the classification\nuses the version of the Unicode Character Database as included in the\n``unicodedata`` module.\n\nIdentifiers are unlimited in length. Case is significant.\n\n identifier ::= id_start id_continue*\n id_start ::= \n id_continue ::= \n\nThe Unicode category codes mentioned above stand for:\n\n* *Lu* - uppercase letters\n\n* *Ll* - lowercase letters\n\n* *Lt* - titlecase letters\n\n* *Lm* - modifier letters\n\n* *Lo* - other letters\n\n* *Nl* - letter numbers\n\n* *Mn* - nonspacing marks\n\n* *Mc* - spacing combining marks\n\n* *Nd* - decimal numbers\n\n* *Pc* - connector punctuations\n\nAll identifiers are converted into the normal form NFC while parsing;\ncomparison of identifiers is based on NFC.\n\nA non-normative HTML file listing all valid identifier characters for\nUnicode 4.1 can be found at http://www.dcl.hpi.uni-\npotsdam.de/home/loewis/table-3131.html.\n\n\nKeywords\n========\n\nThe following identifiers are used as reserved words, or *keywords* of\nthe language, and cannot be used as ordinary identifiers. They must\nbe spelled exactly as written here:\n\n False class finally is return\n None continue for lambda try\n True def from nonlocal while\n and del global not with\n as elif if or yield\n assert else import pass\n break except in raise\n\n\nReserved classes of identifiers\n===============================\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``builtins`` module. When\n not in interactive mode, ``_`` has no special meaning and is not\n defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n',
'if': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n',
'imaginary': '\nImaginary literals\n******************\n\nImaginary literals are described by the following lexical definitions:\n\n imagnumber ::= (floatnumber | intpart) ("j" | "J")\n\nAn imaginary literal yields a complex number with a real part of 0.0.\nComplex numbers are represented as a pair of floating point numbers\nand have the same restrictions on their range. To create a complex\nnumber with a nonzero real part, add a floating point number to it,\ne.g., ``(3+4j)``. Some examples of imaginary literals:\n\n 3.14j 10.j 10j .001j 1e100j 3.14e-10j\n',
- 'import': '\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly. For a reference\nimplementation of step (1), see the ``importlib`` module.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import unless ``None`` is found in ``sys.modules``, in which case\n``ImportError`` is raised.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. The\nwild card form of import --- ``import *`` --- is only allowed at the\nmodule level. Attempting to use it in class or function definitions\nwill raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimprt mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are ``absolute_import``,\n``division``, ``generators``, ``unicode_literals``,\n``print_function``, ``nested_scopes`` and ``with_statement``. They\nare all redundant because they are always enabled, and only kept for\nbackwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions ``exec()`` and\n``compile()`` that occur in a module ``M`` containing a future\nstatement will, by default, use the new syntax or semantics associated\nwith the future statement. This can be controlled by optional\narguments to ``compile()`` --- see the documentation of that function\nfor details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n',
+ 'import': '\nThe ``import`` statement\n************************\n\n import_stmt ::= "import" module ["as" name] ( "," module ["as" name] )*\n | "from" relative_module "import" identifier ["as" name]\n ( "," identifier ["as" name] )*\n | "from" relative_module "import" "(" identifier ["as" name]\n ( "," identifier ["as" name] )* [","] ")"\n | "from" module "import" "*"\n module ::= (identifier ".")* identifier\n relative_module ::= "."* module | "."+\n name ::= identifier\n\nImport statements are executed in two steps: (1) find a module, and\ninitialize it if necessary; (2) define a name or names in the local\nnamespace (of the scope where the ``import`` statement occurs). The\nstatement comes in two forms differing on whether it uses the ``from``\nkeyword. The first form (without ``from``) repeats these steps for\neach identifier in the list. The form with ``from`` performs step (1)\nonce, and then performs step (2) repeatedly. For a reference\nimplementation of step (1), see the ``importlib`` module.\n\nTo understand how step (1) occurs, one must first understand how\nPython handles hierarchical naming of modules. To help organize\nmodules and provide a hierarchy in naming, Python has a concept of\npackages. A package can contain other packages and modules while\nmodules cannot contain other modules or packages. From a file system\nperspective, packages are directories and modules are files. The\noriginal specification for packages is still available to read,\nalthough minor details have changed since the writing of that\ndocument.\n\nOnce the name of the module is known (unless otherwise specified, the\nterm "module" will refer to both packages and modules), searching for\nthe module or package can begin. The first place checked is\n``sys.modules``, the cache of all modules that have been imported\npreviously. If the module is found there then it is used in step (2)\nof import unless ``None`` is found in ``sys.modules``, in which case\n``ImportError`` is raised.\n\nIf the module is not found in the cache, then ``sys.meta_path`` is\nsearched (the specification for ``sys.meta_path`` can be found in\n**PEP 302**). The object is a list of *finder* objects which are\nqueried in order as to whether they know how to load the module by\ncalling their ``find_module()`` method with the name of the module. If\nthe module happens to be contained within a package (as denoted by the\nexistence of a dot in the name), then a second argument to\n``find_module()`` is given as the value of the ``__path__`` attribute\nfrom the parent package (everything up to the last dot in the name of\nthe module being imported). If a finder can find the module it returns\na *loader* (discussed later) or returns ``None``.\n\nIf none of the finders on ``sys.meta_path`` are able to find the\nmodule then some implicitly defined finders are queried.\nImplementations of Python vary in what implicit meta path finders are\ndefined. The one they all do define, though, is one that handles\n``sys.path_hooks``, ``sys.path_importer_cache``, and ``sys.path``.\n\nThe implicit finder searches for the requested module in the "paths"\nspecified in one of two places ("paths" do not have to be file system\npaths). If the module being imported is supposed to be contained\nwithin a package then the second argument passed to ``find_module()``,\n``__path__`` on the parent package, is used as the source of paths. If\nthe module is not contained in a package then ``sys.path`` is used as\nthe source of paths.\n\nOnce the source of paths is chosen it is iterated over to find a\nfinder that can handle that path. The dict at\n``sys.path_importer_cache`` caches finders for paths and is checked\nfor a finder. If the path does not have a finder cached then\n``sys.path_hooks`` is searched by calling each object in the list with\na single argument of the path, returning a finder or raises\n``ImportError``. If a finder is returned then it is cached in\n``sys.path_importer_cache`` and then used for that path entry. If no\nfinder can be found but the path exists then a value of ``None`` is\nstored in ``sys.path_importer_cache`` to signify that an implicit,\nfile-based finder that handles modules stored as individual files\nshould be used for that path. If the path does not exist then a finder\nwhich always returns ``None`` is placed in the cache for the path.\n\nIf no finder can find the module then ``ImportError`` is raised.\nOtherwise some finder returned a loader whose ``load_module()`` method\nis called with the name of the module to load (see **PEP 302** for the\noriginal definition of loaders). A loader has several responsibilities\nto perform on a module it loads. First, if the module already exists\nin ``sys.modules`` (a possibility if the loader is called outside of\nthe import machinery) then it is to use that module for initialization\nand not a new module. But if the module does not exist in\n``sys.modules`` then it is to be added to that dict before\ninitialization begins. If an error occurs during loading of the module\nand it was added to ``sys.modules`` it is to be removed from the dict.\nIf an error occurs but the module was already in ``sys.modules`` it is\nleft in the dict.\n\nThe loader must set several attributes on the module. ``__name__`` is\nto be set to the name of the module. ``__file__`` is to be the "path"\nto the file unless the module is built-in (and thus listed in\n``sys.builtin_module_names``) in which case the attribute is not set.\nIf what is being imported is a package then ``__path__`` is to be set\nto a list of paths to be searched when looking for modules and\npackages contained within the package being imported. ``__package__``\nis optional but should be set to the name of package that contains the\nmodule or package (the empty string is used for module not contained\nin a package). ``__loader__`` is also optional but should be set to\nthe loader object that is loading the module.\n\nIf an error occurs during loading then the loader raises\n``ImportError`` if some other exception is not already being\npropagated. Otherwise the loader returns the module that was loaded\nand initialized.\n\nWhen step (1) finishes without raising an exception, step (2) can\nbegin.\n\nThe first form of ``import`` statement binds the module name in the\nlocal namespace to the module object, and then goes on to import the\nnext identifier, if any. If the module name is followed by ``as``,\nthe name following ``as`` is used as the local name for the module.\n\nThe ``from`` form does not bind the module name: it goes through the\nlist of identifiers, looks each one of them up in the module found in\nstep (1), and binds the name in the local namespace to the object thus\nfound. As with the first form of ``import``, an alternate local name\ncan be supplied by specifying "``as`` localname". If a name is not\nfound, ``ImportError`` is raised. If the list of identifiers is\nreplaced by a star (``\'*\'``), all public names defined in the module\nare bound in the local namespace of the ``import`` statement..\n\nThe *public names* defined by a module are determined by checking the\nmodule\'s namespace for a variable named ``__all__``; if defined, it\nmust be a sequence of strings which are names defined or imported by\nthat module. The names given in ``__all__`` are all considered public\nand are required to exist. If ``__all__`` is not defined, the set of\npublic names includes all names found in the module\'s namespace which\ndo not begin with an underscore character (``\'_\'``). ``__all__``\nshould contain the entire public API. It is intended to avoid\naccidentally exporting items that are not part of the API (such as\nlibrary modules which were imported and used within the module).\n\nThe ``from`` form with ``*`` may only occur in a module scope. The\nwild card form of import --- ``import *`` --- is only allowed at the\nmodule level. Attempting to use it in class or function definitions\nwill raise a ``SyntaxError``.\n\nWhen specifying what module to import you do not have to specify the\nabsolute name of the module. When a module or package is contained\nwithin another package it is possible to make a relative import within\nthe same top package without having to mention the package name. By\nusing leading dots in the specified module or package after ``from``\nyou can specify how high to traverse up the current package hierarchy\nwithout specifying exact names. One leading dot means the current\npackage where the module making the import exists. Two dots means up\none package level. Three dots is up two levels, etc. So if you execute\n``from . import mod`` from a module in the ``pkg`` package then you\nwill end up importing ``pkg.mod``. If you execute ``from ..subpkg2\nimport mod`` from within ``pkg.subpkg1`` you will import\n``pkg.subpkg2.mod``. The specification for relative imports is\ncontained within **PEP 328**.\n\n``importlib.import_module()`` is provided to support applications that\ndetermine which modules need to be loaded dynamically.\n\n\nFuture statements\n=================\n\nA *future statement* is a directive to the compiler that a particular\nmodule should be compiled using syntax or semantics that will be\navailable in a specified future release of Python. The future\nstatement is intended to ease migration to future versions of Python\nthat introduce incompatible changes to the language. It allows use of\nthe new features on a per-module basis before the release in which the\nfeature becomes standard.\n\n future_statement ::= "from" "__future__" "import" feature ["as" name]\n ("," feature ["as" name])*\n | "from" "__future__" "import" "(" feature ["as" name]\n ("," feature ["as" name])* [","] ")"\n feature ::= identifier\n name ::= identifier\n\nA future statement must appear near the top of the module. The only\nlines that can appear before a future statement are:\n\n* the module docstring (if any),\n\n* comments,\n\n* blank lines, and\n\n* other future statements.\n\nThe features recognized by Python 3.0 are ``absolute_import``,\n``division``, ``generators``, ``unicode_literals``,\n``print_function``, ``nested_scopes`` and ``with_statement``. They\nare all redundant because they are always enabled, and only kept for\nbackwards compatibility.\n\nA future statement is recognized and treated specially at compile\ntime: Changes to the semantics of core constructs are often\nimplemented by generating different code. It may even be the case\nthat a new feature introduces new incompatible syntax (such as a new\nreserved word), in which case the compiler may need to parse the\nmodule differently. Such decisions cannot be pushed off until\nruntime.\n\nFor any given release, the compiler knows which feature names have\nbeen defined, and raises a compile-time error if a future statement\ncontains a feature not known to it.\n\nThe direct runtime semantics are the same as for any import statement:\nthere is a standard module ``__future__``, described later, and it\nwill be imported in the usual way at the time the future statement is\nexecuted.\n\nThe interesting runtime semantics depend on the specific feature\nenabled by the future statement.\n\nNote that there is nothing special about the statement:\n\n import __future__ [as name]\n\nThat is not a future statement; it\'s an ordinary import statement with\nno special semantics or syntax restrictions.\n\nCode compiled by calls to the built-in functions ``exec()`` and\n``compile()`` that occur in a module ``M`` containing a future\nstatement will, by default, use the new syntax or semantics associated\nwith the future statement. This can be controlled by optional\narguments to ``compile()`` --- see the documentation of that function\nfor details.\n\nA future statement typed at an interactive interpreter prompt will\ntake effect for the rest of the interpreter session. If an\ninterpreter is started with the *-i* option, is passed a script name\nto execute, and the script includes a future statement, it will be in\neffect in the interactive session started after the script is\nexecuted.\n\nSee also:\n\n **PEP 236** - Back to the __future__\n The original proposal for the __future__ mechanism.\n',
'in': '\nComparisons\n***********\n\nUnlike C, all comparison operations in Python have the same priority,\nwhich is lower than that of any arithmetic, shifting or bitwise\noperation. Also unlike C, expressions like ``a < b < c`` have the\ninterpretation that is conventional in mathematics:\n\n comparison ::= or_expr ( comp_operator or_expr )*\n comp_operator ::= "<" | ">" | "==" | ">=" | "<=" | "!="\n | "is" ["not"] | ["not"] "in"\n\nComparisons yield boolean values: ``True`` or ``False``.\n\nComparisons can be chained arbitrarily, e.g., ``x < y <= z`` is\nequivalent to ``x < y and y <= z``, except that ``y`` is evaluated\nonly once (but in both cases ``z`` is not evaluated at all when ``x <\ny`` is found to be false).\n\nFormally, if *a*, *b*, *c*, ..., *y*, *z* are expressions and *op1*,\n*op2*, ..., *opN* are comparison operators, then ``a op1 b op2 c ... y\nopN z`` is equivalent to ``a op1 b and b op2 c and ... y opN z``,\nexcept that each expression is evaluated at most once.\n\nNote that ``a op1 b op2 c`` doesn\'t imply any kind of comparison\nbetween *a* and *c*, so that, e.g., ``x < y > z`` is perfectly legal\n(though perhaps not pretty).\n\nThe operators ``<``, ``>``, ``==``, ``>=``, ``<=``, and ``!=`` compare\nthe values of two objects. The objects need not have the same type.\nIf both are numbers, they are converted to a common type. Otherwise,\nthe ``==`` and ``!=`` operators *always* consider objects of different\ntypes to be unequal, while the ``<``, ``>``, ``>=`` and ``<=``\noperators raise a ``TypeError`` when comparing objects of different\ntypes that do not implement these operators for the given pair of\ntypes. You can control comparison behavior of objects of non-built-in\ntypes by defining rich comparison methods like ``__gt__()``, described\nin section *Basic customization*.\n\nComparison of objects of the same type depends on the type:\n\n* Numbers are compared arithmetically.\n\n* The values ``float(\'NaN\')`` and ``Decimal(\'NaN\')`` are special. The\n are identical to themselves, ``x is x`` but are not equal to\n themselves, ``x != x``. Additionally, comparing any value to a\n not-a-number value will return ``False``. For example, both ``3 <\n float(\'NaN\')`` and ``float(\'NaN\') < 3`` will return ``False``.\n\n* Bytes objects are compared lexicographically using the numeric\n values of their elements.\n\n* Strings are compared lexicographically using the numeric equivalents\n (the result of the built-in function ``ord()``) of their characters.\n [3] String and bytes object can\'t be compared!\n\n* Tuples and lists are compared lexicographically using comparison of\n corresponding elements. This means that to compare equal, each\n element must compare equal and the two sequences must be of the same\n type and have the same length.\n\n If not equal, the sequences are ordered the same as their first\n differing elements. For example, ``[1,2,x] <= [1,2,y]`` has the\n same value as ``x <= y``. If the corresponding element does not\n exist, the shorter sequence is ordered first (for example, ``[1,2] <\n [1,2,3]``).\n\n* Mappings (dictionaries) compare equal if and only if they have the\n same ``(key, value)`` pairs. Order comparisons ``(\'<\', \'<=\', \'>=\',\n \'>\')`` raise ``TypeError``.\n\n* Sets and frozensets define comparison operators to mean subset and\n superset tests. Those relations do not define total orderings (the\n two sets ``{1,2}`` and {2,3} are not equal, nor subsets of one\n another, nor supersets of one another). Accordingly, sets are not\n appropriate arguments for functions which depend on total ordering.\n For example, ``min()``, ``max()``, and ``sorted()`` produce\n undefined results given a list of sets as inputs.\n\n* Most other objects of built-in types compare unequal unless they are\n the same object; the choice whether one object is considered smaller\n or larger than another one is made arbitrarily but consistently\n within one execution of a program.\n\nComparison of objects of the differing types depends on whether either\nof the types provide explicit support for the comparison. Most\nnumeric types can be compared with one another, but comparisons of\n``float`` and ``Decimal`` are not supported to avoid the inevitable\nconfusion arising from representation issues such as ``float(\'1.1\')``\nbeing inexactly represented and therefore not exactly equal to\n``Decimal(\'1.1\')`` which is. When cross-type comparison is not\nsupported, the comparison method returns ``NotImplemented``. This can\ncreate the illusion of non-transitivity between supported cross-type\ncomparisons and unsupported comparisons. For example, ``Decimal(2) ==\n2`` and *2 == float(2)`* but ``Decimal(2) != float(2)``.\n\nThe operators ``in`` and ``not in`` test for membership. ``x in s``\nevaluates to true if *x* is a member of *s*, and false otherwise. ``x\nnot in s`` returns the negation of ``x in s``. All built-in sequences\nand set types support this as well as dictionary, for which ``in``\ntests whether a the dictionary has a given key. For container types\nsuch as list, tuple, set, frozenset, dict, or collections.deque, the\nexpression ``x in y`` is equivalent to ``any(x is e or x == e for e in\ny)``.\n\nFor the string and bytes types, ``x in y`` is true if and only if *x*\nis a substring of *y*. An equivalent test is ``y.find(x) != -1``.\nEmpty strings are always considered to be a substring of any other\nstring, so ``"" in "abc"`` will return ``True``.\n\nFor user-defined classes which define the ``__contains__()`` method,\n``x in y`` is true if and only if ``y.__contains__(x)`` is true.\n\nFor user-defined classes which do not define ``__contains__()`` but do\ndefine ``__iter__()``, ``x in y`` is true if some value ``z`` with ``x\n== z`` is produced while iterating over ``y``. If an exception is\nraised during the iteration, it is as if ``in`` raised that exception.\n\nLastly, the old-style iteration protocol is tried: if a class defines\n``__getitem__()``, ``x in y`` is true if and only if there is a non-\nnegative integer index *i* such that ``x == y[i]``, and all lower\ninteger indices do not raise ``IndexError`` exception. (If any other\nexception is raised, it is as if ``in`` raised that exception).\n\nThe operator ``not in`` is defined to have the inverse true value of\n``in``.\n\nThe operators ``is`` and ``is not`` test for object identity: ``x is\ny`` is true if and only if *x* and *y* are the same object. ``x is\nnot y`` yields the inverse truth value. [4]\n',
'integers': '\nInteger literals\n****************\n\nInteger literals are described by the following lexical definitions:\n\n integer ::= decimalinteger | octinteger | hexinteger | bininteger\n decimalinteger ::= nonzerodigit digit* | "0"+\n nonzerodigit ::= "1"..."9"\n digit ::= "0"..."9"\n octinteger ::= "0" ("o" | "O") octdigit+\n hexinteger ::= "0" ("x" | "X") hexdigit+\n bininteger ::= "0" ("b" | "B") bindigit+\n octdigit ::= "0"..."7"\n hexdigit ::= digit | "a"..."f" | "A"..."F"\n bindigit ::= "0" | "1"\n\nThere is no limit for the length of integer literals apart from what\ncan be stored in available memory.\n\nNote that leading zeros in a non-zero decimal number are not allowed.\nThis is for disambiguation with C-style octal literals, which Python\nused before version 3.0.\n\nSome examples of integer literals:\n\n 7 2147483647 0o177 0b100110111\n 3 79228162514264337593543950336 0o377 0x100000000\n 79228162514264337593543950336 0xdeadbeef\n',
'lambda': '\nLambdas\n*******\n\n lambda_form ::= "lambda" [parameter_list]: expression\n lambda_form_nocond ::= "lambda" [parameter_list]: expression_nocond\n\nLambda forms (lambda expressions) have the same syntactic position as\nexpressions. They are a shorthand to create anonymous functions; the\nexpression ``lambda arguments: expression`` yields a function object.\nThe unnamed object behaves like a function object defined with\n\n def (arguments):\n return expression\n\nSee section *Function definitions* for the syntax of parameter lists.\nNote that functions created with lambda forms cannot contain\nstatements or annotations.\n',
'lists': '\nList displays\n*************\n\nA list display is a possibly empty series of expressions enclosed in\nsquare brackets:\n\n list_display ::= "[" [expression_list | comprehension] "]"\n\nA list display yields a new list object, the contents being specified\nby either a list of expressions or a comprehension. When a comma-\nseparated list of expressions is supplied, its elements are evaluated\nfrom left to right and placed into the list object in that order.\nWhen a comprehension is supplied, the list is constructed from the\nelements resulting from the comprehension.\n',
'naming': "\nNaming and binding\n******************\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the '**-c**' option) is a code block. The string argument passed\nto the built-in functions ``eval()`` and ``exec()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block's execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes comprehensions and generator\nexpressions since they are implemented using a function scope. This\nmeans that the following will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block's *environment*.\n\nIf a name is bound in a block, it is a local variable of that block,\nunless declared as ``nonlocal``. If a name is bound at the module\nlevel, it is a global variable. (The variables of the module code\nblock are local and global.) If a variable is used in a code block\nbut not defined there, it is a *free variable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, or\nafter ``as`` in a ``with`` statement or :keyword.`except` clause. The\n``import`` statement of the form ``from ... import *`` binds all names\ndefined in the imported module, except those beginning with an\nunderscore. This form may only be used at the module level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the ``global`` statement occurs within a block, all uses of the\nname specified in the statement refer to the binding of that name in\nthe top-level namespace. Names are resolved in the top-level\nnamespace by searching the global namespace, i.e. the namespace of the\nmodule containing the code block, and the builtins namespace, the\nnamespace of the module ``builtins``. The global namespace is\nsearched first. If the name is not found there, the builtins\nnamespace is searched. The global statement must precede all uses of\nthe name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module's dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``builtins``; when in any other module, ``__builtins__`` is an alias\nfor the dictionary of the ``builtins`` module itself.\n``__builtins__`` can be set to a user-created dictionary to create a\nweak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``builtins`` module and modify its attributes appropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe global statement has the same scope as a name binding operation in\nthe same block. If the nearest enclosing scope for a free variable\ncontains a global statement, the free variable is treated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n=================================\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nThe ``eval()`` and ``exec()`` functions do not have access to the full\nenvironment for resolving names. Names may be resolved in the local\nand global namespaces of the caller. Free variables are not resolved\nin the nearest enclosing namespace, but in the global namespace. [1]\nThe ``exec()`` and ``eval()`` functions have optional arguments to\noverride the global and local namespace. If only one namespace is\nspecified, it is used for both.\n",
+ 'nonlocal': '\nThe ``nonlocal`` statement\n**************************\n\n nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n\nThe ``nonlocal`` statement causes the listed identifiers to refer to\npreviously bound variables in the nearest enclosing scope. This is\nimportant because the default behavior for binding is to search the\nlocal namespace first. The statement allows encapsulated code to\nrebind variables outside of the local scope besides the global\n(module) scope.\n\nNames listed in a ``nonlocal`` statement, unlike to those listed in a\n``global`` statement, must refer to pre-existing bindings in an\nenclosing scope (the scope in which a new binding should be created\ncannot be determined unambiguously).\n\nNames listed in a ``nonlocal`` statement must not collide with pre-\nexisting bindings in the local scope.\n\nSee also:\n\n **PEP 3104** - Access to Names in Outer Scopes\n The specification for the ``nonlocal`` statement.\n\n-[ Footnotes ]-\n\n[1] It may occur within an ``except`` or ``else`` clause. The\n restriction on occurring in the ``try`` clause is implementor\'s\n laziness and will eventually be lifted.\n',
'numbers': "\nNumeric literals\n****************\n\nThere are three types of numeric literals: integers, floating point\nnumbers, and imaginary numbers. There are no complex literals\n(complex numbers can be formed by adding a real number and an\nimaginary number).\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator '``-``' and\nthe literal ``1``.\n",
'numeric-types': "\nEmulating numeric types\n***********************\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``). For instance, to evaluate the expression ``x + y``, where\n *x* is an instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()``. Note that\n ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``) with reflected (swapped) operands. These functions are only\n called if the left operand does not support the corresponding\n operation and the operands are of different types. [2] For\n instance, to evaluate the expression ``x - y``, where *y* is an\n instance of a class that has an ``__rsub__()`` method,\n ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand's type is a subclass of the left operand's\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand's\n non-reflected method. This behavior allows subclasses to\n override their ancestors' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``float()`` and ``round()``. Should return a value of\n the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n",
'objects': '\nObjects, values and types\n*************************\n\n*Objects* are Python\'s abstraction for data. All data in a Python\nprogram is represented by objects or by relations between objects. (In\na sense, and in conformance to Von Neumann\'s model of a "stored\nprogram computer," code is also represented by objects.)\n\nEvery object has an identity, a type and a value. An object\'s\n*identity* never changes once it has been created; you may think of it\nas the object\'s address in memory. The \'``is``\' operator compares the\nidentity of two objects; the ``id()`` function returns an integer\nrepresenting its identity (currently implemented as its address). An\nobject\'s *type* is also unchangeable. [1] An object\'s type determines\nthe operations that the object supports (e.g., "does it have a\nlength?") and also defines the possible values for objects of that\ntype. The ``type()`` function returns an object\'s type (which is an\nobject itself). The *value* of some objects can change. Objects\nwhose value can change are said to be *mutable*; objects whose value\nis unchangeable once they are created are called *immutable*. (The\nvalue of an immutable container object that contains a reference to a\nmutable object can change when the latter\'s value is changed; however\nthe container is still considered immutable, because the collection of\nobjects it contains cannot be changed. So, immutability is not\nstrictly the same as having an unchangeable value, it is more subtle.)\nAn object\'s mutability is determined by its type; for instance,\nnumbers, strings and tuples are immutable, while dictionaries and\nlists are mutable.\n\nObjects are never explicitly destroyed; however, when they become\nunreachable they may be garbage-collected. An implementation is\nallowed to postpone garbage collection or omit it altogether --- it is\na matter of implementation quality how garbage collection is\nimplemented, as long as no objects are collected that are still\nreachable.\n\n**CPython implementation detail:** CPython currently uses a reference-\ncounting scheme with (optional) delayed detection of cyclically linked\ngarbage, which collects most objects as soon as they become\nunreachable, but is not guaranteed to collect garbage containing\ncircular references. See the documentation of the ``gc`` module for\ninformation on controlling the collection of cyclic garbage. Other\nimplementations act differently and CPython may change.\n\nNote that the use of the implementation\'s tracing or debugging\nfacilities may keep objects alive that would normally be collectable.\nAlso note that catching an exception with a \'``try``...``except``\'\nstatement may keep objects alive.\n\nSome objects contain references to "external" resources such as open\nfiles or windows. It is understood that these resources are freed\nwhen the object is garbage-collected, but since garbage collection is\nnot guaranteed to happen, such objects also provide an explicit way to\nrelease the external resource, usually a ``close()`` method. Programs\nare strongly recommended to explicitly close such objects. The\n\'``try``...``finally``\' statement and the \'``with``\' statement provide\nconvenient ways to do this.\n\nSome objects contain references to other objects; these are called\n*containers*. Examples of containers are tuples, lists and\ndictionaries. The references are part of a container\'s value. In\nmost cases, when we talk about the value of a container, we imply the\nvalues, not the identities of the contained objects; however, when we\ntalk about the mutability of a container, only the identities of the\nimmediately contained objects are implied. So, if an immutable\ncontainer (like a tuple) contains a reference to a mutable object, its\nvalue changes if that mutable object is changed.\n\nTypes affect almost all aspects of object behavior. Even the\nimportance of object identity is affected in some sense: for immutable\ntypes, operations that compute new values may actually return a\nreference to any existing object with the same type and value, while\nfor mutable objects this is not allowed. E.g., after ``a = 1; b =\n1``, ``a`` and ``b`` may or may not refer to the same object with the\nvalue one, depending on the implementation, but after ``c = []; d =\n[]``, ``c`` and ``d`` are guaranteed to refer to two different,\nunique, newly created empty lists. (Note that ``c = d = []`` assigns\nthe same object to both ``c`` and ``d``.)\n',
@@ -59,19 +60,19 @@
'slicings': '\nSlicings\n********\n\nA slicing selects a range of items in a sequence object (e.g., a\nstring, tuple or list). Slicings may be used as expressions or as\ntargets in assignment or ``del`` statements. The syntax for a\nslicing:\n\n slicing ::= primary "[" slice_list "]"\n slice_list ::= slice_item ("," slice_item)* [","]\n slice_item ::= expression | proper_slice\n proper_slice ::= [lower_bound] ":" [upper_bound] [ ":" [stride] ]\n lower_bound ::= expression\n upper_bound ::= expression\n stride ::= expression\n\nThere is ambiguity in the formal syntax here: anything that looks like\nan expression list also looks like a slice list, so any subscription\ncan be interpreted as a slicing. Rather than further complicating the\nsyntax, this is disambiguated by defining that in this case the\ninterpretation as a subscription takes priority over the\ninterpretation as a slicing (this is the case if the slice list\ncontains no proper slice).\n\nThe semantics for a slicing are as follows. The primary must evaluate\nto a mapping object, and it is indexed (using the same\n``__getitem__()`` method as normal subscription) with a key that is\nconstructed from the slice list, as follows. If the slice list\ncontains at least one comma, the key is a tuple containing the\nconversion of the slice items; otherwise, the conversion of the lone\nslice item is the key. The conversion of a slice item that is an\nexpression is that expression. The conversion of a proper slice is a\nslice object (see section *The standard type hierarchy*) whose\n``start``, ``stop`` and ``step`` attributes are the values of the\nexpressions given as lower bound, upper bound and stride,\nrespectively, substituting ``None`` for missing expressions.\n',
'specialattrs': "\nSpecial Attributes\n******************\n\nThe implementation adds a few special read-only attributes to several\nobject types, where they are relevant. Some of these are not reported\nby the ``dir()`` built-in function.\n\nobject.__dict__\n\n A dictionary or other mapping object used to store an object's\n (writable) attributes.\n\ninstance.__class__\n\n The class to which a class instance belongs.\n\nclass.__bases__\n\n The tuple of base classes of a class object.\n\nclass.__name__\n\n The name of the class or type.\n\nThe following attributes are only supported by *new-style class*es.\n\nclass.__mro__\n\n This attribute is a tuple of classes that are considered when\n looking for base classes during method resolution.\n\nclass.mro()\n\n This method can be overridden by a metaclass to customize the\n method resolution order for its instances. It is called at class\n instantiation, and its result is stored in ``__mro__``.\n\nclass.__subclasses__()\n\n Each new-style class keeps a list of weak references to its\n immediate subclasses. This method returns a list of all those\n references still alive. Example:\n\n >>> int.__subclasses__()\n []\n\n-[ Footnotes ]-\n\n[1] Additional information on these special methods may be found in\n the Python Reference Manual (*Basic customization*).\n\n[2] As a consequence, the list ``[1, 2]`` is considered equal to\n ``[1.0, 2.0]``, and similarly for tuples.\n\n[3] They must have since the parser can't tell the type of the\n operands.\n\n[4] To format only a tuple you should therefore provide a singleton\n tuple whose only element is the tuple to be formatted.\n",
'specialnames': '\nSpecial method names\n********************\n\nA class can implement certain operations that are invoked by special\nsyntax (such as arithmetic operations or subscripting and slicing) by\ndefining methods with special names. This is Python\'s approach to\n*operator overloading*, allowing classes to define their own behavior\nwith respect to language operators. For instance, if a class defines\na method named ``__getitem__()``, and ``x`` is an instance of this\nclass, then ``x[i]`` is roughly equivalent to ``type(x).__getitem__(x,\ni)``. Except where mentioned, attempts to execute an operation raise\nan exception when no appropriate method is defined (typically\n``AttributeError`` or ``TypeError``).\n\nWhen implementing a class that emulates any built-in type, it is\nimportant that the emulation only be implemented to the degree that it\nmakes sense for the object being modelled. For example, some\nsequences may work well with retrieval of individual elements, but\nextracting a slice may not make sense. (One example of this is the\n``NodeList`` interface in the W3C\'s Document Object Model.)\n\n\nBasic customization\n===================\n\nobject.__new__(cls[, ...])\n\n Called to create a new instance of class *cls*. ``__new__()`` is a\n static method (special-cased so you need not declare it as such)\n that takes the class of which an instance was requested as its\n first argument. The remaining arguments are those passed to the\n object constructor expression (the call to the class). The return\n value of ``__new__()`` should be the new object instance (usually\n an instance of *cls*).\n\n Typical implementations create a new instance of the class by\n invoking the superclass\'s ``__new__()`` method using\n ``super(currentclass, cls).__new__(cls[, ...])`` with appropriate\n arguments and then modifying the newly-created instance as\n necessary before returning it.\n\n If ``__new__()`` returns an instance of *cls*, then the new\n instance\'s ``__init__()`` method will be invoked like\n ``__init__(self[, ...])``, where *self* is the new instance and the\n remaining arguments are the same as were passed to ``__new__()``.\n\n If ``__new__()`` does not return an instance of *cls*, then the new\n instance\'s ``__init__()`` method will not be invoked.\n\n ``__new__()`` is intended mainly to allow subclasses of immutable\n types (like int, str, or tuple) to customize instance creation. It\n is also commonly overridden in custom metaclasses in order to\n customize class creation.\n\nobject.__init__(self[, ...])\n\n Called when the instance is created. The arguments are those\n passed to the class constructor expression. If a base class has an\n ``__init__()`` method, the derived class\'s ``__init__()`` method,\n if any, must explicitly call it to ensure proper initialization of\n the base class part of the instance; for example:\n ``BaseClass.__init__(self, [args...])``. As a special constraint\n on constructors, no value may be returned; doing so will cause a\n ``TypeError`` to be raised at runtime.\n\nobject.__del__(self)\n\n Called when the instance is about to be destroyed. This is also\n called a destructor. If a base class has a ``__del__()`` method,\n the derived class\'s ``__del__()`` method, if any, must explicitly\n call it to ensure proper deletion of the base class part of the\n instance. Note that it is possible (though not recommended!) for\n the ``__del__()`` method to postpone destruction of the instance by\n creating a new reference to it. It may then be called at a later\n time when this new reference is deleted. It is not guaranteed that\n ``__del__()`` methods are called for objects that still exist when\n the interpreter exits.\n\n Note: ``del x`` doesn\'t directly call ``x.__del__()`` --- the former\n decrements the reference count for ``x`` by one, and the latter\n is only called when ``x``\'s reference count reaches zero. Some\n common situations that may prevent the reference count of an\n object from going to zero include: circular references between\n objects (e.g., a doubly-linked list or a tree data structure with\n parent and child pointers); a reference to the object on the\n stack frame of a function that caught an exception (the traceback\n stored in ``sys.exc_info()[2]`` keeps the stack frame alive); or\n a reference to the object on the stack frame that raised an\n unhandled exception in interactive mode (the traceback stored in\n ``sys.last_traceback`` keeps the stack frame alive). The first\n situation can only be remedied by explicitly breaking the cycles;\n the latter two situations can be resolved by storing ``None`` in\n ``sys.last_traceback``. Circular references which are garbage are\n detected when the option cycle detector is enabled (it\'s on by\n default), but can only be cleaned up if there are no Python-\n level ``__del__()`` methods involved. Refer to the documentation\n for the ``gc`` module for more information about how\n ``__del__()`` methods are handled by the cycle detector,\n particularly the description of the ``garbage`` value.\n\n Warning: Due to the precarious circumstances under which ``__del__()``\n methods are invoked, exceptions that occur during their execution\n are ignored, and a warning is printed to ``sys.stderr`` instead.\n Also, when ``__del__()`` is invoked in response to a module being\n deleted (e.g., when execution of the program is done), other\n globals referenced by the ``__del__()`` method may already have\n been deleted or in the process of being torn down (e.g. the\n import machinery shutting down). For this reason, ``__del__()``\n methods should do the absolute minimum needed to maintain\n external invariants. Starting with version 1.5, Python\n guarantees that globals whose name begins with a single\n underscore are deleted from their module before other globals are\n deleted; if no other references to such globals exist, this may\n help in assuring that imported modules are still available at the\n time when the ``__del__()`` method is called.\n\nobject.__repr__(self)\n\n Called by the ``repr()`` built-in function to compute the\n "official" string representation of an object. If at all possible,\n this should look like a valid Python expression that could be used\n to recreate an object with the same value (given an appropriate\n environment). If this is not possible, a string of the form\n ``<...some useful description...>`` should be returned. The return\n value must be a string object. If a class defines ``__repr__()``\n but not ``__str__()``, then ``__repr__()`` is also used when an\n "informal" string representation of instances of that class is\n required.\n\n This is typically used for debugging, so it is important that the\n representation is information-rich and unambiguous.\n\nobject.__str__(self)\n\n Called by the ``str()`` built-in function and by the ``print()``\n function to compute the "informal" string representation of an\n object. This differs from ``__repr__()`` in that it does not have\n to be a valid Python expression: a more convenient or concise\n representation may be used instead. The return value must be a\n string object.\n\nobject.__format__(self, format_spec)\n\n Called by the ``format()`` built-in function (and by extension, the\n ``format()`` method of class ``str``) to produce a "formatted"\n string representation of an object. The ``format_spec`` argument is\n a string that contains a description of the formatting options\n desired. The interpretation of the ``format_spec`` argument is up\n to the type implementing ``__format__()``, however most classes\n will either delegate formatting to one of the built-in types, or\n use a similar formatting option syntax.\n\n See *Format Specification Mini-Language* for a description of the\n standard formatting syntax.\n\n The return value must be a string object.\n\nobject.__lt__(self, other)\nobject.__le__(self, other)\nobject.__eq__(self, other)\nobject.__ne__(self, other)\nobject.__gt__(self, other)\nobject.__ge__(self, other)\n\n These are the so-called "rich comparison" methods. The\n correspondence between operator symbols and method names is as\n follows: ``xy`` calls ``x.__gt__(y)``, and ``x>=y`` calls\n ``x.__ge__(y)``.\n\n A rich comparison method may return the singleton\n ``NotImplemented`` if it does not implement the operation for a\n given pair of arguments. By convention, ``False`` and ``True`` are\n returned for a successful comparison. However, these methods can\n return any value, so if the comparison operator is used in a\n Boolean context (e.g., in the condition of an ``if`` statement),\n Python will call ``bool()`` on the value to determine if the result\n is true or false.\n\n There are no implied relationships among the comparison operators.\n The truth of ``x==y`` does not imply that ``x!=y`` is false.\n Accordingly, when defining ``__eq__()``, one should also define\n ``__ne__()`` so that the operators will behave as expected. See\n the paragraph on ``__hash__()`` for some important notes on\n creating *hashable* objects which support custom comparison\n operations and are usable as dictionary keys.\n\n There are no swapped-argument versions of these methods (to be used\n when the left argument does not support the operation but the right\n argument does); rather, ``__lt__()`` and ``__gt__()`` are each\n other\'s reflection, ``__le__()`` and ``__ge__()`` are each other\'s\n reflection, and ``__eq__()`` and ``__ne__()`` are their own\n reflection.\n\n Arguments to rich comparison methods are never coerced.\n\n To automatically generate ordering operations from a single root\n operation, see ``functools.total_ordering()``.\n\nobject.__hash__(self)\n\n Called by built-in function ``hash()`` and for operations on\n members of hashed collections including ``set``, ``frozenset``, and\n ``dict``. ``__hash__()`` should return an integer. The only\n required property is that objects which compare equal have the same\n hash value; it is advised to somehow mix together (e.g. using\n exclusive or) the hash values for the components of the object that\n also play a part in comparison of objects.\n\n If a class does not define an ``__eq__()`` method it should not\n define a ``__hash__()`` operation either; if it defines\n ``__eq__()`` but not ``__hash__()``, its instances will not be\n usable as items in hashable collections. If a class defines\n mutable objects and implements an ``__eq__()`` method, it should\n not implement ``__hash__()``, since the implementation of hashable\n collections requires that a key\'s hash value is immutable (if the\n object\'s hash value changes, it will be in the wrong hash bucket).\n\n User-defined classes have ``__eq__()`` and ``__hash__()`` methods\n by default; with them, all objects compare unequal (except with\n themselves) and ``x.__hash__()`` returns ``id(x)``.\n\n Classes which inherit a ``__hash__()`` method from a parent class\n but change the meaning of ``__eq__()`` such that the hash value\n returned is no longer appropriate (e.g. by switching to a value-\n based concept of equality instead of the default identity based\n equality) can explicitly flag themselves as being unhashable by\n setting ``__hash__ = None`` in the class definition. Doing so means\n that not only will instances of the class raise an appropriate\n ``TypeError`` when a program attempts to retrieve their hash value,\n but they will also be correctly identified as unhashable when\n checking ``isinstance(obj, collections.Hashable)`` (unlike classes\n which define their own ``__hash__()`` to explicitly raise\n ``TypeError``).\n\n If a class that overrides ``__eq__()`` needs to retain the\n implementation of ``__hash__()`` from a parent class, the\n interpreter must be told this explicitly by setting ``__hash__ =\n .__hash__``. Otherwise the inheritance of\n ``__hash__()`` will be blocked, just as if ``__hash__`` had been\n explicitly set to ``None``.\n\nobject.__bool__(self)\n\n Called to implement truth value testing and the built-in operation\n ``bool()``; should return ``False`` or ``True``. When this method\n is not defined, ``__len__()`` is called, if it is defined, and the\n object is considered true if its result is nonzero. If a class\n defines neither ``__len__()`` nor ``__bool__()``, all its instances\n are considered true.\n\n\nCustomizing attribute access\n============================\n\nThe following methods can be defined to customize the meaning of\nattribute access (use of, assignment to, or deletion of ``x.name``)\nfor class instances.\n\nobject.__getattr__(self, name)\n\n Called when an attribute lookup has not found the attribute in the\n usual places (i.e. it is not an instance attribute nor is it found\n in the class tree for ``self``). ``name`` is the attribute name.\n This method should return the (computed) attribute value or raise\n an ``AttributeError`` exception.\n\n Note that if the attribute is found through the normal mechanism,\n ``__getattr__()`` is not called. (This is an intentional asymmetry\n between ``__getattr__()`` and ``__setattr__()``.) This is done both\n for efficiency reasons and because otherwise ``__getattr__()``\n would have no way to access other attributes of the instance. Note\n that at least for instance variables, you can fake total control by\n not inserting any values in the instance attribute dictionary (but\n instead inserting them in another object). See the\n ``__getattribute__()`` method below for a way to actually get total\n control over attribute access.\n\nobject.__getattribute__(self, name)\n\n Called unconditionally to implement attribute accesses for\n instances of the class. If the class also defines\n ``__getattr__()``, the latter will not be called unless\n ``__getattribute__()`` either calls it explicitly or raises an\n ``AttributeError``. This method should return the (computed)\n attribute value or raise an ``AttributeError`` exception. In order\n to avoid infinite recursion in this method, its implementation\n should always call the base class method with the same name to\n access any attributes it needs, for example,\n ``object.__getattribute__(self, name)``.\n\n Note: This method may still be bypassed when looking up special methods\n as the result of implicit invocation via language syntax or\n built-in functions. See *Special method lookup*.\n\nobject.__setattr__(self, name, value)\n\n Called when an attribute assignment is attempted. This is called\n instead of the normal mechanism (i.e. store the value in the\n instance dictionary). *name* is the attribute name, *value* is the\n value to be assigned to it.\n\n If ``__setattr__()`` wants to assign to an instance attribute, it\n should call the base class method with the same name, for example,\n ``object.__setattr__(self, name, value)``.\n\nobject.__delattr__(self, name)\n\n Like ``__setattr__()`` but for attribute deletion instead of\n assignment. This should only be implemented if ``del obj.name`` is\n meaningful for the object.\n\nobject.__dir__(self)\n\n Called when ``dir()`` is called on the object. A list must be\n returned.\n\n\nImplementing Descriptors\n------------------------\n\nThe following methods only apply when an instance of the class\ncontaining the method (a so-called *descriptor* class) appears in the\nclass dictionary of another class, known as the *owner* class. In the\nexamples below, "the attribute" refers to the attribute whose name is\nthe key of the property in the owner class\' ``__dict__``.\n\nobject.__get__(self, instance, owner)\n\n Called to get the attribute of the owner class (class attribute\n access) or of an instance of that class (instance attribute\n access). *owner* is always the owner class, while *instance* is the\n instance that the attribute was accessed through, or ``None`` when\n the attribute is accessed through the *owner*. This method should\n return the (computed) attribute value or raise an\n ``AttributeError`` exception.\n\nobject.__set__(self, instance, value)\n\n Called to set the attribute on an instance *instance* of the owner\n class to a new value, *value*.\n\nobject.__delete__(self, instance)\n\n Called to delete the attribute on an instance *instance* of the\n owner class.\n\n\nInvoking Descriptors\n--------------------\n\nIn general, a descriptor is an object attribute with "binding\nbehavior", one whose attribute access has been overridden by methods\nin the descriptor protocol: ``__get__()``, ``__set__()``, and\n``__delete__()``. If any of those methods are defined for an object,\nit is said to be a descriptor.\n\nThe default behavior for attribute access is to get, set, or delete\nthe attribute from an object\'s dictionary. For instance, ``a.x`` has a\nlookup chain starting with ``a.__dict__[\'x\']``, then\n``type(a).__dict__[\'x\']``, and continuing through the base classes of\n``type(a)`` excluding metaclasses.\n\nHowever, if the looked-up value is an object defining one of the\ndescriptor methods, then Python may override the default behavior and\ninvoke the descriptor method instead. Where this occurs in the\nprecedence chain depends on which descriptor methods were defined and\nhow they were called.\n\nThe starting point for descriptor invocation is a binding, ``a.x``.\nHow the arguments are assembled depends on ``a``:\n\nDirect Call\n The simplest and least common call is when user code directly\n invokes a descriptor method: ``x.__get__(a)``.\n\nInstance Binding\n If binding to an object instance, ``a.x`` is transformed into the\n call: ``type(a).__dict__[\'x\'].__get__(a, type(a))``.\n\nClass Binding\n If binding to a class, ``A.x`` is transformed into the call:\n ``A.__dict__[\'x\'].__get__(None, A)``.\n\nSuper Binding\n If ``a`` is an instance of ``super``, then the binding ``super(B,\n obj).m()`` searches ``obj.__class__.__mro__`` for the base class\n ``A`` immediately preceding ``B`` and then invokes the descriptor\n with the call: ``A.__dict__[\'m\'].__get__(obj, A)``.\n\nFor instance bindings, the precedence of descriptor invocation depends\non the which descriptor methods are defined. A descriptor can define\nany combination of ``__get__()``, ``__set__()`` and ``__delete__()``.\nIf it does not define ``__get__()``, then accessing the attribute will\nreturn the descriptor object itself unless there is a value in the\nobject\'s instance dictionary. If the descriptor defines ``__set__()``\nand/or ``__delete__()``, it is a data descriptor; if it defines\nneither, it is a non-data descriptor. Normally, data descriptors\ndefine both ``__get__()`` and ``__set__()``, while non-data\ndescriptors have just the ``__get__()`` method. Data descriptors with\n``__set__()`` and ``__get__()`` defined always override a redefinition\nin an instance dictionary. In contrast, non-data descriptors can be\noverridden by instances.\n\nPython methods (including ``staticmethod()`` and ``classmethod()``)\nare implemented as non-data descriptors. Accordingly, instances can\nredefine and override methods. This allows individual instances to\nacquire behaviors that differ from other instances of the same class.\n\nThe ``property()`` function is implemented as a data descriptor.\nAccordingly, instances cannot override the behavior of a property.\n\n\n__slots__\n---------\n\nBy default, instances of classes have a dictionary for attribute\nstorage. This wastes space for objects having very few instance\nvariables. The space consumption can become acute when creating large\nnumbers of instances.\n\nThe default can be overridden by defining *__slots__* in a class\ndefinition. The *__slots__* declaration takes a sequence of instance\nvariables and reserves just enough space in each instance to hold a\nvalue for each variable. Space is saved because *__dict__* is not\ncreated for each instance.\n\nobject.__slots__\n\n This class variable can be assigned a string, iterable, or sequence\n of strings with variable names used by instances. If defined in a\n class, *__slots__* reserves space for the declared variables and\n prevents the automatic creation of *__dict__* and *__weakref__* for\n each instance.\n\n\nNotes on using *__slots__*\n~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n* When inheriting from a class without *__slots__*, the *__dict__*\n attribute of that class will always be accessible, so a *__slots__*\n definition in the subclass is meaningless.\n\n* Without a *__dict__* variable, instances cannot be assigned new\n variables not listed in the *__slots__* definition. Attempts to\n assign to an unlisted variable name raises ``AttributeError``. If\n dynamic assignment of new variables is desired, then add\n ``\'__dict__\'`` to the sequence of strings in the *__slots__*\n declaration.\n\n* Without a *__weakref__* variable for each instance, classes defining\n *__slots__* do not support weak references to its instances. If weak\n reference support is needed, then add ``\'__weakref__\'`` to the\n sequence of strings in the *__slots__* declaration.\n\n* *__slots__* are implemented at the class level by creating\n descriptors (*Implementing Descriptors*) for each variable name. As\n a result, class attributes cannot be used to set default values for\n instance variables defined by *__slots__*; otherwise, the class\n attribute would overwrite the descriptor assignment.\n\n* The action of a *__slots__* declaration is limited to the class\n where it is defined. As a result, subclasses will have a *__dict__*\n unless they also define *__slots__* (which must only contain names\n of any *additional* slots).\n\n* If a class defines a slot also defined in a base class, the instance\n variable defined by the base class slot is inaccessible (except by\n retrieving its descriptor directly from the base class). This\n renders the meaning of the program undefined. In the future, a\n check may be added to prevent this.\n\n* Nonempty *__slots__* does not work for classes derived from\n "variable-length" built-in types such as ``int``, ``str`` and\n ``tuple``.\n\n* Any non-string iterable may be assigned to *__slots__*. Mappings may\n also be used; however, in the future, special meaning may be\n assigned to the values corresponding to each key.\n\n* *__class__* assignment works only if both classes have the same\n *__slots__*.\n\n\nCustomizing class creation\n==========================\n\nBy default, classes are constructed using ``type()``. A class\ndefinition is read into a separate namespace and the value of class\nname is bound to the result of ``type(name, bases, dict)``.\n\nWhen the class definition is read, if a callable ``metaclass`` keyword\nargument is passed after the bases in the class definition, the\ncallable given will be called instead of ``type()``. If other keyword\narguments are passed, they will also be passed to the metaclass. This\nallows classes or functions to be written which monitor or alter the\nclass creation process:\n\n* Modifying the class dictionary prior to the class being created.\n\n* Returning an instance of another class -- essentially performing the\n role of a factory function.\n\nThese steps will have to be performed in the metaclass\'s ``__new__()``\nmethod -- ``type.__new__()`` can then be called from this method to\ncreate a class with different properties. This example adds a new\nelement to the class dictionary before creating the class:\n\n class metacls(type):\n def __new__(mcs, name, bases, dict):\n dict[\'foo\'] = \'metacls was here\'\n return type.__new__(mcs, name, bases, dict)\n\nYou can of course also override other class methods (or add new\nmethods); for example defining a custom ``__call__()`` method in the\nmetaclass allows custom behavior when the class is called, e.g. not\nalways creating a new instance.\n\nIf the metaclass has a ``__prepare__()`` attribute (usually\nimplemented as a class or static method), it is called before the\nclass body is evaluated with the name of the class and a tuple of its\nbases for arguments. It should return an object that supports the\nmapping interface that will be used to store the namespace of the\nclass. The default is a plain dictionary. This could be used, for\nexample, to keep track of the order that class attributes are declared\nin by returning an ordered dictionary.\n\nThe appropriate metaclass is determined by the following precedence\nrules:\n\n* If the ``metaclass`` keyword argument is passed with the bases, it\n is used.\n\n* Otherwise, if there is at least one base class, its metaclass is\n used.\n\n* Otherwise, the default metaclass (``type``) is used.\n\nThe potential uses for metaclasses are boundless. Some ideas that have\nbeen explored including logging, interface checking, automatic\ndelegation, automatic property creation, proxies, frameworks, and\nautomatic resource locking/synchronization.\n\nHere is an example of a metaclass that uses an\n``collections.OrderedDict`` to remember the order that class members\nwere defined:\n\n class OrderedClass(type):\n\n @classmethod\n def __prepare__(metacls, name, bases, **kwds):\n return collections.OrderedDict()\n\n def __new__(cls, name, bases, classdict):\n result = type.__new__(cls, name, bases, dict(classdict))\n result.members = tuple(classdict)\n return result\n\n class A(metaclass=OrderedClass):\n def one(self): pass\n def two(self): pass\n def three(self): pass\n def four(self): pass\n\n >>> A.members\n (\'__module__\', \'one\', \'two\', \'three\', \'four\')\n\nWhen the class definition for *A* gets executed, the process begins\nwith calling the metaclass\'s ``__prepare__()`` method which returns an\nempty ``collections.OrderedDict``. That mapping records the methods\nand attributes of *A* as they are defined within the body of the class\nstatement. Once those definitions are executed, the ordered dictionary\nis fully populated and the metaclass\'s ``__new__()`` method gets\ninvoked. That method builds the new type and it saves the ordered\ndictionary keys in an attribute called *members*.\n\n\nCustomizing instance and subclass checks\n========================================\n\nThe following methods are used to override the default behavior of the\n``isinstance()`` and ``issubclass()`` built-in functions.\n\nIn particular, the metaclass ``abc.ABCMeta`` implements these methods\nin order to allow the addition of Abstract Base Classes (ABCs) as\n"virtual base classes" to any class or type (including built-in\ntypes), including other ABCs.\n\nclass.__instancecheck__(self, instance)\n\n Return true if *instance* should be considered a (direct or\n indirect) instance of *class*. If defined, called to implement\n ``isinstance(instance, class)``.\n\nclass.__subclasscheck__(self, subclass)\n\n Return true if *subclass* should be considered a (direct or\n indirect) subclass of *class*. If defined, called to implement\n ``issubclass(subclass, class)``.\n\nNote that these methods are looked up on the type (metaclass) of a\nclass. They cannot be defined as class methods in the actual class.\nThis is consistent with the lookup of special methods that are called\non instances, only in this case the instance is itself a class.\n\nSee also:\n\n **PEP 3119** - Introducing Abstract Base Classes\n Includes the specification for customizing ``isinstance()`` and\n ``issubclass()`` behavior through ``__instancecheck__()`` and\n ``__subclasscheck__()``, with motivation for this functionality\n in the context of adding Abstract Base Classes (see the ``abc``\n module) to the language.\n\n\nEmulating callable objects\n==========================\n\nobject.__call__(self[, args...])\n\n Called when the instance is "called" as a function; if this method\n is defined, ``x(arg1, arg2, ...)`` is a shorthand for\n ``x.__call__(arg1, arg2, ...)``.\n\n\nEmulating container types\n=========================\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``get()``,\n``clear()``, ``setdefault()``, ``pop()``, ``popitem()``, ``copy()``,\nand ``update()`` behaving similar to those for Python\'s standard\ndictionary objects. The ``collections`` module provides a\n``MutableMapping`` abstract base class to help create those methods\nfrom a base set of ``__getitem__()``, ``__setitem__()``,\n``__delitem__()``, and ``keys()``. Mutable sequences should provide\nmethods ``append()``, ``count()``, ``index()``, ``extend()``,\n``insert()``, ``pop()``, ``remove()``, ``reverse()`` and ``sort()``,\nlike Python standard list objects. Finally, sequence types should\nimplement addition (meaning concatenation) and multiplication (meaning\nrepetition) by defining the methods ``__add__()``, ``__radd__()``,\n``__iadd__()``, ``__mul__()``, ``__rmul__()`` and ``__imul__()``\ndescribed below; they should not define other numerical operators. It\nis recommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should search the mapping\'s keys; for\nsequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``keys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn\'t define a ``__bool__()`` method and whose ``__len__()``\n method returns zero is considered to be false in a Boolean context.\n\nNote: Slicing is done exclusively with the following three methods. A\n call like\n\n a[1:2] = b\n\n is translated to\n\n a[slice(1, 2, None)] = b\n\n and so forth. Missing slice items are always filled in with\n ``None``.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``keys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don\'t define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n\n\nEmulating numeric types\n=======================\n\nThe following methods can be defined to emulate numeric objects.\nMethods corresponding to operations that are not supported by the\nparticular kind of number implemented (e.g., bitwise operations for\nnon-integral numbers) should be left undefined.\n\nobject.__add__(self, other)\nobject.__sub__(self, other)\nobject.__mul__(self, other)\nobject.__truediv__(self, other)\nobject.__floordiv__(self, other)\nobject.__mod__(self, other)\nobject.__divmod__(self, other)\nobject.__pow__(self, other[, modulo])\nobject.__lshift__(self, other)\nobject.__rshift__(self, other)\nobject.__and__(self, other)\nobject.__xor__(self, other)\nobject.__or__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``). For instance, to evaluate the expression ``x + y``, where\n *x* is an instance of a class that has an ``__add__()`` method,\n ``x.__add__(y)`` is called. The ``__divmod__()`` method should be\n the equivalent to using ``__floordiv__()`` and ``__mod__()``; it\n should not be related to ``__truediv__()``. Note that\n ``__pow__()`` should be defined to accept an optional third\n argument if the ternary version of the built-in ``pow()`` function\n is to be supported.\n\n If one of those methods does not support the operation with the\n supplied arguments, it should return ``NotImplemented``.\n\nobject.__radd__(self, other)\nobject.__rsub__(self, other)\nobject.__rmul__(self, other)\nobject.__rtruediv__(self, other)\nobject.__rfloordiv__(self, other)\nobject.__rmod__(self, other)\nobject.__rdivmod__(self, other)\nobject.__rpow__(self, other)\nobject.__rlshift__(self, other)\nobject.__rrshift__(self, other)\nobject.__rand__(self, other)\nobject.__rxor__(self, other)\nobject.__ror__(self, other)\n\n These methods are called to implement the binary arithmetic\n operations (``+``, ``-``, ``*``, ``/``, ``//``, ``%``,\n ``divmod()``, ``pow()``, ``**``, ``<<``, ``>>``, ``&``, ``^``,\n ``|``) with reflected (swapped) operands. These functions are only\n called if the left operand does not support the corresponding\n operation and the operands are of different types. [2] For\n instance, to evaluate the expression ``x - y``, where *y* is an\n instance of a class that has an ``__rsub__()`` method,\n ``y.__rsub__(x)`` is called if ``x.__sub__(y)`` returns\n *NotImplemented*.\n\n Note that ternary ``pow()`` will not try calling ``__rpow__()``\n (the coercion rules would become too complicated).\n\n Note: If the right operand\'s type is a subclass of the left operand\'s\n type and that subclass provides the reflected method for the\n operation, this method will be called before the left operand\'s\n non-reflected method. This behavior allows subclasses to\n override their ancestors\' operations.\n\nobject.__iadd__(self, other)\nobject.__isub__(self, other)\nobject.__imul__(self, other)\nobject.__itruediv__(self, other)\nobject.__ifloordiv__(self, other)\nobject.__imod__(self, other)\nobject.__ipow__(self, other[, modulo])\nobject.__ilshift__(self, other)\nobject.__irshift__(self, other)\nobject.__iand__(self, other)\nobject.__ixor__(self, other)\nobject.__ior__(self, other)\n\n These methods are called to implement the augmented arithmetic\n assignments (``+=``, ``-=``, ``*=``, ``/=``, ``//=``, ``%=``,\n ``**=``, ``<<=``, ``>>=``, ``&=``, ``^=``, ``|=``). These methods\n should attempt to do the operation in-place (modifying *self*) and\n return the result (which could be, but does not have to be,\n *self*). If a specific method is not defined, the augmented\n assignment falls back to the normal methods. For instance, to\n execute the statement ``x += y``, where *x* is an instance of a\n class that has an ``__iadd__()`` method, ``x.__iadd__(y)`` is\n called. If *x* is an instance of a class that does not define a\n ``__iadd__()`` method, ``x.__add__(y)`` and ``y.__radd__(x)`` are\n considered, as with the evaluation of ``x + y``.\n\nobject.__neg__(self)\nobject.__pos__(self)\nobject.__abs__(self)\nobject.__invert__(self)\n\n Called to implement the unary arithmetic operations (``-``, ``+``,\n ``abs()`` and ``~``).\n\nobject.__complex__(self)\nobject.__int__(self)\nobject.__float__(self)\nobject.__round__(self[, n])\n\n Called to implement the built-in functions ``complex()``,\n ``int()``, ``float()`` and ``round()``. Should return a value of\n the appropriate type.\n\nobject.__index__(self)\n\n Called to implement ``operator.index()``. Also called whenever\n Python needs an integer object (such as in slicing, or in the\n built-in ``bin()``, ``hex()`` and ``oct()`` functions). Must return\n an integer.\n\n\nWith Statement Context Managers\n===============================\n\nA *context manager* is an object that defines the runtime context to\nbe established when executing a ``with`` statement. The context\nmanager handles the entry into, and the exit from, the desired runtime\ncontext for the execution of the block of code. Context managers are\nnormally invoked using the ``with`` statement (described in section\n*The with statement*), but can also be used by directly invoking their\nmethods.\n\nTypical uses of context managers include saving and restoring various\nkinds of global state, locking and unlocking resources, closing opened\nfiles, etc.\n\nFor more information on context managers, see *Context Manager Types*.\n\nobject.__enter__(self)\n\n Enter the runtime context related to this object. The ``with``\n statement will bind this method\'s return value to the target(s)\n specified in the ``as`` clause of the statement, if any.\n\nobject.__exit__(self, exc_type, exc_value, traceback)\n\n Exit the runtime context related to this object. The parameters\n describe the exception that caused the context to be exited. If the\n context was exited without an exception, all three arguments will\n be ``None``.\n\n If an exception is supplied, and the method wishes to suppress the\n exception (i.e., prevent it from being propagated), it should\n return a true value. Otherwise, the exception will be processed\n normally upon exit from this method.\n\n Note that ``__exit__()`` methods should not reraise the passed-in\n exception; this is the caller\'s responsibility.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n\n\nSpecial method lookup\n=====================\n\nFor custom classes, implicit invocations of special methods are only\nguaranteed to work correctly if defined on an object\'s type, not in\nthe object\'s instance dictionary. That behaviour is the reason why\nthe following code raises an exception:\n\n >>> class C(object):\n ... pass\n ...\n >>> c = C()\n >>> c.__len__ = lambda: 5\n >>> len(c)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: object of type \'C\' has no len()\n\nThe rationale behind this behaviour lies with a number of special\nmethods such as ``__hash__()`` and ``__repr__()`` that are implemented\nby all objects, including type objects. If the implicit lookup of\nthese methods used the conventional lookup process, they would fail\nwhen invoked on the type object itself:\n\n >>> 1 .__hash__() == hash(1)\n True\n >>> int.__hash__() == hash(int)\n Traceback (most recent call last):\n File "", line 1, in \n TypeError: descriptor \'__hash__\' of \'int\' object needs an argument\n\nIncorrectly attempting to invoke an unbound method of a class in this\nway is sometimes referred to as \'metaclass confusion\', and is avoided\nby bypassing the instance when looking up special methods:\n\n >>> type(1).__hash__(1) == hash(1)\n True\n >>> type(int).__hash__(int) == hash(int)\n True\n\nIn addition to bypassing any instance attributes in the interest of\ncorrectness, implicit special method lookup generally also bypasses\nthe ``__getattribute__()`` method even of the object\'s metaclass:\n\n >>> class Meta(type):\n ... def __getattribute__(*args):\n ... print("Metaclass getattribute invoked")\n ... return type.__getattribute__(*args)\n ...\n >>> class C(object, metaclass=Meta):\n ... def __len__(self):\n ... return 10\n ... def __getattribute__(*args):\n ... print("Class getattribute invoked")\n ... return object.__getattribute__(*args)\n ...\n >>> c = C()\n >>> c.__len__() # Explicit lookup via instance\n Class getattribute invoked\n 10\n >>> type(c).__len__(c) # Explicit lookup via type\n Metaclass getattribute invoked\n 10\n >>> len(c) # Implicit lookup\n 10\n\nBypassing the ``__getattribute__()`` machinery in this fashion\nprovides significant scope for speed optimisations within the\ninterpreter, at the cost of some flexibility in the handling of\nspecial methods (the special method *must* be set on the class object\nitself in order to be consistently invoked by the interpreter).\n\n-[ Footnotes ]-\n\n[1] It *is* possible in some cases to change an object\'s type, under\n certain controlled conditions. It generally isn\'t a good idea\n though, since it can lead to some very strange behaviour if it is\n handled incorrectly.\n\n[2] For operands of the same type, it is assumed that if the non-\n reflected method (such as ``__add__()``) fails the operation is\n not supported, which is why the reflected method is not called.\n',
- 'string-methods': '\nString Methods\n**************\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding=sys.getdefaultencoding(), errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is the current default string encoding. *errors* may be\n given to set a different error handling scheme. The default for\n *errors* is ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n Changed in version 3.1: Added support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters include digit characters, and all characters that that\n can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when ``repr()`` is\n invoked on a string. It has no bearing on the handling of strings\n written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A ``TypeError`` will be raised if there are\n any non-string values in *seq*, including ``bytes`` objects. The\n separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or ``None``. Unmapped\n characters are left untouched. Characters mapped to ``None`` are\n deleted.\n\n You can use ``str.maketrans()`` to create a translation map from\n character-to-character mappings in different formats.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n',
+ 'string-methods': '\nString Methods\n**************\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding=sys.getdefaultencoding(), errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is the current default string encoding. *errors* may be\n given to set a different error handling scheme. The default for\n *errors* is ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters include digit characters, and all characters that that\n can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when ``repr()`` is\n invoked on a string. It has no bearing on the handling of strings\n written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A ``TypeError`` will be raised if there are\n any non-string values in *seq*, including ``bytes`` objects. The\n separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or ``None``. Unmapped\n characters are left untouched. Characters mapped to ``None`` are\n deleted.\n\n You can use ``str.maketrans()`` to create a translation map from\n character-to-character mappings in different formats.\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n',
'strings': '\nString and Bytes literals\n*************************\n\nString literals are described by the following lexical definitions:\n\n stringliteral ::= [stringprefix](shortstring | longstring)\n stringprefix ::= "r" | "R"\n shortstring ::= "\'" shortstringitem* "\'" | \'"\' shortstringitem* \'"\'\n longstring ::= "\'\'\'" longstringitem* "\'\'\'" | \'"""\' longstringitem* \'"""\'\n shortstringitem ::= shortstringchar | stringescapeseq\n longstringitem ::= longstringchar | stringescapeseq\n shortstringchar ::= \n longstringchar ::= \n stringescapeseq ::= "\\" \n\n bytesliteral ::= bytesprefix(shortbytes | longbytes)\n bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR"\n shortbytes ::= "\'" shortbytesitem* "\'" | \'"\' shortbytesitem* \'"\'\n longbytes ::= "\'\'\'" longbytesitem* "\'\'\'" | \'"""\' longbytesitem* \'"""\'\n shortbytesitem ::= shortbyteschar | bytesescapeseq\n longbytesitem ::= longbyteschar | bytesescapeseq\n shortbyteschar ::= \n longbyteschar ::= \n bytesescapeseq ::= "\\" \n\nOne syntactic restriction not indicated by these productions is that\nwhitespace is not allowed between the ``stringprefix`` or\n``bytesprefix`` and the rest of the literal. The source character set\nis defined by the encoding declaration; it is UTF-8 if no encoding\ndeclaration is given in the source file; see section *Encoding\ndeclarations*.\n\nIn plain English: Both types of literals can be enclosed in matching\nsingle quotes (``\'``) or double quotes (``"``). They can also be\nenclosed in matching groups of three single or double quotes (these\nare generally referred to as *triple-quoted strings*). The backslash\n(``\\``) character is used to escape characters that otherwise have a\nspecial meaning, such as newline, backslash itself, or the quote\ncharacter.\n\nBytes literals are always prefixed with ``\'b\'`` or ``\'B\'``; they\nproduce an instance of the ``bytes`` type instead of the ``str`` type.\nThey may only contain ASCII characters; bytes with a numeric value of\n128 or greater must be expressed with escapes.\n\nBoth string and bytes literals may optionally be prefixed with a\nletter ``\'r\'`` or ``\'R\'``; such strings are called *raw strings* and\ntreat backslashes as literal characters. As a result, in string\nliterals, ``\'\\U\'`` and ``\'\\u\'`` escapes in raw strings are not treated\nspecially.\n\nIn triple-quoted strings, unescaped newlines and quotes are allowed\n(and are retained), except that three unescaped quotes in a row\nterminate the string. (A "quote" is the character used to open the\nstring, i.e. either ``\'`` or ``"``.)\n\nUnless an ``\'r\'`` or ``\'R\'`` prefix is present, escape sequences in\nstrings are interpreted according to rules similar to those used by\nStandard C. The recognized escape sequences are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\newline`` | Backslash and newline ignored | |\n+-------------------+-----------------------------------+---------+\n| ``\\\\`` | Backslash (``\\``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\\'`` | Single quote (``\'``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\"`` | Double quote (``"``) | |\n+-------------------+-----------------------------------+---------+\n| ``\\a`` | ASCII Bell (BEL) | |\n+-------------------+-----------------------------------+---------+\n| ``\\b`` | ASCII Backspace (BS) | |\n+-------------------+-----------------------------------+---------+\n| ``\\f`` | ASCII Formfeed (FF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\n`` | ASCII Linefeed (LF) | |\n+-------------------+-----------------------------------+---------+\n| ``\\r`` | ASCII Carriage Return (CR) | |\n+-------------------+-----------------------------------+---------+\n| ``\\t`` | ASCII Horizontal Tab (TAB) | |\n+-------------------+-----------------------------------+---------+\n| ``\\v`` | ASCII Vertical Tab (VT) | |\n+-------------------+-----------------------------------+---------+\n| ``\\ooo`` | Character with octal value *ooo* | (1,3) |\n+-------------------+-----------------------------------+---------+\n| ``\\xhh`` | Character with hex value *hh* | (2,3) |\n+-------------------+-----------------------------------+---------+\n\nEscape sequences only recognized in string literals are:\n\n+-------------------+-----------------------------------+---------+\n| Escape Sequence | Meaning | Notes |\n+===================+===================================+=========+\n| ``\\N{name}`` | Character named *name* in the | |\n| | Unicode database | |\n+-------------------+-----------------------------------+---------+\n| ``\\uxxxx`` | Character with 16-bit hex value | (4) |\n| | *xxxx* | |\n+-------------------+-----------------------------------+---------+\n| ``\\Uxxxxxxxx`` | Character with 32-bit hex value | (5) |\n| | *xxxxxxxx* | |\n+-------------------+-----------------------------------+---------+\n\nNotes:\n\n1. As in Standard C, up to three octal digits are accepted.\n\n2. Unlike in Standard C, exactly two hex digits are required.\n\n3. In a bytes literal, hexadecimal and octal escapes denote the byte\n with the given value. In a string literal, these escapes denote a\n Unicode character with the given value.\n\n4. Individual code units which form parts of a surrogate pair can be\n encoded using this escape sequence. Exactly four hex digits are\n required.\n\n5. Any Unicode character can be encoded this way, but characters\n outside the Basic Multilingual Plane (BMP) will be encoded using a\n surrogate pair if Python is compiled to use 16-bit code units (the\n default). Exactly eight hex digits are required.\n\nUnlike Standard C, all unrecognized escape sequences are left in the\nstring unchanged, i.e., *the backslash is left in the string*. (This\nbehavior is useful when debugging: if an escape sequence is mistyped,\nthe resulting output is more easily recognized as broken.) It is also\nimportant to note that the escape sequences only recognized in string\nliterals fall into the category of unrecognized escapes for bytes\nliterals.\n\nEven in a raw string, string quotes can be escaped with a backslash,\nbut the backslash remains in the string; for example, ``r"\\""`` is a\nvalid string literal consisting of two characters: a backslash and a\ndouble quote; ``r"\\"`` is not a valid string literal (even a raw\nstring cannot end in an odd number of backslashes). Specifically, *a\nraw string cannot end in a single backslash* (since the backslash\nwould escape the following quote character). Note also that a single\nbackslash followed by a newline is interpreted as those two characters\nas part of the string, *not* as a line continuation.\n',
'subscriptions': '\nSubscriptions\n*************\n\nA subscription selects an item of a sequence (string, tuple or list)\nor mapping (dictionary) object:\n\n subscription ::= primary "[" expression_list "]"\n\nThe primary must evaluate to an object that supports subscription,\ne.g. a list or dictionary. User-defined objects can support\nsubscription by defining a ``__getitem__()`` method.\n\nFor built-in objects, there are two types of objects that support\nsubscription:\n\nIf the primary is a mapping, the expression list must evaluate to an\nobject whose value is one of the keys of the mapping, and the\nsubscription selects the value in the mapping that corresponds to that\nkey. (The expression list is a tuple except if it has exactly one\nitem.)\n\nIf the primary is a sequence, the expression (list) must evaluate to\nan integer. If this value is negative, the length of the sequence is\nadded to it (so that, e.g., ``x[-1]`` selects the last item of ``x``.)\nThe resulting value must be a nonnegative integer less than the number\nof items in the sequence, and the subscription selects the item whose\nindex is that value (counting from zero).\n\nA string\'s items are characters. A character is not a separate data\ntype but a string of exactly one character.\n',
'truth': "\nTruth Value Testing\n*******************\n\nAny object can be tested for truth value, for use in an ``if`` or\n``while`` condition or as operand of the Boolean operations below. The\nfollowing values are considered false:\n\n* ``None``\n\n* ``False``\n\n* zero of any numeric type, for example, ``0``, ``0.0``, ``0j``.\n\n* any empty sequence, for example, ``''``, ``()``, ``[]``.\n\n* any empty mapping, for example, ``{}``.\n\n* instances of user-defined classes, if the class defines a\n ``__bool__()`` or ``__len__()`` method, when that method returns the\n integer zero or ``bool`` value ``False``. [1]\n\nAll other values are considered true --- so objects of many types are\nalways true.\n\nOperations and built-in functions that have a Boolean result always\nreturn ``0`` or ``False`` for false and ``1`` or ``True`` for true,\nunless otherwise stated. (Important exception: the Boolean operations\n``or`` and ``and`` always return one of their operands.)\n",
'try': '\nThe ``try`` statement\n*********************\n\nThe ``try`` statement specifies exception handlers and/or cleanup code\nfor a group of statements:\n\n try_stmt ::= try1_stmt | try2_stmt\n try1_stmt ::= "try" ":" suite\n ("except" [expression ["as" target]] ":" suite)+\n ["else" ":" suite]\n ["finally" ":" suite]\n try2_stmt ::= "try" ":" suite\n "finally" ":" suite\n\nThe ``except`` clause(s) specify one or more exception handlers. When\nno exception occurs in the ``try`` clause, no exception handler is\nexecuted. When an exception occurs in the ``try`` suite, a search for\nan exception handler is started. This search inspects the except\nclauses in turn until one is found that matches the exception. An\nexpression-less except clause, if present, must be last; it matches\nany exception. For an except clause with an expression, that\nexpression is evaluated, and the clause matches the exception if the\nresulting object is "compatible" with the exception. An object is\ncompatible with an exception if it is the class or a base class of the\nexception object or a tuple containing an item compatible with the\nexception.\n\nIf no except clause matches the exception, the search for an exception\nhandler continues in the surrounding code and on the invocation stack.\n[1]\n\nIf the evaluation of an expression in the header of an except clause\nraises an exception, the original search for a handler is canceled and\na search starts for the new exception in the surrounding code and on\nthe call stack (it is treated as if the entire ``try`` statement\nraised the exception).\n\nWhen a matching except clause is found, the exception is assigned to\nthe target specified after the ``as`` keyword in that except clause,\nif present, and the except clause\'s suite is executed. All except\nclauses must have an executable block. When the end of this block is\nreached, execution continues normally after the entire try statement.\n(This means that if two nested handlers exist for the same exception,\nand the exception occurs in the try clause of the inner handler, the\nouter handler will not handle the exception.)\n\nWhen an exception has been assigned using ``as target``, it is cleared\nat the end of the except clause. This is as if\n\n except E as N:\n foo\n\nwas translated to\n\n except E as N:\n try:\n foo\n finally:\n del N\n\nThis means the exception must be assigned to a different name to be\nable to refer to it after the except clause. Exceptions are cleared\nbecause with the traceback attached to them, they form a reference\ncycle with the stack frame, keeping all locals in that frame alive\nuntil the next garbage collection occurs.\n\nBefore an except clause\'s suite is executed, details about the\nexception are stored in the ``sys`` module and can be access via\n``sys.exc_info()``. ``sys.exc_info()`` returns a 3-tuple consisting\nof: ``exc_type``, the exception class; ``exc_value``, the exception\ninstance; ``exc_traceback``, a traceback object (see section *The\nstandard type hierarchy*) identifying the point in the program where\nthe exception occurred. ``sys.exc_info()`` values are restored to\ntheir previous values (before the call) when returning from a function\nthat handled an exception.\n\nThe optional ``else`` clause is executed if and when control flows off\nthe end of the ``try`` clause. [2] Exceptions in the ``else`` clause\nare not handled by the preceding ``except`` clauses.\n\nIf ``finally`` is present, it specifies a \'cleanup\' handler. The\n``try`` clause is executed, including any ``except`` and ``else``\nclauses. If an exception occurs in any of the clauses and is not\nhandled, the exception is temporarily saved. The ``finally`` clause is\nexecuted. If there is a saved exception, it is re-raised at the end\nof the ``finally`` clause. If the ``finally`` clause raises another\nexception or executes a ``return`` or ``break`` statement, the saved\nexception is lost. The exception information is not available to the\nprogram during execution of the ``finally`` clause.\n\nWhen a ``return``, ``break`` or ``continue`` statement is executed in\nthe ``try`` suite of a ``try``...``finally`` statement, the\n``finally`` clause is also executed \'on the way out.\' A ``continue``\nstatement is illegal in the ``finally`` clause. (The reason is a\nproblem with the current implementation --- this restriction may be\nlifted in the future).\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information on using the ``raise`` statement to\ngenerate exceptions may be found in section *The raise statement*.\n',
'types': '\nThe standard type hierarchy\n***************************\n\nBelow is a list of the types that are built into Python. Extension\nmodules (written in C, Java, or other languages, depending on the\nimplementation) can define additional types. Future versions of\nPython may add types to the type hierarchy (e.g., rational numbers,\nefficiently stored arrays of integers, etc.), although such additions\nwill often be provided via the standard library instead.\n\nSome of the type descriptions below contain a paragraph listing\n\'special attributes.\' These are attributes that provide access to the\nimplementation and are not intended for general use. Their definition\nmay change in the future.\n\nNone\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name ``None``.\n It is used to signify the absence of a value in many situations,\n e.g., it is returned from functions that don\'t explicitly return\n anything. Its truth value is false.\n\nNotImplemented\n This type has a single value. There is a single object with this\n value. This object is accessed through the built-in name\n ``NotImplemented``. Numeric methods and rich comparison methods may\n return this value if they do not implement the operation for the\n operands provided. (The interpreter will then try the reflected\n operation, or some other fallback, depending on the operator.) Its\n truth value is true.\n\nEllipsis\n This type has a single value. There is a single object with this\n value. This object is accessed through the literal ``...`` or the\n built-in name ``Ellipsis``. Its truth value is true.\n\n``numbers.Number``\n These are created by numeric literals and returned as results by\n arithmetic operators and arithmetic built-in functions. Numeric\n objects are immutable; once created their value never changes.\n Python numbers are of course strongly related to mathematical\n numbers, but subject to the limitations of numerical representation\n in computers.\n\n Python distinguishes between integers, floating point numbers, and\n complex numbers:\n\n ``numbers.Integral``\n These represent elements from the mathematical set of integers\n (positive and negative).\n\n There are two types of integers:\n\n Integers (``int``)\n\n These represent numbers in an unlimited range, subject to\n available (virtual) memory only. For the purpose of shift\n and mask operations, a binary representation is assumed, and\n negative numbers are represented in a variant of 2\'s\n complement which gives the illusion of an infinite string of\n sign bits extending to the left.\n\n Booleans (``bool``)\n These represent the truth values False and True. The two\n objects representing the values False and True are the only\n Boolean objects. The Boolean type is a subtype of the integer\n type, and Boolean values behave like the values 0 and 1,\n respectively, in almost all contexts, the exception being\n that when converted to a string, the strings ``"False"`` or\n ``"True"`` are returned, respectively.\n\n The rules for integer representation are intended to give the\n most meaningful interpretation of shift and mask operations\n involving negative integers.\n\n ``numbers.Real`` (``float``)\n These represent machine-level double precision floating point\n numbers. You are at the mercy of the underlying machine\n architecture (and C or Java implementation) for the accepted\n range and handling of overflow. Python does not support single-\n precision floating point numbers; the savings in processor and\n memory usage that are usually the reason for using these is\n dwarfed by the overhead of using objects in Python, so there is\n no reason to complicate the language with two kinds of floating\n point numbers.\n\n ``numbers.Complex`` (``complex``)\n These represent complex numbers as a pair of machine-level\n double precision floating point numbers. The same caveats apply\n as for floating point numbers. The real and imaginary parts of a\n complex number ``z`` can be retrieved through the read-only\n attributes ``z.real`` and ``z.imag``.\n\nSequences\n These represent finite ordered sets indexed by non-negative\n numbers. The built-in function ``len()`` returns the number of\n items of a sequence. When the length of a sequence is *n*, the\n index set contains the numbers 0, 1, ..., *n*-1. Item *i* of\n sequence *a* is selected by ``a[i]``.\n\n Sequences also support slicing: ``a[i:j]`` selects all items with\n index *k* such that *i* ``<=`` *k* ``<`` *j*. When used as an\n expression, a slice is a sequence of the same type. This implies\n that the index set is renumbered so that it starts at 0.\n\n Some sequences also support "extended slicing" with a third "step"\n parameter: ``a[i:j:k]`` selects all items of *a* with index *x*\n where ``x = i + n*k``, *n* ``>=`` ``0`` and *i* ``<=`` *x* ``<``\n *j*.\n\n Sequences are distinguished according to their mutability:\n\n Immutable sequences\n An object of an immutable sequence type cannot change once it is\n created. (If the object contains references to other objects,\n these other objects may be mutable and may be changed; however,\n the collection of objects directly referenced by an immutable\n object cannot change.)\n\n The following types are immutable sequences:\n\n Strings\n The items of a string object are Unicode code units. A\n Unicode code unit is represented by a string object of one\n item and can hold either a 16-bit or 32-bit value\n representing a Unicode ordinal (the maximum value for the\n ordinal is given in ``sys.maxunicode``, and depends on how\n Python is configured at compile time). Surrogate pairs may\n be present in the Unicode object, and will be reported as two\n separate items. The built-in functions ``chr()`` and\n ``ord()`` convert between code units and nonnegative integers\n representing the Unicode ordinals as defined in the Unicode\n Standard 3.0. Conversion from and to other encodings are\n possible through the string method ``encode()``.\n\n Tuples\n The items of a tuple are arbitrary Python objects. Tuples of\n two or more items are formed by comma-separated lists of\n expressions. A tuple of one item (a \'singleton\') can be\n formed by affixing a comma to an expression (an expression by\n itself does not create a tuple, since parentheses must be\n usable for grouping of expressions). An empty tuple can be\n formed by an empty pair of parentheses.\n\n Bytes\n A bytes object is an immutable array. The items are 8-bit\n bytes, represented by integers in the range 0 <= x < 256.\n Bytes literals (like ``b\'abc\'`` and the built-in function\n ``bytes()`` can be used to construct bytes objects. Also,\n bytes objects can be decoded to strings via the ``decode()``\n method.\n\n Mutable sequences\n Mutable sequences can be changed after they are created. The\n subscription and slicing notations can be used as the target of\n assignment and ``del`` (delete) statements.\n\n There are currently two intrinsic mutable sequence types:\n\n Lists\n The items of a list are arbitrary Python objects. Lists are\n formed by placing a comma-separated list of expressions in\n square brackets. (Note that there are no special cases needed\n to form lists of length 0 or 1.)\n\n Byte Arrays\n A bytearray object is a mutable array. They are created by\n the built-in ``bytearray()`` constructor. Aside from being\n mutable (and hence unhashable), byte arrays otherwise provide\n the same interface and functionality as immutable bytes\n objects.\n\n The extension module ``array`` provides an additional example of\n a mutable sequence type, as does the ``collections`` module.\n\nSet types\n These represent unordered, finite sets of unique, immutable\n objects. As such, they cannot be indexed by any subscript. However,\n they can be iterated over, and the built-in function ``len()``\n returns the number of items in a set. Common uses for sets are fast\n membership testing, removing duplicates from a sequence, and\n computing mathematical operations such as intersection, union,\n difference, and symmetric difference.\n\n For set elements, the same immutability rules apply as for\n dictionary keys. Note that numeric types obey the normal rules for\n numeric comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``), only one of them can be contained in a set.\n\n There are currently two intrinsic set types:\n\n Sets\n These represent a mutable set. They are created by the built-in\n ``set()`` constructor and can be modified afterwards by several\n methods, such as ``add()``.\n\n Frozen sets\n These represent an immutable set. They are created by the\n built-in ``frozenset()`` constructor. As a frozenset is\n immutable and *hashable*, it can be used again as an element of\n another set, or as a dictionary key.\n\nMappings\n These represent finite sets of objects indexed by arbitrary index\n sets. The subscript notation ``a[k]`` selects the item indexed by\n ``k`` from the mapping ``a``; this can be used in expressions and\n as the target of assignments or ``del`` statements. The built-in\n function ``len()`` returns the number of items in a mapping.\n\n There is currently a single intrinsic mapping type:\n\n Dictionaries\n These represent finite sets of objects indexed by nearly\n arbitrary values. The only types of values not acceptable as\n keys are values containing lists or dictionaries or other\n mutable types that are compared by value rather than by object\n identity, the reason being that the efficient implementation of\n dictionaries requires a key\'s hash value to remain constant.\n Numeric types used for keys obey the normal rules for numeric\n comparison: if two numbers compare equal (e.g., ``1`` and\n ``1.0``) then they can be used interchangeably to index the same\n dictionary entry.\n\n Dictionaries are mutable; they can be created by the ``{...}``\n notation (see section *Dictionary displays*).\n\n The extension modules ``dbm.ndbm`` and ``dbm.gnu`` provide\n additional examples of mapping types, as does the\n ``collections`` module.\n\nCallable types\n These are the types to which the function call operation (see\n section *Calls*) can be applied:\n\n User-defined functions\n A user-defined function object is created by a function\n definition (see section *Function definitions*). It should be\n called with an argument list containing the same number of items\n as the function\'s formal parameter list.\n\n Special attributes:\n\n +---------------------------+---------------------------------+-------------+\n | Attribute | Meaning | |\n +===========================+=================================+=============+\n | ``__doc__`` | The function\'s documentation | Writable |\n | | string, or ``None`` if | |\n | | unavailable | |\n +---------------------------+---------------------------------+-------------+\n | ``__name__`` | The function\'s name | Writable |\n +---------------------------+---------------------------------+-------------+\n | ``__module__`` | The name of the module the | Writable |\n | | function was defined in, or | |\n | | ``None`` if unavailable. | |\n +---------------------------+---------------------------------+-------------+\n | ``__defaults__`` | A tuple containing default | Writable |\n | | argument values for those | |\n | | arguments that have defaults, | |\n | | or ``None`` if no arguments | |\n | | have a default value | |\n +---------------------------+---------------------------------+-------------+\n | ``__code__`` | The code object representing | Writable |\n | | the compiled function body. | |\n +---------------------------+---------------------------------+-------------+\n | ``__globals__`` | A reference to the dictionary | Read-only |\n | | that holds the function\'s | |\n | | global variables --- the global | |\n | | namespace of the module in | |\n | | which the function was defined. | |\n +---------------------------+---------------------------------+-------------+\n | ``__dict__`` | The namespace supporting | Writable |\n | | arbitrary function attributes. | |\n +---------------------------+---------------------------------+-------------+\n | ``__closure__`` | ``None`` or a tuple of cells | Read-only |\n | | that contain bindings for the | |\n | | function\'s free variables. | |\n +---------------------------+---------------------------------+-------------+\n | ``__annotations__`` | A dict containing annotations | Writable |\n | | of parameters. The keys of the | |\n | | dict are the parameter names, | |\n | | or ``\'return\'`` for the return | |\n | | annotation, if provided. | |\n +---------------------------+---------------------------------+-------------+\n | ``__kwdefaults__`` | A dict containing defaults for | Writable |\n | | keyword-only parameters. | |\n +---------------------------+---------------------------------+-------------+\n\n Most of the attributes labelled "Writable" check the type of the\n assigned value.\n\n Function objects also support getting and setting arbitrary\n attributes, which can be used, for example, to attach metadata\n to functions. Regular attribute dot-notation is used to get and\n set such attributes. *Note that the current implementation only\n supports function attributes on user-defined functions. Function\n attributes on built-in functions may be supported in the\n future.*\n\n Additional information about a function\'s definition can be\n retrieved from its code object; see the description of internal\n types below.\n\n Instance methods\n An instance method object combines a class, a class instance and\n any callable object (normally a user-defined function).\n\n Special read-only attributes: ``__self__`` is the class instance\n object, ``__func__`` is the function object; ``__doc__`` is the\n method\'s documentation (same as ``__func__.__doc__``);\n ``__name__`` is the method name (same as ``__func__.__name__``);\n ``__module__`` is the name of the module the method was defined\n in, or ``None`` if unavailable.\n\n Methods also support accessing (but not setting) the arbitrary\n function attributes on the underlying function object.\n\n User-defined method objects may be created when getting an\n attribute of a class (perhaps via an instance of that class), if\n that attribute is a user-defined function object or a class\n method object.\n\n When an instance method object is created by retrieving a user-\n defined function object from a class via one of its instances,\n its ``__self__`` attribute is the instance, and the method\n object is said to be bound. The new method\'s ``__func__``\n attribute is the original function object.\n\n When a user-defined method object is created by retrieving\n another method object from a class or instance, the behaviour is\n the same as for a function object, except that the ``__func__``\n attribute of the new instance is not the original method object\n but its ``__func__`` attribute.\n\n When an instance method object is created by retrieving a class\n method object from a class or instance, its ``__self__``\n attribute is the class itself, and its ``__func__`` attribute is\n the function object underlying the class method.\n\n When an instance method object is called, the underlying\n function (``__func__``) is called, inserting the class instance\n (``__self__``) in front of the argument list. For instance,\n when ``C`` is a class which contains a definition for a function\n ``f()``, and ``x`` is an instance of ``C``, calling ``x.f(1)``\n is equivalent to calling ``C.f(x, 1)``.\n\n When an instance method object is derived from a class method\n object, the "class instance" stored in ``__self__`` will\n actually be the class itself, so that calling either ``x.f(1)``\n or ``C.f(1)`` is equivalent to calling ``f(C,1)`` where ``f`` is\n the underlying function.\n\n Note that the transformation from function object to instance\n method object happens each time the attribute is retrieved from\n the instance. In some cases, a fruitful optimization is to\n assign the attribute to a local variable and call that local\n variable. Also notice that this transformation only happens for\n user-defined functions; other callable objects (and all non-\n callable objects) are retrieved without transformation. It is\n also important to note that user-defined functions which are\n attributes of a class instance are not converted to bound\n methods; this *only* happens when the function is an attribute\n of the class.\n\n Generator functions\n A function or method which uses the ``yield`` statement (see\n section *The yield statement*) is called a *generator function*.\n Such a function, when called, always returns an iterator object\n which can be used to execute the body of the function: calling\n the iterator\'s ``__next__()`` method will cause the function to\n execute until it provides a value using the ``yield`` statement.\n When the function executes a ``return`` statement or falls off\n the end, a ``StopIteration`` exception is raised and the\n iterator will have reached the end of the set of values to be\n returned.\n\n Built-in functions\n A built-in function object is a wrapper around a C function.\n Examples of built-in functions are ``len()`` and ``math.sin()``\n (``math`` is a standard built-in module). The number and type of\n the arguments are determined by the C function. Special read-\n only attributes: ``__doc__`` is the function\'s documentation\n string, or ``None`` if unavailable; ``__name__`` is the\n function\'s name; ``__self__`` is set to ``None`` (but see the\n next item); ``__module__`` is the name of the module the\n function was defined in or ``None`` if unavailable.\n\n Built-in methods\n This is really a different disguise of a built-in function, this\n time containing an object passed to the C function as an\n implicit extra argument. An example of a built-in method is\n ``alist.append()``, assuming *alist* is a list object. In this\n case, the special read-only attribute ``__self__`` is set to the\n object denoted by *list*.\n\n Classes\n Classes are callable. These objects normally act as factories\n for new instances of themselves, but variations are possible for\n class types that override ``__new__()``. The arguments of the\n call are passed to ``__new__()`` and, in the typical case, to\n ``__init__()`` to initialize the new instance.\n\n Class Instances\n Instances of arbitrary classes can be made callable by defining\n a ``__call__()`` method in their class.\n\nModules\n Modules are imported by the ``import`` statement (see section *The\n import statement*). A module object has a namespace implemented by\n a dictionary object (this is the dictionary referenced by the\n __globals__ attribute of functions defined in the module).\n Attribute references are translated to lookups in this dictionary,\n e.g., ``m.x`` is equivalent to ``m.__dict__["x"]``. A module object\n does not contain the code object used to initialize the module\n (since it isn\'t needed once the initialization is done).\n\n Attribute assignment updates the module\'s namespace dictionary,\n e.g., ``m.x = 1`` is equivalent to ``m.__dict__["x"] = 1``.\n\n Special read-only attribute: ``__dict__`` is the module\'s namespace\n as a dictionary object.\n\n Predefined (writable) attributes: ``__name__`` is the module\'s\n name; ``__doc__`` is the module\'s documentation string, or ``None``\n if unavailable; ``__file__`` is the pathname of the file from which\n the module was loaded, if it was loaded from a file. The\n ``__file__`` attribute is not present for C modules that are\n statically linked into the interpreter; for extension modules\n loaded dynamically from a shared library, it is the pathname of the\n shared library file.\n\nCustom classes\n Custom class types are typically created by class definitions (see\n section *Class definitions*). A class has a namespace implemented\n by a dictionary object. Class attribute references are translated\n to lookups in this dictionary, e.g., ``C.x`` is translated to\n ``C.__dict__["x"]`` (although there are a number of hooks which\n allow for other means of locating attributes). When the attribute\n name is not found there, the attribute search continues in the base\n classes. This search of the base classes uses the C3 method\n resolution order which behaves correctly even in the presence of\n \'diamond\' inheritance structures where there are multiple\n inheritance paths leading back to a common ancestor. Additional\n details on the C3 MRO used by Python can be found in the\n documentation accompanying the 2.3 release at\n http://www.python.org/download/releases/2.3/mro/.\n\n When a class attribute reference (for class ``C``, say) would yield\n a class method object, it is transformed into an instance method\n object whose ``__self__`` attributes is ``C``. When it would yield\n a static method object, it is transformed into the object wrapped\n by the static method object. See section *Implementing Descriptors*\n for another way in which attributes retrieved from a class may\n differ from those actually contained in its ``__dict__``.\n\n Class attribute assignments update the class\'s dictionary, never\n the dictionary of a base class.\n\n A class object can be called (see above) to yield a class instance\n (see below).\n\n Special attributes: ``__name__`` is the class name; ``__module__``\n is the module name in which the class was defined; ``__dict__`` is\n the dictionary containing the class\'s namespace; ``__bases__`` is a\n tuple (possibly empty or a singleton) containing the base classes,\n in the order of their occurrence in the base class list;\n ``__doc__`` is the class\'s documentation string, or None if\n undefined.\n\nClass instances\n A class instance is created by calling a class object (see above).\n A class instance has a namespace implemented as a dictionary which\n is the first place in which attribute references are searched.\n When an attribute is not found there, and the instance\'s class has\n an attribute by that name, the search continues with the class\n attributes. If a class attribute is found that is a user-defined\n function object, it is transformed into an instance method object\n whose ``__self__`` attribute is the instance. Static method and\n class method objects are also transformed; see above under\n "Classes". See section *Implementing Descriptors* for another way\n in which attributes of a class retrieved via its instances may\n differ from the objects actually stored in the class\'s\n ``__dict__``. If no class attribute is found, and the object\'s\n class has a ``__getattr__()`` method, that is called to satisfy the\n lookup.\n\n Attribute assignments and deletions update the instance\'s\n dictionary, never a class\'s dictionary. If the class has a\n ``__setattr__()`` or ``__delattr__()`` method, this is called\n instead of updating the instance dictionary directly.\n\n Class instances can pretend to be numbers, sequences, or mappings\n if they have methods with certain special names. See section\n *Special method names*.\n\n Special attributes: ``__dict__`` is the attribute dictionary;\n ``__class__`` is the instance\'s class.\n\nI/O objects (also known as file objects)\n A file object represents an open file. Various shortcuts are\n available to create file objects: the ``open()`` built-in function,\n and also ``os.popen()``, ``os.fdopen()``, and the ``makefile()``\n method of socket objects (and perhaps by other functions or methods\n provided by extension modules).\n\n The objects ``sys.stdin``, ``sys.stdout`` and ``sys.stderr`` are\n initialized to file objects corresponding to the interpreter\'s\n standard input, output and error streams; they are all open in text\n mode and therefore follow the interface defined by the\n ``io.TextIOBase`` abstract class.\n\nInternal types\n A few types used internally by the interpreter are exposed to the\n user. Their definitions may change with future versions of the\n interpreter, but they are mentioned here for completeness.\n\n Code objects\n Code objects represent *byte-compiled* executable Python code,\n or *bytecode*. The difference between a code object and a\n function object is that the function object contains an explicit\n reference to the function\'s globals (the module in which it was\n defined), while a code object contains no context; also the\n default argument values are stored in the function object, not\n in the code object (because they represent values calculated at\n run-time). Unlike function objects, code objects are immutable\n and contain no references (directly or indirectly) to mutable\n objects.\n\n Special read-only attributes: ``co_name`` gives the function\n name; ``co_argcount`` is the number of positional arguments\n (including arguments with default values); ``co_nlocals`` is the\n number of local variables used by the function (including\n arguments); ``co_varnames`` is a tuple containing the names of\n the local variables (starting with the argument names);\n ``co_cellvars`` is a tuple containing the names of local\n variables that are referenced by nested functions;\n ``co_freevars`` is a tuple containing the names of free\n variables; ``co_code`` is a string representing the sequence of\n bytecode instructions; ``co_consts`` is a tuple containing the\n literals used by the bytecode; ``co_names`` is a tuple\n containing the names used by the bytecode; ``co_filename`` is\n the filename from which the code was compiled;\n ``co_firstlineno`` is the first line number of the function;\n ``co_lnotab`` is a string encoding the mapping from bytecode\n offsets to line numbers (for details see the source code of the\n interpreter); ``co_stacksize`` is the required stack size\n (including local variables); ``co_flags`` is an integer encoding\n a number of flags for the interpreter.\n\n The following flag bits are defined for ``co_flags``: bit\n ``0x04`` is set if the function uses the ``*arguments`` syntax\n to accept an arbitrary number of positional arguments; bit\n ``0x08`` is set if the function uses the ``**keywords`` syntax\n to accept arbitrary keyword arguments; bit ``0x20`` is set if\n the function is a generator.\n\n Future feature declarations (``from __future__ import\n division``) also use bits in ``co_flags`` to indicate whether a\n code object was compiled with a particular feature enabled: bit\n ``0x2000`` is set if the function was compiled with future\n division enabled; bits ``0x10`` and ``0x1000`` were used in\n earlier versions of Python.\n\n Other bits in ``co_flags`` are reserved for internal use.\n\n If a code object represents a function, the first item in\n ``co_consts`` is the documentation string of the function, or\n ``None`` if undefined.\n\n Frame objects\n Frame objects represent execution frames. They may occur in\n traceback objects (see below).\n\n Special read-only attributes: ``f_back`` is to the previous\n stack frame (towards the caller), or ``None`` if this is the\n bottom stack frame; ``f_code`` is the code object being executed\n in this frame; ``f_locals`` is the dictionary used to look up\n local variables; ``f_globals`` is used for global variables;\n ``f_builtins`` is used for built-in (intrinsic) names;\n ``f_lasti`` gives the precise instruction (this is an index into\n the bytecode string of the code object).\n\n Special writable attributes: ``f_trace``, if not ``None``, is a\n function called at the start of each source code line (this is\n used by the debugger); ``f_lineno`` is the current line number\n of the frame --- writing to this from within a trace function\n jumps to the given line (only for the bottom-most frame). A\n debugger can implement a Jump command (aka Set Next Statement)\n by writing to f_lineno.\n\n Traceback objects\n Traceback objects represent a stack trace of an exception. A\n traceback object is created when an exception occurs. When the\n search for an exception handler unwinds the execution stack, at\n each unwound level a traceback object is inserted in front of\n the current traceback. When an exception handler is entered,\n the stack trace is made available to the program. (See section\n *The try statement*.) It is accessible as the third item of the\n tuple returned by ``sys.exc_info()``. When the program contains\n no suitable handler, the stack trace is written (nicely\n formatted) to the standard error stream; if the interpreter is\n interactive, it is also made available to the user as\n ``sys.last_traceback``.\n\n Special read-only attributes: ``tb_next`` is the next level in\n the stack trace (towards the frame where the exception\n occurred), or ``None`` if there is no next level; ``tb_frame``\n points to the execution frame of the current level;\n ``tb_lineno`` gives the line number where the exception\n occurred; ``tb_lasti`` indicates the precise instruction. The\n line number and last instruction in the traceback may differ\n from the line number of its frame object if the exception\n occurred in a ``try`` statement with no matching except clause\n or with a finally clause.\n\n Slice objects\n Slice objects are used to represent slices for ``__getitem__()``\n methods. They are also created by the built-in ``slice()``\n function.\n\n Special read-only attributes: ``start`` is the lower bound;\n ``stop`` is the upper bound; ``step`` is the step value; each is\n ``None`` if omitted. These attributes can have any type.\n\n Slice objects support one method:\n\n slice.indices(self, length)\n\n This method takes a single integer argument *length* and\n computes information about the slice that the slice object\n would describe if applied to a sequence of *length* items.\n It returns a tuple of three integers; respectively these are\n the *start* and *stop* indices and the *step* or stride\n length of the slice. Missing or out-of-bounds indices are\n handled in a manner consistent with regular slices.\n\n Static method objects\n Static method objects provide a way of defeating the\n transformation of function objects to method objects described\n above. A static method object is a wrapper around any other\n object, usually a user-defined method object. When a static\n method object is retrieved from a class or a class instance, the\n object actually returned is the wrapped object, which is not\n subject to any further transformation. Static method objects are\n not themselves callable, although the objects they wrap usually\n are. Static method objects are created by the built-in\n ``staticmethod()`` constructor.\n\n Class method objects\n A class method object, like a static method object, is a wrapper\n around another object that alters the way in which that object\n is retrieved from classes and class instances. The behaviour of\n class method objects upon such retrieval is described above,\n under "User-defined methods". Class method objects are created\n by the built-in ``classmethod()`` constructor.\n',
'typesfunctions': '\nFunctions\n*********\n\nFunction objects are created by function definitions. The only\noperation on a function object is to call it: ``func(argument-list)``.\n\nThere are really two flavors of function objects: built-in functions\nand user-defined functions. Both support the same operation (to call\nthe function), but the implementation is different, hence the\ndifferent object types.\n\nSee *Function definitions* for more information.\n',
- 'typesmapping': '\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key\n is specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n If a subclass of dict defines a method ``__missing__()``, if the\n key *key* is not present, the ``d[key]`` operation calls that\n method with the key *key* as argument. The ``d[key]`` operation\n then returns or raises whatever is returned or raised by the\n ``__missing__(key)`` call if the key is not present. No other\n operations or methods invoke ``__missing__()``. If\n ``__missing__()`` is not defined, ``KeyError`` is raised.\n ``__missing__()`` must be a method; it cannot be an instance\n variable. For an example, see ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iter(d.keys())``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n classmethod fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n items()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as a tuple or other iterable of\n length two). If keyword arguments are specified, the\n dictionary is then updated with those key/value pairs:\n ``d.update(red=1, blue=2)``.\n\n values()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.keys()``, ``dict.values()`` and\n``dict.items()`` are *view objects*. They provide a dynamic view on\nthe dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n',
+ 'typesmapping': '\nMapping Types --- ``dict``\n**************************\n\nA *mapping* object maps *hashable* values to arbitrary objects.\nMappings are mutable objects. There is currently only one standard\nmapping type, the *dictionary*. (For other containers see the built\nin ``list``, ``set``, and ``tuple`` classes, and the ``collections``\nmodule.)\n\nA dictionary\'s keys are *almost* arbitrary values. Values that are\nnot *hashable*, that is, values containing lists, dictionaries or\nother mutable types (that are compared by value rather than by object\nidentity) may not be used as keys. Numeric types used for keys obey\nthe normal rules for numeric comparison: if two numbers compare equal\n(such as ``1`` and ``1.0``) then they can be used interchangeably to\nindex the same dictionary entry. (Note however, that since computers\nstore floating-point numbers as approximations it is usually unwise to\nuse them as dictionary keys.)\n\nDictionaries can be created by placing a comma-separated list of\n``key: value`` pairs within braces, for example: ``{\'jack\': 4098,\n\'sjoerd\': 4127}`` or ``{4098: \'jack\', 4127: \'sjoerd\'}``, or by the\n``dict`` constructor.\n\nclass class dict([arg])\n\n Return a new dictionary initialized from an optional positional\n argument or from a set of keyword arguments. If no arguments are\n given, return a new empty dictionary. If the positional argument\n *arg* is a mapping object, return a dictionary mapping the same\n keys to the same values as does the mapping object. Otherwise the\n positional argument must be a sequence, a container that supports\n iteration, or an iterator object. The elements of the argument\n must each also be of one of those kinds, and each must in turn\n contain exactly two objects. The first is used as a key in the new\n dictionary, and the second as the key\'s value. If a given key is\n seen more than once, the last value associated with it is retained\n in the new dictionary.\n\n If keyword arguments are given, the keywords themselves with their\n associated values are added as items to the dictionary. If a key\n is specified both in the positional argument and as a keyword\n argument, the value associated with the keyword is retained in the\n dictionary. For example, these all return a dictionary equal to\n ``{"one": 2, "two": 3}``:\n\n * ``dict(one=2, two=3)``\n\n * ``dict({\'one\': 2, \'two\': 3})``\n\n * ``dict(zip((\'one\', \'two\'), (2, 3)))``\n\n * ``dict([[\'two\', 3], [\'one\', 2]])``\n\n The first example only works for keys that are valid Python\n identifiers; the others work with any valid keys.\n\n These are the operations that dictionaries support (and therefore,\n custom mapping types should support too):\n\n len(d)\n\n Return the number of items in the dictionary *d*.\n\n d[key]\n\n Return the item of *d* with key *key*. Raises a ``KeyError`` if\n *key* is not in the map.\n\n If a subclass of dict defines a method ``__missing__()``, if the\n key *key* is not present, the ``d[key]`` operation calls that\n method with the key *key* as argument. The ``d[key]`` operation\n then returns or raises whatever is returned or raised by the\n ``__missing__(key)`` call if the key is not present. No other\n operations or methods invoke ``__missing__()``. If\n ``__missing__()`` is not defined, ``KeyError`` is raised.\n ``__missing__()`` must be a method; it cannot be an instance\n variable. For an example, see ``collections.defaultdict``.\n\n d[key] = value\n\n Set ``d[key]`` to *value*.\n\n del d[key]\n\n Remove ``d[key]`` from *d*. Raises a ``KeyError`` if *key* is\n not in the map.\n\n key in d\n\n Return ``True`` if *d* has a key *key*, else ``False``.\n\n key not in d\n\n Equivalent to ``not key in d``.\n\n iter(d)\n\n Return an iterator over the keys of the dictionary. This is a\n shortcut for ``iter(d.keys())``.\n\n clear()\n\n Remove all items from the dictionary.\n\n copy()\n\n Return a shallow copy of the dictionary.\n\n classmethod fromkeys(seq[, value])\n\n Create a new dictionary with keys from *seq* and values set to\n *value*.\n\n ``fromkeys()`` is a class method that returns a new dictionary.\n *value* defaults to ``None``.\n\n get(key[, default])\n\n Return the value for *key* if *key* is in the dictionary, else\n *default*. If *default* is not given, it defaults to ``None``,\n so that this method never raises a ``KeyError``.\n\n items()\n\n Return a new view of the dictionary\'s items (``(key, value)``\n pairs). See below for documentation of view objects.\n\n keys()\n\n Return a new view of the dictionary\'s keys. See below for\n documentation of view objects.\n\n pop(key[, default])\n\n If *key* is in the dictionary, remove it and return its value,\n else return *default*. If *default* is not given and *key* is\n not in the dictionary, a ``KeyError`` is raised.\n\n popitem()\n\n Remove and return an arbitrary ``(key, value)`` pair from the\n dictionary.\n\n ``popitem()`` is useful to destructively iterate over a\n dictionary, as often used in set algorithms. If the dictionary\n is empty, calling ``popitem()`` raises a ``KeyError``.\n\n setdefault(key[, default])\n\n If *key* is in the dictionary, return its value. If not, insert\n *key* with a value of *default* and return *default*. *default*\n defaults to ``None``.\n\n update([other])\n\n Update the dictionary with the key/value pairs from *other*,\n overwriting existing keys. Return ``None``.\n\n ``update()`` accepts either another dictionary object or an\n iterable of key/value pairs (as a tuple or other iterable of\n length two). If keyword arguments are specified, the dictionary\n is then updated with those key/value pairs: ``d.update(red=1,\n blue=2)``.\n\n values()\n\n Return a new view of the dictionary\'s values. See below for\n documentation of view objects.\n\n\nDictionary view objects\n=======================\n\nThe objects returned by ``dict.keys()``, ``dict.values()`` and\n``dict.items()`` are *view objects*. They provide a dynamic view on\nthe dictionary\'s entries, which means that when the dictionary\nchanges, the view reflects these changes.\n\nDictionary views can be iterated over to yield their respective data,\nand support membership tests:\n\nlen(dictview)\n\n Return the number of entries in the dictionary.\n\niter(dictview)\n\n Return an iterator over the keys, values or items (represented as\n tuples of ``(key, value)``) in the dictionary.\n\n Keys and values are iterated over in an arbitrary order which is\n non-random, varies across Python implementations, and depends on\n the dictionary\'s history of insertions and deletions. If keys,\n values and items views are iterated over with no intervening\n modifications to the dictionary, the order of items will directly\n correspond. This allows the creation of ``(value, key)`` pairs\n using ``zip()``: ``pairs = zip(d.values(), d.keys())``. Another\n way to create the same list is ``pairs = [(v, k) for (k, v) in\n d.items()]``.\n\n Iterating views while adding or deleting entries in the dictionary\n may raise a ``RuntimeError`` or fail to iterate over all entries.\n\nx in dictview\n\n Return ``True`` if *x* is in the underlying dictionary\'s keys,\n values or items (in the latter case, *x* should be a ``(key,\n value)`` tuple).\n\nKeys views are set-like since their entries are unique and hashable.\nIf all values are hashable, so that (key, value) pairs are unique and\nhashable, then the items view is also set-like. (Values views are not\ntreated as set-like since the entries are generally not unique.) Then\nthese set operations are available ("other" refers either to another\nview or a set):\n\ndictview & other\n\n Return the intersection of the dictview and the other object as a\n new set.\n\ndictview | other\n\n Return the union of the dictview and the other object as a new set.\n\ndictview - other\n\n Return the difference between the dictview and the other object\n (all elements in *dictview* that aren\'t in *other*) as a new set.\n\ndictview ^ other\n\n Return the symmetric difference (all elements either in *dictview*\n or *other*, but not in both) of the dictview and the other object\n as a new set.\n\ndictview.isdisjoint(other)\n\n Return True if the view has no elements in common with *other*.\n Sets are disjoint if and only if their intersection is the empty\n set.\n\nAn example of dictionary view usage:\n\n >>> dishes = {\'eggs\': 2, \'sausage\': 1, \'bacon\': 1, \'spam\': 500}\n >>> keys = dishes.keys()\n >>> values = dishes.values()\n\n >>> # iteration\n >>> n = 0\n >>> for val in values:\n ... n += val\n >>> print(n)\n 504\n\n >>> # keys and values are iterated over in the same order\n >>> list(keys)\n [\'eggs\', \'bacon\', \'sausage\', \'spam\']\n >>> list(values)\n [2, 1, 1, 500]\n\n >>> # view objects are dynamic and reflect dict changes\n >>> del dishes[\'eggs\']\n >>> del dishes[\'sausage\']\n >>> list(keys)\n [\'spam\', \'bacon\']\n\n >>> # set operations\n >>> keys & {\'eggs\', \'bacon\', \'salad\'}\n {\'bacon\'}\n',
'typesmethods': "\nMethods\n*******\n\nMethods are functions that are called using the attribute notation.\nThere are two flavors: built-in methods (such as ``append()`` on\nlists) and class instance methods. Built-in methods are described\nwith the types that support them.\n\nIf you access a method (a function defined in a class namespace)\nthrough an instance, you get a special object: a *bound method* (also\ncalled *instance method*) object. When called, it will add the\n``self`` argument to the argument list. Bound methods have two\nspecial read-only attributes: ``m.__self__`` is the object on which\nthe method operates, and ``m.__func__`` is the function implementing\nthe method. Calling ``m(arg-1, arg-2, ..., arg-n)`` is completely\nequivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ...,\narg-n)``.\n\nLike function objects, bound method objects support getting arbitrary\nattributes. However, since method attributes are actually stored on\nthe underlying function object (``meth.__func__``), setting method\nattributes on bound methods is disallowed. Attempting to set a method\nattribute results in a ``TypeError`` being raised. In order to set a\nmethod attribute, you need to explicitly set it on the underlying\nfunction object:\n\n class C:\n def method(self):\n pass\n\n c = C()\n c.method.__func__.whoami = 'my name is c'\n\nSee *The standard type hierarchy* for more information.\n",
'typesmodules': "\nModules\n*******\n\nThe only special operation on a module is attribute access:\n``m.name``, where *m* is a module and *name* accesses a name defined\nin *m*'s symbol table. Module attributes can be assigned to. (Note\nthat the ``import`` statement is not, strictly speaking, an operation\non a module object; ``import foo`` does not require a module object\nnamed *foo* to exist, rather it requires an (external) *definition*\nfor a module named *foo* somewhere.)\n\nA special member of every module is ``__dict__``. This is the\ndictionary containing the module's symbol table. Modifying this\ndictionary will actually change the module's symbol table, but direct\nassignment to the ``__dict__`` attribute is not possible (you can\nwrite ``m.__dict__['a'] = 1``, which defines ``m.a`` to be ``1``, but\nyou can't write ``m.__dict__ = {}``). Modifying ``__dict__`` directly\nis not recommended.\n\nModules built into the interpreter are written like this: ````. If loaded from a file, they are written as\n````.\n",
- 'typesseq': '\nSequence Types --- ``str``, ``bytes``, ``bytearray``, ``list``, ``tuple``, ``range``\n************************************************************************************\n\nThere are six sequence types: strings, byte sequences (``bytes``\nobjects), byte arrays (``bytearray`` objects), lists, tuples, and\nrange objects. For other containers see the built in ``dict`` and\n``set`` classes, and the ``collections`` module.\n\nStrings contain Unicode characters. Their literals are written in\nsingle or double quotes: ``\'xyzzy\'``, ``"frobozz"``. See *String and\nBytes literals* for more about string literals. In addition to the\nfunctionality described here, there are also string-specific methods\ndescribed in the *String Methods* section.\n\nBytes and bytearray objects contain single bytes -- the former is\nimmutable while the latter is a mutable sequence. Bytes objects can\nbe constructed the constructor, ``bytes()``, and from literals; use a\n``b`` prefix with normal string syntax: ``b\'xyzzy\'``. To construct\nbyte arrays, use the ``bytearray()`` function.\n\nWarning: While string objects are sequences of characters (represented by\n strings of length 1), bytes and bytearray objects are sequences of\n *integers* (between 0 and 255), representing the ASCII value of\n single bytes. That means that for a bytes or bytearray object *b*,\n ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes or\n bytearray object of length 1. The representation of bytes objects\n uses the literal format (``b\'...\'``) since it is generally more\n useful than e.g. ``bytes([50, 19, 100])``. You can always convert a\n bytes object into a list of integers using ``list(b)``.Also, while\n in previous Python versions, byte strings and Unicode strings could\n be exchanged for each other rather freely (barring encoding issues),\n strings and bytes are now completely separate concepts. There\'s no\n implicit en-/decoding if you pass an object of the wrong type. A\n string always compares unequal to a bytes or bytearray object.\n\nLists are constructed with square brackets, separating items with\ncommas: ``[a, b, c]``. Tuples are constructed by the comma operator\n(not within square brackets), with or without enclosing parentheses,\nbut an empty tuple must have the enclosing parentheses, such as ``a,\nb, c`` or ``()``. A single item tuple must have a trailing comma,\nsuch as ``(d,)``.\n\nObjects of type range are created using the ``range()`` function.\nThey don\'t support slicing, concatenation or repetition, and using\n``in``, ``not in``, ``min()`` or ``max()`` on them is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must\ncompare equal and the two sequences must be of the same type and have\nthe same length. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string object, the ``in`` and ``not in`` operations\n act like a substring test.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n\nString Methods\n==============\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding=sys.getdefaultencoding(), errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is the current default string encoding. *errors* may be\n given to set a different error handling scheme. The default for\n *errors* is ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n Changed in version 3.1: Added support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters include digit characters, and all characters that that\n can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when ``repr()`` is\n invoked on a string. It has no bearing on the handling of strings\n written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A ``TypeError`` will be raised if there are\n any non-string values in *seq*, including ``bytes`` objects. The\n separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or ``None``. Unmapped\n characters are left untouched. Characters mapped to ``None`` are\n deleted.\n\n You can use ``str.maketrans()`` to create a translation map from\n character-to-character mappings in different formats.\n\n You can use the ``maketrans()`` helper function in the ``string``\n module to create a translation table. For string objects, set the\n *table* argument to ``None`` for translations that only delete\n characters:\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n\nOld String Formatting Operations\n================================\n\nNote: The formatting operations described here are obsolete and may go\n away in future versions of Python. Use the new *String Formatting*\n in new code.\n\nString objects have one unique built-in operation: the ``%`` operator\n(modulo). This is also known as the string *formatting* or\n*interpolation* operator. Given ``format % values`` (where *format* is\na string), ``%`` conversion specifications in *format* are replaced\nwith zero or more elements of *values*. The effect is similar to the\nusing ``sprintf()`` in the C language.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print(\'%(language)s has %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 2})\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The precision determines the maximal number of characters used.\n\n1. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 3.1: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nRange Type\n==========\n\nThe ``range`` type is an immutable sequence which is commonly used for\nlooping. The advantage of the ``range`` type is that an ``range``\nobject will always take the same amount of memory, no matter the size\nof the range it represents. There are no consistent performance\nadvantages.\n\nRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object. Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (2) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (3) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (5) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (6) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7), (8) |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the sequence length is added, as for slice indices. If it\n is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n ``insert()`` method, the sequence length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n place for economy of space when sorting or reversing a large\n sequence. To remind you that they operate by side effect, they\n don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n comparisons. Each must be specified as a keyword argument.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``. Use ``functools.cmp_to_key()`` to\n convert an old-style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n The ``sort()`` method is guaranteed to be stable. A sort is stable\n if it guarantees not to change the relative order of elements that\n compare equal --- this is helpful for sorting in multiple passes\n (for example, sort by department, then by salary grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises ``ValueError`` if it can detect\n that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n\n\nBytes and Byte Array Methods\n============================\n\nBytes and bytearray objects, being "strings of bytes", have all\nmethods found on strings, with the exception of ``encode()``,\n``format()`` and ``isidentifier()``, which do not make sense with\nthese types. For converting the objects to strings, they have a\n``decode()`` method.\n\nWherever one of these methods needs to interpret the bytes as\ncharacters (e.g. the ``is...()`` methods), the ASCII character set is\nassumed.\n\nNote: The methods on bytes and bytearray objects don\'t accept strings as\n their arguments, just as the methods on strings don\'t accept bytes\n as their arguments. For example, you have to write\n\n a = "abc"\n b = a.replace("a", "f")\n\n and\n\n a = b"abc"\n b = a.replace(b"a", b"f")\n\nbytes.decode(encoding=sys.getdefaultencoding(), errors="strict")\nbytearray.decode(encoding=sys.getdefaultencoding(), errors="strict")\n\n Return a string decoded from the given bytes. Default encoding is\n the current default string encoding. *errors* may be given to set\n a different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'`` and any other name registered via\n ``codecs.register_error()``, see section *Codec Base Classes*. For\n a list of possible encodings, see section *Standard Encodings*.\n\n Changed in version 3.1: Added support for keyword arguments.\n\nThe bytes and bytearray types have an additional class method:\n\nclassmethod bytes.fromhex(string)\nclassmethod bytearray.fromhex(string)\n\n This ``bytes`` class method returns a bytes or bytearray object,\n decoding the given string object. The string must contain two\n hexadecimal digits per byte, spaces are ignored.\n\n >>> bytes.fromhex(\'f0 f1f2 \')\n b\'\\xf0\\xf1\\xf2\'\n\nThe maketrans and translate methods differ in semantics from the\nversions available on strings:\n\nbytes.translate(table[, delete])\nbytearray.translate(table[, delete])\n\n Return a copy of the bytes or bytearray object where all bytes\n occurring in the optional argument *delete* are removed, and the\n remaining bytes have been mapped through the given translation\n table, which must be a bytes object of length 256.\n\n You can use the ``bytes.maketrans()`` method to create a\n translation table.\n\n Set the *table* argument to ``None`` for translations that only\n delete characters:\n\n >>> b\'read this short text\'.translate(None, b\'aeiou\')\n b\'rd ths shrt txt\'\n\nstatic bytes.maketrans(from, to)\nstatic bytearray.maketrans(from, to)\n\n This static method returns a translation table usable for\n ``bytes.translate()`` that will map each character in *from* into\n the character at the same position in *to*; *from* and *to* must be\n bytes objects and have the same length.\n\n New in version 3.1.\n',
+ 'typesseq': '\nSequence Types --- ``str``, ``bytes``, ``bytearray``, ``list``, ``tuple``, ``range``\n************************************************************************************\n\nThere are six sequence types: strings, byte sequences (``bytes``\nobjects), byte arrays (``bytearray`` objects), lists, tuples, and\nrange objects. For other containers see the built in ``dict`` and\n``set`` classes, and the ``collections`` module.\n\nStrings contain Unicode characters. Their literals are written in\nsingle or double quotes: ``\'xyzzy\'``, ``"frobozz"``. See *String and\nBytes literals* for more about string literals. In addition to the\nfunctionality described here, there are also string-specific methods\ndescribed in the *String Methods* section.\n\nBytes and bytearray objects contain single bytes -- the former is\nimmutable while the latter is a mutable sequence. Bytes objects can\nbe constructed the constructor, ``bytes()``, and from literals; use a\n``b`` prefix with normal string syntax: ``b\'xyzzy\'``. To construct\nbyte arrays, use the ``bytearray()`` function.\n\nWarning: While string objects are sequences of characters (represented by\n strings of length 1), bytes and bytearray objects are sequences of\n *integers* (between 0 and 255), representing the ASCII value of\n single bytes. That means that for a bytes or bytearray object *b*,\n ``b[0]`` will be an integer, while ``b[0:1]`` will be a bytes or\n bytearray object of length 1. The representation of bytes objects\n uses the literal format (``b\'...\'``) since it is generally more\n useful than e.g. ``bytes([50, 19, 100])``. You can always convert a\n bytes object into a list of integers using ``list(b)``.Also, while\n in previous Python versions, byte strings and Unicode strings could\n be exchanged for each other rather freely (barring encoding issues),\n strings and bytes are now completely separate concepts. There\'s no\n implicit en-/decoding if you pass an object of the wrong type. A\n string always compares unequal to a bytes or bytearray object.\n\nLists are constructed with square brackets, separating items with\ncommas: ``[a, b, c]``. Tuples are constructed by the comma operator\n(not within square brackets), with or without enclosing parentheses,\nbut an empty tuple must have the enclosing parentheses, such as ``a,\nb, c`` or ``()``. A single item tuple must have a trailing comma,\nsuch as ``(d,)``.\n\nObjects of type range are created using the ``range()`` function.\nThey don\'t support slicing, concatenation or repetition, and using\n``in``, ``not in``, ``min()`` or ``max()`` on them is inefficient.\n\nMost sequence types support the following operations. The ``in`` and\n``not in`` operations have the same priorities as the comparison\noperations. The ``+`` and ``*`` operations have the same priority as\nthe corresponding numeric operations. [3] Additional methods are\nprovided for *Mutable Sequence Types*.\n\nThis table lists the sequence operations sorted in ascending priority\n(operations in the same box have the same priority). In the table,\n*s* and *t* are sequences of the same type; *n*, *i* and *j* are\nintegers:\n\n+--------------------+----------------------------------+------------+\n| Operation | Result | Notes |\n+====================+==================================+============+\n| ``x in s`` | ``True`` if an item of *s* is | (1) |\n| | equal to *x*, else ``False`` | |\n+--------------------+----------------------------------+------------+\n| ``x not in s`` | ``False`` if an item of *s* is | (1) |\n| | equal to *x*, else ``True`` | |\n+--------------------+----------------------------------+------------+\n| ``s + t`` | the concatenation of *s* and *t* | (6) |\n+--------------------+----------------------------------+------------+\n| ``s * n, n * s`` | *n* shallow copies of *s* | (2) |\n| | concatenated | |\n+--------------------+----------------------------------+------------+\n| ``s[i]`` | *i*\'th item of *s*, origin 0 | (3) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j]`` | slice of *s* from *i* to *j* | (3)(4) |\n+--------------------+----------------------------------+------------+\n| ``s[i:j:k]`` | slice of *s* from *i* to *j* | (3)(5) |\n| | with step *k* | |\n+--------------------+----------------------------------+------------+\n| ``len(s)`` | length of *s* | |\n+--------------------+----------------------------------+------------+\n| ``min(s)`` | smallest item of *s* | |\n+--------------------+----------------------------------+------------+\n| ``max(s)`` | largest item of *s* | |\n+--------------------+----------------------------------+------------+\n\nSequence types also support comparisons. In particular, tuples and\nlists are compared lexicographically by comparing corresponding\nelements. This means that to compare equal, every element must\ncompare equal and the two sequences must be of the same type and have\nthe same length. (For full details see *Comparisons* in the language\nreference.)\n\nNotes:\n\n1. When *s* is a string object, the ``in`` and ``not in`` operations\n act like a substring test.\n\n2. Values of *n* less than ``0`` are treated as ``0`` (which yields an\n empty sequence of the same type as *s*). Note also that the copies\n are shallow; nested structures are not copied. This often haunts\n new Python programmers; consider:\n\n >>> lists = [[]] * 3\n >>> lists\n [[], [], []]\n >>> lists[0].append(3)\n >>> lists\n [[3], [3], [3]]\n\n What has happened is that ``[[]]`` is a one-element list containing\n an empty list, so all three elements of ``[[]] * 3`` are (pointers\n to) this single empty list. Modifying any of the elements of\n ``lists`` modifies this single list. You can create a list of\n different lists this way:\n\n >>> lists = [[] for i in range(3)]\n >>> lists[0].append(3)\n >>> lists[1].append(5)\n >>> lists[2].append(7)\n >>> lists\n [[3], [5], [7]]\n\n3. If *i* or *j* is negative, the index is relative to the end of the\n string: ``len(s) + i`` or ``len(s) + j`` is substituted. But note\n that ``-0`` is still ``0``.\n\n4. The slice of *s* from *i* to *j* is defined as the sequence of\n items with index *k* such that ``i <= k < j``. If *i* or *j* is\n greater than ``len(s)``, use ``len(s)``. If *i* is omitted or\n ``None``, use ``0``. If *j* is omitted or ``None``, use\n ``len(s)``. If *i* is greater than or equal to *j*, the slice is\n empty.\n\n5. The slice of *s* from *i* to *j* with step *k* is defined as the\n sequence of items with index ``x = i + n*k`` such that ``0 <= n <\n (j-i)/k``. In other words, the indices are ``i``, ``i+k``,\n ``i+2*k``, ``i+3*k`` and so on, stopping when *j* is reached (but\n never including *j*). If *i* or *j* is greater than ``len(s)``,\n use ``len(s)``. If *i* or *j* are omitted or ``None``, they become\n "end" values (which end depends on the sign of *k*). Note, *k*\n cannot be zero. If *k* is ``None``, it is treated like ``1``.\n\n6. **CPython implementation detail:** If *s* and *t* are both strings,\n some Python implementations such as CPython can usually perform an\n in-place optimization for assignments of the form ``s = s + t`` or\n ``s += t``. When applicable, this optimization makes quadratic\n run-time much less likely. This optimization is both version and\n implementation dependent. For performance sensitive code, it is\n preferable to use the ``str.join()`` method which assures\n consistent linear concatenation performance across versions and\n implementations.\n\n\nString Methods\n==============\n\nString objects support the methods listed below.\n\nIn addition, Python\'s strings support the sequence type methods\ndescribed in the *Sequence Types --- str, bytes, bytearray, list,\ntuple, range* section. To output formatted strings, see the *String\nFormatting* section. Also, see the ``re`` module for string functions\nbased on regular expressions.\n\nstr.capitalize()\n\n Return a copy of the string with its first character capitalized\n and the rest lowercased.\n\nstr.center(width[, fillchar])\n\n Return centered in a string of length *width*. Padding is done\n using the specified *fillchar* (default is a space).\n\nstr.count(sub[, start[, end]])\n\n Return the number of non-overlapping occurrences of substring *sub*\n in the range [*start*, *end*]. Optional arguments *start* and\n *end* are interpreted as in slice notation.\n\nstr.encode(encoding=sys.getdefaultencoding(), errors="strict")\n\n Return an encoded version of the string as a bytes object. Default\n encoding is the current default string encoding. *errors* may be\n given to set a different error handling scheme. The default for\n *errors* is ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'``, ``\'xmlcharrefreplace\'``, ``\'backslashreplace\'`` and\n any other name registered via ``codecs.register_error()``, see\n section *Codec Base Classes*. For a list of possible encodings, see\n section *Standard Encodings*.\n\n Changed in version 3.1: Support for keyword arguments added.\n\nstr.endswith(suffix[, start[, end]])\n\n Return ``True`` if the string ends with the specified *suffix*,\n otherwise return ``False``. *suffix* can also be a tuple of\n suffixes to look for. With optional *start*, test beginning at\n that position. With optional *end*, stop comparing at that\n position.\n\nstr.expandtabs([tabsize])\n\n Return a copy of the string where all tab characters are replaced\n by one or more spaces, depending on the current column and the\n given tab size. The column number is reset to zero after each\n newline occurring in the string. If *tabsize* is not given, a tab\n size of ``8`` characters is assumed. This doesn\'t understand other\n non-printing characters or escape sequences.\n\nstr.find(sub[, start[, end]])\n\n Return the lowest index in the string where substring *sub* is\n found, such that *sub* is contained in the slice ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` if *sub* is not found.\n\nstr.format(*args, **kwargs)\n\n Perform a string formatting operation. The string on which this\n method is called can contain literal text or replacement fields\n delimited by braces ``{}``. Each replacement field contains either\n the numeric index of a positional argument, or the name of a\n keyword argument. Returns a copy of the string where each\n replacement field is replaced with the string value of the\n corresponding argument.\n\n >>> "The sum of 1 + 2 is {0}".format(1+2)\n \'The sum of 1 + 2 is 3\'\n\n See *Format String Syntax* for a description of the various\n formatting options that can be specified in format strings.\n\nstr.index(sub[, start[, end]])\n\n Like ``find()``, but raise ``ValueError`` when the substring is not\n found.\n\nstr.isalnum()\n\n Return true if all characters in the string are alphanumeric and\n there is at least one character, false otherwise.\n\nstr.isalpha()\n\n Return true if all characters in the string are alphabetic and\n there is at least one character, false otherwise.\n\nstr.isdecimal()\n\n Return true if all characters in the string are decimal characters\n and there is at least one character, false otherwise. Decimal\n characters include digit characters, and all characters that that\n can be used to form decimal-radix numbers, e.g. U+0660, ARABIC-\n INDIC DIGIT ZERO.\n\nstr.isdigit()\n\n Return true if all characters in the string are digits and there is\n at least one character, false otherwise.\n\nstr.isidentifier()\n\n Return true if the string is a valid identifier according to the\n language definition, section *Identifiers and keywords*.\n\nstr.islower()\n\n Return true if all cased characters in the string are lowercase and\n there is at least one cased character, false otherwise.\n\nstr.isnumeric()\n\n Return true if all characters in the string are numeric characters,\n and there is at least one character, false otherwise. Numeric\n characters include digit characters, and all characters that have\n the Unicode numeric value property, e.g. U+2155, VULGAR FRACTION\n ONE FIFTH.\n\nstr.isprintable()\n\n Return true if all characters in the string are printable or the\n string is empty, false otherwise. Nonprintable characters are\n those characters defined in the Unicode character database as\n "Other" or "Separator", excepting the ASCII space (0x20) which is\n considered printable. (Note that printable characters in this\n context are those which should not be escaped when ``repr()`` is\n invoked on a string. It has no bearing on the handling of strings\n written to ``sys.stdout`` or ``sys.stderr``.)\n\nstr.isspace()\n\n Return true if there are only whitespace characters in the string\n and there is at least one character, false otherwise.\n\nstr.istitle()\n\n Return true if the string is a titlecased string and there is at\n least one character, for example uppercase characters may only\n follow uncased characters and lowercase characters only cased ones.\n Return false otherwise.\n\nstr.isupper()\n\n Return true if all cased characters in the string are uppercase and\n there is at least one cased character, false otherwise.\n\nstr.join(iterable)\n\n Return a string which is the concatenation of the strings in the\n *iterable* *iterable*. A ``TypeError`` will be raised if there are\n any non-string values in *seq*, including ``bytes`` objects. The\n separator between elements is the string providing this method.\n\nstr.ljust(width[, fillchar])\n\n Return the string left justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.lower()\n\n Return a copy of the string converted to lowercase.\n\nstr.lstrip([chars])\n\n Return a copy of the string with leading characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a prefix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.lstrip()\n \'spacious \'\n >>> \'www.example.com\'.lstrip(\'cmowz.\')\n \'example.com\'\n\nstatic str.maketrans(x[, y[, z]])\n\n This static method returns a translation table usable for\n ``str.translate()``.\n\n If there is only one argument, it must be a dictionary mapping\n Unicode ordinals (integers) or characters (strings of length 1) to\n Unicode ordinals, strings (of arbitrary lengths) or None.\n Character keys will then be converted to ordinals.\n\n If there are two arguments, they must be strings of equal length,\n and in the resulting dictionary, each character in x will be mapped\n to the character at the same position in y. If there is a third\n argument, it must be a string, whose characters will be mapped to\n None in the result.\n\nstr.partition(sep)\n\n Split the string at the first occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing the string itself, followed by\n two empty strings.\n\nstr.replace(old, new[, count])\n\n Return a copy of the string with all occurrences of substring *old*\n replaced by *new*. If the optional argument *count* is given, only\n the first *count* occurrences are replaced.\n\nstr.rfind(sub[, start[, end]])\n\n Return the highest index in the string where substring *sub* is\n found, such that *sub* is contained within ``s[start:end]``.\n Optional arguments *start* and *end* are interpreted as in slice\n notation. Return ``-1`` on failure.\n\nstr.rindex(sub[, start[, end]])\n\n Like ``rfind()`` but raises ``ValueError`` when the substring *sub*\n is not found.\n\nstr.rjust(width[, fillchar])\n\n Return the string right justified in a string of length *width*.\n Padding is done using the specified *fillchar* (default is a\n space). The original string is returned if *width* is less than\n ``len(s)``.\n\nstr.rpartition(sep)\n\n Split the string at the last occurrence of *sep*, and return a\n 3-tuple containing the part before the separator, the separator\n itself, and the part after the separator. If the separator is not\n found, return a 3-tuple containing two empty strings, followed by\n the string itself.\n\nstr.rsplit([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit* splits\n are done, the *rightmost* ones. If *sep* is not specified or\n ``None``, any whitespace string is a separator. Except for\n splitting from the right, ``rsplit()`` behaves like ``split()``\n which is described in detail below.\n\nstr.rstrip([chars])\n\n Return a copy of the string with trailing characters removed. The\n *chars* argument is a string specifying the set of characters to be\n removed. If omitted or ``None``, the *chars* argument defaults to\n removing whitespace. The *chars* argument is not a suffix; rather,\n all combinations of its values are stripped:\n\n >>> \' spacious \'.rstrip()\n \' spacious\'\n >>> \'mississippi\'.rstrip(\'ipz\')\n \'mississ\'\n\nstr.split([sep[, maxsplit]])\n\n Return a list of the words in the string, using *sep* as the\n delimiter string. If *maxsplit* is given, at most *maxsplit*\n splits are done (thus, the list will have at most ``maxsplit+1``\n elements). If *maxsplit* is not specified, then there is no limit\n on the number of splits (all possible splits are made).\n\n If *sep* is given, consecutive delimiters are not grouped together\n and are deemed to delimit empty strings (for example,\n ``\'1,,2\'.split(\',\')`` returns ``[\'1\', \'\', \'2\']``). The *sep*\n argument may consist of multiple characters (for example,\n ``\'1<>2<>3\'.split(\'<>\')`` returns ``[\'1\', \'2\', \'3\']``). Splitting\n an empty string with a specified separator returns ``[\'\']``.\n\n If *sep* is not specified or is ``None``, a different splitting\n algorithm is applied: runs of consecutive whitespace are regarded\n as a single separator, and the result will contain no empty strings\n at the start or end if the string has leading or trailing\n whitespace. Consequently, splitting an empty string or a string\n consisting of just whitespace with a ``None`` separator returns\n ``[]``.\n\n For example, ``\' 1 2 3 \'.split()`` returns ``[\'1\', \'2\', \'3\']``,\n and ``\' 1 2 3 \'.split(None, 1)`` returns ``[\'1\', \'2 3 \']``.\n\nstr.splitlines([keepends])\n\n Return a list of the lines in the string, breaking at line\n boundaries. Line breaks are not included in the resulting list\n unless *keepends* is given and true.\n\nstr.startswith(prefix[, start[, end]])\n\n Return ``True`` if string starts with the *prefix*, otherwise\n return ``False``. *prefix* can also be a tuple of prefixes to look\n for. With optional *start*, test string beginning at that\n position. With optional *end*, stop comparing string at that\n position.\n\nstr.strip([chars])\n\n Return a copy of the string with the leading and trailing\n characters removed. The *chars* argument is a string specifying the\n set of characters to be removed. If omitted or ``None``, the\n *chars* argument defaults to removing whitespace. The *chars*\n argument is not a prefix or suffix; rather, all combinations of its\n values are stripped:\n\n >>> \' spacious \'.strip()\n \'spacious\'\n >>> \'www.example.com\'.strip(\'cmowz.\')\n \'example\'\n\nstr.swapcase()\n\n Return a copy of the string with uppercase characters converted to\n lowercase and vice versa.\n\nstr.title()\n\n Return a titlecased version of the string where words start with an\n uppercase character and the remaining characters are lowercase.\n\n The algorithm uses a simple language-independent definition of a\n word as groups of consecutive letters. The definition works in\n many contexts but it means that apostrophes in contractions and\n possessives form word boundaries, which may not be the desired\n result:\n\n >>> "they\'re bill\'s friends from the UK".title()\n "They\'Re Bill\'S Friends From The Uk"\n\n A workaround for apostrophes can be constructed using regular\n expressions:\n\n >>> import re\n >>> def titlecase(s):\n return re.sub(r"[A-Za-z]+(\'[A-Za-z]+)?",\n lambda mo: mo.group(0)[0].upper() +\n mo.group(0)[1:].lower(),\n s)\n\n >>> titlecase("they\'re bill\'s friends.")\n "They\'re Bill\'s Friends."\n\nstr.translate(map)\n\n Return a copy of the *s* where all characters have been mapped\n through the *map* which must be a dictionary of Unicode ordinals\n (integers) to Unicode ordinals, strings or ``None``. Unmapped\n characters are left untouched. Characters mapped to ``None`` are\n deleted.\n\n You can use ``str.maketrans()`` to create a translation map from\n character-to-character mappings in different formats.\n\n Note: An even more flexible approach is to create a custom character\n mapping codec using the ``codecs`` module (see\n ``encodings.cp1251`` for an example).\n\nstr.upper()\n\n Return a copy of the string converted to uppercase.\n\nstr.zfill(width)\n\n Return the numeric string left filled with zeros in a string of\n length *width*. A sign prefix is handled correctly. The original\n string is returned if *width* is less than ``len(s)``.\n\n\nOld String Formatting Operations\n================================\n\nNote: The formatting operations described here are obsolete and may go\n away in future versions of Python. Use the new *String Formatting*\n in new code.\n\nString objects have one unique built-in operation: the ``%`` operator\n(modulo). This is also known as the string *formatting* or\n*interpolation* operator. Given ``format % values`` (where *format* is\na string), ``%`` conversion specifications in *format* are replaced\nwith zero or more elements of *values*. The effect is similar to the\nusing ``sprintf()`` in the C language.\n\nIf *format* requires a single argument, *values* may be a single non-\ntuple object. [4] Otherwise, *values* must be a tuple with exactly\nthe number of items specified by the format string, or a single\nmapping object (for example, a dictionary).\n\nA conversion specifier contains two or more characters and has the\nfollowing components, which must occur in this order:\n\n1. The ``\'%\'`` character, which marks the start of the specifier.\n\n2. Mapping key (optional), consisting of a parenthesised sequence of\n characters (for example, ``(somename)``).\n\n3. Conversion flags (optional), which affect the result of some\n conversion types.\n\n4. Minimum field width (optional). If specified as an ``\'*\'``\n (asterisk), the actual width is read from the next element of the\n tuple in *values*, and the object to convert comes after the\n minimum field width and optional precision.\n\n5. Precision (optional), given as a ``\'.\'`` (dot) followed by the\n precision. If specified as ``\'*\'`` (an asterisk), the actual width\n is read from the next element of the tuple in *values*, and the\n value to convert comes after the precision.\n\n6. Length modifier (optional).\n\n7. Conversion type.\n\nWhen the right argument is a dictionary (or other mapping type), then\nthe formats in the string *must* include a parenthesised mapping key\ninto that dictionary inserted immediately after the ``\'%\'`` character.\nThe mapping key selects the value to be formatted from the mapping.\nFor example:\n\n>>> print(\'%(language)s has %(#)03d quote types.\' % \\\n... {\'language\': "Python", "#": 2})\nPython has 002 quote types.\n\nIn this case no ``*`` specifiers may occur in a format (since they\nrequire a sequential parameter list).\n\nThe conversion flag characters are:\n\n+-----------+-----------------------------------------------------------------------+\n| Flag | Meaning |\n+===========+=======================================================================+\n| ``\'#\'`` | The value conversion will use the "alternate form" (where defined |\n| | below). |\n+-----------+-----------------------------------------------------------------------+\n| ``\'0\'`` | The conversion will be zero padded for numeric values. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'-\'`` | The converted value is left adjusted (overrides the ``\'0\'`` |\n| | conversion if both are given). |\n+-----------+-----------------------------------------------------------------------+\n| ``\' \'`` | (a space) A blank should be left before a positive number (or empty |\n| | string) produced by a signed conversion. |\n+-----------+-----------------------------------------------------------------------+\n| ``\'+\'`` | A sign character (``\'+\'`` or ``\'-\'``) will precede the conversion |\n| | (overrides a "space" flag). |\n+-----------+-----------------------------------------------------------------------+\n\nA length modifier (``h``, ``l``, or ``L``) may be present, but is\nignored as it is not necessary for Python -- so e.g. ``%ld`` is\nidentical to ``%d``.\n\nThe conversion types are:\n\n+--------------+-------------------------------------------------------+---------+\n| Conversion | Meaning | Notes |\n+==============+=======================================================+=========+\n| ``\'d\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'i\'`` | Signed integer decimal. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'o\'`` | Signed octal value. | (1) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'u\'`` | Obsolete type -- it is identical to ``\'d\'``. | (7) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'x\'`` | Signed hexadecimal (lowercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'X\'`` | Signed hexadecimal (uppercase). | (2) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'e\'`` | Floating point exponential format (lowercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'E\'`` | Floating point exponential format (uppercase). | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'f\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'F\'`` | Floating point decimal format. | (3) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'g\'`` | Floating point format. Uses lowercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'G\'`` | Floating point format. Uses uppercase exponential | (4) |\n| | format if exponent is less than -4 or not less than | |\n| | precision, decimal format otherwise. | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'c\'`` | Single character (accepts integer or single character | |\n| | string). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'r\'`` | String (converts any Python object using ``repr()``). | (5) |\n+--------------+-------------------------------------------------------+---------+\n| ``\'s\'`` | String (converts any Python object using ``str()``). | |\n+--------------+-------------------------------------------------------+---------+\n| ``\'%\'`` | No argument is converted, results in a ``\'%\'`` | |\n| | character in the result. | |\n+--------------+-------------------------------------------------------+---------+\n\nNotes:\n\n1. The alternate form causes a leading zero (``\'0\'``) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n2. The alternate form causes a leading ``\'0x\'`` or ``\'0X\'`` (depending\n on whether the ``\'x\'`` or ``\'X\'`` format was used) to be inserted\n between left-hand padding and the formatting of the number if the\n leading character of the result is not already a zero.\n\n3. The alternate form causes the result to always contain a decimal\n point, even if no digits follow it.\n\n The precision determines the number of digits after the decimal\n point and defaults to 6.\n\n4. The alternate form causes the result to always contain a decimal\n point, and trailing zeroes are not removed as they would otherwise\n be.\n\n The precision determines the number of significant digits before\n and after the decimal point and defaults to 6.\n\n5. The precision determines the maximal number of characters used.\n\n1. See **PEP 237**.\n\nSince Python strings have an explicit length, ``%s`` conversions do\nnot assume that ``\'\\0\'`` is the end of the string.\n\nChanged in version 3.1: ``%f`` conversions for numbers whose absolute\nvalue is over 1e50 are no longer replaced by ``%g`` conversions.\n\nAdditional string operations are defined in standard modules\n``string`` and ``re``.\n\n\nRange Type\n==========\n\nThe ``range`` type is an immutable sequence which is commonly used for\nlooping. The advantage of the ``range`` type is that an ``range``\nobject will always take the same amount of memory, no matter the size\nof the range it represents. There are no consistent performance\nadvantages.\n\nRange objects have very little behavior: they only support indexing,\niteration, and the ``len()`` function.\n\n\nMutable Sequence Types\n======================\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object. Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (2) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (3) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (5) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (6) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7), (8) |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the sequence length is added, as for slice indices. If it\n is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n ``insert()`` method, the sequence length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n place for economy of space when sorting or reversing a large\n sequence. To remind you that they operate by side effect, they\n don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n comparisons. Each must be specified as a keyword argument.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``. Use ``functools.cmp_to_key()`` to\n convert an old-style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n The ``sort()`` method is guaranteed to be stable. A sort is stable\n if it guarantees not to change the relative order of elements that\n compare equal --- this is helpful for sorting in multiple passes\n (for example, sort by department, then by salary grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises ``ValueError`` if it can detect\n that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n\n\nBytes and Byte Array Methods\n============================\n\nBytes and bytearray objects, being "strings of bytes", have all\nmethods found on strings, with the exception of ``encode()``,\n``format()`` and ``isidentifier()``, which do not make sense with\nthese types. For converting the objects to strings, they have a\n``decode()`` method.\n\nWherever one of these methods needs to interpret the bytes as\ncharacters (e.g. the ``is...()`` methods), the ASCII character set is\nassumed.\n\nNote: The methods on bytes and bytearray objects don\'t accept strings as\n their arguments, just as the methods on strings don\'t accept bytes\n as their arguments. For example, you have to write\n\n a = "abc"\n b = a.replace("a", "f")\n\n and\n\n a = b"abc"\n b = a.replace(b"a", b"f")\n\nbytes.decode(encoding=sys.getdefaultencoding(), errors="strict")\nbytearray.decode(encoding=sys.getdefaultencoding(), errors="strict")\n\n Return a string decoded from the given bytes. Default encoding is\n the current default string encoding. *errors* may be given to set\n a different error handling scheme. The default for *errors* is\n ``\'strict\'``, meaning that encoding errors raise a\n ``UnicodeError``. Other possible values are ``\'ignore\'``,\n ``\'replace\'`` and any other name registered via\n ``codecs.register_error()``, see section *Codec Base Classes*. For\n a list of possible encodings, see section *Standard Encodings*.\n\n Changed in version 3.1: Added support for keyword arguments.\n\nThe bytes and bytearray types have an additional class method:\n\nclassmethod bytes.fromhex(string)\nclassmethod bytearray.fromhex(string)\n\n This ``bytes`` class method returns a bytes or bytearray object,\n decoding the given string object. The string must contain two\n hexadecimal digits per byte, spaces are ignored.\n\n >>> bytes.fromhex(\'f0 f1f2 \')\n b\'\\xf0\\xf1\\xf2\'\n\nThe maketrans and translate methods differ in semantics from the\nversions available on strings:\n\nbytes.translate(table[, delete])\nbytearray.translate(table[, delete])\n\n Return a copy of the bytes or bytearray object where all bytes\n occurring in the optional argument *delete* are removed, and the\n remaining bytes have been mapped through the given translation\n table, which must be a bytes object of length 256.\n\n You can use the ``bytes.maketrans()`` method to create a\n translation table.\n\n Set the *table* argument to ``None`` for translations that only\n delete characters:\n\n >>> b\'read this short text\'.translate(None, b\'aeiou\')\n b\'rd ths shrt txt\'\n\nstatic bytes.maketrans(from, to)\nstatic bytearray.maketrans(from, to)\n\n This static method returns a translation table usable for\n ``bytes.translate()`` that will map each character in *from* into\n the character at the same position in *to*; *from* and *to* must be\n bytes objects and have the same length.\n\n New in version 3.1.\n',
'typesseq-mutable': '\nMutable Sequence Types\n**********************\n\nList and bytearray objects support additional operations that allow\nin-place modification of the object. Other mutable sequence types\n(when added to the language) should also support these operations.\nStrings and tuples are immutable sequence types: such objects cannot\nbe modified once created. The following operations are defined on\nmutable sequence types (where *x* is an arbitrary object).\n\nNote that while lists allow their items to be of any type, bytearray\nobject "items" are all integers in the range 0 <= x < 256.\n\n+--------------------------------+----------------------------------+-----------------------+\n| Operation | Result | Notes |\n+================================+==================================+=======================+\n| ``s[i] = x`` | item *i* of *s* is replaced by | |\n| | *x* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j] = t`` | slice of *s* from *i* to *j* is | |\n| | replaced by the contents of the | |\n| | iterable *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j]`` | same as ``s[i:j] = []`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s[i:j:k] = t`` | the elements of ``s[i:j:k]`` are | (1) |\n| | replaced by those of *t* | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``del s[i:j:k]`` | removes the elements of | |\n| | ``s[i:j:k]`` from the list | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.append(x)`` | same as ``s[len(s):len(s)] = | |\n| | [x]`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.extend(x)`` | same as ``s[len(s):len(s)] = x`` | (2) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.count(x)`` | return number of *i*\'s for which | |\n| | ``s[i] == x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.index(x[, i[, j]])`` | return smallest *k* such that | (3) |\n| | ``s[k] == x`` and ``i <= k < j`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.insert(i, x)`` | same as ``s[i:i] = [x]`` | (4) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.pop([i])`` | same as ``x = s[i]; del s[i]; | (5) |\n| | return x`` | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.remove(x)`` | same as ``del s[s.index(x)]`` | (3) |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.reverse()`` | reverses the items of *s* in | (6) |\n| | place | |\n+--------------------------------+----------------------------------+-----------------------+\n| ``s.sort([key[, reverse]])`` | sort the items of *s* in place | (6), (7), (8) |\n+--------------------------------+----------------------------------+-----------------------+\n\nNotes:\n\n1. *t* must have the same length as the slice it is replacing.\n\n2. *x* can be any iterable object.\n\n3. Raises ``ValueError`` when *x* is not found in *s*. When a negative\n index is passed as the second or third parameter to the ``index()``\n method, the sequence length is added, as for slice indices. If it\n is still negative, it is truncated to zero, as for slice indices.\n\n4. When a negative index is passed as the first parameter to the\n ``insert()`` method, the sequence length is added, as for slice\n indices. If it is still negative, it is truncated to zero, as for\n slice indices.\n\n5. The optional argument *i* defaults to ``-1``, so that by default\n the last item is removed and returned.\n\n6. The ``sort()`` and ``reverse()`` methods modify the sequence in\n place for economy of space when sorting or reversing a large\n sequence. To remind you that they operate by side effect, they\n don\'t return the sorted or reversed sequence.\n\n7. The ``sort()`` method takes optional arguments for controlling the\n comparisons. Each must be specified as a keyword argument.\n\n *key* specifies a function of one argument that is used to extract\n a comparison key from each list element: ``key=str.lower``. The\n default value is ``None``. Use ``functools.cmp_to_key()`` to\n convert an old-style *cmp* function to a *key* function.\n\n *reverse* is a boolean value. If set to ``True``, then the list\n elements are sorted as if each comparison were reversed.\n\n The ``sort()`` method is guaranteed to be stable. A sort is stable\n if it guarantees not to change the relative order of elements that\n compare equal --- this is helpful for sorting in multiple passes\n (for example, sort by department, then by salary grade).\n\n **CPython implementation detail:** While a list is being sorted,\n the effect of attempting to mutate, or even inspect, the list is\n undefined. The C implementation of Python makes the list appear\n empty for the duration, and raises ``ValueError`` if it can detect\n that the list has been mutated during a sort.\n\n8. ``sort()`` is not supported by ``bytearray`` objects.\n',
'unary': '\nUnary arithmetic and bitwise operations\n***************************************\n\nAll unary arithmetic and bitwise operations have the same priority:\n\n u_expr ::= power | "-" u_expr | "+" u_expr | "~" u_expr\n\nThe unary ``-`` (minus) operator yields the negation of its numeric\nargument.\n\nThe unary ``+`` (plus) operator yields its numeric argument unchanged.\n\nThe unary ``~`` (invert) operator yields the bitwise inversion of its\ninteger argument. The bitwise inversion of ``x`` is defined as\n``-(x+1)``. It only applies to integral numbers.\n\nIn all three cases, if the argument does not have the proper type, a\n``TypeError`` exception is raised.\n',
'while': '\nThe ``while`` statement\n***********************\n\nThe ``while`` statement is used for repeated execution as long as an\nexpression is true:\n\n while_stmt ::= "while" expression ":" suite\n ["else" ":" suite]\n\nThis repeatedly tests the expression and, if it is true, executes the\nfirst suite; if the expression is false (which may be the first time\nit is tested) the suite of the ``else`` clause, if present, is\nexecuted and the loop terminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ngoes back to testing the expression.\n',
- 'with': '\nThe ``with`` statement\n**********************\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n',
+ 'with': '\nThe ``with`` statement\n**********************\n\nThe ``with`` statement is used to wrap the execution of a block with\nmethods defined by a context manager (see section *With Statement\nContext Managers*). This allows common\n``try``...``except``...``finally`` usage patterns to be encapsulated\nfor convenient reuse.\n\n with_stmt ::= "with" with_item ("," with_item)* ":" suite\n with_item ::= expression ["as" target]\n\nThe execution of the ``with`` statement with one "item" proceeds as\nfollows:\n\n1. The context expression (the expression given in the ``with_item``)\n is evaluated to obtain a context manager.\n\n2. The context manager\'s ``__exit__()`` is loaded for later use.\n\n3. The context manager\'s ``__enter__()`` method is invoked.\n\n4. If a target was included in the ``with`` statement, the return\n value from ``__enter__()`` is assigned to it.\n\n Note: The ``with`` statement guarantees that if the ``__enter__()``\n method returns without an error, then ``__exit__()`` will always\n be called. Thus, if an error occurs during the assignment to the\n target list, it will be treated the same as an error occurring\n within the suite would be. See step 6 below.\n\n5. The suite is executed.\n\n6. The context manager\'s ``__exit__()`` method is invoked. If an\n exception caused the suite to be exited, its type, value, and\n traceback are passed as arguments to ``__exit__()``. Otherwise,\n three ``None`` arguments are supplied.\n\n If the suite was exited due to an exception, and the return value\n from the ``__exit__()`` method was false, the exception is\n reraised. If the return value was true, the exception is\n suppressed, and execution continues with the statement following\n the ``with`` statement.\n\n If the suite was exited for any reason other than an exception, the\n return value from ``__exit__()`` is ignored, and execution proceeds\n at the normal location for the kind of exit that was taken.\n\nWith more than one item, the context managers are processed as if\nmultiple ``with`` statements were nested:\n\n with A() as a, B() as b:\n suite\n\nis equivalent to\n\n with A() as a:\n with B() as b:\n suite\n\nChanged in version 3.1: Support for multiple context expressions.\n\nSee also:\n\n **PEP 0343** - The "with" statement\n The specification, background, and examples for the Python\n ``with`` statement.\n',
'yield': '\nThe ``yield`` statement\n***********************\n\n yield_stmt ::= yield_expression\n\nThe ``yield`` statement is only used when defining a generator\nfunction, and is only used in the body of the generator function.\nUsing a ``yield`` statement in a function definition is sufficient to\ncause that definition to create a generator function instead of a\nnormal function. When a generator function is called, it returns an\niterator known as a generator iterator, or more commonly, a generator.\nThe body of the generator function is executed by calling the\n``next()`` function on the generator repeatedly until it raises an\nexception.\n\nWhen a ``yield`` statement is executed, the state of the generator is\nfrozen and the value of ``expression_list`` is returned to\n``next()``\'s caller. By "frozen" we mean that all local state is\nretained, including the current bindings of local variables, the\ninstruction pointer, and the internal evaluation stack: enough\ninformation is saved so that the next time ``next()`` is invoked, the\nfunction can proceed exactly as if the ``yield`` statement were just\nanother external call.\n\nThe ``yield`` statement is allowed in the ``try`` clause of a ``try``\n... ``finally`` construct. If the generator is not resumed before it\nis finalized (by reaching a zero reference count or by being garbage\ncollected), the generator-iterator\'s ``close()`` method will be\ncalled, allowing any pending ``finally`` clauses to execute.\n\nSee also:\n\n **PEP 0255** - Simple Generators\n The proposal for adding generators and the ``yield`` statement\n to Python.\n\n **PEP 0342** - Coroutines via Enhanced Generators\n The proposal that, among other generator enhancements, proposed\n allowing ``yield`` to appear inside a ``try`` ... ``finally``\n block.\n'}
From python-checkins at python.org Sun Sep 5 10:30:10 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 10:30:10 +0200 (CEST)
Subject: [Python-checkins] r84521 - sandbox/trunk/release/release.py
Message-ID: <20100905083010.1CA2AEE9C0@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 10:30:09 2010
New Revision: 84521
Log:
Fix constant name.
Modified:
sandbox/trunk/release/release.py
Modified: sandbox/trunk/release/release.py
==============================================================================
--- sandbox/trunk/release/release.py (original)
+++ sandbox/trunk/release/release.py Sun Sep 5 10:30:09 2010
@@ -148,7 +148,7 @@
print('File was renamed; please commit')
run_cmd(['svn', 'commit'])
new = '%define version ' + tag.text + \
- '\n%define libver ' + tag.basic_version
+ '\n%define libvers ' + tag.basic_version
constant_replace(wanted_file, new, '#', '')
print('done')
From python-checkins at python.org Sun Sep 5 10:30:40 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 10:30:40 +0200 (CEST)
Subject: [Python-checkins] r84522 - in python/branches/py3k:
Include/patchlevel.h Lib/distutils/__init__.py
Lib/idlelib/idlever.py Misc/NEWS Misc/RPM/python-3.2.spec README
Message-ID: <20100905083040.C3E7FEE999@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 10:30:40 2010
New Revision: 84522
Log:
Bump to 3.2a2.
Modified:
python/branches/py3k/Include/patchlevel.h
python/branches/py3k/Lib/distutils/__init__.py
python/branches/py3k/Lib/idlelib/idlever.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Misc/RPM/python-3.2.spec
python/branches/py3k/README
Modified: python/branches/py3k/Include/patchlevel.h
==============================================================================
--- python/branches/py3k/Include/patchlevel.h (original)
+++ python/branches/py3k/Include/patchlevel.h Sun Sep 5 10:30:40 2010
@@ -20,10 +20,10 @@
#define PY_MINOR_VERSION 2
#define PY_MICRO_VERSION 0
#define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA
-#define PY_RELEASE_SERIAL 1
+#define PY_RELEASE_SERIAL 2
/* Version as a string */
-#define PY_VERSION "3.2a1+"
+#define PY_VERSION "3.2a2"
/*--end constants--*/
/* Subversion Revision number of this file (not of the repository) */
Modified: python/branches/py3k/Lib/distutils/__init__.py
==============================================================================
--- python/branches/py3k/Lib/distutils/__init__.py (original)
+++ python/branches/py3k/Lib/distutils/__init__.py Sun Sep 5 10:30:40 2010
@@ -15,5 +15,5 @@
# Updated automatically by the Python release process.
#
#--start constants--
-__version__ = "3.2a1"
+__version__ = "3.2a2"
#--end constants--
Modified: python/branches/py3k/Lib/idlelib/idlever.py
==============================================================================
--- python/branches/py3k/Lib/idlelib/idlever.py (original)
+++ python/branches/py3k/Lib/idlelib/idlever.py Sun Sep 5 10:30:40 2010
@@ -1 +1 @@
-IDLE_VERSION = "3.2a1"
+IDLE_VERSION = "3.2a2"
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 5 10:30:40 2010
@@ -7,7 +7,7 @@
What's New in Python 3.2 Alpha 2?
=================================
-*Release date: XX-Sep-2010*
+*Release date: 05-Sep-2010*
Core and Builtins
-----------------
Modified: python/branches/py3k/Misc/RPM/python-3.2.spec
==============================================================================
--- python/branches/py3k/Misc/RPM/python-3.2.spec (original)
+++ python/branches/py3k/Misc/RPM/python-3.2.spec Sun Sep 5 10:30:40 2010
@@ -39,7 +39,7 @@
%define name python
#--start constants--
-%define version 3.2a1
+%define version 3.2a2
%define libvers 3.2
#--end constants--
%define release 1pydotorg
Modified: python/branches/py3k/README
==============================================================================
--- python/branches/py3k/README (original)
+++ python/branches/py3k/README Sun Sep 5 10:30:40 2010
@@ -1,4 +1,4 @@
-This is Python version 3.2 alpha 1
+This is Python version 3.2 alpha 2
==================================
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
From python-checkins at python.org Sun Sep 5 10:35:38 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 10:35:38 +0200 (CEST)
Subject: [Python-checkins] r84523 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905083538.6ADF5FB8D@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 10:35:38 2010
New Revision: 84523
Log:
Add PEP 391 to whatsnew
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 10:35:38 2010
@@ -51,6 +51,49 @@
This article explains the new features in Python 3.2, compared to 3.1.
+PEP 391: Dictionary Based Configuration for Logging
+===================================================
+
+The :mod:`logging` module had two ways of configuring the module, either
+calling functions for each option or by reading an external file saved
+in a ConfigParser format. Those options did not provide the flexibility
+to create configurations from JSON or YAML files and they did not support
+incremental configuration which is needed for specifying logger options
+from a command line.
+
+To support a more flexible style, the module now offers
+:func:`logging.config.dictConfig` to use dictionaries to specify logger
+configurations (including formatters, handlers, filters, and loggers).
+For example::
+
+ >>> import logging.config
+ >>> logging.config.dictConfig(json.load(open('log.cfg', 'rb')))
+
+The above fragment configures logging from a JSON encoded dictionary stored in
+file called "log.cfg". Here's a working example of a configuration dictionary::
+
+ {"version": 1,
+ "formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
+ "full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"},
+ },
+ "handlers": {"console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"},
+ "console_priority": {
+ "class": "logging.StreamHandler",
+ "formatter": "full",
+ "level": "ERROR",
+ "stream": "ext://sys.stderr"},
+ },
+ "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
+
+.. seealso::
+
+ :pep:`391` - Dictionary Based Configuration for Logging
+ PEP written by Vinay Sajip.
+
PEP 3147: PYC Repository Directories
=====================================
From python-checkins at python.org Sun Sep 5 10:46:36 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 10:46:36 +0200 (CEST)
Subject: [Python-checkins] r84524 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905084636.55287EE9AA@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 10:46:36 2010
New Revision: 84524
Log:
Add example of ftplib's new context manager.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 10:46:36 2010
@@ -216,7 +216,7 @@
:issue:`8814`.)
* The :mod:`abc` module now supports :func:`abstractclassmethod` and
- :func:`staticmethod`.
+ :func:`abstractstaticmethod`.
(:issue:`5867`)
@@ -261,6 +261,20 @@
`appspot issue 53094 `_.)
* The :class:`ftplib.FTP` class now supports the context manager protocol
+ to unconditionally consume :exc:`socket.error` exceptions and to close
+ the ftp connection when done::
+
+ >>> from ftplib import FTP
+ >>> with FTP("ftp1.at.proftpd.org") as ftp:
+ ... ftp.login()
+ ... ftp.dir()
+ ...
+ '230 Anonymous login ok, restrictions apply.'
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
+ dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
+ dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
+
(Contributed by Tarek Ziad? and Giampaolo Rodol?; :issue:`4972`.)
* A warning message will now get printed at interpreter shutdown if
@@ -270,16 +284,17 @@
* The :mod:`os` module now has the :const:`ST_RDONLY` and :const:`ST_NOSUID`
constants, for use with the :func:`~os.statvfs` function.
+
(Patch by Adam Jackson; :issue:`7647`.)
* The :func:`shutil.copytree` function has two new options:
- * *ignore_dangling_symlinks*: when ``symlinks=False`` (meaning that the
+ * *ignore_dangling_symlinks*: when ``symlinks=False`` dp that the
function copies the file pointed to by the symlink, not the symlink
- itself) this option will silence the error raised if the file doesn't
+ itself. This option will silence the error raised if the file doesn't
exist.
- * *copy_function*: a callable that will be used to copy files.
+ * *copy_function*: is a callable that will be used to copy files.
:func:`shutil.copy2` is used by default.
(Contributed by Tarek Ziad?.)
From python-checkins at python.org Sun Sep 5 10:54:32 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 5 Sep 2010 10:54:32 +0200 (CEST)
Subject: [Python-checkins] r84525 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905085432.70434F860@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 5 10:54:32 2010
New Revision: 84525
Log:
Fill-in sqlite3 stubs
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 10:54:32 2010
@@ -305,16 +305,17 @@
(Added by Antoine Pitrou; :issue:`8524`.)
-* The :mod:`sqlite3` module has some new features:
+* The :mod:`sqlite3` module has two new capabilities.
- * XXX *enable_load_extension*
+ The :attr:`Connection.in_transit` attribute is true if there is an
+ active transaction for uncommitted changes.
- * XXX *load_extension*
+ The :meth:`Connection.enable_load_extension` and
+ :meth:`Connection.load_extension` methods allows you to load SQLite extensions
+ from ".so" files. One well-known extension is the fulltext-search extension
+ distributed with SQLite.
- * New :class:`~sqlite3.Connection` attribute
- :attr:`~sqlite3.Connection.in_transaction` is :const:`True` when there
- are uncommitted changes, and :const:`False` otherwise. (Contributed
- by R. David Murray and Shashwat Anand, :issue:`8845`.)
+ (Contributed by R. David Murray and Shashwat Anand, :issue:`8845`.)
* The :mod:`ssl` module has a new class, :class:`~ssl.SSLContext` which
serves as a container for various persistent SSL data, such as protocol
From python-checkins at python.org Sun Sep 5 11:06:42 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 11:06:42 +0200 (CEST)
Subject: [Python-checkins] r84526 - sandbox/trunk/release/release.py
Message-ID: <20100905090642.02377EE999@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 11:06:41 2010
New Revision: 84526
Log:
Fix a few nits and unbound locals.
Modified:
sandbox/trunk/release/release.py
Modified: sandbox/trunk/release/release.py
==============================================================================
--- sandbox/trunk/release/release.py (original)
+++ sandbox/trunk/release/release.py Sun Sep 5 11:06:41 2010
@@ -3,7 +3,7 @@
"""An assistant for making Python releases.
Original code by Benjamin Peterson
-Additions by Barry Warsaw and Benjamin Peterson
+Additions by Barry Warsaw, Georg Brandl and Benjamin Peterson
"""
import sys
@@ -13,7 +13,6 @@
import re
import subprocess
import shutil
-import tempfile
from contextlib import contextmanager
from string import Template
@@ -44,6 +43,8 @@
code = subprocess.call(cmd, shell=True)
except OSError:
error('%s failed' % cmd)
+ else:
+ return code
def check_env():
@@ -249,7 +250,6 @@
def export(tag):
make_dist()
- old_cur = os.getcwd()
with changed_dir('dist'):
print('Exporting tag:', tag.text)
archivename = 'Python-%s' % tag.text
@@ -310,7 +310,7 @@
"""scp everything to dinsdale"""
address ='"%s at dinsdale.python.org:' % username
def scp(from_loc, to_loc):
- run_cmd(['scp %s %s' % (from_loc, to_loc)])
+ run_cmd(['scp %s %s' % (from_loc, address + to_loc)])
with changed_dir('dist'):
print("Uploading source tarballs")
scp('src', '/data/python-releases/%s' % tag.nickname)
@@ -325,7 +325,7 @@
def __init__(self, tag_name):
result = tag_cre.search(tag_name)
if result is None:
- error('tag %s is not valid' % tag)
+ error('tag %s is not valid' % tag_name)
data = list(result.groups())
if data[3] is None:
# A final release.
From python-checkins at python.org Sun Sep 5 11:27:23 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 11:27:23 +0200 (CEST)
Subject: [Python-checkins] r84527 - sandbox/trunk/release/release.py
Message-ID: <20100905092723.AE5F9FBFF@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 11:27:23 2010
New Revision: 84527
Log:
Use new-style string formatting.
Modified:
sandbox/trunk/release/release.py
Modified: sandbox/trunk/release/release.py
==============================================================================
--- sandbox/trunk/release/release.py (original)
+++ sandbox/trunk/release/release.py Sun Sep 5 11:27:23 2010
@@ -15,7 +15,6 @@
import shutil
from contextlib import contextmanager
-from string import Template
from urllib.parse import urlsplit, urlunsplit
COMMASPACE = ', '
@@ -108,27 +107,23 @@
def tweak_patchlevel(tag, done=False):
print('Updating Include/patchlevel.h...', end=' ')
- template = Template("""\
-#define PY_MAJOR_VERSION\t$major
-#define PY_MINOR_VERSION\t$minor
-#define PY_MICRO_VERSION\t$patch
-#define PY_RELEASE_LEVEL\t$level
-#define PY_RELEASE_SERIAL\t$serial
+ template = """\
+#define PY_MAJOR_VERSION\t{tag.major}
+#define PY_MINOR_VERSION\t{tag.minor}
+#define PY_MICRO_VERSION\t{tag.patch}
+#define PY_RELEASE_LEVEL\t{level_def}
+#define PY_RELEASE_SERIAL\t{tag.serial}
/* Version as a string */
-#define PY_VERSION \t\"$text\"""")
- substitutions = {}
- for what in ('major', 'minor', 'patch', 'serial', 'text'):
- substitutions[what] = getattr(tag, what)
- substitutions['level'] = dict(
+#define PY_VERSION \t\"{tag.text}{plus}\""""
+ level_def = dict(
a = 'PY_RELEASE_LEVEL_ALPHA',
b = 'PY_RELEASE_LEVEL_BETA',
rc = 'PY_RELEASE_LEVEL_GAMMA',
f = 'PY_RELEASE_LEVEL_FINAL',
)[tag.level]
- if done:
- substitutions['text'] += '+'
- new_constants = template.substitute(substitutions)
+ new_constants = template.format(tag=tag, level_def=level_def,
+ plus=done and '+' or '')
constant_replace('Include/patchlevel.h', new_constants)
print('done')
From python-checkins at python.org Sun Sep 5 13:28:33 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 13:28:33 +0200 (CEST)
Subject: [Python-checkins] r84528 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905112833.97F68F629@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 13:28:33 2010
New Revision: 84528
Log:
Rewrap and consistency fixes.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 13:28:33 2010
@@ -36,14 +36,12 @@
necessary (especially when a final release is some months away).
* Credit the author of a patch or bugfix. Just the name is
- sufficient; the e-mail address isn't necessary.
+ sufficient; the e-mail address isn't necessary. It's helpful to
+ add the issue number:
- * It's helpful to add the bug/patch number as a comment:
-
- % Patch 12345
XXX Describe the transmogrify() function added to the socket
module.
- (Contributed by P.Y. Developer.)
+ (Contributed by P.Y. Developer; :issue:`12345`.)
This saves the maintainer the effort of going through the SVN log
when researching a change.
@@ -54,46 +52,46 @@
PEP 391: Dictionary Based Configuration for Logging
===================================================
-The :mod:`logging` module had two ways of configuring the module, either
-calling functions for each option or by reading an external file saved
-in a ConfigParser format. Those options did not provide the flexibility
-to create configurations from JSON or YAML files and they did not support
-incremental configuration which is needed for specifying logger options
-from a command line.
+The :mod:`logging` module had two ways of configuring the module, either calling
+functions for each option or by reading an external file saved in a ConfigParser
+format. Those options did not provide the flexibility to create configurations
+from JSON or YAML files and they did not support incremental configuration which
+is needed for specifying logger options from a command line.
To support a more flexible style, the module now offers
:func:`logging.config.dictConfig` to use dictionaries to specify logger
-configurations (including formatters, handlers, filters, and loggers).
-For example::
+configurations (including formatters, handlers, filters, and loggers). For
+example:
- >>> import logging.config
- >>> logging.config.dictConfig(json.load(open('log.cfg', 'rb')))
+>>> import logging.config
+>>> logging.config.dictConfig(json.load(open('log.cfg', 'rb')))
The above fragment configures logging from a JSON encoded dictionary stored in
file called "log.cfg". Here's a working example of a configuration dictionary::
- {"version": 1,
- "formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
- "full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"},
- },
- "handlers": {"console": {
- "class": "logging.StreamHandler",
- "formatter": "brief",
- "level": "INFO",
- "stream": "ext://sys.stdout"},
- "console_priority": {
- "class": "logging.StreamHandler",
- "formatter": "full",
- "level": "ERROR",
- "stream": "ext://sys.stderr"},
- },
- "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
+ {"version": 1,
+ "formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
+ "full": {"format": "%(asctime)s %(name)-15s %(levelname)-8s %(message)s"},
+ },
+ "handlers": {"console": {
+ "class": "logging.StreamHandler",
+ "formatter": "brief",
+ "level": "INFO",
+ "stream": "ext://sys.stdout"},
+ "console_priority": {
+ "class": "logging.StreamHandler",
+ "formatter": "full",
+ "level": "ERROR",
+ "stream": "ext://sys.stderr"},
+ },
+ "root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
.. seealso::
:pep:`391` - Dictionary Based Configuration for Logging
PEP written by Vinay Sajip.
+
PEP 3147: PYC Repository Directories
=====================================
@@ -117,28 +115,28 @@
Aside from the filenames and target directories, the new scheme has a few
aspects that are visible to the programmer:
-* Imported modules now have a :attr:`__cached__` attribute which stores the
- name of the actual file that was imported::
+* Imported modules now have a :attr:`__cached__` attribute which stores the name
+ of the actual file that was imported:
- >>> import collections
- >>> collections.__cached__
- 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
+ >>> import collections
+ >>> collections.__cached__
+ 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
* The tag that is unique to each interpreter is accessible from the :mod:`imp`
- module::
+ module:
- >>> import imp
- >>> imp.get_tag()
- 'cpython-32'
+ >>> import imp
+ >>> imp.get_tag()
+ 'cpython-32'
* Scripts that try to deduce source filename from the imported file now need to
be smarter. It is no longer sufficient to simply strip the "c" from a ".pyc"
filename. Instead, use the new functions in the :mod:`imp` module:
- >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')
- 'c:/py32/lib/collections.py'
- >>> imp.cache_from_source('c:/py32/lib/collections.py')
- 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
+ >>> imp.source_from_cache('c:/py32/lib/__pycache__/collections.cpython-32.pyc')
+ 'c:/py32/lib/collections.py'
+ >>> imp.cache_from_source('c:/py32/lib/collections.py')
+ 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
* The :mod:`py_compile` and :mod:`compileall` modules have been updated to
reflect the new naming convention and target directory.
@@ -148,6 +146,7 @@
:pep:`3147` - PYC Repository Directories
PEP written by Barry Warsaw.
+
PEP 3149 ABI Version Tagged .so Files
=====================================
@@ -184,27 +183,27 @@
Some smaller changes made to the core Python language are:
-* The :func:`hasattr` function used to catch and suppress any Exception.
- Now, it only catches :exc:`AttributeError`. Under the hood, :func:`hasattr`
- works by calling :func:`getattr` and throwing away the results. This is
- necessary because dynamic attribute creation is possible using
- :meth:`__getattribute__` or :meth:`__getattr`. If :func:`hasattr` were to
- just scan instance and class dictionaries it would miss the dynmaic methods
- and make it difficult to implement proxy objects.
+* The :func:`hasattr` function used to catch and suppress any Exception. Now,
+ it only catches :exc:`AttributeError`. Under the hood, :func:`hasattr` works
+ by calling :func:`getattr` and throwing away the results. This is necessary
+ because dynamic attribute creation is possible using :meth:`__getattribute__`
+ or :meth:`__getattr`. If :func:`hasattr` were to just scan instance and class
+ dictionaries it would miss the dynmaic methods and make it difficult to
+ implement proxy objects.
(Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.)
* The :func:`str` of a float or complex number is now the same as it
:func:`repr`. Previously, the :func:`str` form was shorter but that just
caused confusion and is no longer needed now that we the shortest possible
- :func:`repr` is displayed by default::
+ :func:`repr` is displayed by default:
- >>> repr(math.pi)
- '3.141592653589793'
- >>> str(math.pi)
- '3.141592653589793'
+ >>> repr(math.pi)
+ '3.141592653589793'
+ >>> str(math.pi)
+ '3.141592653589793'
- (Proposed and implemented by Mark Dickinson; :issue:`9337`).
+ (Proposed and implemented by Mark Dickinson; :issue:`9337`.)
* The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
pointing to the original callable function. This allows wrapped functions to
@@ -218,68 +217,70 @@
* The :mod:`abc` module now supports :func:`abstractclassmethod` and
:func:`abstractstaticmethod`.
- (:issue:`5867`)
+ (:issue:`5867`.)
+
New, Improved, and Deprecated Modules
=====================================
-* The :mod:`functools` module now includes a new decorator for caching
- function calls. :func:`functools.lru_cache` can save repeated queries to an
- external resource whenever the results are expected to be the same.
+* The :mod:`functools` module now includes a new decorator for caching function
+ calls. :func:`functools.lru_cache` can save repeated queries to an external
+ resource whenever the results are expected to be the same.
For example, adding a caching decorator to a database query function can save
database accesses for popular searches::
- @functools.lru_cache(maxsize=300)
- def get_phone_number(name):
- c = conn.cursor()
- c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
- return c.fetchone()[0]
+ @functools.lru_cache(maxsize=300)
+ def get_phone_number(name):
+ c = conn.cursor()
+ c.execute('SELECT phonenumber FROM phonelist WHERE name=?', (name,))
+ return c.fetchone()[0]
To help with choosing an effective cache size, the wrapped function is
- instrumented with two attributes *cache_hits* and *cache_misses*::
+ instrumented with two attributes *cache_hits* and *cache_misses*:
- >>> for name in user_requests:
- ... get_phone_number(name)
- >>> print(get_phone_number.cache_hits, get_phone_number.cache_misses)
- 4805 980
+ >>> for name in user_requests:
+ ... get_phone_number(name)
+ >>> print(get_phone_number.cache_hits, get_phone_number.cache_misses)
+ 4805 980
If the phonelist table gets updated, the outdated contents of the cache can be
- cleared with::
+ cleared with:
- >>> get_phone_number.cache_clear()
+ >>> get_phone_number.cache_clear()
- (Contributed by Raymond Hettinger)
+ (Contributed by Raymond Hettinger.)
-* The previously deprecated :func:`contextlib.nested` function has been
- removed in favor of a plain :keyword:`with` statement which can
- accept multiple context managers. The latter technique is faster
- (because it is built-in), and it does a better job finalizing multiple
- context managers when one of them raises an exception.
+* The previously deprecated :func:`contextlib.nested` function has been removed
+ in favor of a plain :keyword:`with` statement which can accept multiple
+ context managers. The latter technique is faster (because it is built-in),
+ and it does a better job finalizing multiple context managers when one of them
+ raises an exception.
(Contributed by Georg Brandl and Mattias Br?ndstr?m;
`appspot issue 53094 `_.)
-* The :class:`ftplib.FTP` class now supports the context manager protocol
- to unconditionally consume :exc:`socket.error` exceptions and to close
- the ftp connection when done::
-
- >>> from ftplib import FTP
- >>> with FTP("ftp1.at.proftpd.org") as ftp:
- ... ftp.login()
- ... ftp.dir()
- ...
- '230 Anonymous login ok, restrictions apply.'
- dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
- dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
- dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
- dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
+* The :class:`ftplib.FTP` class now supports the context manager protocol to
+ unconditionally consume :exc:`socket.error` exceptions and to close the ftp
+ connection when done:
+
+ >>> from ftplib import FTP
+ >>> with FTP("ftp1.at.proftpd.org") as ftp:
+ ... ftp.login()
+ ... ftp.dir()
+ ...
+ '230 Anonymous login ok, restrictions apply.'
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
+ dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
+ dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
(Contributed by Tarek Ziad? and Giampaolo Rodol?; :issue:`4972`.)
-* A warning message will now get printed at interpreter shutdown if
- the :data:`gc.garbage` list isn't empty. This is meant to make the
- programmer aware that his code contains object finalization issues.
+* A warning message will now get printed at interpreter shutdown if the
+ :data:`gc.garbage` list isn't empty. This is meant to make the programmer
+ aware that his code contains object finalization issues.
+
(Added by Antoine Pitrou; :issue:`477863`.)
* The :mod:`os` module now has the :const:`ST_RDONLY` and :const:`ST_NOSUID`
@@ -289,72 +290,66 @@
* The :func:`shutil.copytree` function has two new options:
- * *ignore_dangling_symlinks*: when ``symlinks=False`` dp that the
- function copies the file pointed to by the symlink, not the symlink
- itself. This option will silence the error raised if the file doesn't
- exist.
+ * *ignore_dangling_symlinks*: when ``symlinks=False`` dp that the function
+ copies the file pointed to by the symlink, not the symlink itself. This
+ option will silence the error raised if the file doesn't exist.
* *copy_function*: is a callable that will be used to copy files.
:func:`shutil.copy2` is used by default.
(Contributed by Tarek Ziad?.)
-* Socket objects now have a :meth:`~socket.socket.detach()` method which
- puts the socket into closed state without actually closing the underlying
- file descriptor. The latter can then be reused for other purposes.
+* Socket objects now have a :meth:`~socket.socket.detach()` method which puts
+ the socket into closed state without actually closing the underlying file
+ descriptor. The latter can then be reused for other purposes.
(Added by Antoine Pitrou; :issue:`8524`.)
* The :mod:`sqlite3` module has two new capabilities.
- The :attr:`Connection.in_transit` attribute is true if there is an
- active transaction for uncommitted changes.
+ The :attr:`Connection.in_transit` attribute is true if there is an active
+ transaction for uncommitted changes.
The :meth:`Connection.enable_load_extension` and
:meth:`Connection.load_extension` methods allows you to load SQLite extensions
from ".so" files. One well-known extension is the fulltext-search extension
distributed with SQLite.
- (Contributed by R. David Murray and Shashwat Anand, :issue:`8845`.)
+ (Contributed by R. David Murray and Shashwat Anand; :issue:`8845`.)
-* The :mod:`ssl` module has a new class, :class:`~ssl.SSLContext` which
- serves as a container for various persistent SSL data, such as protocol
- settings, certificates, private keys, and various other options.
- The :meth:`~ssl.SSLContext.wrap_socket` method allows to create an
- SSL socket from such an SSL context.
- (Added by Antoine Pitrou; :issue:`8550`.)
-
- The :func:`ssl.wrap_socket` constructor function now takes a
- *ciphers* argument that's a string listing the encryption algorithms
- to be allowed; the format of the string is described
- `in the OpenSSL documentation
- `__.
- (Added by Antoine Pitrou; :issue:`8322`.)
+* The :mod:`ssl` module has a new class, :class:`~ssl.SSLContext` which serves
+ as a container for various persistent SSL data, such as protocol settings,
+ certificates, private keys, and various other options. The
+ :meth:`~ssl.SSLContext.wrap_socket` method allows to create an SSL socket from
+ such an SSL context. (Added by Antoine Pitrou; :issue:`8550`.)
+
+ The :func:`ssl.wrap_socket` constructor function now takes a *ciphers*
+ argument that's a string listing the encryption algorithms to be allowed; the
+ format of the string is described `in the OpenSSL documentation
+ `__. (Added
+ by Antoine Pitrou; :issue:`8322`.)
Various options have been added to the :mod:`ssl` module, such as
- :data:`~ssl.OP_NO_SSLv2` which allows to force disabling of the insecure
- and obsolete SSLv2 protocol.
- (Added by Antoine Pitrou; :issue:`4870`.)
-
- Another change makes the extension load all of OpenSSL's ciphers and
- digest algorithms so that they're all available. Some SSL
- certificates couldn't be verified, reporting an "unknown algorithm"
- error. (Reported by Beda Kosata, and fixed by Antoine Pitrou;
- :issue:`8484`.)
-
- The version of OpenSSL being used is now available as the module
- attributes :data:`ssl.OPENSSL_VERSION` (a string),
- :data:`ssl.OPENSSL_VERSION_INFO` (a 5-tuple), and
- :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by Antoine
- Pitrou; :issue:`8321`.)
+ :data:`~ssl.OP_NO_SSLv2` which allows to force disabling of the insecure and
+ obsolete SSLv2 protocol. (Added by Antoine Pitrou; :issue:`4870`.)
-* The previously deprecated :func:`string.maketrans` function has been
- removed in favor of the static methods, :meth:`bytes.maketrans` and
+ Another change makes the extension load all of OpenSSL's ciphers and digest
+ algorithms so that they're all available. Some SSL certificates couldn't be
+ verified, reporting an "unknown algorithm" error. (Reported by Beda Kosata,
+ and fixed by Antoine Pitrou; :issue:`8484`.)
+
+ The version of OpenSSL being used is now available as the module attributes
+ :data:`ssl.OPENSSL_VERSION` (a string), :data:`ssl.OPENSSL_VERSION_INFO` (a
+ 5-tuple), and :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by
+ Antoine Pitrou; :issue:`8321`.)
+
+* The previously deprecated :func:`string.maketrans` function has been removed
+ in favor of the static methods, :meth:`bytes.maketrans` and
:meth:`bytearray.maketrans`. This change solves the confusion around which
- types were supported by the :mod:`string` module. Now, :class:`str`,
+ types were supported by the :mod:`string` module. Now, :class:`str`,
:class:`bytes`, and :class:`bytearray` each have their own **maketrans** and
- **translate** methods with intermediate translation tables of the
- appropriate type.
+ **translate** methods with intermediate translation tables of the appropriate
+ type.
(Contributed by Georg Brandl; :issue:`5675`.)
@@ -365,44 +360,46 @@
(Contributed by Giampaolo Rodol?; :issue:`8807`.)
+
Multi-threading
===============
-* The mechanism for serializing execution of concurrently running Python
- threads (generally known as the GIL or Global Interpreter Lock) has been
- rewritten. Among the objectives were more predictable switching intervals
- and reduced overhead due to lock contention and the number of ensuing
- system calls. The notion of a "check interval" to allow thread switches
- has been abandoned and replaced by an absolute duration expressed in
- seconds. This parameter is tunable through :func:`sys.setswitchinterval()`.
- It currently defaults to 5 milliseconds.
+* The mechanism for serializing execution of concurrently running Python threads
+ (generally known as the GIL or Global Interpreter Lock) has been rewritten.
+ Among the objectives were more predictable switching intervals and reduced
+ overhead due to lock contention and the number of ensuing system calls. The
+ notion of a "check interval" to allow thread switches has been abandoned and
+ replaced by an absolute duration expressed in seconds. This parameter is
+ tunable through :func:`sys.setswitchinterval()`. It currently defaults to 5
+ milliseconds.
Additional details about the implementation can be read from a `python-dev
mailing-list message
`_
- (however, "priority requests" as exposed in this message have not been
- kept for inclusion).
+ (however, "priority requests" as exposed in this message have not been kept
+ for inclusion).
(Contributed by Antoine Pitrou.)
* Recursive locks (created with the :func:`threading.RLock` API) now benefit
- from a C implementation which makes them as fast as regular locks, and
- between 10x and 15x faster than their previous pure Python implementation.
+ from a C implementation which makes them as fast as regular locks, and between
+ 10x and 15x faster than their previous pure Python implementation.
(Contributed by Antoine Pitrou; :issue:`3001`.)
-* Regular and recursive locks now accept an optional *timeout* argument
- to their ``acquire`` method. (Contributed by Antoine Pitrou; :issue:`7316`)
+* Regular and recursive locks now accept an optional *timeout* argument to their
+ ``acquire`` method. (Contributed by Antoine Pitrou; :issue:`7316`.)
+
Similarly, :meth:`threading.Semaphore.acquire` also gains a *timeout*
- argument. (Contributed by Torsten Landschoff; :issue:`850728`.)
+ argument. (Contributed by Torsten Landschoff; :issue:`850728`.)
-Optimizations
-=============
+.. Optimizations
+ =============
-Major performance enhancements have been added:
+ Major performance enhancements have been added:
-* Stub
+ * Stub
Filenames and unicode
@@ -418,10 +415,10 @@
:func:`os.fsdecode`.
-IDLE
-====
+.. IDLE
+ ====
-* Stub
+ * Stub
Build and C API Changes
@@ -429,27 +426,30 @@
Changes to Python's build process and to the C API include:
-* The C functions that access the Unicode Database now accept and
- return characters from the full Unicode range, even on narrow unicode builds
+* The C functions that access the Unicode Database now accept and return
+ characters from the full Unicode range, even on narrow unicode builds
(Py_UNICODE_TOLOWER, Py_UNICODE_ISDECIMAL, and others). A visible difference
- in Python is that :cfunc:`unicodedata.numeric` now returns the correct value for
- large code points, and :func:`repr` may consider more characters as printable.
+ in Python is that :func:`unicodedata.numeric` now returns the correct value
+ for large code points, and :func:`repr` may consider more characters as
+ printable.
(Reported by Bupjoe Lee and fixed by Amaury Forgeot D'Arc; :issue:`5127`.)
-* Computed gotos are now enabled by default on supported
- compilers (which are detected by the configure script). They can still
- be disable selectively by specifying ``--without-computed-gotos``.
+* Computed gotos are now enabled by default on supported compilers (which are
+ detected by the configure script). They can still be disable selectively by
+ specifying ``--without-computed-gotos``.
+
+ (Contributed by Antoine Pitrou; :issue:`9203`.)
- (:issue:`9203`)
Porting to Python 3.2
=====================
-This section lists previously described changes and other bugfixes
-that may require changes to your code:
+This section lists previously described changes and other bugfixes that may
+require changes to your code:
-* bytearray objects cannot be used anymore as filenames: convert them to bytes
+* :class:`bytearray` objects cannot be used anymore as filenames: convert them
+ to :class:`bytes`.
* PyArg_Parse*() functions:
@@ -457,6 +457,6 @@
* "w" and "w#" formats has been removed: use "w*" instead
* The :ctype:`PyCObject` type, deprecated in 3.1, has been removed. To wrap
- opaque C pointers in Python objects, the :ctype:`PyCapsule` API should be
- used instead; the new type has a well defined interface for passing typing
- safety information and a less complicated signature for calling a destructor.
+ opaque C pointers in Python objects, the :ctype:`PyCapsule` API should be used
+ instead; the new type has a well defined interface for passing typing safety
+ information and a less complicated signature for calling a destructor.
From python-checkins at python.org Sun Sep 5 19:06:54 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 19:06:54 +0200 (CEST)
Subject: [Python-checkins] r84529 - python/branches/py3k/Misc/NEWS
Message-ID: <20100905170654.8D145EE9B8@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 19:06:50 2010
New Revision: 84529
Log:
Rewrap.
Modified:
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 5 19:06:50 2010
@@ -12,39 +12,38 @@
Core and Builtins
-----------------
-- Issue #9225: Remove the ROT_FOUR and DUP_TOPX opcode, the latter replaced
- by the new (and simpler) DUP_TOP_TWO. Performance isn't changed, but
- our bytecode is a bit simplified. Patch by Demur Rumed.
+- Issue #9225: Remove the ROT_FOUR and DUP_TOPX opcode, the latter replaced by
+ the new (and simpler) DUP_TOP_TWO. Performance isn't changed, but our
+ bytecode is a bit simplified. Patch by Demur Rumed.
- Issue #9766: Rename poorly named variables exposed by _warnings to prevent
confusion with the proper variables names from 'warnings' itself.
-- Issue #9212: dict_keys and dict_items now provide the isdisjoint()
- method, to conform to the Set ABC. Patch by Daniel Urban.
+- Issue #9212: dict_keys and dict_items now provide the isdisjoint() method, to
+ conform to the Set ABC. Patch by Daniel Urban.
-- Issue #9737: Fix a crash when trying to delete a slice or an item from
- a memoryview object.
+- Issue #9737: Fix a crash when trying to delete a slice or an item from a
+ memoryview object.
-- Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding()
- are now removed, since their effect was inexistent in 3.x (the default
- encoding is hardcoded to utf-8 and cannot be changed).
+- Issue #9549: sys.setdefaultencoding() and PyUnicode_SetDefaultEncoding() are
+ now removed, since their effect was inexistent in 3.x (the default encoding is
+ hardcoded to utf-8 and cannot be changed).
- Issue #7415: PyUnicode_FromEncodedObject() now uses the new buffer API
properly. Patch by Stefan Behnel.
-- Issue #5553: The Py_LOCAL_INLINE macro now results in inlining on
- most platforms. Previously, it inlined when using Microsoft
- Visual C.
+- Issue #5553: The Py_LOCAL_INLINE macro now results in inlining on most
+ platforms. Previously, it inlined only when using Microsoft Visual C.
- Issue #9712: Fix tokenize on identifiers that start with non-ascii names.
- Issue #9688: __basicsize__ and __itemsize__ must be accessed as Py_ssize_t.
-- Issue #9684: Added a definition for SIZEOF_WCHAR_T to PC/pyconfig.h,
- to match the pyconfig.h generated by configure on other systems.
+- Issue #9684: Added a definition for SIZEOF_WCHAR_T to PC/pyconfig.h, to match
+ the pyconfig.h generated by configure on other systems.
-- Issue #9666: Only catch AttributeError in hasattr(). All other exceptions
- that occur during attribute lookup are now propagated to the caller.
+- Issue #9666: Only catch AttributeError in hasattr(). All other exceptions that
+ occur during attribute lookup are now propagated to the caller.
- Issue #8622: Add PYTHONFSENCODING environment variable to override the
filesystem encoding.
@@ -64,35 +63,34 @@
- Issue #9612: The set object is now 64-bit clean under Windows.
-- Issue #8202: sys.argv[0] is now set to '-m' instead of '-c' when searching
- for the module file to be executed with the -m command line option.
+- Issue #8202: sys.argv[0] is now set to '-m' instead of '-c' when searching for
+ the module file to be executed with the -m command line option.
-- Issue #9599: Create PySys_FormatStdout() and PySys_FormatStderr() functions
- to write a message formatted by PyUnicode_FromFormatV() to sys.stdout and
+- Issue #9599: Create PySys_FormatStdout() and PySys_FormatStderr() functions to
+ write a message formatted by PyUnicode_FromFormatV() to sys.stdout and
sys.stderr.
- Issue #9542: Create PyUnicode_FSDecoder() function, a ParseTuple converter:
- decode bytes objects to unicode using PyUnicode_DecodeFSDefaultAndSize();
- str objects are output as-is.
+ decode bytes objects to unicode using PyUnicode_DecodeFSDefaultAndSize(); str
+ objects are output as-is.
-- Issue #9203: Computed gotos are now enabled by default on supported
- compilers (which are detected by the configure script). They can still
- be disable selectively by specifying --without-computed-gotos.
+- Issue #9203: Computed gotos are now enabled by default on supported compilers
+ (which are detected by the configure script). They can still be disable
+ selectively by specifying --without-computed-gotos.
-- Issue #9425: Create PyErr_WarnFormat() function, similar to PyErr_WarnEx()
- but use PyUnicode_FromFormatV() to format the warning message.
+- Issue #9425: Create PyErr_WarnFormat() function, similar to PyErr_WarnEx() but
+ use PyUnicode_FromFormatV() to format the warning message.
-- Issue #8530: Prevent stringlib fastsearch from reading beyond the front
- of an array.
+- Issue #8530: Prevent stringlib fastsearch from reading beyond the front of an
+ array.
-- Issue #5319: Print an error if flushing stdout fails at interpreter
- shutdown.
+- Issue #5319: Print an error if flushing stdout fails at interpreter shutdown.
-- Issue #9337: The str() of a float or complex number is now identical
- to its repr().
+- Issue #9337: The str() of a float or complex number is now identical to its
+ repr().
-- Issue #9416: Fix some issues with complex formatting where the
- output with no type specifier failed to match the str output:
+- Issue #9416: Fix some issues with complex formatting where the output with no
+ type specifier failed to match the str output:
- format(complex(-0.0, 2.0), '-') omitted the real part from the output,
- format(complex(0.0, 2.0), '-') included a sign and parentheses.
@@ -103,103 +101,100 @@
- Issue #8734: Avoid crash in msvcrt.get_osfhandle() when an invalid file
descriptor is provided. Patch by Pascal Chambon.
-- Issue #7736: Release the GIL around calls to opendir() and closedir()
- in the posix module. Patch by Marcin Bachry.
+- Issue #7736: Release the GIL around calls to opendir() and closedir() in the
+ posix module. Patch by Marcin Bachry.
-- Issue #4835: make PyLong_FromSocket_t() and PyLong_AsSocket_t() private
- to the socket module, and fix the width of socket descriptors to be
- correctly detected under 64-bit Windows.
-
-- Issue #1027206: Support IDNA in gethostbyname, gethostbyname_ex,
- getaddrinfo and gethostbyaddr. getnameinfo is now restricted to numeric
- addresses as input.
+- Issue #4835: make PyLong_FromSocket_t() and PyLong_AsSocket_t() private to the
+ socket module, and fix the width of socket descriptors to be correctly
+ detected under 64-bit Windows.
+
+- Issue #1027206: Support IDNA in gethostbyname, gethostbyname_ex, getaddrinfo
+ and gethostbyaddr. getnameinfo is now restricted to numeric addresses as
+ input.
-- Issue #9214: Set operations on a KeysView or ItemsView in collections
- now correctly return a set. (Patch by Eli Bendersky.)
+- Issue #9214: Set operations on a KeysView or ItemsView in collections now
+ correctly return a set. Patch by Eli Bendersky.
- Issue #5737: Add Solaris-specific mnemonics in the errno module. Patch by
Matthew Ahrens.
-- Restore GIL in nis_cat in case of error. Decode NIS data to fs encoding,
- using the surrogate error handler.
+- Restore GIL in nis_cat in case of error. Decode NIS data to fs encoding, using
+ the surrogate error handler.
-- Issue #665761: ``functools.reduce()`` will no longer mask exceptions
- other than ``TypeError`` raised by the iterator argument.
+- Issue #665761: ``functools.reduce()`` will no longer mask exceptions other
+ than ``TypeError`` raised by the iterator argument.
- Issue #9570: Use PEP 383 decoding in os.mknod and os.mkfifo.
-- Issue #6915: Under Windows, os.listdir() didn't release the Global
- Interpreter Lock around all system calls. Original patch by Ryan Kelly.
+- Issue #6915: Under Windows, os.listdir() didn't release the Global Interpreter
+ Lock around all system calls. Original patch by Ryan Kelly.
-- Issue #8524: Add a detach() method to socket objects, so as to put the
- socket into the closed state without closing the underlying file
- descriptor.
+- Issue #8524: Add a detach() method to socket objects, so as to put the socket
+ into the closed state without closing the underlying file descriptor.
- Issue #477863: Print a warning at shutdown if gc.garbage is not empty.
- Issue #6869: Fix a refcount problem in the _ctypes extension.
-- Issue #5504: ctypes should now work with systems where mmap can't
- be PROT_WRITE and PROT_EXEC.
+- Issue #5504: ctypes should now work with systems where mmap can't be
+ PROT_WRITE and PROT_EXEC.
-- Issue #9507: Named tuple repr will now automatically display the right
- name in a tuple subclass.
+- Issue #9507: Named tuple repr will now automatically display the right name in
+ a tuple subclass.
-- Issue #9324: Add parameter validation to signal.signal on Windows in order
- to prevent crashes.
+- Issue #9324: Add parameter validation to signal.signal on Windows in order to
+ prevent crashes.
-- Issue #9526: Remove some outdated (int) casts that were preventing
- the array module from working correctly with arrays of more than
- 2**31 elements.
+- Issue #9526: Remove some outdated (int) casts that were preventing the array
+ module from working correctly with arrays of more than 2**31 elements.
- Fix memory leak in ssl._ssl._test_decode_cert.
-- Issue #8065: Fix memory leak in readline module (from failure to
- free the result of history_get_history_state()).
+- Issue #8065: Fix memory leak in readline module (from failure to free the
+ result of history_get_history_state()).
- Issue #9450: Fix memory leak in readline.replace_history_item and
readline.remove_history_item for readline version >= 5.0.
- Issue #8105: Validate file descriptor passed to mmap.mmap on Windows.
-- Issue #8046: Add context manager protocol support and .closed property
- to mmap objects.
+- Issue #8046: Add context manager protocol support and .closed property to mmap
+ objects.
Library
-------
-- Issue #7451: Improve decoding performance of JSON objects, and reduce
- the memory consumption of said decoded objects when they use the same
- strings as keys.
+- Issue #7451: Improve decoding performance of JSON objects, and reduce the
+ memory consumption of said decoded objects when they use the same strings as
+ keys.
-- Issue #1100562: Fix deep-copying of objects derived from the list and
- dict types. Patch by Michele Orr? and Bj?rn Lindqvist.
+- Issue #1100562: Fix deep-copying of objects derived from the list and dict
+ types. Patch by Michele Orr? and Bj?rn Lindqvist.
-- Issue #9753: Fixed socket.dup, which did not always work correctly
- on Windows.
+- Issue #9753: Fixed socket.dup, which did not always work correctly on Windows.
-- Issue #9421: Made the get methods consistently accept the vars
- and default arguments on all parser classes.
+- Issue #9421: Made the get methods consistently accept the vars and
+ default arguments on all parser classes.
- Issue #7005: Fixed output of None values for RawConfigParser.write and
ConfigParser.write.
- Issue #8990: array.fromstring() and array.tostring() get renamed to
frombytes() and tobytes(), respectively, to avoid confusion. Furthermore,
- array.frombytes(), array.extend() as well as the array.array()
- constructor now accept bytearray objects. Patch by Thomas Jollans.
+ array.frombytes(), array.extend() as well as the array.array() constructor now
+ accept bytearray objects. Patch by Thomas Jollans.
-- Issue #808164: Fixed socket.close to avoid references to globals, to
- avoid issues when socket.close is called from a __del__ method.
+- Issue #808164: Fixed socket.close to avoid references to globals, to avoid
+ issues when socket.close is called from a __del__ method.
-- Issue #9706: ssl module provides a better error handling in various
+- Issue #9706: ssl module provides a better error handling in various
circumstances.
-- Issue #1868: Eliminate subtle timing issues in thread-local objects by
- getting rid of the cached copy of thread-local attribute dictionary.
+- Issue #1868: Eliminate subtle timing issues in thread-local objects by getting
+ rid of the cached copy of thread-local attribute dictionary.
-- Issue #1512791: In setframerate() in the wave module, non-integral
- frame rates are rounded to the nearest integer.
+- Issue #1512791: In setframerate() in the wave module, non-integral frame rates
+ are rounded to the nearest integer.
- Issue #8797: urllib2 does a retry for Basic Authentication failure instead of
falling into recursion.
@@ -210,54 +205,53 @@
- Issue #8750: Fixed MutableSet's methods to correctly handle reflexive
operations on its self, namely x -= x and x ^= x.
-- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing
- error handling when accepting a new connection.
+- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing error
+ handling when accepting a new connection.
- Issue #9601: ftplib now provides a workaround for non-compliant
- implementations such as IIS shipped with Windows server 2003 returning
- invalid response codes for MKD and PWD commands.
+ implementations such as IIS shipped with Windows server 2003 returning invalid
+ response codes for MKD and PWD commands.
- Issue #658749: asyncore's connect() method now correctly interprets winsock
errors.
- Issue #9501: Fixed logging regressions in cleanup code.
-- Fix functools.total_ordering() to skip methods inherited from object().
+- Fix functools.total_ordering() to skip methods inherited from object.
-- Issue #9572: Importlib should not raise an exception if a directory it
- thought it needed to create was done concurrently by another process.
+- Issue #9572: Importlib should not raise an exception if a directory it thought
+ it needed to create was done concurrently by another process.
- Issue #9617: Signals received during a low-level write operation aren't
ignored by the buffered IO layer anymore.
- Issue #843590: Make "macintosh" an alias to the "mac_roman" encoding.
-- Create os.fsdecode(): decode from the filesystem encoding with
- surrogateescape error handler, or strict error handler on Windows.
+- Create os.fsdecode(): decode from the filesystem encoding with surrogateescape
+ error handler, or strict error handler on Windows.
-- Issue #3488: Provide convenient shorthand functions ``gzip.compress``
- and ``gzip.decompress``. Original patch by Anand B. Pillai.
+- Issue #3488: Provide convenient shorthand functions ``gzip.compress`` and
+ ``gzip.decompress``. Original patch by Anand B. Pillai.
-- Issue #8807: poplib.POP3_SSL class now accepts a context parameter, which is
- a ssl.SSLContext object allowing bundling SSL configuration options,
+- Issue #8807: poplib.POP3_SSL class now accepts a context parameter, which is a
+ ssl.SSLContext object allowing bundling SSL configuration options,
certificates and private keys into a single (potentially long-lived)
structure.
- Issue #8866: parameters passed to socket.getaddrinfo can now be specified as
single keyword arguments.
-- Address XXX comment in dis.py by having inspect.py prefer to reuse the
- dis.py compiler flag values over defining its own
+- Address XXX comment in dis.py by having inspect.py prefer to reuse the dis.py
+ compiler flag values over defining its own.
-- Issue #9147: Added dis.code_info() which is similar to show_code()
- but returns formatted code information in a string rather than
- displaying on screen.
+- Issue #9147: Added dis.code_info() which is similar to show_code() but returns
+ formatted code information in a string rather than displaying on screen.
- Issue #9567: functools.update_wrapper now adds a __wrapped__ attribute
- pointing to the original callable
+ pointing to the original callable.
-- Issue #3445: functools.update_wrapper now tolerates missing attributes
- on wrapped callables
+- Issue #3445: functools.update_wrapper now tolerates missing attributes on
+ wrapped callables.
- Issue #5867: Add abc.abstractclassmethod and abc.abstractstaticmethod.
@@ -268,79 +262,79 @@
encoding and surrogateescape error handler. Patch written by David Watson.
- Issue #9603: posix.ttyname() and posix.ctermid() decode the terminal name
- using the filesystem encoding and surrogateescape error handler. Patch
- written by David Watson.
+ using the filesystem encoding and surrogateescape error handler. Patch written
+ by David Watson.
-- Issue #7647: The posix module now has the ST_RDONLY and ST_NOSUID
- constants, for use with the statvfs() function. Patch by Adam Jackson.
+- Issue #7647: The posix module now has the ST_RDONLY and ST_NOSUID constants,
+ for use with the statvfs() function. Patch by Adam Jackson.
-- Issue #8688: MANIFEST files created by distutils now include a magic
- comment indicating they are generated. Manually maintained MANIFESTs
- without this marker will not be overwritten or removed.
-
-- Issue #7467: when reading a file from a ZIP archive, its CRC is checked
- and a BadZipfile error is raised if it doesn't match (as used to be the
- case in Python 2.5 and earlier).
-
-- Issue #9550: a BufferedReader could issue an additional read when the
- original read request had been satisfied, which could block indefinitely
- when the underlying raw IO channel was e.g. a socket. Report and original
- patch by Jason V. Miller.
+- Issue #8688: MANIFEST files created by distutils now include a magic comment
+ indicating they are generated. Manually maintained MANIFESTs without this
+ marker will not be overwritten or removed.
+
+- Issue #7467: when reading a file from a ZIP archive, its CRC is checked and a
+ BadZipfile error is raised if it doesn't match (as used to be the case in
+ Python 2.5 and earlier).
+
+- Issue #9550: a BufferedReader could issue an additional read when the original
+ read request had been satisfied, which could block indefinitely when the
+ underlying raw IO channel was e.g. a socket. Report and original patch by
+ Jason V. Miller.
- Issue #3757: thread-local objects now support cyclic garbage collection.
- Thread-local objects involved in reference cycles will be deallocated
- timely by the cyclic GC, even if the underlying thread is still running.
+ Thread-local objects involved in reference cycles will be deallocated timely
+ by the cyclic GC, even if the underlying thread is still running.
- Issue #9452: Add read_file, read_string, and read_dict to the configparser
API; new source attribute to exceptions.
-- Issue #6231: Fix xml.etree.ElementInclude to include the tail of the
- current node.
+- Issue #6231: Fix xml.etree.ElementInclude to include the tail of the current
+ node.
- Issue #8047: Fix the xml.etree serializer to return bytes by default. Use
``encoding="unicode"`` to generate a Unicode string.
-- Issue #8280: urllib2's Request method will remove fragments in the url.
- This is how it is supposed to work, wget and curl do the same. Previous
- behavior was wrong.
+- Issue #8280: urllib2's Request method will remove fragments in the url. This
+ is how it is supposed to work, wget and curl do the same. Previous behavior
+ was wrong.
- Issue #6683: For SMTP logins we now try all authentication methods advertised
by the server. Many servers are buggy and advertise authentication methods
they do not support in reality.
-- Issue #8814: function annotations (the ``__annotations__`` attribute)
- are now included in the set of attributes copied by default by
- functools.wraps and functools.update_wrapper. Patch by Terrence Cole.
+- Issue #8814: function annotations (the ``__annotations__`` attribute) are now
+ included in the set of attributes copied by default by functools.wraps and
+ functools.update_wrapper. Patch by Terrence Cole.
- Issue #2944: asyncore doesn't handle connection refused correctly.
-- Issue #4184: Private attributes on smtpd.SMTPChannel made public and
- deprecate the private attributes. Add tests for smtpd module.
+- Issue #4184: Private attributes on smtpd.SMTPChannel made public and deprecate
+ the private attributes. Add tests for smtpd module.
-- Issue #3196: email header decoding is now forgiving if an RFC2047
- encoded word encoded in base64 is lacking padding.
+- Issue #3196: email header decoding is now forgiving if an RFC2047 encoded word
+ encoded in base64 is lacking padding.
-- Issue #9444: Argparse now uses the first element of prefix_chars as
- the option character for the added 'h/help' option if prefix_chars
- does not contain a '-', instead of raising an error.
+- Issue #9444: Argparse now uses the first element of prefix_chars as the option
+ character for the added 'h/help' option if prefix_chars does not contain a
+ '-', instead of raising an error.
-- Issue #7372: Fix pstats regression when stripping paths from profile
- data generated with the profile module.
+- Issue #7372: Fix pstats regression when stripping paths from profile data
+ generated with the profile module.
-- Issue #9428: Fix running scripts with the profile/cProfile modules from
- the command line.
+- Issue #9428: Fix running scripts with the profile/cProfile modules from the
+ command line.
-- Issue #7781: Fix restricting stats by entry counts in the pstats
- interactive browser.
+- Issue #7781: Fix restricting stats by entry counts in the pstats interactive
+ browser.
-- Issue #9209: Do not crash in the pstats interactive browser on invalid
- regular expressions.
+- Issue #9209: Do not crash in the pstats interactive browser on invalid regular
+ expressions.
-- Update collections.OrderedDict to match the implementation in Py2.7
- (based on lists instead of weakly referenced Link objects).
+- Update collections.OrderedDict to match the implementation in Py2.7 (based on
+ lists instead of weakly referenced Link objects).
-- Issue #8397: Raise an error when attempting to mix iteration and regular
- reads on a BZ2File object, rather than returning incorrect results.
+- Issue #8397: Raise an error when attempting to mix iteration and regular reads
+ on a BZ2File object, rather than returning incorrect results.
- Issue #9448: Fix a leak of OS resources (mutexes or semaphores) when
re-initializing a buffered IO object by calling its ``__init__`` method.
@@ -356,19 +350,19 @@
- Issue #8230: Fix Lib/test/sortperf.py.
-- Issue #8620: when a Cmd is fed input that reaches EOF without a final
- newline, it no longer truncates the last character of the last command line.
+- Issue #8620: when a Cmd is fed input that reaches EOF without a final newline,
+ it no longer truncates the last character of the last command line.
- Issue #5146: Handle UID THREAD command correctly in imaplib.
- Issue #5147: Fix the header generated for cookie files written by
http.cookiejar.MozillaCookieJar.
-- Issue #8198: In pydoc, output all help text to the correct stream
- when sys.stdout is reassigned.
+- Issue #8198: In pydoc, output all help text to the correct stream when
+ sys.stdout is reassigned.
-- Issue #7909: Do not touch paths with the special prefixes ``\\.\``
- or ``\\?\`` in ntpath.normpath().
+- Issue #7909: Do not touch paths with the special prefixes ``\\.\`` or ``\\?\``
+ in ntpath.normpath().
- Issue #1286: Allow using fileinput.FileInput as a context manager.
@@ -405,9 +399,8 @@
- Issue #9193: PEP 3149 is accepted.
-- Issue #3101: Helper functions _add_one_to_index_C() and
- _add_one_to_index_F() become _Py_add_one_to_index_C() and
- _Py_add_one_to_index_F(), respectively.
+- Issue #3101: Helper functions _add_one_to_index_C() and _add_one_to_index_F()
+ become _Py_add_one_to_index_C() and _Py_add_one_to_index_F(), respectively.
- Issue #9700: define HAVE_BROKEN_POSIX_SEMAPHORES under AIX 6.x. Patch by
S?bastien Sabl?.
From python-checkins at python.org Sun Sep 5 19:07:12 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 19:07:12 +0200 (CEST)
Subject: [Python-checkins] r84530 - in python/branches/py3k:
Doc/library/os.rst Modules/posixmodule.c
Message-ID: <20100905170712.B8FAEEE9B8@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 19:07:12 2010
New Revision: 84530
Log:
#9747: fix copy-paste error in getresgid() doc.
Modified:
python/branches/py3k/Doc/library/os.rst
python/branches/py3k/Modules/posixmodule.c
Modified: python/branches/py3k/Doc/library/os.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.rst (original)
+++ python/branches/py3k/Doc/library/os.rst Sun Sep 5 19:07:12 2010
@@ -299,7 +299,7 @@
.. function:: getresgid()
Return a tuple (rgid, egid, sgid) denoting the current process's
- real, effective, and saved user ids.
+ real, effective, and saved group ids.
Availability: Unix.
Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Sun Sep 5 19:07:12 2010
@@ -7600,7 +7600,7 @@
#ifdef HAVE_GETRESGID
PyDoc_STRVAR(posix_getresgid__doc__,
"getresgid() -> (rgid, egid, sgid)\n\n\
-Get tuple of the current process's real, effective, and saved user ids.");
+Get tuple of the current process's real, effective, and saved group ids.");
static PyObject*
posix_getresgid (PyObject *self, PyObject *noargs)
From python-checkins at python.org Sun Sep 5 19:09:18 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 19:09:18 +0200 (CEST)
Subject: [Python-checkins] r84531 -
python/branches/py3k/Modules/fcntlmodule.c
Message-ID: <20100905170918.4DE91EE9B8@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 19:09:18 2010
New Revision: 84531
Log:
#9776: fix some spacing.
Modified:
python/branches/py3k/Modules/fcntlmodule.c
Modified: python/branches/py3k/Modules/fcntlmodule.c
==============================================================================
--- python/branches/py3k/Modules/fcntlmodule.c (original)
+++ python/branches/py3k/Modules/fcntlmodule.c Sun Sep 5 19:09:18 2010
@@ -82,10 +82,10 @@
Perform the requested operation on file descriptor fd. The operation\n\
is defined by op and is operating system dependent. These constants are\n\
available from the fcntl module. The argument arg is optional, and\n\
-defaults to 0; it may be an int or a string. If arg is given as a string,\n\
+defaults to 0; it may be an int or a string. If arg is given as a string,\n\
the return value of fcntl is a string of that length, containing the\n\
-resulting value put in the arg buffer by the operating system.The length\n\
-of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
+resulting value put in the arg buffer by the operating system. The length\n\
+of the arg string is not allowed to exceed 1024 bytes. If the arg given\n\
is an integer or if none is specified, the result value is an integer\n\
corresponding to the return value of the fcntl call in the C code.");
From python-checkins at python.org Sun Sep 5 19:32:25 2010
From: python-checkins at python.org (eric.araujo)
Date: Sun, 5 Sep 2010 19:32:25 +0200 (CEST)
Subject: [Python-checkins] r84532 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100905173225.46FC1EE9AE@mail.python.org>
Author: eric.araujo
Date: Sun Sep 5 19:32:25 2010
New Revision: 84532
Log:
Fix typos and wording in what?s new 3.2.
- The entry about shutil.copytree is just a revert of r84524 which
looks like an unfinished edition.
- The use of gender-neutral language (s/his/their/) removes the
implicit assumption that programmer == male (change agreed by Antoine).
- Other changes should be uncontroversial fixes.
I haven?t rewrapped under 80 lines to keep the diffs readable; I?ll
rewrap later.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 5 19:32:25 2010
@@ -39,9 +39,10 @@
sufficient; the e-mail address isn't necessary. It's helpful to
add the issue number:
- XXX Describe the transmogrify() function added to the socket
- module.
- (Contributed by P.Y. Developer; :issue:`12345`.)
+ XXX Describe the transmogrify() function added to the socket
+ module.
+
+ (Contributed by P.Y. Developer; :issue:`12345`.)
This saves the maintainer the effort of going through the SVN log
when researching a change.
@@ -49,24 +50,24 @@
This article explains the new features in Python 3.2, compared to 3.1.
-PEP 391: Dictionary Based Configuration for Logging
-===================================================
+PEP 391: Dictionary Based Configuration for Logging
+====================================================
-The :mod:`logging` module had two ways of configuring the module, either calling
-functions for each option or by reading an external file saved in a ConfigParser
+The :mod:`logging` module had two ways of configuring the module, either by calling
+functions for each option or by reading an external file saved in a :mod:`ConfigParser`
format. Those options did not provide the flexibility to create configurations
-from JSON or YAML files and they did not support incremental configuration which
+from JSON or YAML files and they did not support incremental configuration, which
is needed for specifying logger options from a command line.
To support a more flexible style, the module now offers
:func:`logging.config.dictConfig` to use dictionaries to specify logger
-configurations (including formatters, handlers, filters, and loggers). For
+configuration (including formatters, handlers, filters, and loggers). For
example:
>>> import logging.config
>>> logging.config.dictConfig(json.load(open('log.cfg', 'rb')))
-The above fragment configures logging from a JSON encoded dictionary stored in
+The above fragment configures logging from a JSON-encoded dictionary stored in a
file called "log.cfg". Here's a working example of a configuration dictionary::
{"version": 1,
@@ -101,14 +102,14 @@
overwrite the cached file, thus losing the benefits of caching.
The issue of "pyc fights" has become more pronounced as it has become
-common-place for Linux distributions to ship with multiple versions of Python.
+commonplace for Linux distributions to ship with multiple versions of Python.
These conflicts also arise with CPython alternatives such as Unladen Swallow.
To solve this problem, Python's import machinery has been extended to use
-distinct filenames for each interpreter. Instead of Python3.2 and Python3.3 and
-UnladenSwallow each competing for a file called "mymodule.pyc", they will now
+distinct filenames for each interpreter. Instead of Python 3.2 and Python 3.3 and
+Unladen Swallow each competing for a file called "mymodule.pyc", they will now
look for "mymodule.cpython-32.pyc", "mymodule.cpython-33.pyc", and
-"mymodule.unladen10.pyc". And to keep prevent all of these new files from
+"mymodule.unladen10.pyc". And to prevent all of these new files from
cluttering source directories, the *pyc* files are now collected in a
"__pycache__" directory stored under the package directory.
@@ -157,7 +158,7 @@
The common directory is "pyshared" and the file names are made distinct by
identifying the Python implementation (such as CPython, PyPy, Jython, etc.), the
major and minor version numbers, and optional build flags (such as "d" for
-debug, "m" for pymalloc, "u" for wide-unicode). For an arbtrary package, "foo",
+debug, "m" for pymalloc, "u" for wide-unicode). For an arbitrary package "foo",
you may see these files when the distribution package is installed::
/usr/share/pyshared/foo.cpython-32m.so
@@ -187,15 +188,15 @@
it only catches :exc:`AttributeError`. Under the hood, :func:`hasattr` works
by calling :func:`getattr` and throwing away the results. This is necessary
because dynamic attribute creation is possible using :meth:`__getattribute__`
- or :meth:`__getattr`. If :func:`hasattr` were to just scan instance and class
+ or :meth:`__getattr__`. If :func:`hasattr` were to just scan instance and class
dictionaries it would miss the dynmaic methods and make it difficult to
implement proxy objects.
(Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.)
-* The :func:`str` of a float or complex number is now the same as it
+* The :func:`str` of a float or complex number is now the same as its
:func:`repr`. Previously, the :func:`str` form was shorter but that just
- caused confusion and is no longer needed now that we the shortest possible
+ caused confusion and is no longer needed now that the shortest possible
:func:`repr` is displayed by default:
>>> repr(math.pi)
@@ -223,7 +224,7 @@
New, Improved, and Deprecated Modules
=====================================
-* The :mod:`functools` module now includes a new decorator for caching function
+* The :mod:`functools` module includes a new decorator for caching function
calls. :func:`functools.lru_cache` can save repeated queries to an external
resource whenever the results are expected to be the same.
@@ -261,7 +262,7 @@
`appspot issue 53094 `_.)
* The :class:`ftplib.FTP` class now supports the context manager protocol to
- unconditionally consume :exc:`socket.error` exceptions and to close the ftp
+ unconditionally consume :exc:`socket.error` exceptions and to close the FTP
connection when done:
>>> from ftplib import FTP
@@ -279,7 +280,7 @@
* A warning message will now get printed at interpreter shutdown if the
:data:`gc.garbage` list isn't empty. This is meant to make the programmer
- aware that his code contains object finalization issues.
+ aware that their code contains object finalization issues.
(Added by Antoine Pitrou; :issue:`477863`.)
@@ -290,11 +291,11 @@
* The :func:`shutil.copytree` function has two new options:
- * *ignore_dangling_symlinks*: when ``symlinks=False`` dp that the function
- copies the file pointed to by the symlink, not the symlink itself. This
+ * *ignore_dangling_symlinks*: when ``symlinks=False`` (meaning that the function
+ copies the file pointed to by the symlink, not the symlink itself), this
option will silence the error raised if the file doesn't exist.
- * *copy_function*: is a callable that will be used to copy files.
+ * *copy_function*: a callable that will be used to copy files.
:func:`shutil.copy2` is used by default.
(Contributed by Tarek Ziad?.)
@@ -411,8 +412,8 @@
available (ignored) on Windows and Mac OS X: the filesystem encoding is pinned
to ``'mbcs'`` on Windows and ``'utf-8'`` on Mac OS X.
-The :mod:`os` module has two new functions: :func:`os.fsencode` and
-:func:`os.fsdecode`.
+The :mod:`os` module has two new functions: :func:`~os.fsencode` and
+:func:`~os.fsdecode`.
.. IDLE
@@ -458,5 +459,5 @@
* The :ctype:`PyCObject` type, deprecated in 3.1, has been removed. To wrap
opaque C pointers in Python objects, the :ctype:`PyCapsule` API should be used
- instead; the new type has a well defined interface for passing typing safety
+ instead; the new type has a well-defined interface for passing typing safety
information and a less complicated signature for calling a destructor.
From python-checkins at python.org Sun Sep 5 19:32:31 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 19:32:31 +0200 (CEST)
Subject: [Python-checkins] r84533 - in python/branches/py3k/Misc: NEWS
NEWS.help
Message-ID: <20100905173231.9C478EE9EC@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 19:32:31 2010
New Revision: 84533
Log:
Fix reST in NEWS, and remove NEWS.help (all committers should now know reST anyway, and for those who do not, there is Documenting Python.)
Removed:
python/branches/py3k/Misc/NEWS.help
Modified:
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 5 19:32:31 2010
@@ -2,8 +2,6 @@
Python News
+++++++++++
-(editors: check NEWS.help for information about editing NEWS using ReST.)
-
What's New in Python 3.2 Alpha 2?
=================================
@@ -802,8 +800,8 @@
- Issue #7072: isspace(0xa0) is true on Mac OS X.
- Issue #8084: PEP 370 now conforms to system conventions for framework builds
- on MacOS X. That is, "python setup.py install --user" will install
- into "~/Library/Python/2.7" instead of "~/.local".
+ on MacOS X. That is, "python setup.py install --user" will install into
+ "~/Library/Python/2.7" instead of "~/.local".
C-API
-----
@@ -916,7 +914,7 @@
- Issue #4179: In pdb, allow "list ." as a command to return to the currently
debugged line.
-- Issue #4108: In urllib.robotparser, if there are multiple 'User-agent: *'
+- Issue #4108: In urllib.robotparser, if there are multiple ``User-agent: *``
entries, consider the first one.
- Issue #6630: Allow customizing regex flags when subclassing the
@@ -2051,7 +2049,7 @@
- Issue #7347: winreg: Add CreateKeyEx and DeleteKeyEx, as well as fix a bug in
the return value of QueryReflectionKey.
-- Issue #7567: PyCurses_setupterm: Don't call `setupterm' twice.
+- Issue #7567: PyCurses_setupterm: Don't call ``setupterm`` twice.
Build
-----
@@ -2138,7 +2136,7 @@
- Issue #8510: Update to autoconf2.65.
Documentation
-------------
+-------------
- Issue #9524: Document that two CTRL* signals are meant for use only
with os.kill.
@@ -2681,7 +2679,7 @@
- Issue #2170: refactored xml.dom.minidom.normalize, increasing both
its clarity and its speed.
-- Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add `do { ... } while (0)'
+- Issue #1113244: Py_XINCREF, Py_DECREF, Py_XDECREF: Add ``do { ... } while (0)``
to avoid compiler warnings.
- Issue #3739: The unicode-internal encoder now reports the number of characters
@@ -3005,7 +3003,7 @@
optional module state data.
- Issue #4910: Rename nb_long slot to nb_reserved, and change its
- type to (void *).
+ type to ``(void *)``.
- Issue #4935: The overflow checking code in the expandtabs() method common
to str, bytes and bytearray could be optimized away by the compiler, letting
@@ -3060,8 +3058,8 @@
- Issue #4747: When the terminal does not use utf-8, executing a script with
non-ascii characters in its name could fail with a "SyntaxError: None" error.
-- Issue #4797: IOError.filename was not set when _fileio.FileIO failed to open
- file with `bytes' filename on Windows.
+- Issue #4797: IOError.filename was not set when ``_fileio.FileIO`` failed
+ to open file with a bytes filename on Windows.
- Issue #3680: Reference cycles created through a dict, set or deque iterator
did not get collected.
@@ -3312,7 +3310,7 @@
- Issue #5386: mmap.write_byte didn't check map size, so it could cause buffer
overrun.
-- Issue #1533164: Installed but not listed *.pyo was breaking Distutils
+- Issue #1533164: Installed but not listed ``*.pyo`` was breaking Distutils
bdist_rpm command.
- Issue #5378: added --quiet option to Distutils bdist_rpm command.
@@ -3465,8 +3463,8 @@
- Issue #4959: inspect.formatargspec now works for keyword only arguments
without defaults.
-- Issue #3321: _multiprocessing.Connection() doesn't check handle; added checks
- for *nix machines for negative handles and large int handles. Without this check
+- Issue #3321: ``_multiprocessing.Connection()`` doesn't check handle; added checks
+ for Unix machines for negative handles and large int handles. Without this check
it is possible to segfault the interpreter.
- Issue #4449: AssertionError in mp_benchmarks.py, caused by an underlying issue
Deleted: python/branches/py3k/Misc/NEWS.help
==============================================================================
--- python/branches/py3k/Misc/NEWS.help Sun Sep 5 19:32:31 2010
+++ (empty file)
@@ -1,73 +0,0 @@
- -*- text -*-
-
-If you edited Misc/NEWS before it was converted to ReST format skimming this
-file should help make the transition a bit easier. For full details about
-Docutils and ReST, go to the Docutils website:
-
- http://docutils.sourceforge.net/
-
-To process Misc/NEWS using Docutils, you'll need the latest docutils
-snapshot:
-
- http://docutils.sf.net/docutils-snapshot.tgz
-
-Docutils works with Python 2.2 or newer.
-
-To process NEWS into NEWS.html, first install Docutils, and then run
-this command:
-
- python .../docutils/tools/rst2html.py NEWS NEWS.html
-
-Here ".../docutils" is the directory into which the above snapshot was
-extracted. (I hope this recipe will change for the better.)
-
-David Goodger made a change to the allowable structure of internal
-references which greatly simplified initial conversion of the file.
-
-The changes required fell into the following categories:
-
-* The top-level "What's New" section headers changed to:
-
- What's New in Python 2.3 alpha 1?
- =================================
-
- *Release date: DD-MMM-2002*
-
- Note that the release date line is emphasized, with a "*" at each
- end.
-
-* Subsections are underlined with a single row of hyphens:
-
- Type/class unification and new-style classes
- --------------------------------------------
-
-* Places where "balanced" single quotes were used were changed to use
- apostrophes as both the opening and closing quote (`string' -> 'string').
-
-* In a few places asterisks needed to be escaped which would otherwise have
- been interpreted as beginning blocks of italic or bold text, e.g.:
-
- - The type of tp_free has been changed from "``void (*)(PyObject *)``"
- to "``void (*)(void *)``".
-
- Note that only the asterisks preceded by whitespace needed to be escaped.
-
-* One instance of a word ending with an underscore needed to be quoted
- ("PyCmp_" became "``PyCmp_``").
-
-* One table was converted to ReST form (search Misc/NEWS for "New codecs"
- for this example).
-
-* A few places where chunks of code or indented text were displayed needed
- to be properly introduced (preceding paragraph terminated by "::" and the
- chunk of code or text indented w.r.t. the paragraph). For example:
-
- - Note that PyLong_AsDouble can fail! This has always been true,
- but no callers checked for it. It's more likely to fail now,
- because overflow errors are properly detected now. The proper way
- to check::
-
- double x = PyLong_AsDouble(some_long_object);
- if (x == -1.0 && PyErr_Occurred()) {
- /* The conversion failed. */
- }
From python-checkins at python.org Sun Sep 5 20:21:47 2010
From: python-checkins at python.org (eric.araujo)
Date: Sun, 5 Sep 2010 20:21:47 +0200 (CEST)
Subject: [Python-checkins] r84534 - python/branches/py3k/Misc/maintainers.rst
Message-ID: <20100905182147.211BAEE9CB@mail.python.org>
Author: eric.araujo
Date: Sun Sep 5 20:21:46 2010
New Revision: 84534
Log:
Fix amk?s tracker name
Modified:
python/branches/py3k/Misc/maintainers.rst
Modified: python/branches/py3k/Misc/maintainers.rst
==============================================================================
--- python/branches/py3k/Misc/maintainers.rst (original)
+++ python/branches/py3k/Misc/maintainers.rst Sun Sep 5 20:21:46 2010
@@ -83,7 +83,7 @@
crypt
csv
ctypes theller
-curses andrew.kuchling
+curses akuchling
datetime alexander.belopolsky
dbm
decimal facundobatista, rhettinger, mark.dickinson
@@ -132,7 +132,7 @@
locale loewis, lemburg
logging vinay.sajip
macpath
-mailbox andrew.kuchling
+mailbox akuchling
mailcap
marshal
math mark.dickinson, rhettinger, stutzbach
From python-checkins at python.org Sun Sep 5 20:25:59 2010
From: python-checkins at python.org (ronald.oussoren)
Date: Sun, 5 Sep 2010 20:25:59 +0200 (CEST)
Subject: [Python-checkins] r84535 - in python/branches/py3k:
Modules/_ctypes/callbacks.c Modules/_ctypes/libffi_osx/include/ffi.h
Modules/_ctypes/malloc_closure.c setup.py
Message-ID: <20100905182559.BC496EE9F8@mail.python.org>
Author: ronald.oussoren
Date: Sun Sep 5 20:25:59 2010
New Revision: 84535
Log:
Fix for issue9662, patch by ?ukasz Langa in issue5504.
Modified:
python/branches/py3k/Modules/_ctypes/callbacks.c
python/branches/py3k/Modules/_ctypes/libffi_osx/include/ffi.h
python/branches/py3k/Modules/_ctypes/malloc_closure.c
python/branches/py3k/setup.py
Modified: python/branches/py3k/Modules/_ctypes/callbacks.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/callbacks.c (original)
+++ python/branches/py3k/Modules/_ctypes/callbacks.c Sun Sep 5 20:25:59 2010
@@ -416,9 +416,13 @@
"ffi_prep_cif failed with %d", result);
goto error;
}
+#if defined(X86_DARWIN) || defined(POWERPC_DARWIN)
+ result = ffi_prep_closure(p->pcl_write, &p->cif, closure_fcn, p);
+#else
result = ffi_prep_closure_loc(p->pcl_write, &p->cif, closure_fcn,
p,
p->pcl_exec);
+#endif
if (result != FFI_OK) {
PyErr_Format(PyExc_RuntimeError,
"ffi_prep_closure failed with %d", result);
Modified: python/branches/py3k/Modules/_ctypes/libffi_osx/include/ffi.h
==============================================================================
--- python/branches/py3k/Modules/_ctypes/libffi_osx/include/ffi.h (original)
+++ python/branches/py3k/Modules/_ctypes/libffi_osx/include/ffi.h Sun Sep 5 20:25:59 2010
@@ -264,6 +264,9 @@
void (*fun)(ffi_cif*,void*,void**,void*),
void* user_data);
+void ffi_closure_free(void *);
+void *ffi_closure_alloc (size_t size, void **code);
+
typedef struct ffi_raw_closure {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif* cif;
@@ -349,4 +352,4 @@
}
#endif
-#endif // #ifndef LIBFFI_H
\ No newline at end of file
+#endif // #ifndef LIBFFI_H
Modified: python/branches/py3k/Modules/_ctypes/malloc_closure.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/malloc_closure.c (original)
+++ python/branches/py3k/Modules/_ctypes/malloc_closure.c Sun Sep 5 20:25:59 2010
@@ -106,7 +106,6 @@
return NULL;
item = free_list;
free_list = item->next;
- *codeloc = (void *)item;
+ *codeloc = (void *)item;
return (void *)item;
}
-
Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py (original)
+++ python/branches/py3k/setup.py Sun Sep 5 20:25:59 2010
@@ -1657,6 +1657,7 @@
depends = ['_ctypes/ctypes.h']
if sys.platform == 'darwin':
+ sources.append('_ctypes/malloc_closure.c')
sources.append('_ctypes/darwin/dlfcn_simple.c')
extra_compile_args.append('-DMACOSX')
include_dirs.append('_ctypes/darwin')
From python-checkins at python.org Sun Sep 5 20:28:46 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 20:28:46 +0200 (CEST)
Subject: [Python-checkins] r84536 - sandbox/trunk/release/release.py
Message-ID: <20100905182846.4E3DAEEA02@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 20:28:46 2010
New Revision: 84536
Log:
Fix after changing NEWS layout.
Modified:
sandbox/trunk/release/release.py
Modified: sandbox/trunk/release/release.py
==============================================================================
--- sandbox/trunk/release/release.py (original)
+++ sandbox/trunk/release/release.py Sun Sep 5 20:28:46 2010
@@ -396,13 +396,13 @@
with open('Misc/NEWS', encoding="utf-8") as fp:
lines = fp.readlines()
for i, line in enumerate(lines):
- if line.startswith("(editors"):
+ if line.startswith("Python News"):
start = i
if line.startswith("What's"):
end = i
break
with open('Misc/NEWS', 'w', encoding="utf-8") as fp:
- fp.writelines(lines[:start+1])
+ fp.writelines(lines[:start+2])
fp.write(NEWS_TEMPLATE)
fp.writelines(lines[end-1:])
print("Please fill in the the name of the next version.")
From python-checkins at python.org Sun Sep 5 20:43:07 2010
From: python-checkins at python.org (eric.araujo)
Date: Sun, 5 Sep 2010 20:43:07 +0200 (CEST)
Subject: [Python-checkins] r84537 - python/branches/py3k/Lib/test/test_set.py
Message-ID: <20100905184307.9E8A5EEA03@mail.python.org>
Author: eric.araujo
Date: Sun Sep 5 20:43:07 2010
New Revision: 84537
Log:
Make naming consistent
Modified:
python/branches/py3k/Lib/test/test_set.py
Modified: python/branches/py3k/Lib/test/test_set.py
==============================================================================
--- python/branches/py3k/Lib/test/test_set.py (original)
+++ python/branches/py3k/Lib/test/test_set.py Sun Sep 5 20:43:07 2010
@@ -1,4 +1,4 @@
-import unittest
+mport unittest
from test import support
import gc
import weakref
@@ -1677,7 +1677,7 @@
def __hash__(self):
return 0
-class Test_Weird_Bugs(unittest.TestCase):
+class TestWeirdBugs(unittest.TestCase):
def test_8420_set_merge(self):
# This used to segfault
global be_bad, set2, dict2
@@ -1837,7 +1837,7 @@
TestIdentities,
TestVariousIteratorArgs,
TestGraphs,
- Test_Weird_Bugs,
+ TestWeirdBugs,
)
support.run_unittest(*test_classes)
From python-checkins at python.org Sun Sep 5 20:48:14 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 20:48:14 +0200 (CEST)
Subject: [Python-checkins] r84538 - python/tags/r32a2
Message-ID: <20100905184814.D9905EE9AC@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 20:48:14 2010
New Revision: 84538
Log:
Tagging release 3.2a2.
Added:
python/tags/r32a2/
- copied from r84537, /python/branches/py3k/
From python-checkins at python.org Sun Sep 5 20:58:42 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 20:58:42 +0200 (CEST)
Subject: [Python-checkins] r84539 - python/tags/r32a2
Message-ID: <20100905185842.764A2D8D8@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 20:58:42 2010
New Revision: 84539
Log:
Remove tag.
Removed:
python/tags/r32a2/
From python-checkins at python.org Sun Sep 5 20:59:49 2010
From: python-checkins at python.org (eric.araujo)
Date: Sun, 5 Sep 2010 20:59:49 +0200 (CEST)
Subject: [Python-checkins] r84540 - python/branches/py3k/Lib/test/test_set.py
Message-ID: <20100905185949.BACB4D8D8@mail.python.org>
Author: eric.araujo
Date: Sun Sep 5 20:59:49 2010
New Revision: 84540
Log:
Fix accidental suppression in r84537
Modified:
python/branches/py3k/Lib/test/test_set.py
Modified: python/branches/py3k/Lib/test/test_set.py
==============================================================================
--- python/branches/py3k/Lib/test/test_set.py (original)
+++ python/branches/py3k/Lib/test/test_set.py Sun Sep 5 20:59:49 2010
@@ -1,4 +1,4 @@
-mport unittest
+import unittest
from test import support
import gc
import weakref
From python-checkins at python.org Sun Sep 5 21:01:40 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 21:01:40 +0200 (CEST)
Subject: [Python-checkins] r84541 - python/tags/r32a2
Message-ID: <20100905190140.67A89EE9AC@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 21:01:40 2010
New Revision: 84541
Log:
Re-tag 3.2a2.
Added:
python/tags/r32a2/
- copied from r84540, /python/branches/py3k/
From python-checkins at python.org Sun Sep 5 23:29:17 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 5 Sep 2010 23:29:17 +0200 (CEST)
Subject: [Python-checkins] r84542 - in python/branches/py3k:
Include/patchlevel.h Misc/NEWS
Message-ID: <20100905212917.6C60DEE9AE@mail.python.org>
Author: georg.brandl
Date: Sun Sep 5 23:29:17 2010
New Revision: 84542
Log:
Post-release update.
Modified:
python/branches/py3k/Include/patchlevel.h
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Include/patchlevel.h
==============================================================================
--- python/branches/py3k/Include/patchlevel.h (original)
+++ python/branches/py3k/Include/patchlevel.h Sun Sep 5 23:29:17 2010
@@ -23,7 +23,7 @@
#define PY_RELEASE_SERIAL 2
/* Version as a string */
-#define PY_VERSION "3.2a2"
+#define PY_VERSION "3.2a2+"
/*--end constants--*/
/* Subversion Revision number of this file (not of the repository) */
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 5 23:29:17 2010
@@ -2,6 +2,18 @@
Python News
+++++++++++
+What's New in Python 3.2 Alpha 3?
+=================================
+
+*Release date: XX-Oct-2010*
+
+Core and Builtins
+-----------------
+
+Library
+-------
+
+
What's New in Python 3.2 Alpha 2?
=================================
From python-checkins at python.org Mon Sep 6 00:40:42 2010
From: python-checkins at python.org (r.david.murray)
Date: Mon, 6 Sep 2010 00:40:42 +0200 (CEST)
Subject: [Python-checkins] r84543 - in python/branches/release31-maint:
Lib/locale.py Lib/test/test_locale.py Misc/NEWS
Message-ID: <20100905224042.1E1E8EE9AC@mail.python.org>
Author: r.david.murray
Date: Mon Sep 6 00:40:41 2010
New Revision: 84543
Log:
Merged revisions 80521 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
................
r80521 | r.david.murray | 2010-04-26 22:45:53 -0400 (Mon, 26 Apr 2010) | 13 lines
Merged revisions 80512 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/trunk
........
r80512 | r.david.murray | 2010-04-26 17:17:14 -0400 (Mon, 26 Apr 2010) | 7 lines
Issue #6656: fix locale.format_string to handle escaped percents and mappings.
Refactors format_string. Includes tests for the two problems noted in
the issue, but as far as I can see there are no other tests that confirm
that format_string conforms to normal % formatting rules.
........
................
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/locale.py
python/branches/release31-maint/Lib/test/test_locale.py
python/branches/release31-maint/Misc/NEWS
Modified: python/branches/release31-maint/Lib/locale.py
==============================================================================
--- python/branches/release31-maint/Lib/locale.py (original)
+++ python/branches/release31-maint/Lib/locale.py Mon Sep 6 00:40:41 2010
@@ -224,22 +224,30 @@
percents = list(_percent_re.finditer(f))
new_f = _percent_re.sub('%s', f)
- if isinstance(val, tuple):
- new_val = list(val)
- i = 0
- for perc in percents:
- starcount = perc.group('modifiers').count('*')
- new_val[i] = format(perc.group(), new_val[i], grouping, False, *new_val[i+1:i+1+starcount])
- del new_val[i+1:i+1+starcount]
- i += (1 + starcount)
- val = tuple(new_val)
- elif isinstance(val, collections.Mapping):
+ if isinstance(val, collections.Mapping):
+ new_val = []
for perc in percents:
- key = perc.group("key")
- val[key] = format(perc.group(), val[key], grouping)
+ if perc.group()[-1]=='%':
+ new_val.append('%')
+ else:
+ new_val.append(format(perc.group(), val, grouping))
else:
- # val is a single value
- val = format(percents[0].group(), val, grouping)
+ if not isinstance(val, tuple):
+ val = (val,)
+ new_val = []
+ i = 0
+ for perc in percents:
+ if perc.group()[-1]=='%':
+ new_val.append('%')
+ else:
+ starcount = perc.group('modifiers').count('*')
+ new_val.append(_format(perc.group(),
+ val[i],
+ grouping,
+ False,
+ *val[i+1:i+1+starcount]))
+ i += (1 + starcount)
+ val = tuple(new_val)
return new_f % val
Modified: python/branches/release31-maint/Lib/test/test_locale.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_locale.py (original)
+++ python/branches/release31-maint/Lib/test/test_locale.py Mon Sep 6 00:40:41 2010
@@ -236,6 +236,25 @@
self.assertRaises(ValueError, locale.format, " %f", 'foo')
self.assertRaises(ValueError, locale.format, "%fg", 'foo')
self.assertRaises(ValueError, locale.format, "%^g", 'foo')
+ self.assertRaises(ValueError, locale.format, "%f%%", 'foo')
+
+
+class TestLocaleFormatString(unittest.TestCase):
+ """General tests on locale.format_string"""
+
+ def test_percent_escape(self):
+ self.assertEqual(locale.format_string('%f%%', 1.0), '%f%%' % 1.0)
+ self.assertEqual(locale.format_string('%d %f%%d', (1, 1.0)),
+ '%d %f%%d' % (1, 1.0))
+ self.assertEqual(locale.format_string('%(foo)s %%d', {'foo': 'bar'}),
+ ('%(foo)s %%d' % {'foo': 'bar'}))
+
+ def test_mapping(self):
+ self.assertEqual(locale.format_string('%(foo)s bing.', {'foo': 'bar'}),
+ ('%(foo)s bing.' % {'foo': 'bar'}))
+ self.assertEqual(locale.format_string('%(foo)s', {'foo': 'bar'}),
+ ('%(foo)s' % {'foo': 'bar'}))
+
class TestNumberFormatting(BaseLocalizedTest, EnUSNumberFormatting):
@@ -377,6 +396,7 @@
tests = [
TestMiscellaneous,
TestFormatPatternArg,
+ TestLocaleFormatString,
TestEnUSNumberFormatting,
TestCNumberFormatting,
TestFrFRNumberFormatting,
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Mon Sep 6 00:40:41 2010
@@ -105,6 +105,9 @@
Library
-------
+- Issue #6656: fix locale.format_string to handle escaped percents
+ and mappings.
+
- Issue #1100562: Fix deep-copying of objects derived from the list and
dict types. Patch by Michele Orr? and Bj?rn Lindqvist.
From python-checkins at python.org Mon Sep 6 01:01:12 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Mon, 6 Sep 2010 01:01:12 +0200 (CEST)
Subject: [Python-checkins] r84544 - in python/branches/py3k: Lib/_pyio.py
Lib/test/test_io.py Misc/NEWS Modules/_io/fileio.c
Modules/_io/iobase.c Modules/_io/textio.c
Message-ID: <20100905230112.76A4BEE9E0@mail.python.org>
Author: antoine.pitrou
Date: Mon Sep 6 01:01:12 2010
New Revision: 84544
Log:
Issue #9293: I/O streams now raise `io.UnsupportedOperation` when an
unsupported operation is attempted (for example, writing to a file open
only for reading).
Modified:
python/branches/py3k/Lib/_pyio.py
python/branches/py3k/Lib/test/test_io.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/_io/fileio.c
python/branches/py3k/Modules/_io/iobase.c
python/branches/py3k/Modules/_io/textio.c
Modified: python/branches/py3k/Lib/_pyio.py
==============================================================================
--- python/branches/py3k/Lib/_pyio.py (original)
+++ python/branches/py3k/Lib/_pyio.py Mon Sep 6 01:01:12 2010
@@ -243,8 +243,13 @@
return open(*args, **kwargs)
-class UnsupportedOperation(ValueError, IOError):
- pass
+# In normal operation, both `UnsupportedOperation`s should be bound to the
+# same object.
+try:
+ UnsupportedOperation = io.UnsupportedOperation
+except AttributeError:
+ class UnsupportedOperation(ValueError, IOError):
+ pass
class IOBase(metaclass=abc.ABCMeta):
@@ -362,9 +367,8 @@
"""Internal: raise an IOError if file is not seekable
"""
if not self.seekable():
- raise IOError("File or stream is not seekable."
- if msg is None else msg)
-
+ raise UnsupportedOperation("File or stream is not seekable."
+ if msg is None else msg)
def readable(self) -> bool:
"""Return whether object was opened for reading.
@@ -377,8 +381,8 @@
"""Internal: raise an IOError if file is not readable
"""
if not self.readable():
- raise IOError("File or stream is not readable."
- if msg is None else msg)
+ raise UnsupportedOperation("File or stream is not readable."
+ if msg is None else msg)
def writable(self) -> bool:
"""Return whether object was opened for writing.
@@ -391,8 +395,8 @@
"""Internal: raise an IOError if file is not writable
"""
if not self.writable():
- raise IOError("File or stream is not writable."
- if msg is None else msg)
+ raise UnsupportedOperation("File or stream is not writable."
+ if msg is None else msg)
@property
def closed(self):
@@ -1647,7 +1651,7 @@
def tell(self):
if not self._seekable:
- raise IOError("underlying stream is not seekable")
+ raise UnsupportedOperation("underlying stream is not seekable")
if not self._telling:
raise IOError("telling position disabled by next() call")
self.flush()
@@ -1726,17 +1730,17 @@
if self.closed:
raise ValueError("tell on closed file")
if not self._seekable:
- raise IOError("underlying stream is not seekable")
+ raise UnsupportedOperation("underlying stream is not seekable")
if whence == 1: # seek relative to current position
if cookie != 0:
- raise IOError("can't do nonzero cur-relative seeks")
+ raise UnsupportedOperation("can't do nonzero cur-relative seeks")
# Seeking to the current position should attempt to
# sync the underlying buffer with the current position.
whence = 0
cookie = self.tell()
if whence == 2: # seek relative to end of file
if cookie != 0:
- raise IOError("can't do nonzero end-relative seeks")
+ raise UnsupportedOperation("can't do nonzero end-relative seeks")
self.flush()
position = self.buffer.seek(0, 2)
self._set_decoded_chars('')
Modified: python/branches/py3k/Lib/test/test_io.py
==============================================================================
--- python/branches/py3k/Lib/test/test_io.py (original)
+++ python/branches/py3k/Lib/test/test_io.py Mon Sep 6 01:01:12 2010
@@ -179,6 +179,23 @@
pass
+class MockUnseekableIO:
+ def seekable(self):
+ return False
+
+ def seek(self, *args):
+ raise self.UnsupportedOperation("not seekable")
+
+ def tell(self, *args):
+ raise self.UnsupportedOperation("not seekable")
+
+class CMockUnseekableIO(MockUnseekableIO, io.BytesIO):
+ UnsupportedOperation = io.UnsupportedOperation
+
+class PyMockUnseekableIO(MockUnseekableIO, pyio.BytesIO):
+ UnsupportedOperation = pyio.UnsupportedOperation
+
+
class MockNonBlockWriterIO:
def __init__(self):
@@ -304,16 +321,26 @@
def test_invalid_operations(self):
# Try writing on a file opened in read mode and vice-versa.
+ exc = self.UnsupportedOperation
for mode in ("w", "wb"):
with self.open(support.TESTFN, mode) as fp:
- self.assertRaises(IOError, fp.read)
- self.assertRaises(IOError, fp.readline)
+ self.assertRaises(exc, fp.read)
+ self.assertRaises(exc, fp.readline)
+ with self.open(support.TESTFN, "wb", buffering=0) as fp:
+ self.assertRaises(exc, fp.read)
+ self.assertRaises(exc, fp.readline)
+ with self.open(support.TESTFN, "rb", buffering=0) as fp:
+ self.assertRaises(exc, fp.write, b"blah")
+ self.assertRaises(exc, fp.writelines, [b"blah\n"])
with self.open(support.TESTFN, "rb") as fp:
- self.assertRaises(IOError, fp.write, b"blah")
- self.assertRaises(IOError, fp.writelines, [b"blah\n"])
+ self.assertRaises(exc, fp.write, b"blah")
+ self.assertRaises(exc, fp.writelines, [b"blah\n"])
with self.open(support.TESTFN, "r") as fp:
- self.assertRaises(IOError, fp.write, "blah")
- self.assertRaises(IOError, fp.writelines, ["blah\n"])
+ self.assertRaises(exc, fp.write, "blah")
+ self.assertRaises(exc, fp.writelines, ["blah\n"])
+ # Non-zero seeking from current or end pos
+ self.assertRaises(exc, fp.seek, 1, self.SEEK_CUR)
+ self.assertRaises(exc, fp.seek, -1, self.SEEK_END)
def test_raw_file_io(self):
with self.open(support.TESTFN, "wb", buffering=0) as f:
@@ -670,6 +697,11 @@
b.close()
self.assertRaises(ValueError, b.flush)
+ def test_unseekable(self):
+ bufio = self.tp(self.MockUnseekableIO(b"A" * 10))
+ self.assertRaises(self.UnsupportedOperation, bufio.tell)
+ self.assertRaises(self.UnsupportedOperation, bufio.seek, 0)
+
class BufferedReaderTest(unittest.TestCase, CommonBufferedTests):
read_mode = "rb"
@@ -1433,6 +1465,9 @@
BufferedReaderTest.test_misbehaved_io(self)
BufferedWriterTest.test_misbehaved_io(self)
+ # You can't construct a BufferedRandom over a non-seekable stream.
+ test_unseekable = None
+
class CBufferedRandomTest(BufferedRandomTest):
tp = io.BufferedRandom
@@ -2177,6 +2212,11 @@
txt.close()
self.assertRaises(ValueError, txt.flush)
+ def test_unseekable(self):
+ txt = self.TextIOWrapper(self.MockUnseekableIO(self.testdata))
+ self.assertRaises(self.UnsupportedOperation, txt.tell)
+ self.assertRaises(self.UnsupportedOperation, txt.seek, 0)
+
class CTextIOWrapperTest(TextIOWrapperTest):
def test_initialization(self):
@@ -2550,7 +2590,7 @@
# Put the namespaces of the IO module we are testing and some useful mock
# classes in the __dict__ of each test.
mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO,
- MockNonBlockWriterIO)
+ MockNonBlockWriterIO, MockUnseekableIO)
all_members = io.__all__ + ["IncrementalNewlineDecoder"]
c_io_ns = {name : getattr(io, name) for name in all_members}
py_io_ns = {name : getattr(pyio, name) for name in all_members}
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 6 01:01:12 2010
@@ -13,6 +13,10 @@
Library
-------
+- Issue #9293: I/O streams now raise ``io.UnsupportedOperation`` when an
+ unsupported operation is attempted (for example, writing to a file open
+ only for reading).
+
What's New in Python 3.2 Alpha 2?
=================================
Modified: python/branches/py3k/Modules/_io/fileio.c
==============================================================================
--- python/branches/py3k/Modules/_io/fileio.c (original)
+++ python/branches/py3k/Modules/_io/fileio.c Mon Sep 6 01:01:12 2010
@@ -417,7 +417,8 @@
static PyObject *
err_mode(char *action)
{
- PyErr_Format(PyExc_ValueError, "File not open for %s", action);
+ PyErr_Format(IO_STATE->unsupported_operation,
+ "File not open for %s", action);
return NULL;
}
Modified: python/branches/py3k/Modules/_io/iobase.c
==============================================================================
--- python/branches/py3k/Modules/_io/iobase.c (original)
+++ python/branches/py3k/Modules/_io/iobase.c Mon Sep 6 01:01:12 2010
@@ -317,7 +317,7 @@
return NULL;
if (res != Py_True) {
Py_CLEAR(res);
- PyErr_SetString(PyExc_IOError, "File or stream is not seekable.");
+ iobase_unsupported("File or stream is not seekable.");
return NULL;
}
if (args == Py_True) {
@@ -346,7 +346,7 @@
return NULL;
if (res != Py_True) {
Py_CLEAR(res);
- PyErr_SetString(PyExc_IOError, "File or stream is not readable.");
+ iobase_unsupported("File or stream is not readable.");
return NULL;
}
if (args == Py_True) {
@@ -375,7 +375,7 @@
return NULL;
if (res != Py_True) {
Py_CLEAR(res);
- PyErr_SetString(PyExc_IOError, "File or stream is not writable.");
+ iobase_unsupported("File or stream is not writable.");
return NULL;
}
if (args == Py_True) {
Modified: python/branches/py3k/Modules/_io/textio.c
==============================================================================
--- python/branches/py3k/Modules/_io/textio.c (original)
+++ python/branches/py3k/Modules/_io/textio.c Mon Sep 6 01:01:12 2010
@@ -1259,10 +1259,8 @@
CHECK_CLOSED(self);
- if (self->encoder == NULL) {
- PyErr_SetString(PyExc_IOError, "not writable");
- return NULL;
- }
+ if (self->encoder == NULL)
+ return _unsupported("not writable");
Py_INCREF(text);
@@ -1399,7 +1397,7 @@
*/
if (self->decoder == NULL) {
- PyErr_SetString(PyExc_IOError, "not readable");
+ _unsupported("not readable");
return -1;
}
@@ -1489,10 +1487,8 @@
CHECK_CLOSED(self);
- if (self->decoder == NULL) {
- PyErr_SetString(PyExc_IOError, "not readable");
- return NULL;
- }
+ if (self->decoder == NULL)
+ return _unsupported("not readable");
if (_textiowrapper_writeflush(self) < 0)
return NULL;
@@ -1983,8 +1979,7 @@
Py_INCREF(cookieObj);
if (!self->seekable) {
- PyErr_SetString(PyExc_IOError,
- "underlying stream is not seekable");
+ _unsupported("underlying stream is not seekable");
goto fail;
}
@@ -1995,8 +1990,7 @@
goto fail;
if (cmp == 0) {
- PyErr_SetString(PyExc_IOError,
- "can't do nonzero cur-relative seeks");
+ _unsupported("can't do nonzero cur-relative seeks");
goto fail;
}
@@ -2016,8 +2010,7 @@
goto fail;
if (cmp == 0) {
- PyErr_SetString(PyExc_IOError,
- "can't do nonzero end-relative seeks");
+ _unsupported("can't do nonzero end-relative seeks");
goto fail;
}
@@ -2151,8 +2144,7 @@
CHECK_CLOSED(self);
if (!self->seekable) {
- PyErr_SetString(PyExc_IOError,
- "underlying stream is not seekable");
+ _unsupported("underlying stream is not seekable");
goto fail;
}
if (!self->telling) {
From python-checkins at python.org Mon Sep 6 01:15:07 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon, 6 Sep 2010 01:15:07 +0200 (CEST)
Subject: [Python-checkins] r84545 - in python/branches/py3k/Lib:
_markupbase.py ftplib.py
Message-ID: <20100905231507.076BEEEA01@mail.python.org>
Author: raymond.hettinger
Date: Mon Sep 6 01:15:06 2010
New Revision: 84545
Log:
Take advantage of the frozenset constant optimization.
Modified:
python/branches/py3k/Lib/_markupbase.py
python/branches/py3k/Lib/ftplib.py
Modified: python/branches/py3k/Lib/_markupbase.py
==============================================================================
--- python/branches/py3k/Lib/_markupbase.py (original)
+++ python/branches/py3k/Lib/_markupbase.py Mon Sep 6 01:15:06 2010
@@ -122,7 +122,7 @@
# this could be handled in a separate doctype parser
if decltype == "doctype":
j = self._parse_doctype_subset(j + 1, i)
- elif decltype in ("attlist", "linktype", "link", "element"):
+ elif decltype in {"attlist", "linktype", "link", "element"}:
# must tolerate []'d groups in a content model in an element declaration
# also in data attribute specifications of attlist declaration
# also link type declaration subsets in linktype declarations
@@ -145,10 +145,10 @@
sectName, j = self._scan_name( i+3, i )
if j < 0:
return j
- if sectName in ("temp", "cdata", "ignore", "include", "rcdata"):
+ if sectName in {"temp", "cdata", "ignore", "include", "rcdata"}:
# look for standard ]]> ending
match= _markedsectionclose.search(rawdata, i+3)
- elif sectName in ("if", "else", "endif"):
+ elif sectName in {"if", "else", "endif"}:
# look for MS Office ]> ending
match= _msmarkedsectionclose.search(rawdata, i+3)
else:
@@ -203,7 +203,7 @@
name, j = self._scan_name(j + 2, declstartpos)
if j == -1:
return -1
- if name not in ("attlist", "element", "entity", "notation"):
+ if name not in {"attlist", "element", "entity", "notation"}:
self.updatepos(declstartpos, j + 2)
self.error(
"unknown declaration %r in internal subset" % name)
Modified: python/branches/py3k/Lib/ftplib.py
==============================================================================
--- python/branches/py3k/Lib/ftplib.py (original)
+++ python/branches/py3k/Lib/ftplib.py Mon Sep 6 01:15:06 2010
@@ -171,7 +171,7 @@
def sanitize(self, s):
if s[:5] == 'pass ' or s[:5] == 'PASS ':
i = len(s)
- while i > 5 and s[i-1] in '\r\n':
+ while i > 5 and s[i-1] in {'\r', '\n'}:
i = i-1
s = s[:5] + '*'*(i-5) + s[i:]
return repr(s)
@@ -221,7 +221,7 @@
if self.debugging: print('*resp*', self.sanitize(resp))
self.lastresp = resp[:3]
c = resp[:1]
- if c in ('1', '2', '3'):
+ if c in {'1', '2', '3'}:
return resp
if c == '4':
raise error_temp(resp)
@@ -245,7 +245,7 @@
if self.debugging > 1: print('*put urgent*', self.sanitize(line))
self.sock.sendall(line, MSG_OOB)
resp = self.getmultiline()
- if resp[:3] not in ('426', '225', '226'):
+ if resp[:3] not in {'426', '225', '226'}:
raise error_proto(resp)
def sendcmd(self, cmd):
@@ -375,7 +375,7 @@
if not user: user = 'anonymous'
if not passwd: passwd = ''
if not acct: acct = ''
- if user == 'anonymous' and passwd in ('', '-'):
+ if user == 'anonymous' and passwd in {'', '-'}:
# If there is no anonymous ftp password specified
# then we'll just use anonymous@
# We don't send any other thing because:
@@ -534,7 +534,7 @@
def delete(self, filename):
'''Delete a file.'''
resp = self.sendcmd('DELE ' + filename)
- if resp[:3] in ('250', '200'):
+ if resp[:3] in {'250', '200'}:
return resp
else:
raise error_reply(resp)
@@ -897,9 +897,9 @@
# transfer request.
# So: STOR before RETR, because here the target is a "user".
treply = target.sendcmd('STOR ' + targetname)
- if treply[:3] not in ('125', '150'): raise error_proto # RFC 959
+ if treply[:3] not in {'125', '150'}: raise error_proto # RFC 959
sreply = source.sendcmd('RETR ' + sourcename)
- if sreply[:3] not in ('125', '150'): raise error_proto # RFC 959
+ if sreply[:3] not in {'125', '150'}: raise error_proto # RFC 959
source.voidresp()
target.voidresp()
From python-checkins at python.org Mon Sep 6 01:50:32 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon, 6 Sep 2010 01:50:32 +0200 (CEST)
Subject: [Python-checkins] r84546 -
python/branches/py3k/Doc/library/fileinput.rst
Message-ID: <20100905235032.2B208EEA12@mail.python.org>
Author: raymond.hettinger
Date: Mon Sep 6 01:50:32 2010
New Revision: 84546
Log:
Clean-up example of using fileinput as a context manager.
Modified:
python/branches/py3k/Doc/library/fileinput.rst
Modified: python/branches/py3k/Doc/library/fileinput.rst
==============================================================================
--- python/branches/py3k/Doc/library/fileinput.rst (original)
+++ python/branches/py3k/Doc/library/fileinput.rst Mon Sep 6 01:50:32 2010
@@ -58,8 +58,9 @@
:keyword:`with` statement. In this example, *input* is closed after the
:keyword:`with` statement is exited, even if an exception occurs::
- with fileinput.input(files=('spam.txt', 'eggs.txt')) as input:
- process(input)
+ with fileinput.input(files=('spam.txt', 'eggs.txt')) as f:
+ for line in f:
+ process(line)
.. versionchanged:: 3.2
Can be used as a context manager.
From python-checkins at python.org Mon Sep 6 02:32:13 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Mon, 6 Sep 2010 02:32:13 +0200 (CEST)
Subject: [Python-checkins] r84547 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100906003213.0914EEE994@mail.python.org>
Author: benjamin.peterson
Date: Mon Sep 6 02:32:12 2010
New Revision: 84547
Log:
link to docs
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Mon Sep 6 02:32:12 2010
@@ -215,8 +215,8 @@
(By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
:issue:`8814`.)
-* The :mod:`abc` module now supports :func:`abstractclassmethod` and
- :func:`abstractstaticmethod`.
+* The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
+ :func:`~abc.abstractstaticmethod`.
(:issue:`5867`.)
From python-checkins at python.org Mon Sep 6 03:16:46 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon, 6 Sep 2010 03:16:46 +0200 (CEST)
Subject: [Python-checkins] r84548 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100906011646.9430DEE993@mail.python.org>
Author: raymond.hettinger
Date: Mon Sep 6 03:16:46 2010
New Revision: 84548
Log:
More updates to whatsnew3.2
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Mon Sep 6 03:16:46 2010
@@ -53,22 +53,18 @@
PEP 391: Dictionary Based Configuration for Logging
====================================================
-The :mod:`logging` module had two ways of configuring the module, either by calling
-functions for each option or by reading an external file saved in a :mod:`ConfigParser`
-format. Those options did not provide the flexibility to create configurations
-from JSON or YAML files and they did not support incremental configuration, which
-is needed for specifying logger options from a command line.
+The :mod:`logging` module provided two kinds of configuration, one style with
+function calls for each option or another style driven by an external file saved
+in a :mod:`ConfigParser` format. Those options did not provide the flexibility
+to create configurations from JSON or YAML files, nor they did not support
+incremental configuration, which is needed for specifying logger options from a
+command line.
To support a more flexible style, the module now offers
-:func:`logging.config.dictConfig` to use dictionaries to specify logger
-configuration (including formatters, handlers, filters, and loggers). For
-example:
-
->>> import logging.config
->>> logging.config.dictConfig(json.load(open('log.cfg', 'rb')))
-
-The above fragment configures logging from a JSON-encoded dictionary stored in a
-file called "log.cfg". Here's a working example of a configuration dictionary::
+:func:`logging.config.dictConfig` for specifying logging configuration with
+plain Python dictionaries. The configuration options include formatters,
+handlers, filters, and loggers. Here's a working example of a configuration
+dictionary::
{"version": 1,
"formatters": {"brief": {"format": "%(levelname)-8s: %(name)-15s: %(message)s"},
@@ -87,6 +83,15 @@
},
"root": {"level": "DEBUG", "handlers": ["console", "console_priority"]}}
+
+If that dictionary is stored in a file called "conf.json", it can loaded
+and called with code like this::
+
+ >>> import logging.config
+ >>> logging.config.dictConfig(json.load(open('conf.json', 'rb')))
+ >>> logging.info("Transaction completed normally")
+ >>> logging.critical("Abnormal termination")
+
.. seealso::
:pep:`391` - Dictionary Based Configuration for Logging
@@ -119,16 +124,16 @@
* Imported modules now have a :attr:`__cached__` attribute which stores the name
of the actual file that was imported:
- >>> import collections
- >>> collections.__cached__
- 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
+ >>> import collections
+ >>> collections.__cached__
+ 'c:/py32/lib/__pycache__/collections.cpython-32.pyc'
* The tag that is unique to each interpreter is accessible from the :mod:`imp`
module:
- >>> import imp
- >>> imp.get_tag()
- 'cpython-32'
+ >>> import imp
+ >>> imp.get_tag()
+ 'cpython-32'
* Scripts that try to deduce source filename from the imported file now need to
be smarter. It is no longer sufficient to simply strip the "c" from a ".pyc"
@@ -199,10 +204,10 @@
caused confusion and is no longer needed now that the shortest possible
:func:`repr` is displayed by default:
- >>> repr(math.pi)
- '3.141592653589793'
- >>> str(math.pi)
- '3.141592653589793'
+ >>> repr(math.pi)
+ '3.141592653589793'
+ >>> str(math.pi)
+ '3.141592653589793'
(Proposed and implemented by Mark Dickinson; :issue:`9337`.)
@@ -218,8 +223,22 @@
* The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
:func:`~abc.abstractstaticmethod`.
- (:issue:`5867`.)
+ (Patch submitted by Daniel Urban; :issue:`5867`.)
+
+* A warning message will now get printed at interpreter shutdown if the
+ :data:`gc.garbage` list isn't empty. This is meant to make the programmer
+ aware that their code contains object finalization issues.
+
+ (Added by Antoine Pitrou; :issue:`477863`.)
+
+* Mark Dickinson crafted an elegant and efficient scheme for assuring that
+ different numeric datatypes will have the same hash value whenever their
+ actual values are equal::
+
+ >>> assert hash(Fraction(3, 2)) == hash(1.5) == \
+ hash(Decimal("1.5")) == hash(complex(1.5, 0))
+ (See :issue:`8188`.)
New, Improved, and Deprecated Modules
=====================================
@@ -263,26 +282,28 @@
* The :class:`ftplib.FTP` class now supports the context manager protocol to
unconditionally consume :exc:`socket.error` exceptions and to close the FTP
- connection when done:
+ connection when done::
- >>> from ftplib import FTP
- >>> with FTP("ftp1.at.proftpd.org") as ftp:
- ... ftp.login()
- ... ftp.dir()
- ...
- '230 Anonymous login ok, restrictions apply.'
- dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
- dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
- dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
- dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
+ >>> from ftplib import FTP
+ >>> with FTP("ftp1.at.proftpd.org") as ftp:
+ ... ftp.login()
+ ... ftp.dir()
+ ...
+ '230 Anonymous login ok, restrictions apply.'
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 .
+ dr-xr-xr-x 9 ftp ftp 154 May 6 10:43 ..
+ dr-xr-xr-x 5 ftp ftp 4096 May 6 10:43 CentOS
+ dr-xr-xr-x 3 ftp ftp 18 Jul 10 2008 Fedora
+
+ Other file-like objects such as :class:`mmap.mmap` and :func:`fileinput.input`
+ also grew auto-closing context managers::
+
+ with fileinput.input(files=('log1.txt', 'log2.txt')) as f:
+ for line in f:
+ process(line)
- (Contributed by Tarek Ziad? and Giampaolo Rodol?; :issue:`4972`.)
-
-* A warning message will now get printed at interpreter shutdown if the
- :data:`gc.garbage` list isn't empty. This is meant to make the programmer
- aware that their code contains object finalization issues.
-
- (Added by Antoine Pitrou; :issue:`477863`.)
+ (Contributed by Tarek Ziad? and Giampaolo Rodol? in :issue:`4972`, and
+ by Georg Brandl in :issue:`8046` and :issue:`1286`.)
* The :mod:`os` module now has the :const:`ST_RDONLY` and :const:`ST_NOSUID`
constants, for use with the :func:`~os.statvfs` function.
@@ -395,15 +416,39 @@
argument. (Contributed by Torsten Landschoff; :issue:`850728`.)
-.. Optimizations
- =============
+Optimizations
+=============
- Major performance enhancements have been added:
+A number of small performance enhancements have been added:
- * Stub
+* JSON decoding performance is improved and memory consumption is reduced
+ whenever the same string is repeated for multiple keys.
+
+ (Contributed by Antoine Pitrou; :issue:`7451`.)
+
+- Python's peephole optimizer now recognizes patterns such ``x in {1, 2, 3}`` as
+ being a test for membership in a set of constants. The optimizer recasts the
+ :class:`set` as a :class:`frozenset` and stores the pre-built constant.
+
+ Now that the speed penalty is gone, it is practical to start writing
+ membership tests using set-notation. This style is both semantically clear
+ and operationally fast::
+
+ extension = name.rpartition('.')[2]
+ if extension in {'xml', 'html', 'xhtml', 'css'}:
+ handle(name)
+
+ (Patch and additional tests by Dave Malcolm; :issue:`6690`).
+
+* The fast-search algorithm in stringlib is now used by the :meth:`split`,
+ :meth:`rsplit`, :meth:`splitlines` and :meth:`replace` methods on
+ :class:`bytes`, :class:`bytearray` and :class:`str` objects. Likewise, the
+ algorithm is also used by :meth:`rfind`, :meth:`rindex`, :meth:`rsplit` and
+ :meth:`rpartition`.
+ (Patch by Florent Xicluna in :issue:`7622` and :issue:`7462`.)
-Filenames and unicode
+Filenames and Unicode
=====================
The filesystem encoding can be specified by setting the
From python-checkins at python.org Mon Sep 6 03:27:07 2010
From: python-checkins at python.org (eric.araujo)
Date: Mon, 6 Sep 2010 03:27:07 +0200 (CEST)
Subject: [Python-checkins] r84549 - python/branches/py3k/Doc/Makefile
Message-ID: <20100906012707.1893DF4EC@mail.python.org>
Author: eric.araujo
Date: Mon Sep 6 03:27:06 2010
New Revision: 84549
Log:
Update
Modified:
python/branches/py3k/Doc/Makefile
Modified: python/branches/py3k/Doc/Makefile
==============================================================================
--- python/branches/py3k/Doc/Makefile (original)
+++ python/branches/py3k/Doc/Makefile Mon Sep 6 03:27:06 2010
@@ -55,9 +55,9 @@
svn checkout $(SVNROOT)/external/Pygments-1.3.1/pygments tools/pygments; \
fi
-update: clean checkout
+update: clean
-build: checkout
+build:
mkdir -p build/$(BUILDER) build/doctrees
$(PYTHON) tools/sphinx-build.py $(ALLSPHINXOPTS)
@echo
From python-checkins at python.org Mon Sep 6 03:29:23 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon, 6 Sep 2010 03:29:23 +0200 (CEST)
Subject: [Python-checkins] r84550 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100906012923.5A5CFF4EC@mail.python.org>
Author: raymond.hettinger
Date: Mon Sep 6 03:29:23 2010
New Revision: 84550
Log:
Fix nits
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Mon Sep 6 03:29:23 2010
@@ -56,7 +56,7 @@
The :mod:`logging` module provided two kinds of configuration, one style with
function calls for each option or another style driven by an external file saved
in a :mod:`ConfigParser` format. Those options did not provide the flexibility
-to create configurations from JSON or YAML files, nor they did not support
+to create configurations from JSON or YAML files, nor did they not support
incremental configuration, which is needed for specifying logger options from a
command line.
@@ -220,8 +220,8 @@
(By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
:issue:`8814`.)
-* The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
- :func:`~abc.abstractstaticmethod`.
+* The :mod:`abc` module now supports :func:`abstractclassmethod` and
+ :func:`abstractstaticmethod`.
(Patch submitted by Daniel Urban; :issue:`5867`.)
@@ -312,11 +312,11 @@
* The :func:`shutil.copytree` function has two new options:
- * *ignore_dangling_symlinks*: when ``symlinks=False`` (meaning that the function
- copies the file pointed to by the symlink, not the symlink itself), this
+ * *ignore_dangling_symlinks*: when ``symlinks=False`` so that the function
+ copies the file pointed to by the symlink, not the symlink itself. This
option will silence the error raised if the file doesn't exist.
- * *copy_function*: a callable that will be used to copy files.
+ * *copy_function*: is a callable that will be used to copy files.
:func:`shutil.copy2` is used by default.
(Contributed by Tarek Ziad?.)
@@ -482,7 +482,7 @@
(Reported by Bupjoe Lee and fixed by Amaury Forgeot D'Arc; :issue:`5127`.)
* Computed gotos are now enabled by default on supported compilers (which are
- detected by the configure script). They can still be disable selectively by
+ detected by the configure script). They can still be disabled selectively by
specifying ``--without-computed-gotos``.
(Contributed by Antoine Pitrou; :issue:`9203`.)
From python-checkins at python.org Mon Sep 6 03:31:11 2010
From: python-checkins at python.org (eric.araujo)
Date: Mon, 6 Sep 2010 03:31:11 +0200 (CEST)
Subject: [Python-checkins] r84551 - python/branches/py3k/Doc/Makefile
Message-ID: <20100906013111.59735EE984@mail.python.org>
Author: eric.araujo
Date: Mon Sep 6 03:31:11 2010
New Revision: 84551
Log:
Revert accidental commit, apologies for the noise
Modified:
python/branches/py3k/Doc/Makefile
Modified: python/branches/py3k/Doc/Makefile
==============================================================================
--- python/branches/py3k/Doc/Makefile (original)
+++ python/branches/py3k/Doc/Makefile Mon Sep 6 03:31:11 2010
@@ -55,9 +55,9 @@
svn checkout $(SVNROOT)/external/Pygments-1.3.1/pygments tools/pygments; \
fi
-update: clean
+update: clean checkout
-build:
+build: checkout
mkdir -p build/$(BUILDER) build/doctrees
$(PYTHON) tools/sphinx-build.py $(ALLSPHINXOPTS)
@echo
From solipsis at pitrou.net Mon Sep 6 05:04:47 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Mon, 06 Sep 2010 05:04:47 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84548): sum=0
Message-ID:
py3k results for svn r84548 (hg cset 61710858c559)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogOtCbK0', '-x']
From python-checkins at python.org Mon Sep 6 08:45:47 2010
From: python-checkins at python.org (georg.brandl)
Date: Mon, 6 Sep 2010 08:45:47 +0200 (CEST)
Subject: [Python-checkins] r84552 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100906064547.8E946EE984@mail.python.org>
Author: georg.brandl
Date: Mon Sep 6 08:45:47 2010
New Revision: 84552
Log:
Remove redundant word.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Mon Sep 6 08:45:47 2010
@@ -56,7 +56,7 @@
The :mod:`logging` module provided two kinds of configuration, one style with
function calls for each option or another style driven by an external file saved
in a :mod:`ConfigParser` format. Those options did not provide the flexibility
-to create configurations from JSON or YAML files, nor did they not support
+to create configurations from JSON or YAML files, nor did they support
incremental configuration, which is needed for specifying logger options from a
command line.
From python-checkins at python.org Mon Sep 6 08:49:07 2010
From: python-checkins at python.org (georg.brandl)
Date: Mon, 6 Sep 2010 08:49:07 +0200 (CEST)
Subject: [Python-checkins] r84553 -
python/branches/py3k/Doc/library/string.rst
Message-ID: <20100906064907.E6752EE984@mail.python.org>
Author: georg.brandl
Date: Mon Sep 6 08:49:07 2010
New Revision: 84553
Log:
#9780: both { and } are not valid fill characters.
Modified:
python/branches/py3k/Doc/library/string.rst
Modified: python/branches/py3k/Doc/library/string.rst
==============================================================================
--- python/branches/py3k/Doc/library/string.rst (original)
+++ python/branches/py3k/Doc/library/string.rst Mon Sep 6 08:49:07 2010
@@ -299,11 +299,11 @@
precision: `integer`
type: "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
-The *fill* character can be any character other than '}' (which signifies the
-end of the field). The presence of a fill character is signaled by the *next*
-character, which must be one of the alignment options. If the second character
-of *format_spec* is not a valid alignment option, then it is assumed that both
-the fill character and the alignment option are absent.
+The *fill* character can be any character other than '{' or '}'. The presence
+of a fill character is signaled by the character following it, which must be
+one of the alignment options. If the second character of *format_spec* is not
+a valid alignment option, then it is assumed that both the fill character and
+the alignment option are absent.
The meaning of the various alignment options is as follows:
From python-checkins at python.org Mon Sep 6 10:30:24 2010
From: python-checkins at python.org (gregory.p.smith)
Date: Mon, 6 Sep 2010 10:30:24 +0200 (CEST)
Subject: [Python-checkins] r84554 - in python/branches/py3k:
Doc/library/hashlib.rst Lib/hashlib.py
Lib/test/test_hashlib.py Misc/NEWS Modules/_hashopenssl.c
Message-ID: <20100906083024.2813DEEA21@mail.python.org>
Author: gregory.p.smith
Date: Mon Sep 6 10:30:23 2010
New Revision: 84554
Log:
hashlib has two new constant attributes: algorithms_guaranteed and
algorithms_avaiable that respectively list the names of hash algorithms
guaranteed to exist in all Python implementations and the names of hash
algorithms available in the current process.
Renames the attribute new in 3.2a0 'algorithms' to 'algorithms_guaranteed'.
Modified:
python/branches/py3k/Doc/library/hashlib.rst
python/branches/py3k/Lib/hashlib.py
python/branches/py3k/Lib/test/test_hashlib.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/_hashopenssl.c
Modified: python/branches/py3k/Doc/library/hashlib.rst
==============================================================================
--- python/branches/py3k/Doc/library/hashlib.rst (original)
+++ python/branches/py3k/Doc/library/hashlib.rst Mon Sep 6 10:30:23 2010
@@ -70,10 +70,13 @@
>>> hashlib.sha224(b"Nobody inspects the spammish repetition").hexdigest()
'a4337bc45a8fc544c03f52dc550cd6e1e87021bc896588bd79e901e2'
-A generic :func:`new` constructor that takes the string name of the desired
-algorithm as its first parameter also exists to allow access to the above listed
-hashes as well as any other algorithms that your OpenSSL library may offer. The
-named constructors are much faster than :func:`new` and should be preferred.
+.. function:: new(name[, data])
+
+ Is a generic constructor that takes the string name of the desired
+ algorithm as its first parameter. It also exists to allow access to the
+ above listed hashes as well as any other algorithms that your OpenSSL
+ library may offer. The named constructors are much faster than :func:`new`
+ and should be preferred.
Using :func:`new` with an algorithm provided by OpenSSL:
@@ -82,12 +85,22 @@
>>> h.hexdigest()
'cc4a5ce1b3df48aec5d22d1f16b894a0b894eccc'
-This module provides the following constant attribute:
+Hashlib provides the following constant attributes:
+
+.. data:: algorithms_guaranteed
+
+ Contains the names of the hash algorithms guaranteed to be supported
+ by this module on all platforms.
+
+ .. versionadded:: 3.2
-.. data:: hashlib.algorithms
+.. data:: algorithms_available
- A tuple providing the names of the hash algorithms guaranteed to be
- supported by this module.
+ Contains the names of the hash algorithms that are available
+ in the running Python interpreter. These names will be recognized
+ when passed to :func:`new`. :attr:`algorithms_guaranteed`
+ will always be a subset. Duplicate algorithms with different
+ name formats may appear in this set (thanks to OpenSSL).
.. versionadded:: 3.2
Modified: python/branches/py3k/Lib/hashlib.py
==============================================================================
--- python/branches/py3k/Lib/hashlib.py (original)
+++ python/branches/py3k/Lib/hashlib.py Mon Sep 6 10:30:23 2010
@@ -1,6 +1,4 @@
-# $Id$
-#
-# Copyright (C) 2005-2007 Gregory P. Smith (greg at krypto.org)
+# Copyright (C) 2005-2010 Gregory P. Smith (greg at krypto.org)
# Licensed to PSF under a Contributor Agreement.
#
@@ -15,8 +13,9 @@
md5(), sha1(), sha224(), sha256(), sha384(), and sha512()
-More algorithms may be available on your platform but the above are
-guaranteed to exist.
+More algorithms may be available on your platform but the above are guaranteed
+to exist. See the algorithms_guaranteed and algorithms_available attributes
+to find out what algorithm names can be passed to new().
NOTE: If you want the adler32 or crc32 hash functions they are available in
the zlib module.
@@ -57,9 +56,11 @@
# always available algorithm is added.
__always_supported = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
-algorithms = __always_supported
+algorithms_guaranteed = __always_supported
+algorithms_available = frozenset(__always_supported)
-__all__ = __always_supported + ('new', 'algorithms')
+__all__ = __always_supported + ('new', 'algorithms_guaranteed',
+ 'algorithms_available')
def __get_builtin_constructor(name):
@@ -124,6 +125,8 @@
import _hashlib
new = __hash_new
__get_hash = __get_openssl_constructor
+ algorithms_available = algorithms_available.union(
+ _hashlib.openssl_md_meth_names)
except ImportError:
new = __py_new
__get_hash = __get_builtin_constructor
Modified: python/branches/py3k/Lib/test/test_hashlib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_hashlib.py (original)
+++ python/branches/py3k/Lib/test/test_hashlib.py Mon Sep 6 10:30:23 2010
@@ -101,11 +101,15 @@
c = cons(a)
c.hexdigest()
- def test_algorithms_attribute(self):
- self.assertEqual(hashlib.algorithms,
+ def test_algorithms_guaranteed(self):
+ self.assertEqual(hashlib.algorithms_guaranteed,
tuple(_algo for _algo in self.supported_hash_names
if _algo.islower()))
+ def test_algorithms_available(self):
+ self.assertTrue(set(hashlib.algorithms_guaranteed).
+ issubset(hashlib.algorithms_available))
+
def test_unknown_hash(self):
try:
hashlib.new('spam spam spam spam spam')
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 6 10:30:23 2010
@@ -17,6 +17,11 @@
unsupported operation is attempted (for example, writing to a file open
only for reading).
+- hashlib has two new constant attributes: algorithms_guaranteed and
+ algorithms_avaiable that respectively list the names of hash algorithms
+ guaranteed to exist in all Python implementations and the names of hash
+ algorithms available in the current process.
+
What's New in Python 3.2 Alpha 2?
=================================
Modified: python/branches/py3k/Modules/_hashopenssl.c
==============================================================================
--- python/branches/py3k/Modules/_hashopenssl.c (original)
+++ python/branches/py3k/Modules/_hashopenssl.c Mon Sep 6 10:30:23 2010
@@ -38,6 +38,8 @@
/* EVP is the preferred interface to hashing in OpenSSL */
#include
+/* We use the object interface to discover what hashes OpenSSL supports. */
+#include
#define MUNCH_SIZE INT_MAX
@@ -488,6 +490,62 @@
return ret_obj;
}
+
+/* State for our callback function so that it can accumulate a result. */
+typedef struct _internal_name_mapper_state {
+ PyObject *set;
+ int error;
+} _InternalNameMapperState;
+
+
+/* A callback function to pass to OpenSSL's OBJ_NAME_do_all(...) */
+static void
+_openssl_hash_name_mapper(const OBJ_NAME *openssl_obj_name, void *arg)
+{
+ _InternalNameMapperState *state = (_InternalNameMapperState *)arg;
+ PyObject *py_name;
+
+ assert(state != NULL);
+ if (openssl_obj_name == NULL)
+ return;
+ /* Ignore aliased names, they pollute the list and OpenSSL appears to
+ * have a its own definition of alias as the resulting list still
+ * contains duplicate and alternate names for several algorithms. */
+ if (openssl_obj_name->alias)
+ return;
+
+ py_name = PyUnicode_FromString(openssl_obj_name->name);
+ if (py_name == NULL) {
+ state->error = 1;
+ } else {
+ if (PySet_Add(state->set, py_name) != 0) {
+ Py_DECREF(py_name);
+ state->error = 1;
+ }
+ }
+}
+
+
+/* Ask OpenSSL for a list of supported ciphers, filling in a Python set. */
+static PyObject*
+generate_hash_name_list(void)
+{
+ _InternalNameMapperState state;
+ state.set = PyFrozenSet_New(NULL);
+ if (state.set == NULL)
+ return NULL;
+ state.error = 0;
+
+ OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, &_openssl_hash_name_mapper, &state);
+
+ if (state.error) {
+ Py_DECREF(state.set);
+ return NULL;
+ }
+ return state.set;
+}
+
+
/*
* This macro generates constructor function definitions for specific
* hash algorithms. These constructors are much faster than calling
@@ -581,7 +639,7 @@
PyMODINIT_FUNC
PyInit__hashlib(void)
{
- PyObject *m;
+ PyObject *m, *openssl_md_meth_names;
OpenSSL_add_all_digests();
@@ -598,6 +656,16 @@
if (m == NULL)
return NULL;
+ openssl_md_meth_names = generate_hash_name_list();
+ if (openssl_md_meth_names == NULL) {
+ Py_DECREF(m);
+ return NULL;
+ }
+ if (PyModule_AddObject(m, "openssl_md_meth_names", openssl_md_meth_names)) {
+ Py_DECREF(m);
+ return NULL;
+ }
+
#if HASH_OBJ_CONSTRUCTOR
Py_INCREF(&EVPtype);
PyModule_AddObject(m, "HASH", (PyObject *)&EVPtype);
From python-checkins at python.org Mon Sep 6 14:36:55 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Mon, 6 Sep 2010 14:36:55 +0200 (CEST)
Subject: [Python-checkins] r84555 -
python/branches/py3k/Tools/iobench/iobench.py
Message-ID: <20100906123655.91168EEA58@mail.python.org>
Author: antoine.pitrou
Date: Mon Sep 6 14:36:55 2010
New Revision: 84555
Log:
Add an option to choose the IO module under test (allows to bench
e.g. the pure Python implementation in _pyio).
Modified:
python/branches/py3k/Tools/iobench/iobench.py
Modified: python/branches/py3k/Tools/iobench/iobench.py
==============================================================================
--- python/branches/py3k/Tools/iobench/iobench.py (original)
+++ python/branches/py3k/Tools/iobench/iobench.py Mon Sep 6 14:36:55 2010
@@ -427,6 +427,9 @@
action="store", dest="newlines", default='lf',
help="line endings for text tests "
"(one of: {lf (default), cr, crlf, all})")
+ parser.add_option("-m", "--io-module",
+ action="store", dest="io_module", default=None,
+ help="io module to test (default: builtin open())")
options, args = parser.parse_args()
if args:
parser.error("unexpected arguments")
@@ -451,6 +454,9 @@
if options.encoding:
TEXT_ENCODING = options.encoding
+ if options.io_module:
+ globals()['open'] = __import__(options.io_module, {}, {}, ['open']).open
+
prepare_files()
run_all_tests(test_options)
From python-checkins at python.org Mon Sep 6 18:04:11 2010
From: python-checkins at python.org (brian.curtin)
Date: Mon, 6 Sep 2010 18:04:11 +0200 (CEST)
Subject: [Python-checkins] r84556 - in python/branches/py3k:
Lib/test/test_signal.py Modules/signalmodule.c
Message-ID: <20100906160411.1CACBEE9D5@mail.python.org>
Author: brian.curtin
Date: Mon Sep 6 18:04:10 2010
New Revision: 84556
Log:
Clean up the fix to #9324 with some of the suggestions raised on python-dev
in response to the original checkin.
Move the validation from the original loop into a switch statement,
and adjust a platform check in the tests.
Modified:
python/branches/py3k/Lib/test/test_signal.py
python/branches/py3k/Modules/signalmodule.c
Modified: python/branches/py3k/Lib/test/test_signal.py
==============================================================================
--- python/branches/py3k/Lib/test/test_signal.py (original)
+++ python/branches/py3k/Lib/test/test_signal.py Mon Sep 6 18:04:10 2010
@@ -9,9 +9,8 @@
import traceback
import sys, os, time, errno
-if sys.platform == 'os2' or sys.platform == 'riscos':
- raise unittest.SkipTest("Can't test signal on %s" % \
- sys.platform)
+if sys.platform in ('os2', 'riscos'):
+ raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
class HandlerBCalled(Exception):
Modified: python/branches/py3k/Modules/signalmodule.c
==============================================================================
--- python/branches/py3k/Modules/signalmodule.c (original)
+++ python/branches/py3k/Modules/signalmodule.c Mon Sep 6 18:04:10 2010
@@ -255,21 +255,20 @@
int sig_num;
PyObject *old_handler;
void (*func)(int);
-#ifdef MS_WINDOWS
- int cur_sig, num_valid_sigs = 6;
- static int valid_sigs[] = {SIGABRT, SIGFPE, SIGILL, SIGINT,
- SIGSEGV, SIGTERM};
- BOOL valid_sig = FALSE;
-#endif
if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
return NULL;
#ifdef MS_WINDOWS
/* Validate that sig_num is one of the allowable signals */
- for (cur_sig = 0; cur_sig < num_valid_sigs; cur_sig++)
- valid_sig |= (sig_num == valid_sigs[cur_sig]);
- if (!valid_sig) {
- PyErr_SetString(PyExc_ValueError, "signal number out of range");
- return NULL;
+ switch (sig_num) {
+ case SIGABRT: break;
+ case SIGFPE: break;
+ case SIGILL: break;
+ case SIGINT: break;
+ case SIGSEGV: break;
+ case SIGTERM: break;
+ default:
+ PyErr_SetString(PyExc_ValueError, "invalid signal value");
+ return NULL;
}
#endif
#ifdef WITH_THREAD
From python-checkins at python.org Mon Sep 6 18:10:04 2010
From: python-checkins at python.org (brian.curtin)
Date: Mon, 6 Sep 2010 18:10:04 +0200 (CEST)
Subject: [Python-checkins] r84557 - in python/branches/release31-maint:
Lib/test/test_signal.py Modules/signalmodule.c
Message-ID: <20100906161004.5E0DADDAF@mail.python.org>
Author: brian.curtin
Date: Mon Sep 6 18:10:04 2010
New Revision: 84557
Log:
Merged revisions 84556 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84556 | brian.curtin | 2010-09-06 11:04:10 -0500 (Mon, 06 Sep 2010) | 7 lines
Clean up the fix to #9324 with some of the suggestions raised on python-dev
in response to the original checkin.
Move the validation from the original loop into a switch statement,
and adjust a platform check in the tests.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_signal.py
python/branches/release31-maint/Modules/signalmodule.c
Modified: python/branches/release31-maint/Lib/test/test_signal.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_signal.py (original)
+++ python/branches/release31-maint/Lib/test/test_signal.py Mon Sep 6 18:10:04 2010
@@ -9,9 +9,8 @@
import traceback
import sys, os, time, errno
-if sys.platform == 'os2' or sys.platform == 'riscos':
- raise unittest.SkipTest("Can't test signal on %s" % \
- sys.platform)
+if sys.platform in ('os2', 'riscos'):
+ raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
class HandlerBCalled(Exception):
Modified: python/branches/release31-maint/Modules/signalmodule.c
==============================================================================
--- python/branches/release31-maint/Modules/signalmodule.c (original)
+++ python/branches/release31-maint/Modules/signalmodule.c Mon Sep 6 18:10:04 2010
@@ -252,21 +252,20 @@
int sig_num;
PyObject *old_handler;
void (*func)(int);
-#ifdef MS_WINDOWS
- int cur_sig, num_valid_sigs = 6;
- static int valid_sigs[] = {SIGABRT, SIGFPE, SIGILL, SIGINT,
- SIGSEGV, SIGTERM};
- BOOL valid_sig = FALSE;
-#endif
if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
return NULL;
#ifdef MS_WINDOWS
/* Validate that sig_num is one of the allowable signals */
- for (cur_sig = 0; cur_sig < num_valid_sigs; cur_sig++)
- valid_sig |= (sig_num == valid_sigs[cur_sig]);
- if (!valid_sig) {
- PyErr_SetString(PyExc_ValueError, "signal number out of range");
- return NULL;
+ switch (sig_num) {
+ case SIGABRT: break;
+ case SIGFPE: break;
+ case SIGILL: break;
+ case SIGINT: break;
+ case SIGSEGV: break;
+ case SIGTERM: break;
+ default:
+ PyErr_SetString(PyExc_ValueError, "invalid signal value");
+ return NULL;
}
#endif
#ifdef WITH_THREAD
From python-checkins at python.org Mon Sep 6 18:17:50 2010
From: python-checkins at python.org (brian.curtin)
Date: Mon, 6 Sep 2010 18:17:50 +0200 (CEST)
Subject: [Python-checkins] r84558 - in python/branches/release27-maint:
Lib/test/test_signal.py Modules/signalmodule.c
Message-ID: <20100906161750.5ADD3EE9B6@mail.python.org>
Author: brian.curtin
Date: Mon Sep 6 18:17:50 2010
New Revision: 84558
Log:
Merged revisions 84556 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84556 | brian.curtin | 2010-09-06 11:04:10 -0500 (Mon, 06 Sep 2010) | 7 lines
Clean up the fix to #9324 with some of the suggestions raised on python-dev
in response to the original checkin.
Move the validation from the original loop into a switch statement,
and adjust a platform check in the tests.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_signal.py
python/branches/release27-maint/Modules/signalmodule.c
Modified: python/branches/release27-maint/Lib/test/test_signal.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_signal.py (original)
+++ python/branches/release27-maint/Lib/test/test_signal.py Mon Sep 6 18:17:50 2010
@@ -9,9 +9,8 @@
import traceback
import sys, os, time, errno
-if sys.platform == 'os2' or sys.platform == 'riscos':
- raise unittest.SkipTest("Can't test signal on %s" % \
- sys.platform)
+if sys.platform in ('os2', 'riscos'):
+ raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
class HandlerBCalled(Exception):
Modified: python/branches/release27-maint/Modules/signalmodule.c
==============================================================================
--- python/branches/release27-maint/Modules/signalmodule.c (original)
+++ python/branches/release27-maint/Modules/signalmodule.c Mon Sep 6 18:17:50 2010
@@ -255,21 +255,20 @@
int sig_num;
PyObject *old_handler;
void (*func)(int);
-#ifdef MS_WINDOWS
- int cur_sig, num_valid_sigs = 6;
- static int valid_sigs[] = {SIGABRT, SIGFPE, SIGILL, SIGINT,
- SIGSEGV, SIGTERM};
- BOOL valid_sig = FALSE;
-#endif
if (!PyArg_ParseTuple(args, "iO:signal", &sig_num, &obj))
return NULL;
#ifdef MS_WINDOWS
/* Validate that sig_num is one of the allowable signals */
- for (cur_sig = 0; cur_sig < num_valid_sigs; cur_sig++)
- valid_sig |= (sig_num == valid_sigs[cur_sig]);
- if (!valid_sig) {
- PyErr_SetString(PyExc_ValueError, "signal number out of range");
- return NULL;
+ switch (sig_num) {
+ case SIGABRT: break;
+ case SIGFPE: break;
+ case SIGILL: break;
+ case SIGINT: break;
+ case SIGSEGV: break;
+ case SIGTERM: break;
+ default:
+ PyErr_SetString(PyExc_ValueError, "invalid signal value");
+ return NULL;
}
#endif
#ifdef WITH_THREAD
From python-checkins at python.org Mon Sep 6 18:29:29 2010
From: python-checkins at python.org (brian.curtin)
Date: Mon, 6 Sep 2010 18:29:29 +0200 (CEST)
Subject: [Python-checkins] r84559 - python/branches/py3k/Lib/subprocess.py
Message-ID: <20100906162929.8439CEE9C7@mail.python.org>
Author: brian.curtin
Date: Mon Sep 6 18:29:29 2010
New Revision: 84559
Log:
Fix #8956. ValueError message was only mentioning one signal.
Rather than list out the three signals (or more over time), the message was
made less specific but still descriptive.
Modified:
python/branches/py3k/Lib/subprocess.py
Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py (original)
+++ python/branches/py3k/Lib/subprocess.py Mon Sep 6 18:29:29 2010
@@ -983,7 +983,7 @@
elif sig == signal.CTRL_BREAK_EVENT:
os.kill(self.pid, signal.CTRL_BREAK_EVENT)
else:
- raise ValueError("Only SIGTERM is supported on Windows")
+ raise ValueError("Unsupported signal")
def terminate(self):
"""Terminates the process
From python-checkins at python.org Mon Sep 6 18:31:27 2010
From: python-checkins at python.org (brian.curtin)
Date: Mon, 6 Sep 2010 18:31:27 +0200 (CEST)
Subject: [Python-checkins] r84560 - in python/branches/release27-maint:
Lib/subprocess.py
Message-ID: <20100906163127.A36DDEE9D9@mail.python.org>
Author: brian.curtin
Date: Mon Sep 6 18:31:27 2010
New Revision: 84560
Log:
Merged revisions 84559 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84559 | brian.curtin | 2010-09-06 11:29:29 -0500 (Mon, 06 Sep 2010) | 6 lines
Fix #8956. ValueError message was only mentioning one signal.
Rather than list out the three signals (or more over time), the message was
made less specific but still descriptive.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/subprocess.py
Modified: python/branches/release27-maint/Lib/subprocess.py
==============================================================================
--- python/branches/release27-maint/Lib/subprocess.py (original)
+++ python/branches/release27-maint/Lib/subprocess.py Mon Sep 6 18:31:27 2010
@@ -993,7 +993,7 @@
elif sig == signal.CTRL_BREAK_EVENT:
os.kill(self.pid, signal.CTRL_BREAK_EVENT)
else:
- raise ValueError("Only SIGTERM is supported on Windows")
+ raise ValueError("Unsupported signal")
def terminate(self):
"""Terminates the process
From python-checkins at python.org Mon Sep 6 19:07:31 2010
From: python-checkins at python.org (brian.curtin)
Date: Mon, 6 Sep 2010 19:07:31 +0200 (CEST)
Subject: [Python-checkins] r84561 - in python/branches/py3k:
Doc/library/os.path.rst Lib/ntpath.py Lib/test/test_ntpath.py
Misc/NEWS Modules/posixmodule.c
Message-ID: <20100906170731.1D7C3EE987@mail.python.org>
Author: brian.curtin
Date: Mon Sep 6 19:07:27 2010
New Revision: 84561
Log:
Implement #7566 - os.path.sameopenfile for Windows.
This uses the GetFileInformationByHandle function to return a tuple of values
to identify a file, then ntpath.sameopenfile compares file tuples, which
is exposed as os.path.sameopenfile.
Modified:
python/branches/py3k/Doc/library/os.path.rst
python/branches/py3k/Lib/ntpath.py
python/branches/py3k/Lib/test/test_ntpath.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/posixmodule.c
Modified: python/branches/py3k/Doc/library/os.path.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.path.rst (original)
+++ python/branches/py3k/Doc/library/os.path.rst Mon Sep 6 19:07:27 2010
@@ -251,7 +251,9 @@
Return ``True`` if the file descriptors *fp1* and *fp2* refer to the same file.
- Availability: Unix.
+ Availability: Unix, Windows.
+
+ .. versionchanged:: 3.2 Added Windows support.
.. function:: samestat(stat1, stat2)
Modified: python/branches/py3k/Lib/ntpath.py
==============================================================================
--- python/branches/py3k/Lib/ntpath.py (original)
+++ python/branches/py3k/Lib/ntpath.py Mon Sep 6 19:07:27 2010
@@ -10,6 +10,7 @@
import stat
import genericpath
from genericpath import *
+from nt import _getfileinformation
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -17,7 +18,7 @@
"ismount", "expanduser","expandvars","normpath","abspath",
"splitunc","curdir","pardir","sep","pathsep","defpath","altsep",
"extsep","devnull","realpath","supports_unicode_filenames","relpath",
- "samefile",]
+ "samefile", "sameopenfile",]
# strings representing various path-related bits and pieces
# These are primarily for export; internally, they are hardcoded.
@@ -652,3 +653,7 @@
# Also, on other operating systems, fake this method with a
# Windows-XP approximation.
return abspath(f1) == abspath(f2)
+
+def sameopenfile(f1, f2):
+ """Test whether two file objects reference the same file"""
+ return _getfileinformation(f1) == _getfileinformation(f2)
Modified: python/branches/py3k/Lib/test/test_ntpath.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ntpath.py (original)
+++ python/branches/py3k/Lib/test/test_ntpath.py Mon Sep 6 19:07:27 2010
@@ -2,6 +2,7 @@
import os
from test.support import TestFailed
from test import support, test_genericpath
+from tempfile import TemporaryFile
import unittest
@@ -237,6 +238,18 @@
tester('ntpath.relpath("/a", "/a")', '.')
tester('ntpath.relpath("/a/b", "/a/b")', '.')
+ def test_sameopenfile(self):
+ with TemporaryFile() as tf1, TemporaryFile() as tf2:
+ # Make sure the same file is really the same
+ self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno()))
+ # Make sure different files are really different
+ self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
+ # Make sure invalid values don't cause issues
+ with self.assertRaises(ValueError):
+ # Invalid file descriptors shouldn't display assert
+ # dialogs (#4804)
+ ntpath.sameopenfile(-1, -1)
+
class NtCommonTest(test_genericpath.CommonTest):
pathmodule = ntpath
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 6 19:07:27 2010
@@ -13,6 +13,8 @@
Library
-------
+- Issue #7566: Implement os.path.sameopenfile for Windows.
+
- Issue #9293: I/O streams now raise ``io.UnsupportedOperation`` when an
unsupported operation is attempted (for example, writing to a file open
only for reading).
Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Mon Sep 6 19:07:27 2010
@@ -2758,6 +2758,33 @@
return result;
} /* end of posix__getfinalpathname */
+
+static PyObject *
+posix__getfileinformation(PyObject *self, PyObject *args)
+{
+ HANDLE hFile;
+ BY_HANDLE_FILE_INFORMATION info;
+ int fd;
+
+ if (!PyArg_ParseTuple(args, "i:_getfileinformation", &fd))
+ return NULL;
+
+ if (!_PyVerify_fd(fd)) {
+ PyErr_SetString(PyExc_ValueError, "received invalid file descriptor");
+ return NULL;
+ }
+
+ hFile = (HANDLE)_get_osfhandle(fd);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return win32_error("_getfileinformation", NULL);
+
+ if (!GetFileInformationByHandle(hFile, &info))
+ return win32_error("_getfileinformation", NULL);
+
+ return Py_BuildValue("iii", info.dwVolumeSerialNumber,
+ info.nFileIndexHigh,
+ info.nFileIndexLow);
+}
#endif /* MS_WINDOWS */
PyDoc_STRVAR(posix_mkdir__doc__,
@@ -7908,6 +7935,7 @@
#ifdef MS_WINDOWS
{"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
{"_getfinalpathname", posix__getfinalpathname, METH_VARARGS, NULL},
+ {"_getfileinformation", posix__getfileinformation, METH_VARARGS, NULL},
#endif
#ifdef HAVE_GETLOADAVG
{"getloadavg", posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
From python-checkins at python.org Mon Sep 6 20:48:22 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Mon, 6 Sep 2010 20:48:22 +0200 (CEST)
Subject: [Python-checkins] r84562 - in python/branches/py3k:
Doc/library/io.rst Lib/_pyio.py Lib/test/test_memoryio.py
Misc/NEWS Modules/_io/_iomodule.c Modules/_io/_iomodule.h
Modules/_io/bytesio.c
Message-ID: <20100906184822.26A92FA6F@mail.python.org>
Author: antoine.pitrou
Date: Mon Sep 6 20:48:21 2010
New Revision: 84562
Log:
Issue #5506: BytesIO objects now have a getbuffer() method exporting a
view of their contents without duplicating them. The view is both readable
and writable.
Modified:
python/branches/py3k/Doc/library/io.rst
python/branches/py3k/Lib/_pyio.py
python/branches/py3k/Lib/test/test_memoryio.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/_io/_iomodule.c
python/branches/py3k/Modules/_io/_iomodule.h
python/branches/py3k/Modules/_io/bytesio.c
Modified: python/branches/py3k/Doc/library/io.rst
==============================================================================
--- python/branches/py3k/Doc/library/io.rst (original)
+++ python/branches/py3k/Doc/library/io.rst Mon Sep 6 20:48:21 2010
@@ -518,6 +518,24 @@
:class:`BytesIO` provides or overrides these methods in addition to those
from :class:`BufferedIOBase` and :class:`IOBase`:
+ .. method:: getbuffer()
+
+ Return a readable and writable view over the contents of the buffer
+ without copying them. Also, mutating the view will transparently
+ update the contents of the buffer::
+
+ >>> b = io.BytesIO(b"abcdef")
+ >>> view = b.getbuffer()
+ >>> view[2:4] = b"56"
+ >>> b.getvalue()
+ b'ab56ef'
+
+ .. note::
+ As long as the view exists, the :class:`BytesIO` object cannot be
+ resized.
+
+ .. versionadded:: 3.2
+
.. method:: getvalue()
Return ``bytes`` containing the entire contents of the buffer.
Modified: python/branches/py3k/Lib/_pyio.py
==============================================================================
--- python/branches/py3k/Lib/_pyio.py (original)
+++ python/branches/py3k/Lib/_pyio.py Mon Sep 6 20:48:21 2010
@@ -785,6 +785,11 @@
raise ValueError("getvalue on closed file")
return bytes(self._buffer)
+ def getbuffer(self):
+ """Return a readable and writable view of the buffer.
+ """
+ return memoryview(self._buffer)
+
def read(self, n=None):
if self.closed:
raise ValueError("read from closed file")
Modified: python/branches/py3k/Lib/test/test_memoryio.py
==============================================================================
--- python/branches/py3k/Lib/test/test_memoryio.py (original)
+++ python/branches/py3k/Lib/test/test_memoryio.py Mon Sep 6 20:48:21 2010
@@ -384,7 +384,31 @@
del __main__.PickleTestMemIO
-class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
+class BytesIOMixin:
+
+ def test_getbuffer(self):
+ memio = self.ioclass(b"1234567890")
+ buf = memio.getbuffer()
+ self.assertEqual(bytes(buf), b"1234567890")
+ memio.seek(5)
+ buf = memio.getbuffer()
+ self.assertEqual(bytes(buf), b"1234567890")
+ # Trying to change the size of the BytesIO while a buffer is exported
+ # raises a BufferError.
+ self.assertRaises(BufferError, memio.write, b'x' * 100)
+ self.assertRaises(BufferError, memio.truncate)
+ # Mutating the buffer updates the BytesIO
+ buf[3:6] = b"abc"
+ self.assertEqual(bytes(buf), b"123abc7890")
+ self.assertEqual(memio.getvalue(), b"123abc7890")
+ # After the buffer gets released, we can resize the BytesIO again
+ del buf
+ support.gc_collect()
+ memio.truncate()
+
+
+class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,
+ BytesIOMixin, unittest.TestCase):
UnsupportedOperation = pyio.UnsupportedOperation
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 6 20:48:21 2010
@@ -13,6 +13,10 @@
Library
-------
+- Issue #5506: BytesIO objects now have a getbuffer() method exporting a
+ view of their contents without duplicating them. The view is both readable
+ and writable.
+
- Issue #7566: Implement os.path.sameopenfile for Windows.
- Issue #9293: I/O streams now raise ``io.UnsupportedOperation`` when an
Modified: python/branches/py3k/Modules/_io/_iomodule.c
==============================================================================
--- python/branches/py3k/Modules/_io/_iomodule.c (original)
+++ python/branches/py3k/Modules/_io/_iomodule.c Mon Sep 6 20:48:21 2010
@@ -710,6 +710,8 @@
/* BytesIO */
PyBytesIO_Type.tp_base = &PyBufferedIOBase_Type;
ADD_TYPE(&PyBytesIO_Type, "BytesIO");
+ if (PyType_Ready(&_PyBytesIOBuffer_Type) < 0)
+ goto fail;
/* StringIO */
PyStringIO_Type.tp_base = &PyTextIOBase_Type;
Modified: python/branches/py3k/Modules/_io/_iomodule.h
==============================================================================
--- python/branches/py3k/Modules/_io/_iomodule.h (original)
+++ python/branches/py3k/Modules/_io/_iomodule.h Mon Sep 6 20:48:21 2010
@@ -169,3 +169,5 @@
extern PyObject *_PyIO_empty_str;
extern PyObject *_PyIO_empty_bytes;
extern PyObject *_PyIO_zero;
+
+extern PyTypeObject _PyBytesIOBuffer_Type;
Modified: python/branches/py3k/Modules/_io/bytesio.c
==============================================================================
--- python/branches/py3k/Modules/_io/bytesio.c (original)
+++ python/branches/py3k/Modules/_io/bytesio.c Mon Sep 6 20:48:21 2010
@@ -10,8 +10,15 @@
size_t buf_size;
PyObject *dict;
PyObject *weakreflist;
+ Py_ssize_t exports;
} bytesio;
+typedef struct {
+ PyObject_HEAD
+ bytesio *source;
+} bytesiobuf;
+
+
#define CHECK_CLOSED(self) \
if ((self)->buf == NULL) { \
PyErr_SetString(PyExc_ValueError, \
@@ -19,6 +26,14 @@
return NULL; \
}
+#define CHECK_EXPORTS(self) \
+ if ((self)->exports > 0) { \
+ PyErr_SetString(PyExc_BufferError, \
+ "Existing exports of data: object cannot be re-sized"); \
+ return NULL; \
+ }
+
+
/* Internal routine to get a line from the buffer of a BytesIO
object. Returns the length between the current position to the
next newline character. */
@@ -173,6 +188,30 @@
Py_RETURN_NONE;
}
+PyDoc_STRVAR(getbuffer_doc,
+"getbuffer() -> bytes.\n"
+"\n"
+"Get a read-write view over the contents of the BytesIO object.");
+
+static PyObject *
+bytesio_getbuffer(bytesio *self)
+{
+ PyTypeObject *type = &_PyBytesIOBuffer_Type;
+ bytesiobuf *buf;
+ PyObject *view;
+
+ CHECK_CLOSED(self);
+
+ buf = (bytesiobuf *) type->tp_alloc(type, 0);
+ if (buf == NULL)
+ return NULL;
+ Py_INCREF(self);
+ buf->source = self;
+ view = PyMemoryView_FromObject((PyObject *) buf);
+ Py_DECREF(buf);
+ return view;
+}
+
PyDoc_STRVAR(getval_doc,
"getvalue() -> bytes.\n"
"\n"
@@ -422,6 +461,7 @@
PyObject *arg = Py_None;
CHECK_CLOSED(self);
+ CHECK_EXPORTS(self);
if (!PyArg_ParseTuple(args, "|O:truncate", &arg))
return NULL;
@@ -543,6 +583,7 @@
PyObject *result = NULL;
CHECK_CLOSED(self);
+ CHECK_EXPORTS(self);
if (PyObject_GetBuffer(obj, &buf, PyBUF_CONTIG_RO) < 0)
return NULL;
@@ -664,6 +705,7 @@
Py_TYPE(self)->tp_name, Py_TYPE(state)->tp_name);
return NULL;
}
+ CHECK_EXPORTS(self);
/* Reset the object to its default state. This is only needed to handle
the case of repeated calls to __setstate__. */
self->string_size = 0;
@@ -724,6 +766,11 @@
bytesio_dealloc(bytesio *self)
{
_PyObject_GC_UNTRACK(self);
+ if (self->exports > 0) {
+ PyErr_SetString(PyExc_SystemError,
+ "deallocated BytesIO object has exported buffers");
+ PyErr_Print();
+ }
if (self->buf != NULL) {
PyMem_Free(self->buf);
self->buf = NULL;
@@ -818,6 +865,7 @@
{"readline", (PyCFunction)bytesio_readline, METH_VARARGS, readline_doc},
{"readlines", (PyCFunction)bytesio_readlines, METH_VARARGS, readlines_doc},
{"read", (PyCFunction)bytesio_read, METH_VARARGS, read_doc},
+ {"getbuffer", (PyCFunction)bytesio_getbuffer, METH_NOARGS, getbuffer_doc},
{"getvalue", (PyCFunction)bytesio_getvalue, METH_NOARGS, getval_doc},
{"seek", (PyCFunction)bytesio_seek, METH_VARARGS, seek_doc},
{"truncate", (PyCFunction)bytesio_truncate, METH_VARARGS, truncate_doc},
@@ -873,3 +921,96 @@
0, /*tp_alloc*/
bytesio_new, /*tp_new*/
};
+
+
+/*
+ * Implementation of the small intermediate object used by getbuffer().
+ * getbuffer() returns a memoryview over this object, which should make it
+ * invisible from Python code.
+ */
+
+static int
+bytesiobuf_getbuffer(bytesiobuf *obj, Py_buffer *view, int flags)
+{
+ int ret;
+ void *ptr;
+ bytesio *b = (bytesio *) obj->source;
+ if (view == NULL) {
+ b->exports++;
+ return 0;
+ }
+ ptr = (void *) obj;
+ ret = PyBuffer_FillInfo(view, (PyObject*)obj, b->buf, b->string_size,
+ 0, flags);
+ if (ret >= 0) {
+ b->exports++;
+ }
+ return ret;
+}
+
+static void
+bytesiobuf_releasebuffer(bytesiobuf *obj, Py_buffer *view)
+{
+ bytesio *b = (bytesio *) obj->source;
+ b->exports--;
+}
+
+static int
+bytesiobuf_traverse(bytesiobuf *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->source);
+ return 0;
+}
+
+static void
+bytesiobuf_dealloc(bytesiobuf *self)
+{
+ Py_CLEAR(self->source);
+ Py_TYPE(self)->tp_free(self);
+}
+
+static PyBufferProcs bytesiobuf_as_buffer = {
+ (getbufferproc) bytesiobuf_getbuffer,
+ (releasebufferproc) bytesiobuf_releasebuffer,
+};
+
+PyTypeObject _PyBytesIOBuffer_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_io._BytesIOBuffer", /*tp_name*/
+ sizeof(bytesiobuf), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)bytesiobuf_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_reserved*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call*/
+ 0, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ &bytesiobuf_as_buffer, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
+ 0, /*tp_doc*/
+ (traverseproc)bytesiobuf_traverse, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*tp_getset*/
+ 0, /*tp_base*/
+ 0, /*tp_dict*/
+ 0, /*tp_descr_get*/
+ 0, /*tp_descr_set*/
+ 0, /*tp_dictoffset*/
+ 0, /*tp_init*/
+ 0, /*tp_alloc*/
+ 0, /*tp_new*/
+};
From python-checkins at python.org Mon Sep 6 21:25:46 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Mon, 6 Sep 2010 21:25:46 +0200 (CEST)
Subject: [Python-checkins] r84563 - in python/branches/py3k:
Doc/library/unittest.rst Lib/unittest/case.py
Lib/unittest/test/test_case.py Misc/NEWS
Message-ID: <20100906192546.5E27BEE98E@mail.python.org>
Author: antoine.pitrou
Date: Mon Sep 6 21:25:46 2010
New Revision: 84563
Log:
Issue #9754: Similarly to assertRaises and assertRaisesRegexp, unittest
test cases now also have assertWarns and assertWarnsRegexp methods to
check that a given warning type was triggered by the code under test.
Modified:
python/branches/py3k/Doc/library/unittest.rst
python/branches/py3k/Lib/unittest/case.py
python/branches/py3k/Lib/unittest/test/test_case.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/unittest.rst
==============================================================================
--- python/branches/py3k/Doc/library/unittest.rst (original)
+++ python/branches/py3k/Doc/library/unittest.rst Mon Sep 6 21:25:46 2010
@@ -1083,6 +1083,59 @@
.. versionadded:: 3.1
+ .. method:: assertWarns(warning, callable, *args, **kwds)
+ assertWarns(warning)
+
+ Test that a warning is triggered when *callable* is called with any
+ positional or keyword arguments that are also passed to
+ :meth:`assertWarns`. The test passes if *warning* is triggered and
+ fails if it isn't. Also, any unexpected exception is an error.
+ To catch any of a group of warnings, a tuple containing the warning
+ classes may be passed as *warnings*.
+
+ If only the *warning* argument is given, returns a context manager so
+ that the code under test can be written inline rather than as a function::
+
+ with self.assertWarns(SomeWarning):
+ do_something()
+
+ The context manager will store the caught warning object in its
+ :attr:`warning` attribute, and the source line which triggered the
+ warnings in the :attr:`filename` and :attr:`lineno` attributes.
+ This can be useful if the intention is to perform additional checks
+ on the exception raised::
+
+ with self.assertWarns(SomeWarning) as cm:
+ do_something()
+
+ self.assertIn('myfile.py', cm.filename)
+ self.assertEqual(320, cm.lineno)
+
+ This method works regardless of the warning filters in place when it
+ is called.
+
+ .. versionadded:: 3.2
+
+
+ .. method:: assertWarnsRegexp(warning, regexp[, callable, ...])
+
+ Like :meth:`assertWarns` but also tests that *regexp* matches on the
+ message of the triggered warning. *regexp* may be a regular expression
+ object or a string containing a regular expression suitable for use
+ by :func:`re.search`. Example::
+
+ self.assertWarnsRegexp(DeprecationWarning,
+ r'legacy_function\(\) is deprecated',
+ legacy_function, 'XYZ')
+
+ or::
+
+ with self.assertWarnsRegexp(RuntimeWarning, 'unsafe frobnicating'):
+ frobnicate('/etc/passwd')
+
+ .. versionadded:: 3.2
+
+
.. method:: assertIsNone(expr, msg=None)
This signals a test failure if *expr* is not None.
Modified: python/branches/py3k/Lib/unittest/case.py
==============================================================================
--- python/branches/py3k/Lib/unittest/case.py (original)
+++ python/branches/py3k/Lib/unittest/case.py Mon Sep 6 21:25:46 2010
@@ -90,8 +90,7 @@
return wrapper
-class _AssertRaisesContext(object):
- """A context manager used to implement TestCase.assertRaises* methods."""
+class _AssertRaisesBaseContext(object):
def __init__(self, expected, test_case, callable_obj=None,
expected_regexp=None):
@@ -104,8 +103,14 @@
self.obj_name = str(callable_obj)
else:
self.obj_name = None
+ if isinstance(expected_regexp, (bytes, str)):
+ expected_regexp = re.compile(expected_regexp)
self.expected_regexp = expected_regexp
+
+class _AssertRaisesContext(_AssertRaisesBaseContext):
+ """A context manager used to implement TestCase.assertRaises* methods."""
+
def __enter__(self):
return self
@@ -130,14 +135,62 @@
return True
expected_regexp = self.expected_regexp
- if isinstance(expected_regexp, (bytes, str)):
- expected_regexp = re.compile(expected_regexp)
if not expected_regexp.search(str(exc_value)):
raise self.failureException('"%s" does not match "%s"' %
(expected_regexp.pattern, str(exc_value)))
return True
+class _AssertWarnsContext(_AssertRaisesBaseContext):
+ """A context manager used to implement TestCase.assertWarns* methods."""
+
+ def __enter__(self):
+ # The __warningregistry__'s need to be in a pristine state for tests
+ # to work properly.
+ for v in sys.modules.values():
+ if getattr(v, '__warningregistry__', None):
+ v.__warningregistry__ = {}
+ self.warnings_manager = warnings.catch_warnings(record=True)
+ self.warnings = self.warnings_manager.__enter__()
+ warnings.simplefilter("always", self.expected)
+ return self
+
+ def __exit__(self, exc_type, exc_value, tb):
+ self.warnings_manager.__exit__(exc_type, exc_value, tb)
+ if exc_type is not None:
+ # let unexpected exceptions pass through
+ return
+ try:
+ exc_name = self.expected.__name__
+ except AttributeError:
+ exc_name = str(self.expected)
+ first_matching = None
+ for m in self.warnings:
+ w = m.message
+ if not isinstance(w, self.expected):
+ continue
+ if first_matching is None:
+ first_matching = w
+ if (self.expected_regexp is not None and
+ not self.expected_regexp.search(str(w))):
+ continue
+ # store warning for later retrieval
+ self.warning = w
+ self.filename = m.filename
+ self.lineno = m.lineno
+ return
+ # Now we simply try to choose a helpful failure message
+ if first_matching is not None:
+ raise self.failureException('"%s" does not match "%s"' %
+ (self.expected_regexp.pattern, str(first_matching)))
+ if self.obj_name:
+ raise self.failureException("{0} not triggered by {1}"
+ .format(exc_name, self.obj_name))
+ else:
+ raise self.failureException("{0} not triggered"
+ .format(exc_name))
+
+
class TestCase(object):
"""A class whose instances are single test cases.
@@ -464,6 +517,37 @@
with context:
callableObj(*args, **kwargs)
+ def assertWarns(self, expected_warning, callable_obj=None, *args, **kwargs):
+ """Fail unless a warning of class warnClass is triggered
+ by callableObj when invoked with arguments args and keyword
+ arguments kwargs. If a different type of warning is
+ triggered, it will not be handled: depending on the other
+ warning filtering rules in effect, it might be silenced, printed
+ out, or raised as an exception.
+
+ If called with callableObj omitted or None, will return a
+ context object used like this::
+
+ with self.assertWarns(SomeWarning):
+ do_something()
+
+ The context manager keeps a reference to the first matching
+ warning as the 'warning' attribute; similarly, the 'filename'
+ and 'lineno' attributes give you information about the line
+ of Python code from which the warning was triggered.
+ This allows you to inspect the warning after the assertion::
+
+ with self.assertWarns(SomeWarning) as cm:
+ do_something()
+ the_warning = cm.warning
+ self.assertEqual(the_warning.some_attribute, 147)
+ """
+ context = _AssertWarnsContext(expected_warning, self, callable_obj)
+ if callable_obj is None:
+ return context
+ with context:
+ callable_obj(*args, **kwargs)
+
def _getAssertEqualityFunc(self, first, second):
"""Get a detailed comparison function for the types of the two args.
@@ -1019,6 +1103,28 @@
with context:
callable_obj(*args, **kwargs)
+ def assertWarnsRegexp(self, expected_warning, expected_regexp,
+ callable_obj=None, *args, **kwargs):
+ """Asserts that the message in a triggered warning matches a regexp.
+ Basic functioning is similar to assertWarns() with the addition
+ that only warnings whose messages also match the regular expression
+ are considered successful matches.
+
+ Args:
+ expected_warning: Warning class expected to be triggered.
+ expected_regexp: Regexp (re pattern object or string) expected
+ to be found in error message.
+ callable_obj: Function to be called.
+ args: Extra args.
+ kwargs: Extra kwargs.
+ """
+ context = _AssertWarnsContext(expected_warning, self, callable_obj,
+ expected_regexp)
+ if callable_obj is None:
+ return context
+ with context:
+ callable_obj(*args, **kwargs)
+
def assertRegexpMatches(self, text, expected_regexp, msg=None):
"""Fail the test unless the text matches the regular expression."""
if isinstance(expected_regexp, (str, bytes)):
Modified: python/branches/py3k/Lib/unittest/test/test_case.py
==============================================================================
--- python/branches/py3k/Lib/unittest/test/test_case.py (original)
+++ python/branches/py3k/Lib/unittest/test/test_case.py Mon Sep 6 21:25:46 2010
@@ -2,6 +2,8 @@
import pprint
import re
import sys
+import warnings
+import inspect
from copy import deepcopy
from test import support
@@ -917,6 +919,138 @@
self.assertIsInstance(e, ExceptionMock)
self.assertEqual(e.args[0], v)
+ def testAssertWarnsCallable(self):
+ def _runtime_warn():
+ warnings.warn("foo", RuntimeWarning)
+ # Success when the right warning is triggered, even several times
+ self.assertWarns(RuntimeWarning, _runtime_warn)
+ self.assertWarns(RuntimeWarning, _runtime_warn)
+ # A tuple of warning classes is accepted
+ self.assertWarns((DeprecationWarning, RuntimeWarning), _runtime_warn)
+ # *args and **kwargs also work
+ self.assertWarns(RuntimeWarning,
+ warnings.warn, "foo", category=RuntimeWarning)
+ # Failure when no warning is triggered
+ with self.assertRaises(self.failureException):
+ self.assertWarns(RuntimeWarning, lambda: 0)
+ # Failure when another warning is triggered
+ with warnings.catch_warnings():
+ # Force default filter (in case tests are run with -We)
+ warnings.simplefilter("default", RuntimeWarning)
+ with self.assertRaises(self.failureException):
+ self.assertWarns(DeprecationWarning, _runtime_warn)
+ # Filters for other warnings are not modified
+ with warnings.catch_warnings():
+ warnings.simplefilter("error", RuntimeWarning)
+ with self.assertRaises(RuntimeWarning):
+ self.assertWarns(DeprecationWarning, _runtime_warn)
+
+ def testAssertWarnsContext(self):
+ # Believe it or not, it is preferrable to duplicate all tests above,
+ # to make sure the __warningregistry__ $@ is circumvented correctly.
+ def _runtime_warn():
+ warnings.warn("foo", RuntimeWarning)
+ _runtime_warn_lineno = inspect.getsourcelines(_runtime_warn)[1]
+ with self.assertWarns(RuntimeWarning) as cm:
+ _runtime_warn()
+ # A tuple of warning classes is accepted
+ with self.assertWarns((DeprecationWarning, RuntimeWarning)) as cm:
+ _runtime_warn()
+ # The context manager exposes various useful attributes
+ self.assertIsInstance(cm.warning, RuntimeWarning)
+ self.assertEqual(cm.warning.args[0], "foo")
+ self.assertIn("test_case.py", cm.filename)
+ self.assertEqual(cm.lineno, _runtime_warn_lineno + 1)
+ # Same with several warnings
+ with self.assertWarns(RuntimeWarning):
+ _runtime_warn()
+ _runtime_warn()
+ with self.assertWarns(RuntimeWarning):
+ warnings.warn("foo", category=RuntimeWarning)
+ # Failure when no warning is triggered
+ with self.assertRaises(self.failureException):
+ with self.assertWarns(RuntimeWarning):
+ pass
+ # Failure when another warning is triggered
+ with warnings.catch_warnings():
+ # Force default filter (in case tests are run with -We)
+ warnings.simplefilter("default", RuntimeWarning)
+ with self.assertRaises(self.failureException):
+ with self.assertWarns(DeprecationWarning):
+ _runtime_warn()
+ # Filters for other warnings are not modified
+ with warnings.catch_warnings():
+ warnings.simplefilter("error", RuntimeWarning)
+ with self.assertRaises(RuntimeWarning):
+ with self.assertWarns(DeprecationWarning):
+ _runtime_warn()
+
+ def testAssertWarnsRegexpCallable(self):
+ def _runtime_warn(msg):
+ warnings.warn(msg, RuntimeWarning)
+ self.assertWarnsRegexp(RuntimeWarning, "o+",
+ _runtime_warn, "foox")
+ # Failure when no warning is triggered
+ with self.assertRaises(self.failureException):
+ self.assertWarnsRegexp(RuntimeWarning, "o+",
+ lambda: 0)
+ # Failure when another warning is triggered
+ with warnings.catch_warnings():
+ # Force default filter (in case tests are run with -We)
+ warnings.simplefilter("default", RuntimeWarning)
+ with self.assertRaises(self.failureException):
+ self.assertWarnsRegexp(DeprecationWarning, "o+",
+ _runtime_warn, "foox")
+ # Failure when message doesn't match
+ with self.assertRaises(self.failureException):
+ self.assertWarnsRegexp(RuntimeWarning, "o+",
+ _runtime_warn, "barz")
+ # A little trickier: we ask RuntimeWarnings to be raised, and then
+ # check for some of them. It is implementation-defined whether
+ # non-matching RuntimeWarnings are simply re-raised, or produce a
+ # failureException.
+ with warnings.catch_warnings():
+ warnings.simplefilter("error", RuntimeWarning)
+ with self.assertRaises((RuntimeWarning, self.failureException)):
+ self.assertWarnsRegexp(RuntimeWarning, "o+",
+ _runtime_warn, "barz")
+
+ def testAssertWarnsRegexpContext(self):
+ # Same as above, but with assertWarnsRegexp as a context manager
+ def _runtime_warn(msg):
+ warnings.warn(msg, RuntimeWarning)
+ _runtime_warn_lineno = inspect.getsourcelines(_runtime_warn)[1]
+ with self.assertWarnsRegexp(RuntimeWarning, "o+") as cm:
+ _runtime_warn("foox")
+ self.assertIsInstance(cm.warning, RuntimeWarning)
+ self.assertEqual(cm.warning.args[0], "foox")
+ self.assertIn("test_case.py", cm.filename)
+ self.assertEqual(cm.lineno, _runtime_warn_lineno + 1)
+ # Failure when no warning is triggered
+ with self.assertRaises(self.failureException):
+ with self.assertWarnsRegexp(RuntimeWarning, "o+"):
+ pass
+ # Failure when another warning is triggered
+ with warnings.catch_warnings():
+ # Force default filter (in case tests are run with -We)
+ warnings.simplefilter("default", RuntimeWarning)
+ with self.assertRaises(self.failureException):
+ with self.assertWarnsRegexp(DeprecationWarning, "o+"):
+ _runtime_warn("foox")
+ # Failure when message doesn't match
+ with self.assertRaises(self.failureException):
+ with self.assertWarnsRegexp(RuntimeWarning, "o+"):
+ _runtime_warn("barz")
+ # A little trickier: we ask RuntimeWarnings to be raised, and then
+ # check for some of them. It is implementation-defined whether
+ # non-matching RuntimeWarnings are simply re-raised, or produce a
+ # failureException.
+ with warnings.catch_warnings():
+ warnings.simplefilter("error", RuntimeWarning)
+ with self.assertRaises((RuntimeWarning, self.failureException)):
+ with self.assertWarnsRegexp(RuntimeWarning, "o+"):
+ _runtime_warn("barz")
+
def testSynonymAssertMethodNames(self):
"""Test undocumented method name synonyms.
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 6 21:25:46 2010
@@ -13,6 +13,10 @@
Library
-------
+- Issue #9754: Similarly to assertRaises and assertRaisesRegexp, unittest
+ test cases now also have assertWarns and assertWarnsRegexp methods to
+ check that a given warning type was triggered by the code under test.
+
- Issue #5506: BytesIO objects now have a getbuffer() method exporting a
view of their contents without duplicating them. The view is both readable
and writable.
From python-checkins at python.org Mon Sep 6 21:46:17 2010
From: python-checkins at python.org (brian.curtin)
Date: Mon, 6 Sep 2010 21:46:17 +0200 (CEST)
Subject: [Python-checkins] r84564 - in python/branches/py3k/Lib: ntpath.py
test/test_ntpath.py
Message-ID: <20100906194617.4ECACEE9B1@mail.python.org>
Author: brian.curtin
Date: Mon Sep 6 21:46:17 2010
New Revision: 84564
Log:
Fix some errors that #7566 introduced on non-Windows platforms due to
an ImportError. Rearranged the import, faked out the implementation when
the import fails, and reorganized a test that depends on Win32 behavior.
Modified:
python/branches/py3k/Lib/ntpath.py
python/branches/py3k/Lib/test/test_ntpath.py
Modified: python/branches/py3k/Lib/ntpath.py
==============================================================================
--- python/branches/py3k/Lib/ntpath.py (original)
+++ python/branches/py3k/Lib/ntpath.py Mon Sep 6 21:46:17 2010
@@ -10,7 +10,6 @@
import stat
import genericpath
from genericpath import *
-from nt import _getfileinformation
__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
@@ -656,4 +655,10 @@
def sameopenfile(f1, f2):
"""Test whether two file objects reference the same file"""
- return _getfileinformation(f1) == _getfileinformation(f2)
+ try:
+ from nt import _getfileinformation
+ return _getfileinformation(f1) == _getfileinformation(f2)
+ except ImportError:
+ # On other operating systems, return True if the file descriptors
+ # are the same.
+ return f1 == f2
Modified: python/branches/py3k/Lib/test/test_ntpath.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ntpath.py (original)
+++ python/branches/py3k/Lib/test/test_ntpath.py Mon Sep 6 21:46:17 2010
@@ -1,5 +1,6 @@
import ntpath
import os
+import sys
from test.support import TestFailed
from test import support, test_genericpath
from tempfile import TemporaryFile
@@ -244,11 +245,12 @@
self.assertTrue(ntpath.sameopenfile(tf1.fileno(), tf1.fileno()))
# Make sure different files are really different
self.assertFalse(ntpath.sameopenfile(tf1.fileno(), tf2.fileno()))
- # Make sure invalid values don't cause issues
- with self.assertRaises(ValueError):
- # Invalid file descriptors shouldn't display assert
- # dialogs (#4804)
- ntpath.sameopenfile(-1, -1)
+ # Make sure invalid values don't cause issues on win32
+ if sys.platform == "win32":
+ with self.assertRaises(ValueError):
+ # Invalid file descriptors shouldn't display assert
+ # dialogs (#4804)
+ ntpath.sameopenfile(-1, -1)
class NtCommonTest(test_genericpath.CommonTest):
From python-checkins at python.org Mon Sep 6 21:55:51 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon, 6 Sep 2010 21:55:51 +0200 (CEST)
Subject: [Python-checkins] r84565 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100906195551.3F3F0F959@mail.python.org>
Author: raymond.hettinger
Date: Mon Sep 6 21:55:51 2010
New Revision: 84565
Log:
Fix markup nits
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Mon Sep 6 21:55:51 2010
@@ -220,8 +220,8 @@
(By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
:issue:`8814`.)
-* The :mod:`abc` module now supports :func:`abstractclassmethod` and
- :func:`abstractstaticmethod`.
+* The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
+ :func:`~abc.abstractstaticmethod`.
(Patch submitted by Daniel Urban; :issue:`5867`.)
@@ -410,7 +410,7 @@
(Contributed by Antoine Pitrou; :issue:`3001`.)
* Regular and recursive locks now accept an optional *timeout* argument to their
- ``acquire`` method. (Contributed by Antoine Pitrou; :issue:`7316`.)
+ :meth:`acquire` method. (Contributed by Antoine Pitrou; :issue:`7316`.)
Similarly, :meth:`threading.Semaphore.acquire` also gains a *timeout*
argument. (Contributed by Torsten Landschoff; :issue:`850728`.)
From python-checkins at python.org Mon Sep 6 22:27:15 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 6 Sep 2010 22:27:15 +0200 (CEST)
Subject: [Python-checkins] r84566 - python/branches/py3k/Misc/pymemcompat.h
Message-ID: <20100906202715.80F84EE9B7@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 6 22:27:15 2010
New Revision: 84566
Log:
typo
Modified:
python/branches/py3k/Misc/pymemcompat.h
Modified: python/branches/py3k/Misc/pymemcompat.h
==============================================================================
--- python/branches/py3k/Misc/pymemcompat.h (original)
+++ python/branches/py3k/Misc/pymemcompat.h Mon Sep 6 22:27:15 2010
@@ -72,7 +72,7 @@
It is possible to support both the 2.0 and 2.2 GC APIs, but it's
not pretty and this comment block is too narrow to contain a
- desciption of what's required... */
+ description of what's required... */
#if PY_VERSION_HEX < 0x020200B1
#define PyObject_GC_New PyObject_New
From python-checkins at python.org Mon Sep 6 22:27:55 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 6 Sep 2010 22:27:55 +0200 (CEST)
Subject: [Python-checkins] r84567 - python/branches/py3k/Lib/string.py
Message-ID: <20100906202755.E0D73EE98E@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 6 22:27:55 2010
New Revision: 84567
Log:
typo
Modified:
python/branches/py3k/Lib/string.py
Modified: python/branches/py3k/Lib/string.py
==============================================================================
--- python/branches/py3k/Lib/string.py (original)
+++ python/branches/py3k/Lib/string.py Mon Sep 6 22:27:55 2010
@@ -174,7 +174,7 @@
# see PEP 3101 for details and purpose of this class
# The hard parts are reused from the C implementation. They're exposed as "_"
-# prefixed methods of str and unicode.
+# prefixed methods of str.
# The overall parser is implemented in str._formatter_parser.
# The field name parser is implemented in str._formatter_field_name_split
@@ -246,7 +246,7 @@
return str(value)
elif conversion is None:
return value
- raise ValueError("Unknown converion specifier {0!s}".format(conversion))
+ raise ValueError("Unknown conversion specifier {0!s}".format(conversion))
# returns an iterable that contains tuples of the form:
From python-checkins at python.org Mon Sep 6 23:26:09 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon, 6 Sep 2010 23:26:09 +0200 (CEST)
Subject: [Python-checkins] r84568 - in python/branches/py3k:
Doc/library/collections.rst Lib/collections.py
Lib/functools.py Lib/test/test_collections.py Misc/NEWS
Message-ID: <20100906212609.B4701EE982@mail.python.org>
Author: raymond.hettinger
Date: Mon Sep 6 23:26:09 2010
New Revision: 84568
Log:
Add method to OrderedDict for repositioning keys to the ends.
Modified:
python/branches/py3k/Doc/library/collections.rst
python/branches/py3k/Lib/collections.py
python/branches/py3k/Lib/functools.py
python/branches/py3k/Lib/test/test_collections.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/collections.rst
==============================================================================
--- python/branches/py3k/Doc/library/collections.rst (original)
+++ python/branches/py3k/Doc/library/collections.rst Mon Sep 6 23:26:09 2010
@@ -793,6 +793,23 @@
(key, value) pair. The pairs are returned in LIFO order if *last* is true
or FIFO order if false.
+ .. method:: move_to_end(key, last=True)
+
+ Move an existing *key* to either end of an ordered dictionary. The item
+ is moved to the right end if *last* is true (the default) or to the
+ beginning if *last* is false. Raises :exc:`KeyError` if the *key* does
+ not exist::
+
+ >>> d = OrderedDict.fromkeys('abcde')
+ >>> d.move_to_end('b')
+ >>> ''.join(d.keys)
+ 'acdeb'
+ >>> d.move_to_end('b', 0)
+ >>> ''.join(d.keys)
+ 'bacde'
+
+ .. versionadded:: 3.2
+
In addition to the usual mapping methods, ordered dictionaries also support
reverse iteration using :func:`reversed`.
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Mon Sep 6 23:26:09 2010
@@ -173,18 +173,29 @@
def __del__(self):
self.clear() # eliminate cyclical references
- def _renew(self, key, PREV=0, NEXT=1):
- 'Fast version of self[key]=self.pop(key). Private method for internal use.'
+ def move_to_end(self, key, last=True, PREV=0, NEXT=1):
+ '''Move an existing element to the end (or beginning if last==False).
+
+ Raises KeyError if the element does not exist.
+ When last=True, acts like a fast version of self[key]=self.pop(key).
+
+ '''
link = self.__map[key]
link_prev = link[PREV]
link_next = link[NEXT]
link_prev[NEXT] = link_next
link_next[PREV] = link_prev
root = self.__root
- last = root[PREV]
- link[PREV] = last
- link[NEXT] = root
- last[NEXT] = root[PREV] = link
+ if last:
+ last = root[PREV]
+ link[PREV] = last
+ link[NEXT] = root
+ last[NEXT] = root[PREV] = link
+ else:
+ first = root[NEXT]
+ link[PREV] = root
+ link[NEXT] = first
+ root[NEXT] = first[PREV] = link
################################################################################
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Mon Sep 6 23:26:09 2010
@@ -127,7 +127,7 @@
len=len, KeyError=KeyError):
cache = OrderedDict() # ordered least recent to most recent
cache_popitem = cache.popitem
- cache_renew = cache._renew
+ cache_renew = cache.move_to_end
kwd_mark = object() # separate positional and keyword args
lock = Lock()
Modified: python/branches/py3k/Lib/test/test_collections.py
==============================================================================
--- python/branches/py3k/Lib/test/test_collections.py (original)
+++ python/branches/py3k/Lib/test/test_collections.py Mon Sep 6 23:26:09 2010
@@ -973,7 +973,19 @@
od['a'] = 1
self.assertEqual(list(od.items()), [('b', 2), ('a', 1)])
-
+ def test_move_to_end(self):
+ od = OrderedDict.fromkeys('abcde')
+ self.assertEqual(list(od), list('abcde'))
+ od.move_to_end('c')
+ self.assertEqual(list(od), list('abdec'))
+ od.move_to_end('c', 0)
+ self.assertEqual(list(od), list('cabde'))
+ od.move_to_end('c', 0)
+ self.assertEqual(list(od), list('cabde'))
+ od.move_to_end('e')
+ self.assertEqual(list(od), list('cabde'))
+ with self.assertRaises(KeyError):
+ od.move_to_end('x')
class GeneralMappingTests(mapping_tests.BasicTestMappingProtocol):
type2test = OrderedDict
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 6 23:26:09 2010
@@ -13,6 +13,9 @@
Library
-------
+- collections.OrderedDict now supports a new method for repositioning
+ keys to either end.
+
- Issue #9754: Similarly to assertRaises and assertRaisesRegexp, unittest
test cases now also have assertWarns and assertWarnsRegexp methods to
check that a given warning type was triggered by the code under test.
From python-checkins at python.org Tue Sep 7 00:18:20 2010
From: python-checkins at python.org (vinay.sajip)
Date: Tue, 7 Sep 2010 00:18:20 +0200 (CEST)
Subject: [Python-checkins] r84569 - in python/branches:
py3k/Doc/library/logging.rst release27-maint/Doc/library/logging.rst
release31-maint/Doc/library/logging.rst
Message-ID: <20100906221820.D7C1AF525@mail.python.org>
Author: vinay.sajip
Date: Tue Sep 7 00:18:20 2010
New Revision: 84569
Log:
Updated information on logging contextual information.
Modified:
python/branches/py3k/Doc/library/logging.rst
python/branches/release27-maint/Doc/library/logging.rst
python/branches/release31-maint/Doc/library/logging.rst
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Tue Sep 7 00:18:20 2010
@@ -1317,6 +1317,10 @@
be hard to manage if the number of :class:`Logger` instances becomes
effectively unbounded.
+
+Using LoggerAdapters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
An easy way in which you can pass contextual information to be output along
with logging event information is to use the :class:`LoggerAdapter` class.
This class is designed to look like a :class:`Logger`, so that you can call
@@ -1421,6 +1425,78 @@
2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters
+Using Filters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can also add contextual information to log output using a user-defined
+:class:`Filter`. ``Filter`` instances are allowed to modify the ``LogRecords``
+passed to them, including adding additional attributes which can then be output
+using a suitable format string, or if needed a custom :class:`Formatter`.
+
+For example in a web application, the request being processed (or at least,
+the interesting parts of it) can be stored in a threadlocal
+(:class:`threading.local`) variable, and then accessed from a ``Filter`` to
+add, say, information from the request - say, the remote IP address and remote
+user's username - to the ``LogRecord``, using the attribute names 'ip' and
+'user' as in the ``LoggerAdapter`` example above. In that case, the same format
+string can be used to get similar output to that shown above. Here's an example
+script::
+
+ import logging
+ from random import choice
+
+ class ContextFilter(logging.Filter):
+ """
+ This is a filter which injects contextual information into the log.
+
+ Rather than use actual contextual information, we just use random
+ data in this demo.
+ """
+
+ USERS = ['jim', 'fred', 'sheila']
+ IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1']
+
+ def filter(self, record):
+
+ record.ip = choice(ContextFilter.IPS)
+ record.user = choice(ContextFilter.USERS)
+ return True
+
+ if __name__ == "__main__":
+ levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
+ a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"),
+ { "ip" : "123.231.231.123", "user" : "sheila" })
+ logging.basicConfig(level=logging.DEBUG,
+ format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s")
+ a1 = logging.getLogger("a.b.c")
+ a2 = logging.getLogger("d.e.f")
+
+ f = ContextFilter()
+ a1.addFilter(f)
+ a2.addFilter(f)
+ a1.debug("A debug message")
+ a1.info("An info message with %s", "some parameters")
+ for x in range(10):
+ lvl = choice(levels)
+ lvlname = logging.getLevelName(lvl)
+ a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters")
+
+which, when run, produces something like::
+
+ 2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred A debug message
+ 2010-09-06 22:38:15,300 a.b.c INFO IP: 192.168.0.1 User: sheila An info message with some parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 127.0.0.1 User: jim A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 127.0.0.1 User: sheila A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 123.231.231.123 User: fred A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 192.168.0.1 User: jim A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters
+
+
.. _multiple-processes:
Logging to a single file from multiple processes
Modified: python/branches/release27-maint/Doc/library/logging.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/logging.rst (original)
+++ python/branches/release27-maint/Doc/library/logging.rst Tue Sep 7 00:18:20 2010
@@ -1335,6 +1335,10 @@
be hard to manage if the number of :class:`Logger` instances becomes
effectively unbounded.
+
+Using LoggerAdapters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
An easy way in which you can pass contextual information to be output along
with logging event information is to use the :class:`LoggerAdapter` class.
This class is designed to look like a :class:`Logger`, so that you can call
@@ -1442,6 +1446,78 @@
The :class:`LoggerAdapter` class was not present in previous versions.
+Using Filters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can also add contextual information to log output using a user-defined
+:class:`Filter`. ``Filter`` instances are allowed to modify the ``LogRecords``
+passed to them, including adding additional attributes which can then be output
+using a suitable format string, or if needed a custom :class:`Formatter`.
+
+For example in a web application, the request being processed (or at least,
+the interesting parts of it) can be stored in a threadlocal
+(:class:`threading.local`) variable, and then accessed from a ``Filter`` to
+add, say, information from the request - say, the remote IP address and remote
+user's username - to the ``LogRecord``, using the attribute names 'ip' and
+'user' as in the ``LoggerAdapter`` example above. In that case, the same format
+string can be used to get similar output to that shown above. Here's an example
+script::
+
+ import logging
+ from random import choice
+
+ class ContextFilter(logging.Filter):
+ """
+ This is a filter which injects contextual information into the log.
+
+ Rather than use actual contextual information, we just use random
+ data in this demo.
+ """
+
+ USERS = ['jim', 'fred', 'sheila']
+ IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1']
+
+ def filter(self, record):
+
+ record.ip = choice(ContextFilter.IPS)
+ record.user = choice(ContextFilter.USERS)
+ return True
+
+ if __name__ == "__main__":
+ levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
+ a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"),
+ { "ip" : "123.231.231.123", "user" : "sheila" })
+ logging.basicConfig(level=logging.DEBUG,
+ format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s")
+ a1 = logging.getLogger("a.b.c")
+ a2 = logging.getLogger("d.e.f")
+
+ f = ContextFilter()
+ a1.addFilter(f)
+ a2.addFilter(f)
+ a1.debug("A debug message")
+ a1.info("An info message with %s", "some parameters")
+ for x in range(10):
+ lvl = choice(levels)
+ lvlname = logging.getLevelName(lvl)
+ a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters")
+
+which, when run, produces something like::
+
+ 2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred A debug message
+ 2010-09-06 22:38:15,300 a.b.c INFO IP: 192.168.0.1 User: sheila An info message with some parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 127.0.0.1 User: jim A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 127.0.0.1 User: sheila A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 123.231.231.123 User: fred A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 192.168.0.1 User: jim A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters
+
+
.. _multiple-processes:
Logging to a single file from multiple processes
Modified: python/branches/release31-maint/Doc/library/logging.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/logging.rst (original)
+++ python/branches/release31-maint/Doc/library/logging.rst Tue Sep 7 00:18:20 2010
@@ -246,16 +246,16 @@
methods listed above, but this is how to log at custom log levels.
:func:`getLogger` returns a reference to a logger instance with the specified
-if it it is provided, or ``root`` if not. The names are period-separated
+name if it is provided, or ``root`` if not. The names are period-separated
hierarchical structures. Multiple calls to :func:`getLogger` with the same name
will return a reference to the same logger object. Loggers that are further
down in the hierarchical list are children of loggers higher up in the list.
For example, given a logger with a name of ``foo``, loggers with names of
-``foo.bar``, ``foo.bar.baz``, and ``foo.bam`` are all children of ``foo``.
-Child loggers propagate messages up to their parent loggers. Because of this,
-it is unnecessary to define and configure all the loggers an application uses.
-It is sufficient to configure a top-level logger and create child loggers as
-needed.
+``foo.bar``, ``foo.bar.baz``, and ``foo.bam`` are all descendants of ``foo``.
+Child loggers propagate messages up to the handlers associated with their
+ancestor loggers. Because of this, it is unnecessary to define and configure
+handlers for all the loggers an application uses. It is sufficient to
+configure handlers for a top-level logger and create child loggers as needed.
Handlers
@@ -283,15 +283,16 @@
are there two :func:`setLevel` methods? The level set in the logger
determines which severity of messages it will pass to its handlers. The level
set in each handler determines which messages that handler will send on.
- :func:`setFormatter` selects a Formatter object for this handler to use.
+
+* :func:`setFormatter` selects a Formatter object for this handler to use.
* :func:`addFilter` and :func:`removeFilter` respectively configure and
deconfigure filter objects on handlers.
-Application code should not directly instantiate and use handlers. Instead, the
-:class:`Handler` class is a base class that defines the interface that all
-Handlers should have and establishes some default behavior that child classes
-can use (or override).
+Application code should not directly instantiate and use instances of
+:class:`Handler`. Instead, the :class:`Handler` class is a base class that
+defines the interface that all handlers should have and establishes some
+default behavior that child classes can use (or override).
Formatters
@@ -318,6 +319,14 @@
"%(asctime)s - %(levelname)s - %(message)s"
+Formatters use a user-configurable function to convert the creation time of a
+record to a tuple. By default, :func:`time.localtime` is used; to change this
+for a particular formatter instance, set the ``converter`` attribute of the
+instance to a function with the same signature as :func:`time.localtime` or
+:func:`time.gmtime`. To change it for all formatters, for example if you want
+all logging times to be shown in GMT, set the ``converter`` attribute in the
+Formatter class (to ``time.gmtime`` for GMT display).
+
Configuring Logging
^^^^^^^^^^^^^^^^^^^
@@ -464,9 +473,8 @@
just "foo".
.. versionadded:: 3.1
-
-The :class:`NullHandler` class was not present in previous versions, but is now
-included, so that it need not be defined in library code.
+ The :class:`NullHandler` class was not present in previous versions, but is
+ now included, so that it need not be defined in library code.
@@ -516,7 +524,9 @@
can have zero, one or more handlers associated with it (via the
:meth:`addHandler` method of :class:`Logger`). In addition to any handlers
directly associated with a logger, *all handlers associated with all ancestors
-of the logger* are called to dispatch the message.
+of the logger* are called to dispatch the message (unless the *propagate* flag
+for a logger is set to a false value, at which point the passing to ancestor
+handlers stops).
Just as for loggers, handlers can have levels associated with them. A handler's
level acts as a filter in the same way as a logger's level does. If a handler
@@ -729,7 +739,11 @@
Provides an overriding level *lvl* for all loggers which takes precedence over
the logger's own level. When the need arises to temporarily throttle logging
- output down across the whole application, this function can be useful.
+ output down across the whole application, this function can be useful. Its
+ effect is to disable all logging calls of severity *lvl* and below, so that
+ if you call it with a value of INFO, then all INFO and DEBUG events would be
+ discarded, whereas those of severity WARNING and above would be processed
+ according to the logger's effective level.
.. function:: addLevelName(lvl, levelName)
@@ -765,11 +779,13 @@
Does basic configuration for the logging system by creating a
:class:`StreamHandler` with a default :class:`Formatter` and adding it to the
- root logger. The function does nothing if any handlers have been defined for
- the root logger. The functions :func:`debug`, :func:`info`, :func:`warning`,
+ root logger. The functions :func:`debug`, :func:`info`, :func:`warning`,
:func:`error` and :func:`critical` will call :func:`basicConfig` automatically
if no handlers are defined for the root logger.
+ This function does nothing if the root logger already has handlers
+ configured for it.
+
The following keyword arguments are supported.
+--------------+---------------------------------------------+
@@ -838,8 +854,8 @@
.. attribute:: Logger.propagate
If this evaluates to false, logging messages are not passed by this logger or by
- child loggers to higher level (ancestor) loggers. The constructor sets this
- attribute to 1.
+ its child loggers to the handlers of higher level (ancestor) loggers. The
+ constructor sets this attribute to 1.
.. method:: Logger.setLevel(lvl)
@@ -1195,6 +1211,28 @@
This example uses console and file handlers, but you can use any number and
combination of handlers you choose.
+.. _logging-exceptions:
+
+Exceptions raised during logging
+--------------------------------
+
+The logging package is designed to swallow exceptions which occur while logging
+in production. This is so that errors which occur while handling logging events
+- such as logging misconfiguration, network or other similar errors - do not
+cause the application using logging to terminate prematurely.
+
+:class:`SystemExit` and :class:`KeyboardInterrupt` exceptions are never
+swallowed. Other exceptions which occur during the :meth:`emit` method of a
+:class:`Handler` subclass are passed to its :meth:`handleError` method.
+
+The default implementation of :meth:`handleError` in :class:`Handler` checks
+to see if a module-level variable, :data:`raiseExceptions`, is set. If set, a
+traceback is printed to :data:`sys.stderr`. If not set, the exception is swallowed.
+
+**Note:** The default value of :data:`raiseExceptions` is ``True``. This is because
+during development, you typically want to be notified of any exceptions that
+occur. It's advised that you set :data:`raiseExceptions` to ``False`` for production
+usage.
.. _context-info:
@@ -1214,6 +1252,10 @@
be hard to manage if the number of :class:`Logger` instances becomes
effectively unbounded.
+
+Using LoggerAdapters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
An easy way in which you can pass contextual information to be output along
with logging event information is to use the :class:`LoggerAdapter` class.
This class is designed to look like a :class:`Logger`, so that you can call
@@ -1318,6 +1360,104 @@
2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters
+Using Filters to impart contextual information
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can also add contextual information to log output using a user-defined
+:class:`Filter`. ``Filter`` instances are allowed to modify the ``LogRecords``
+passed to them, including adding additional attributes which can then be output
+using a suitable format string, or if needed a custom :class:`Formatter`.
+
+For example in a web application, the request being processed (or at least,
+the interesting parts of it) can be stored in a threadlocal
+(:class:`threading.local`) variable, and then accessed from a ``Filter`` to
+add, say, information from the request - say, the remote IP address and remote
+user's username - to the ``LogRecord``, using the attribute names 'ip' and
+'user' as in the ``LoggerAdapter`` example above. In that case, the same format
+string can be used to get similar output to that shown above. Here's an example
+script::
+
+ import logging
+ from random import choice
+
+ class ContextFilter(logging.Filter):
+ """
+ This is a filter which injects contextual information into the log.
+
+ Rather than use actual contextual information, we just use random
+ data in this demo.
+ """
+
+ USERS = ['jim', 'fred', 'sheila']
+ IPS = ['123.231.231.123', '127.0.0.1', '192.168.0.1']
+
+ def filter(self, record):
+
+ record.ip = choice(ContextFilter.IPS)
+ record.user = choice(ContextFilter.USERS)
+ return True
+
+ if __name__ == "__main__":
+ levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
+ a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"),
+ { "ip" : "123.231.231.123", "user" : "sheila" })
+ logging.basicConfig(level=logging.DEBUG,
+ format="%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s")
+ a1 = logging.getLogger("a.b.c")
+ a2 = logging.getLogger("d.e.f")
+
+ f = ContextFilter()
+ a1.addFilter(f)
+ a2.addFilter(f)
+ a1.debug("A debug message")
+ a1.info("An info message with %s", "some parameters")
+ for x in range(10):
+ lvl = choice(levels)
+ lvlname = logging.getLevelName(lvl)
+ a2.log(lvl, "A message at %s level with %d %s", lvlname, 2, "parameters")
+
+which, when run, produces something like::
+
+ 2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred A debug message
+ 2010-09-06 22:38:15,300 a.b.c INFO IP: 192.168.0.1 User: sheila An info message with some parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 127.0.0.1 User: jim A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 127.0.0.1 User: sheila A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f ERROR IP: 123.231.231.123 User: fred A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A message at CRITICAL level with 2 parameters
+ 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 192.168.0.1 User: jim A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters
+ 2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters
+
+
+.. _multiple-processes:
+
+Logging to a single file from multiple processes
+------------------------------------------------
+
+Although logging is thread-safe, and logging to a single file from multiple
+threads in a single process *is* supported, logging to a single file from
+*multiple processes* is *not* supported, because there is no standard way to
+serialize access to a single file across multiple processes in Python. If you
+need to log to a single file from multiple processes, the best way of doing
+this is to have all the processes log to a :class:`SocketHandler`, and have a
+separate process which implements a socket server which reads from the socket
+and logs to file. (If you prefer, you can dedicate one thread in one of the
+existing processes to perform this function.) The following section documents
+this approach in more detail and includes a working socket receiver which can
+be used as a starting point for you to adapt in your own applications.
+
+If you are using a recent version of Python which includes the
+:mod:`multiprocessing` module, you can write your own handler which uses the
+:class:`Lock` class from this module to serialize access to the file from
+your processes. The existing :class:`FileHandler` and subclasses do not make
+use of :mod:`multiprocessing` at present, though they may do so in the future.
+Note that at present, the :mod:`multiprocessing` module does not provide
+working lock functionality on all platforms (see
+http://bugs.python.org/issue3770).
+
.. _network-logging:
@@ -1449,6 +1589,11 @@
69 myapp.area2 WARNING Jail zesty vixen who grabbed pay from quack.
69 myapp.area2 ERROR The five boxing wizards jump quickly.
+Note that there are some security issues with pickle in some scenarios. If
+these affect you, you can use an alternative serialization scheme by overriding
+the :meth:`makePickle` method and implementing your alternative there, as
+well as adapting the above script to use your alternative serialization.
+
Using arbitrary objects as messages
-----------------------------------
@@ -1604,6 +1749,8 @@
:exc:`NotImplementedError`.
+.. _stream-handler:
+
StreamHandler
^^^^^^^^^^^^^
@@ -1637,6 +1784,8 @@
no output, so an explicit :meth:`flush` call may be needed at times.
+.. _file-handler:
+
FileHandler
^^^^^^^^^^^
@@ -1663,6 +1812,7 @@
Outputs the record to the file.
+.. _null-handler:
NullHandler
^^^^^^^^^^^
@@ -1686,6 +1836,8 @@
See :ref:`library-config` for more information on how to use
:class:`NullHandler`.
+.. _watched-file-handler:
+
WatchedFileHandler
^^^^^^^^^^^^^^^^^^
@@ -1724,6 +1876,7 @@
changed. If it has, the existing stream is flushed and closed and the
file opened again, before outputting the record to the file.
+.. _rotating-file-handler:
RotatingFileHandler
^^^^^^^^^^^^^^^^^^^
@@ -1764,6 +1917,7 @@
Outputs the record to the file, catering for rollover as described
previously.
+.. _timed-rotating-file-handler:
TimedRotatingFileHandler
^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1811,6 +1965,9 @@
one is deleted. The deletion logic uses the interval to determine which
files to delete, so changing the interval may leave old files lying around.
+ If *delay* is true, then file opening is deferred until the first call to
+ :meth:`emit`.
+
.. method:: doRollover()
@@ -1822,6 +1979,8 @@
Outputs the record to the file, catering for rollover as described above.
+.. _socket-handler:
+
SocketHandler
^^^^^^^^^^^^^
@@ -1868,6 +2027,11 @@
Pickles the record's attribute dictionary in binary format with a length
prefix, and returns it ready for transmission across the socket.
+ Note that pickles aren't completely secure. If you are concerned about
+ security, you may want to override this method to implement a more secure
+ mechanism. For example, you can sign pickles using HMAC and then verify
+ them on the receiving end, or alternatively you can disable unpickling of
+ global objects on the receiving end.
.. method:: send(packet)
@@ -1875,6 +2039,8 @@
partial sends which can happen when the network is busy.
+.. _datagram-handler:
+
DatagramHandler
^^^^^^^^^^^^^^^
@@ -1908,6 +2074,8 @@
Send a pickled string to a socket.
+.. _syslog-handler:
+
SysLogHandler
^^^^^^^^^^^^^
@@ -1944,6 +2112,87 @@
or integers - if strings are passed, internal mapping dictionaries are
used to convert them to integers.
+ The symbolic ``LOG_`` values are defined in :class:`SysLogHandler` and
+ mirror the values defined in the ``sys/syslog.h`` header file.
+
+ **Priorities**
+
+ +--------------------------+---------------+
+ | Name (string) | Symbolic value|
+ +==========================+===============+
+ | ``alert`` | LOG_ALERT |
+ +--------------------------+---------------+
+ | ``crit`` or ``critical`` | LOG_CRIT |
+ +--------------------------+---------------+
+ | ``debug`` | LOG_DEBUG |
+ +--------------------------+---------------+
+ | ``emerg`` or ``panic`` | LOG_EMERG |
+ +--------------------------+---------------+
+ | ``err`` or ``error`` | LOG_ERR |
+ +--------------------------+---------------+
+ | ``info`` | LOG_INFO |
+ +--------------------------+---------------+
+ | ``notice`` | LOG_NOTICE |
+ +--------------------------+---------------+
+ | ``warn`` or ``warning`` | LOG_WARNING |
+ +--------------------------+---------------+
+
+ **Facilities**
+
+ +---------------+---------------+
+ | Name (string) | Symbolic value|
+ +===============+===============+
+ | ``auth`` | LOG_AUTH |
+ +---------------+---------------+
+ | ``authpriv`` | LOG_AUTHPRIV |
+ +---------------+---------------+
+ | ``cron`` | LOG_CRON |
+ +---------------+---------------+
+ | ``daemon`` | LOG_DAEMON |
+ +---------------+---------------+
+ | ``ftp`` | LOG_FTP |
+ +---------------+---------------+
+ | ``kern`` | LOG_KERN |
+ +---------------+---------------+
+ | ``lpr`` | LOG_LPR |
+ +---------------+---------------+
+ | ``mail`` | LOG_MAIL |
+ +---------------+---------------+
+ | ``news`` | LOG_NEWS |
+ +---------------+---------------+
+ | ``syslog`` | LOG_SYSLOG |
+ +---------------+---------------+
+ | ``user`` | LOG_USER |
+ +---------------+---------------+
+ | ``uucp`` | LOG_UUCP |
+ +---------------+---------------+
+ | ``local0`` | LOG_LOCAL0 |
+ +---------------+---------------+
+ | ``local1`` | LOG_LOCAL1 |
+ +---------------+---------------+
+ | ``local2`` | LOG_LOCAL2 |
+ +---------------+---------------+
+ | ``local3`` | LOG_LOCAL3 |
+ +---------------+---------------+
+ | ``local4`` | LOG_LOCAL4 |
+ +---------------+---------------+
+ | ``local5`` | LOG_LOCAL5 |
+ +---------------+---------------+
+ | ``local6`` | LOG_LOCAL6 |
+ +---------------+---------------+
+ | ``local7`` | LOG_LOCAL7 |
+ +---------------+---------------+
+
+ .. method:: mapPriority(levelname)
+
+ Maps a logging level name to a syslog priority name.
+ You may need to override this if you are using custom levels, or
+ if the default algorithm is not suitable for your needs. The
+ default algorithm maps ``DEBUG``, ``INFO``, ``WARNING``, ``ERROR`` and
+ ``CRITICAL`` to the equivalent syslog names, and all other level
+ names to "warning".
+
+.. _nt-eventlog-handler:
NTEventLogHandler
^^^^^^^^^^^^^^^^^
@@ -2010,6 +2259,7 @@
lookup to get the message ID. This version returns 1, which is the base
message ID in :file:`win32service.pyd`.
+.. _smtp-handler:
SMTPHandler
^^^^^^^^^^^
@@ -2038,6 +2288,7 @@
If you want to specify a subject line which is record-dependent, override
this method.
+.. _memory-handler:
MemoryHandler
^^^^^^^^^^^^^
@@ -2108,6 +2359,8 @@
Checks for buffer full or a record at the *flushLevel* or higher.
+.. _http-handler:
+
HTTPHandler
^^^^^^^^^^^
@@ -2250,6 +2503,7 @@
just uses :func:`traceback.print_exception`. The resulting string is
returned.
+.. _filter:
Filter Objects
--------------
@@ -2275,6 +2529,14 @@
yes. If deemed appropriate, the record may be modified in-place by this
method.
+Note that filters attached to handlers are consulted whenever an event is
+emitted by the handler, whereas filters attached to loggers are consulted
+whenever an event is logged to the handler (using :meth:`debug`, :meth:`info`,
+etc.) This means that events which have been generated by descendant loggers
+will not be filtered by a logger's filter setting, unless the filter has also
+been applied to those descendant loggers.
+
+.. _log-record:
LogRecord Objects
-----------------
@@ -2306,6 +2568,7 @@
Returns the message for this :class:`LogRecord` instance after merging any
user-supplied arguments with the message.
+.. _logger-adapter:
LoggerAdapter Objects
---------------------
From python-checkins at python.org Tue Sep 7 00:23:13 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 7 Sep 2010 00:23:13 +0200 (CEST)
Subject: [Python-checkins] r84570 - python/branches/py3k/Lib/_pyio.py
Message-ID: <20100906222313.CDB0AEE9E7@mail.python.org>
Author: amaury.forgeotdarc
Date: Tue Sep 7 00:23:13 2010
New Revision: 84570
Log:
Change docstrings to match the implementation
Modified:
python/branches/py3k/Lib/_pyio.py
Modified: python/branches/py3k/Lib/_pyio.py
==============================================================================
--- python/branches/py3k/Lib/_pyio.py (original)
+++ python/branches/py3k/Lib/_pyio.py Tue Sep 7 00:23:13 2010
@@ -358,13 +358,13 @@
def seekable(self) -> bool:
"""Return whether object supports random access.
- If False, seek(), tell() and truncate() will raise IOError.
+ If False, seek(), tell() and truncate() will raise UnsupportedOperation.
This method may need to do a test seek().
"""
return False
def _checkSeekable(self, msg=None):
- """Internal: raise an IOError if file is not seekable
+ """Internal: raise UnsupportedOperation if file is not seekable
"""
if not self.seekable():
raise UnsupportedOperation("File or stream is not seekable."
@@ -373,12 +373,12 @@
def readable(self) -> bool:
"""Return whether object was opened for reading.
- If False, read() will raise IOError.
+ If False, read() will raise UnsupportedOperation.
"""
return False
def _checkReadable(self, msg=None):
- """Internal: raise an IOError if file is not readable
+ """Internal: raise UnsupportedOperation if file is not readable
"""
if not self.readable():
raise UnsupportedOperation("File or stream is not readable."
@@ -387,12 +387,12 @@
def writable(self) -> bool:
"""Return whether object was opened for writing.
- If False, write() and truncate() will raise IOError.
+ If False, write() and truncate() will raise UnsupportedOperation.
"""
return False
def _checkWritable(self, msg=None):
- """Internal: raise an IOError if file is not writable
+ """Internal: raise UnsupportedOperation if file is not writable
"""
if not self.writable():
raise UnsupportedOperation("File or stream is not writable."
From python-checkins at python.org Tue Sep 7 00:31:52 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 7 Sep 2010 00:31:52 +0200 (CEST)
Subject: [Python-checkins] r84571 - in python/branches/py3k: Lib/_pyio.py
Modules/_io/iobase.c
Message-ID: <20100906223152.43E9BC48D@mail.python.org>
Author: amaury.forgeotdarc
Date: Tue Sep 7 00:31:52 2010
New Revision: 84571
Log:
More docstring updates
Modified:
python/branches/py3k/Lib/_pyio.py
python/branches/py3k/Modules/_io/iobase.c
Modified: python/branches/py3k/Lib/_pyio.py
==============================================================================
--- python/branches/py3k/Lib/_pyio.py (original)
+++ python/branches/py3k/Lib/_pyio.py Tue Sep 7 00:31:52 2010
@@ -264,7 +264,8 @@
Even though IOBase does not declare read, readinto, or write because
their signatures will vary, implementations and clients should
consider those methods part of the interface. Also, implementations
- may raise a IOError when operations they do not support are called.
+ may raise UnsupportedOperation when operations they do not support are
+ called.
The basic type used for binary data read from or written to a file is
bytes. bytearrays are accepted too, and in some cases (such as
Modified: python/branches/py3k/Modules/_io/iobase.c
==============================================================================
--- python/branches/py3k/Modules/_io/iobase.c (original)
+++ python/branches/py3k/Modules/_io/iobase.c Tue Sep 7 00:31:52 2010
@@ -35,7 +35,8 @@
"Even though IOBase does not declare read, readinto, or write because\n"
"their signatures will vary, implementations and clients should\n"
"consider those methods part of the interface. Also, implementations\n"
- "may raise a IOError when operations they do not support are called.\n"
+ "may raise UnsupportedOperation when operations they do not support are\n"
+ "called.\n"
"\n"
"The basic type used for binary data read from or written to a file is\n"
"bytes. bytearrays are accepted too, and in some cases (such as\n"
@@ -300,7 +301,7 @@
PyDoc_STRVAR(iobase_seekable_doc,
"Return whether object supports random access.\n"
"\n"
- "If False, seek(), tell() and truncate() will raise IOError.\n"
+ "If False, seek(), tell() and truncate() will raise UnsupportedOperation.\n"
"This method may need to do a test seek().");
static PyObject *
@@ -329,7 +330,7 @@
PyDoc_STRVAR(iobase_readable_doc,
"Return whether object was opened for reading.\n"
"\n"
- "If False, read() will raise IOError.");
+ "If False, read() will raise UnsupportedOperation.");
static PyObject *
iobase_readable(PyObject *self, PyObject *args)
@@ -358,7 +359,7 @@
PyDoc_STRVAR(iobase_writable_doc,
"Return whether object was opened for writing.\n"
"\n"
- "If False, read() will raise IOError.");
+ "If False, write() will raise UnsupportedOperation.");
static PyObject *
iobase_writable(PyObject *self, PyObject *args)
From python-checkins at python.org Tue Sep 7 00:54:24 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 00:54:24 +0200 (CEST)
Subject: [Python-checkins] r84572 -
python/branches/release27-maint/Lib/random.py
Message-ID: <20100906225424.28AB2EE9ED@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 00:54:24 2010
New Revision: 84572
Log:
Remove outdated XXX comment. Mapping support was removed for 3.x.
Modified:
python/branches/release27-maint/Lib/random.py
Modified: python/branches/release27-maint/Lib/random.py
==============================================================================
--- python/branches/release27-maint/Lib/random.py (original)
+++ python/branches/release27-maint/Lib/random.py Tue Sep 7 00:54:24 2010
@@ -292,15 +292,6 @@
large population: sample(xrange(10000000), 60)
"""
- # XXX Although the documentation says `population` is "a sequence",
- # XXX attempts are made to cater to any iterable with a __len__
- # XXX method. This has had mixed success. Examples from both
- # XXX sides: sets work fine, and should become officially supported;
- # XXX dicts are much harder, and have failed in various subtle
- # XXX ways across attempts. Support for mapping types should probably
- # XXX be dropped (and users should pass mapping.keys() or .values()
- # XXX explicitly).
-
# Sampling without replacement entails tracking either potential
# selections (the pool) in a list or previous selections in a set.
From python-checkins at python.org Tue Sep 7 01:36:31 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 01:36:31 +0200 (CEST)
Subject: [Python-checkins] r84573 - in python/branches/py3k:
Doc/library/random.rst Misc/NEWS
Message-ID: <20100906233631.7F9DCFBFF@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 01:36:31 2010
New Revision: 84573
Log:
Document which part of the random module module are guaranteed.
Modified:
python/branches/py3k/Doc/library/random.rst
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst (original)
+++ python/branches/py3k/Doc/library/random.rst Tue Sep 7 01:36:31 2010
@@ -270,3 +270,19 @@
`_ for a compatible alternative
random number generator with a long period and comparatively simple update
operations.
+
+Notes on Reproducibility
+========================
+
+Sometimes it is useful to be able to reproduce the sequences given by a pseudo
+random number generator. By re-using a seed value, the same sequence should be
+reproducible from run to run as long as multiple threads are not running.
+
+Most of the random module's algorithms and seeding functions are subject to
+change across Python versions, but two aspects are guaranteed not to change:
+
+* If a new seeding method is added, then a backward compatible seeder will be
+ offered.
+
+* The generator's :meth:`random` method will continue to produce the same
+ sequence when the compatible seeder is given the same seed.
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 7 01:36:31 2010
@@ -13,6 +13,11 @@
Library
-------
+- Updates to the random module:
+
+ * Document which parts of the module are guaranteed to stay the same
+ across versions and which parts are subject to change.
+
- collections.OrderedDict now supports a new method for repositioning
keys to either end.
From python-checkins at python.org Tue Sep 7 02:38:15 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 02:38:15 +0200 (CEST)
Subject: [Python-checkins] r84574 - in python/branches/py3k:
Doc/library/random.rst Lib/random.py Lib/test/test_random.py
Misc/NEWS
Message-ID: <20100907003815.6BB04EE98A@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 02:38:15 2010
New Revision: 84574
Log:
Document which part of the random module module are guaranteed.
Modified:
python/branches/py3k/Doc/library/random.rst
python/branches/py3k/Lib/random.py
python/branches/py3k/Lib/test/test_random.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst (original)
+++ python/branches/py3k/Doc/library/random.rst Tue Sep 7 02:38:15 2010
@@ -51,18 +51,23 @@
Bookkeeping functions:
-.. function:: seed([x])
+.. function:: seed([x], version=2)
- Initialize the basic random number generator. Optional argument *x* can be any
- :term:`hashable` object. If *x* is omitted or ``None``, current system time is used;
- current system time is also used to initialize the generator when the module is
- first imported. If randomness sources are provided by the operating system,
- they are used instead of the system time (see the :func:`os.urandom` function
- for details on availability).
+ Initialize the random number generator.
- If *x* is not ``None`` or an int, ``hash(x)`` is used instead. If *x* is an
- int, *x* is used directly.
+ If *x* is omitted or ``None``, the current system time is used. If
+ randomness sources are provided by the operating system, they are used
+ instead of the system time (see the :func:`os.urandom` function for details
+ on availability).
+ If *x* is an int, it is used directly.
+
+ With version 2 (the default), a :class:`str`, :class:`bytes`, or :class:`bytearray`
+ object gets converted to a :class:`int` and all of its bits are used. With version 1,
+ the :func:`hash` of *x* is used instead.
+
+ .. versionchanged:: 3.2
+ Moved to the version 2 scheme which uses all of the bits in a string seed.
.. function:: getstate()
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 02:38:15 2010
@@ -91,13 +91,17 @@
self.seed(x)
self.gauss_next = None
- def seed(self, a=None):
+ def seed(self, a=None, version=2):
"""Initialize internal state from hashable object.
None or no argument seeds from current time or from an operating
system specific randomness source if available.
- If a is not None or an int, hash(a) is used instead.
+ For version 2 (the default), all of the bits are used if a is a str,
+ bytes, or bytearray. For version 1, the hash() of a is used instead.
+
+ If a is an int, all bits are used.
+
"""
if a is None:
@@ -107,6 +111,11 @@
import time
a = int(time.time() * 256) # use fractional seconds
+ if version == 2 and isinstance(a, (str, bytes, bytearray)):
+ if isinstance(a, str):
+ a = a.encode("utf8")
+ a = int(_hexlify(a), 16)
+
super().seed(a)
self.gauss_next = None
Modified: python/branches/py3k/Lib/test/test_random.py
==============================================================================
--- python/branches/py3k/Lib/test/test_random.py (original)
+++ python/branches/py3k/Lib/test/test_random.py Tue Sep 7 02:38:15 2010
@@ -39,7 +39,7 @@
self.gen.seed(arg)
for arg in [list(range(3)), dict(one=1)]:
self.assertRaises(TypeError, self.gen.seed, arg)
- self.assertRaises(TypeError, self.gen.seed, 1, 2)
+ self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
self.assertRaises(TypeError, type(self.gen), [])
def test_sample(self):
@@ -223,6 +223,21 @@
class MersenneTwister_TestBasicOps(TestBasicOps):
gen = random.Random()
+ def test_guaranteed_stable(self):
+ # These sequences are guaranteed to stay the same across versions of python
+ self.gen.seed(3456147, version=1)
+ self.assertEqual([self.gen.random().hex() for i in range(4)],
+ ['0x1.ac362300d90d2p-1', '0x1.9d16f74365005p-1',
+ '0x1.1ebb4352e4c4dp-1', '0x1.1a7422abf9c11p-1'])
+ self.gen.seed("the quick brown fox", version=1)
+ self.assertEqual([self.gen.random().hex() for i in range(4)],
+ ['0x1.9ee265c177cdep-2', '0x1.bad51092e3c25p-1',
+ '0x1.85ff833f71576p-1', '0x1.87efb37462927p-1'])
+ self.gen.seed("the quick brown fox", version=2)
+ self.assertEqual([self.gen.random().hex() for i in range(4)],
+ ['0x1.1294009b9eda4p-2', '0x1.2ff96171b0010p-1',
+ '0x1.459e0989bd8e0p-5', '0x1.8b5f55892ddcbp-1'])
+
def test_setstate_first_arg(self):
self.assertRaises(ValueError, self.gen.setstate, (1, None, None))
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 7 02:38:15 2010
@@ -18,6 +18,9 @@
* Document which parts of the module are guaranteed to stay the same
across versions and which parts are subject to change.
+ * Update the seed() method to use all of the bits in a string
+ instead of just the hash value.
+
- collections.OrderedDict now supports a new method for repositioning
keys to either end.
From python-checkins at python.org Tue Sep 7 02:48:40 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 02:48:40 +0200 (CEST)
Subject: [Python-checkins] r84575 - python/branches/py3k/Lib/random.py
Message-ID: <20100907004840.BA9A3EE999@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 02:48:40 2010
New Revision: 84575
Log:
Minor code cleanup
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 02:48:40 2010
@@ -161,13 +161,13 @@
## -------------------- integer methods -------------------
- def randrange(self, start, stop=None, step=1, int=int, default=None,
- maxwidth=1< 0:
if istart >= maxwidth:
return self._randbelow(istart)
From solipsis at pitrou.net Tue Sep 7 05:02:25 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Tue, 07 Sep 2010 05:02:25 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84575): sum=0
Message-ID:
py3k results for svn r84575 (hg cset 70b80c31a453)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog7ZRPx5', '-x']
From python-checkins at python.org Tue Sep 7 06:44:52 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 06:44:52 +0200 (CEST)
Subject: [Python-checkins] r84576 - in python/branches/py3k:
Doc/library/random.rst Lib/random.py Lib/test/test_random.py
Misc/NEWS
Message-ID: <20100907044452.5B0EEFAAC@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 06:44:52 2010
New Revision: 84576
Log:
Issues #7889, #9025 and #9379: Improvements to the random module.
Modified:
python/branches/py3k/Doc/library/random.rst
python/branches/py3k/Lib/random.py
python/branches/py3k/Lib/test/test_random.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst (original)
+++ python/branches/py3k/Doc/library/random.rst Tue Sep 7 06:44:52 2010
@@ -98,6 +98,13 @@
equivalent to ``choice(range(start, stop, step))``, but doesn't actually build a
range object.
+ The positional argument pattern matches that of :func:`range`. Keyword arguments
+ should not be used because the function may use them in unexpected ways.
+
+ .. versionchanged:: 3.2
+ :meth:`randrange` is more sophisticated about producing equally distributed
+ values. Formerly it used a style like ``int(random()*n)`` which could produce
+ slightly uneven distributions.
.. function:: randint(a, b)
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 06:44:52 2010
@@ -161,7 +161,7 @@
## -------------------- integer methods -------------------
- def randrange(self, start, stop=None, step=1, int=int, maxwidth=1< 0:
- if istart >= maxwidth:
- return self._randbelow(istart)
- return int(self.random() * istart)
+ return self._randbelow(istart)
raise ValueError("empty range for randrange()")
# stop argument supplied.
@@ -201,9 +199,7 @@
# a long, but we're supposed to return an int (for backward
# compatibility).
- if width >= maxwidth:
- return int(istart + self._randbelow(width))
- return int(istart + int(self.random()*width))
+ return int(istart + self._randbelow(width))
if step == 1:
raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
@@ -221,9 +217,7 @@
if n <= 0:
raise ValueError("empty range for randrange()")
- if n >= maxwidth:
- return istart + istep*self._randbelow(n)
- return istart + istep*int(self.random() * n)
+ return istart + istep*self._randbelow(n)
def randint(self, a, b):
"""Return random integer in range [a, b], including both end points.
@@ -231,7 +225,7 @@
return self.randrange(a, b+1)
- def _randbelow(self, n, _log=_log, int=int, _maxwidth=1< n-1 > 2**(k-2)
- r = getrandbits(k)
+ k = n.bit_length() # don't use (n-1) here because n can be 1
+ r = getrandbits(k) # 0 <= r < 2**k
while r >= n:
r = getrandbits(k)
return r
@@ -262,7 +256,7 @@
def choice(self, seq):
"""Choose a random element from a non-empty sequence."""
- return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty
+ return seq[self._randbelow(len(seq))] # raises IndexError if seq is empty
def shuffle(self, x, random=None, int=int):
"""x, random=random.random -> shuffle list x in place; return None.
@@ -272,11 +266,15 @@
"""
if random is None:
- random = self.random
- for i in reversed(range(1, len(x))):
- # pick an element in x[:i+1] with which to exchange x[i]
- j = int(random() * (i+1))
- x[i], x[j] = x[j], x[i]
+ for i in reversed(range(1, len(x))):
+ # pick an element in x[:i+1] with which to exchange x[i]
+ j = self._randbelow(i+1)
+ x[i], x[j] = x[j], x[i]
+ else:
+ for i in reversed(range(1, len(x))):
+ # pick an element in x[:i+1] with which to exchange x[i]
+ j = int(random() * (i+1))
+ x[i], x[j] = x[j], x[i]
def sample(self, population, k):
"""Chooses k unique random elements from a population sequence or set.
@@ -314,7 +312,6 @@
n = len(population)
if not 0 <= k <= n:
raise ValueError("Sample larger than population")
- _int = int
result = [None] * k
setsize = 21 # size of a small set minus size of an empty list
if k > 5:
@@ -323,16 +320,16 @@
# An n-length list is smaller than a k-length set
pool = list(population)
for i in range(k): # invariant: non-selected at [0,n-i)
- j = _int(random() * (n-i))
+ j = self._randbelow(n-i)
result[i] = pool[j]
pool[j] = pool[n-i-1] # move non-selected item into vacancy
else:
selected = set()
selected_add = selected.add
for i in range(k):
- j = _int(random() * n)
+ j = self._randbelow(n)
while j in selected:
- j = _int(random() * n)
+ j = self._randbelow(n)
selected_add(j)
result[i] = population[j]
return result
Modified: python/branches/py3k/Lib/test/test_random.py
==============================================================================
--- python/branches/py3k/Lib/test/test_random.py (original)
+++ python/branches/py3k/Lib/test/test_random.py Tue Sep 7 06:44:52 2010
@@ -121,7 +121,15 @@
f = open(support.findfile(file),"rb")
r = pickle.load(f)
f.close()
- self.assertEqual(r.randrange(1000), value)
+ self.assertEqual(int(r.random()*1000), value)
+
+ def test_bug_9025(self):
+ # Had problem with an uneven distribution in int(n*random())
+ # Verify the fix by checking that distributions fall within expectations.
+ n = 100000
+ randrange = self.gen.randrange
+ k = sum(randrange(6755399441055744) % 3 == 2 for i in range(n))
+ self.assertTrue(0.30 < k/n < .37, (k/n))
class SystemRandom_TestBasicOps(TestBasicOps):
gen = random.SystemRandom()
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 7 06:44:52 2010
@@ -19,7 +19,16 @@
across versions and which parts are subject to change.
* Update the seed() method to use all of the bits in a string
- instead of just the hash value.
+ instead of just the hash value. This makes better use of the
+ seed value and assures the seeding is platform independent.
+ Issue #7889.
+
+ * Improved the random()-->integer algorithm used in choice(),
+ shuffle(), sample(), randrange(), and randint(). Formerly, it
+ used int(n*random()) which has a slight bias whenever n is not
+ a power of two. Issue #9025.
+
+ * Improved documentation of arguments to randrange(). Issue #9379.
- collections.OrderedDict now supports a new method for repositioning
keys to either end.
From python-checkins at python.org Tue Sep 7 07:32:49 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 07:32:49 +0200 (CEST)
Subject: [Python-checkins] r84577 -
python/branches/py3k/Doc/library/random.rst
Message-ID: <20100907053249.B849EEE994@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 07:32:49 2010
New Revision: 84577
Log:
Remove outdated reference to Wichmann-Hill algorithm.
Modified:
python/branches/py3k/Doc/library/random.rst
Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst (original)
+++ python/branches/py3k/Doc/library/random.rst Tue Sep 7 07:32:49 2010
@@ -8,9 +8,10 @@
This module implements pseudo-random number generators for various
distributions.
-For integers, uniform selection from a range. For sequences, uniform selection
-of a random element, a function to generate a random permutation of a list
-in-place, and a function for random sampling without replacement.
+For integers, there is uniform selection from a range. For sequences, there is
+uniform selection of a random element, a function to generate a random
+permutation of a list in-place, and a function for random sampling without
+replacement.
On the real line, there are functions to compute uniform, normal (Gaussian),
lognormal, negative exponential, gamma, and beta distributions. For generating
@@ -35,15 +36,6 @@
Optionally, a new generator can supply a :meth:`getrandbits` method --- this
allows :meth:`randrange` to produce selections over an arbitrarily large range.
-As an example of subclassing, the :mod:`random` module provides the
-:class:`WichmannHill` class that implements an alternative generator in pure
-Python. The class provides a backward compatible way to reproduce results from
-earlier versions of Python, which used the Wichmann-Hill algorithm as the core
-generator. Note that this Wichmann-Hill generator can no longer be recommended:
-its period is too short by contemporary standards, and the sequence generated is
-known to fail some stringent randomness tests. See the references below for a
-recent variant that repairs these flaws.
-
The :mod:`random` module also provides the :class:`SystemRandom` class which
uses the system function :func:`os.urandom` to generate random numbers
from sources provided by the operating system.
From python-checkins at python.org Tue Sep 7 07:35:10 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 07:35:10 +0200 (CEST)
Subject: [Python-checkins] r84578 -
python/branches/py3k/Doc/library/random.rst
Message-ID: <20100907053510.B3519F7BC@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 07:35:10 2010
New Revision: 84578
Log:
typo
Modified:
python/branches/py3k/Doc/library/random.rst
Modified: python/branches/py3k/Doc/library/random.rst
==============================================================================
--- python/branches/py3k/Doc/library/random.rst (original)
+++ python/branches/py3k/Doc/library/random.rst Tue Sep 7 07:35:10 2010
@@ -55,7 +55,7 @@
If *x* is an int, it is used directly.
With version 2 (the default), a :class:`str`, :class:`bytes`, or :class:`bytearray`
- object gets converted to a :class:`int` and all of its bits are used. With version 1,
+ object gets converted to an :class:`int` and all of its bits are used. With version 1,
the :func:`hash` of *x* is used instead.
.. versionchanged:: 3.2
From python-checkins at python.org Tue Sep 7 10:18:27 2010
From: python-checkins at python.org (georg.brandl)
Date: Tue, 7 Sep 2010 10:18:27 +0200 (CEST)
Subject: [Python-checkins] r84579 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100907081827.1E1D0EEA44@mail.python.org>
Author: georg.brandl
Date: Tue Sep 7 10:18:26 2010
New Revision: 84579
Log:
Add stub entry for argparse.
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Tue Sep 7 10:18:26 2010
@@ -243,6 +243,8 @@
New, Improved, and Deprecated Modules
=====================================
+* XXX mention :mod:`argparse`.
+
* The :mod:`functools` module includes a new decorator for caching function
calls. :func:`functools.lru_cache` can save repeated queries to an external
resource whenever the results are expected to be the same.
From python-checkins at python.org Tue Sep 7 11:32:57 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 11:32:57 +0200 (CEST)
Subject: [Python-checkins] r84580 - python/branches/py3k/Lib/random.py
Message-ID: <20100907093257.836C2EE997@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 11:32:57 2010
New Revision: 84580
Log:
Small clean-ups.
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 11:32:57 2010
@@ -167,7 +167,7 @@
This fixes the problem with randint() which includes the
endpoint; in Python this is usually not what you want.
- Do not supply the 'int' and 'maxwidth' arguments.
+ Do not supply the 'int' argument.
"""
# This code is a bit messy to make it fast for the
@@ -186,20 +186,7 @@
raise ValueError("non-integer stop for randrange()")
width = istop - istart
if step == 1 and width > 0:
- # Note that
- # int(istart + self.random()*width)
- # instead would be incorrect. For example, consider istart
- # = -2 and istop = 0. Then the guts would be in
- # -2.0 to 0.0 exclusive on both ends (ignoring that random()
- # might return 0.0), and because int() truncates toward 0, the
- # final result would be -1 or 0 (instead of -2 or -1).
- # istart + int(self.random()*width)
- # would also be incorrect, for a subtler reason: the RHS
- # can return a long, and then randrange() would also return
- # a long, but we're supposed to return an int (for backward
- # compatibility).
-
- return int(istart + self._randbelow(width))
+ return istart + self._randbelow(width)
if step == 1:
raise ValueError("empty range for randrange() (%d,%d, %d)" % (istart, istop, width))
@@ -233,20 +220,16 @@
by a single call to the underlying generator.
"""
- try:
- getrandbits = self.getrandbits
- except AttributeError:
- pass
- else:
- # Only call self.getrandbits if the original random() builtin method
- # has not been overridden or if a new getrandbits() was supplied.
- # This assures that the two methods correspond.
- if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
- k = n.bit_length() # don't use (n-1) here because n can be 1
- r = getrandbits(k) # 0 <= r < 2**k
- while r >= n:
- r = getrandbits(k)
- return r
+ getrandbits = self.getrandbits
+ # Only call self.getrandbits if the original random() builtin method
+ # has not been overridden or if a new getrandbits() was supplied.
+ # This assures that the two methods correspond.
+ if type(self.random) is _BuiltinMethod or type(getrandbits) is _Method:
+ k = n.bit_length() # don't use (n-1) here because n can be 1
+ r = getrandbits(k) # 0 <= r < 2**k
+ while r >= n:
+ r = getrandbits(k)
+ return r
if n >= _maxwidth:
_warn("Underlying random() generator does not supply \n"
"enough bits to choose from a population range this large")
From python-checkins at python.org Tue Sep 7 12:06:56 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 12:06:56 +0200 (CEST)
Subject: [Python-checkins] r84581 - in python/branches/py3k/Lib: random.py
test/test_random.py
Message-ID: <20100907100656.DFC4EEEA29@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 12:06:56 2010
New Revision: 84581
Log:
Fix corner case for Random.choice() and add tests.
Modified:
python/branches/py3k/Lib/random.py
python/branches/py3k/Lib/test/test_random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 12:06:56 2010
@@ -239,7 +239,11 @@
def choice(self, seq):
"""Choose a random element from a non-empty sequence."""
- return seq[self._randbelow(len(seq))] # raises IndexError if seq is empty
+ try:
+ i = self._randbelow(len(seq))
+ except ValueError:
+ raise IndexError('Cannot choose from an empty sequence')
+ return seq[i]
def shuffle(self, x, random=None, int=int):
"""x, random=random.random -> shuffle list x in place; return None.
Modified: python/branches/py3k/Lib/test/test_random.py
==============================================================================
--- python/branches/py3k/Lib/test/test_random.py (original)
+++ python/branches/py3k/Lib/test/test_random.py Tue Sep 7 12:06:56 2010
@@ -42,6 +42,13 @@
self.assertRaises(TypeError, self.gen.seed, 1, 2, 3, 4)
self.assertRaises(TypeError, type(self.gen), [])
+ def test_choice(self):
+ choice = self.gen.choice
+ with self.assertRaises(IndexError):
+ choice([])
+ self.assertEqual(choice([50]), 50)
+ self.assertIn(choice([25, 75]), [25, 75])
+
def test_sample(self):
# For the entire allowable range of 0 <= k <= N, validate that
# the sample is of the correct length and contains only unique items
From ncoghlan at gmail.com Tue Sep 7 14:34:18 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Tue, 7 Sep 2010 22:34:18 +1000
Subject: [Python-checkins] r84559 -
python/branches/py3k/Lib/subprocess.py
In-Reply-To: <20100906162929.8439CEE9C7@mail.python.org>
References: <20100906162929.8439CEE9C7@mail.python.org>
Message-ID:
On Tue, Sep 7, 2010 at 2:29 AM, brian.curtin wrote:
> Author: brian.curtin
> Date: Mon Sep ?6 18:29:29 2010
> New Revision: 84559
>
> Log:
> Fix #8956. ValueError message was only mentioning one signal.
>
> Rather than list out the three signals (or more over time), the message was
> made less specific but still descriptive.
>
>
>
> Modified:
> ? python/branches/py3k/Lib/subprocess.py
>
> Modified: python/branches/py3k/Lib/subprocess.py
> ==============================================================================
> --- python/branches/py3k/Lib/subprocess.py ? ? ?(original)
> +++ python/branches/py3k/Lib/subprocess.py ? ? ?Mon Sep ?6 18:29:29 2010
> @@ -983,7 +983,7 @@
> ? ? ? ? ? ? elif sig == signal.CTRL_BREAK_EVENT:
> ? ? ? ? ? ? ? ? os.kill(self.pid, signal.CTRL_BREAK_EVENT)
> ? ? ? ? ? ? else:
> - ? ? ? ? ? ? ? ?raise ValueError("Only SIGTERM is supported on Windows")
> + ? ? ? ? ? ? ? ?raise ValueError("Unsupported signal")
Would it be worth including the signal number here, to at least give
some hint as to exactly which signal was received?
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From ncoghlan at gmail.com Tue Sep 7 15:01:17 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Tue, 7 Sep 2010 23:01:17 +1000
Subject: [Python-checkins] r84562 - in python/branches/py3k:
Doc/library/io.rst Lib/_pyio.py Lib/test/test_memoryio.py Misc/NEWS
Modules/_io/_iomodule.c Modules/_io/_iomodule.h Modules/_io/bytesio.c
In-Reply-To: <20100906184822.26A92FA6F@mail.python.org>
References: <20100906184822.26A92FA6F@mail.python.org>
Message-ID:
On Tue, Sep 7, 2010 at 4:48 AM, antoine.pitrou
wrote:
> Modified: python/branches/py3k/Lib/test/test_memoryio.py
> ==============================================================================
> --- python/branches/py3k/Lib/test/test_memoryio.py ? ? ?(original)
> +++ python/branches/py3k/Lib/test/test_memoryio.py ? ? ?Mon Sep ?6 20:48:21 2010
> @@ -384,7 +384,31 @@
> ? ? ? ? del __main__.PickleTestMemIO
>
>
> -class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase):
> +class BytesIOMixin:
> +
> + ? ?def test_getbuffer(self):
> + ? ? ? ?memio = self.ioclass(b"1234567890")
> + ? ? ? ?buf = memio.getbuffer()
> + ? ? ? ?self.assertEqual(bytes(buf), b"1234567890")
> + ? ? ? ?memio.seek(5)
> + ? ? ? ?buf = memio.getbuffer()
> + ? ? ? ?self.assertEqual(bytes(buf), b"1234567890")
> + ? ? ? ?# Trying to change the size of the BytesIO while a buffer is exported
> + ? ? ? ?# raises a BufferError.
> + ? ? ? ?self.assertRaises(BufferError, memio.write, b'x' * 100)
> + ? ? ? ?self.assertRaises(BufferError, memio.truncate)
> + ? ? ? ?# Mutating the buffer updates the BytesIO
> + ? ? ? ?buf[3:6] = b"abc"
> + ? ? ? ?self.assertEqual(bytes(buf), b"123abc7890")
> + ? ? ? ?self.assertEqual(memio.getvalue(), b"123abc7890")
> + ? ? ? ?# After the buffer gets released, we can resize the BytesIO again
> + ? ? ? ?del buf
> + ? ? ? ?support.gc_collect()
> + ? ? ? ?memio.truncate()
I've raised an RFE (http://bugs.python.org/issue9789) to point out
that the need for that GC collect call in there to make the test
portable to other implementations is rather ugly and supporting an
explicit "buf.release()" call may be a nicer option. (And added Guido
to the nosy list, since he wasn't keen on supporting the context
management protocol idea, but I don't believe he said anything one way
or the other about an ordinary method).
> +class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin,
> + ? ? ? ? ? ? ? ? ? ?BytesIOMixin, unittest.TestCase):
I was going to ask why CBytesIOTest wasn't affected, but checking the
full source of the test file made everything clear :)
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From brian.curtin at gmail.com Tue Sep 7 15:05:21 2010
From: brian.curtin at gmail.com (Brian Curtin)
Date: Tue, 7 Sep 2010 08:05:21 -0500
Subject: [Python-checkins] [Python-Dev] r84559 -
python/branches/py3k/Lib/subprocess.py
In-Reply-To:
References: <20100906162929.8439CEE9C7@mail.python.org>
Message-ID:
On Tue, Sep 7, 2010 at 07:34, Nick Coghlan wrote:
> On Tue, Sep 7, 2010 at 2:29 AM, brian.curtin
> wrote:
> > Author: brian.curtin
> > Date: Mon Sep 6 18:29:29 2010
> > New Revision: 84559
> >
> > Log:
> > Fix #8956. ValueError message was only mentioning one signal.
> >
> > Rather than list out the three signals (or more over time), the message
> was
> > made less specific but still descriptive.
> >
> >
> >
> > Modified:
> > python/branches/py3k/Lib/subprocess.py
> >
> > Modified: python/branches/py3k/Lib/subprocess.py
> >
> ==============================================================================
> > --- python/branches/py3k/Lib/subprocess.py (original)
> > +++ python/branches/py3k/Lib/subprocess.py Mon Sep 6 18:29:29 2010
> > @@ -983,7 +983,7 @@
> > elif sig == signal.CTRL_BREAK_EVENT:
> > os.kill(self.pid, signal.CTRL_BREAK_EVENT)
> > else:
> > - raise ValueError("Only SIGTERM is supported on Windows")
> > + raise ValueError("Unsupported signal")
>
> Would it be worth including the signal number here, to at least give
> some hint as to exactly which signal was received?
>
> Cheers,
> Nick.
Sure, seems reasonable to me.
Does """raise ValueError("Unsupported signal: {}".format(sig))""" look fine,
or is there a more preferred format when displaying bad values in exception
messages?
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From ncoghlan at gmail.com Tue Sep 7 15:12:33 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Tue, 7 Sep 2010 23:12:33 +1000
Subject: [Python-checkins] r84564 - in python/branches/py3k/Lib:
ntpath.py test/test_ntpath.py
In-Reply-To: <20100906194617.4ECACEE9B1@mail.python.org>
References: <20100906194617.4ECACEE9B1@mail.python.org>
Message-ID:
On Tue, Sep 7, 2010 at 5:46 AM, brian.curtin wrote:
> Modified: python/branches/py3k/Lib/ntpath.py
> ==============================================================================
> --- python/branches/py3k/Lib/ntpath.py ?(original)
> +++ python/branches/py3k/Lib/ntpath.py ?Mon Sep ?6 21:46:17 2010
> @@ -10,7 +10,6 @@
> ?import stat
> ?import genericpath
> ?from genericpath import *
> -from nt import _getfileinformation
>
> ?__all__ = ["normcase","isabs","join","splitdrive","split","splitext",
> ? ? ? ? ? ?"basename","dirname","commonprefix","getsize","getmtime",
> @@ -656,4 +655,10 @@
>
> ?def sameopenfile(f1, f2):
> ? ? """Test whether two file objects reference the same file"""
> - ? ?return _getfileinformation(f1) == _getfileinformation(f2)
> + ? ?try:
> + ? ? ? ?from nt import _getfileinformation
> + ? ? ? ?return _getfileinformation(f1) == _getfileinformation(f2)
> + ? ?except ImportError:
> + ? ? ? ?# On other operating systems, return True if the file descriptors
> + ? ? ? ?# are the same.
> + ? ? ? ?return f1 == f2
Given the potential deadlock problems with imports inside functions,
I'd prefer to see this written as either:
try:
from nt import _getfileinformation
def sameopenfile(f1, f2):
return _getfileinformation(f1) == _getfileinformation(f2)
except ImportError:
# On other operating systems, return True if the file descriptors
# are the same.
def sameopenfile(f1, f2):
return f1 == f2
sameopenfile.__doc__ = "Test whether two file objects reference the same file"
or as:
try:
from nt import _getfileinformation
except ImportError:
# On other operating systems, file comparison is by file descriptor anyway
# so a separate file information object is unnecessary
def _getfileinformation(f): return f
def sameopenfile(f1, f2):
"""Test whether two file objects reference the same file"""
return _getfileinformation(f1) == _getfileinformation(f2)
The latter is cleaner code, while the former is likely an unnecessary
micro-optimisation.
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From ncoghlan at gmail.com Tue Sep 7 15:19:47 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Tue, 7 Sep 2010 23:19:47 +1000
Subject: [Python-checkins] [Python-Dev] r84559 -
python/branches/py3k/Lib/subprocess.py
In-Reply-To:
References: <20100906162929.8439CEE9C7@mail.python.org>
Message-ID:
On Tue, Sep 7, 2010 at 11:05 PM, Brian Curtin wrote:
> Sure, seems reasonable to me.
> Does """raise ValueError("Unsupported signal: {}".format(sig))""" look fine,
> or is there a more preferred format when displaying bad values in exception
> messages?
No, that's about what I was thinking as well. When all we have is an
error code (or similar number), it's difficult to make the associated
error message particularly pretty.
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From brian.curtin at gmail.com Tue Sep 7 15:20:21 2010
From: brian.curtin at gmail.com (Brian Curtin)
Date: Tue, 7 Sep 2010 08:20:21 -0500
Subject: [Python-checkins] [Python-Dev] r84564 - in
python/branches/py3k/Lib: ntpath.py test/test_ntpath.py
In-Reply-To:
References: <20100906194617.4ECACEE9B1@mail.python.org>
Message-ID:
On Tue, Sep 7, 2010 at 08:12, Nick Coghlan wrote:
> On Tue, Sep 7, 2010 at 5:46 AM, brian.curtin
> wrote:
> > Modified: python/branches/py3k/Lib/ntpath.py
> >
> ==============================================================================
> > --- python/branches/py3k/Lib/ntpath.py (original)
> > +++ python/branches/py3k/Lib/ntpath.py Mon Sep 6 21:46:17 2010
> > @@ -10,7 +10,6 @@
> > import stat
> > import genericpath
> > from genericpath import *
> > -from nt import _getfileinformation
> >
> > __all__ = ["normcase","isabs","join","splitdrive","split","splitext",
> > "basename","dirname","commonprefix","getsize","getmtime",
> > @@ -656,4 +655,10 @@
> >
> > def sameopenfile(f1, f2):
> > """Test whether two file objects reference the same file"""
> > - return _getfileinformation(f1) == _getfileinformation(f2)
> > + try:
> > + from nt import _getfileinformation
> > + return _getfileinformation(f1) == _getfileinformation(f2)
> > + except ImportError:
> > + # On other operating systems, return True if the file
> descriptors
> > + # are the same.
> > + return f1 == f2
>
> Given the potential deadlock problems with imports inside functions,
> I'd prefer to see this written as either:
>
> try:
> from nt import _getfileinformation
> def sameopenfile(f1, f2):
> return _getfileinformation(f1) == _getfileinformation(f2)
> except ImportError:
> # On other operating systems, return True if the file descriptors
> # are the same.
> def sameopenfile(f1, f2):
> return f1 == f2
> sameopenfile.__doc__ = "Test whether two file objects reference the same
> file"
>
> or as:
>
> try:
> from nt import _getfileinformation
> except ImportError:
> # On other operating systems, file comparison is by file descriptor anyway
> # so a separate file information object is unnecessary
> def _getfileinformation(f): return f
>
> def sameopenfile(f1, f2):
> """Test whether two file objects reference the same file"""
> return _getfileinformation(f1) == _getfileinformation(f2)
>
> The latter is cleaner code, while the former is likely an unnecessary
> micro-optimisation.
>
> Cheers,
> Nick.
Similar idea(s) would also apply to the function right above that, samefile.
I'll create a new issue for cleaning this up.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From python-checkins at python.org Tue Sep 7 15:24:38 2010
From: python-checkins at python.org (brian.curtin)
Date: Tue, 7 Sep 2010 15:24:38 +0200 (CEST)
Subject: [Python-checkins] r84582 - python/branches/py3k/Lib/subprocess.py
Message-ID: <20100907132438.BD8ECEEA3E@mail.python.org>
Author: brian.curtin
Date: Tue Sep 7 15:24:38 2010
New Revision: 84582
Log:
Adjust #8956 to add the bad signal number to the exception message.
Modified:
python/branches/py3k/Lib/subprocess.py
Modified: python/branches/py3k/Lib/subprocess.py
==============================================================================
--- python/branches/py3k/Lib/subprocess.py (original)
+++ python/branches/py3k/Lib/subprocess.py Tue Sep 7 15:24:38 2010
@@ -983,7 +983,7 @@
elif sig == signal.CTRL_BREAK_EVENT:
os.kill(self.pid, signal.CTRL_BREAK_EVENT)
else:
- raise ValueError("Unsupported signal")
+ raise ValueError("Unsupported signal: {}".format(sig))
def terminate(self):
"""Terminates the process
From python-checkins at python.org Tue Sep 7 15:27:20 2010
From: python-checkins at python.org (brian.curtin)
Date: Tue, 7 Sep 2010 15:27:20 +0200 (CEST)
Subject: [Python-checkins] r84583 - in python/branches/release27-maint:
Lib/subprocess.py
Message-ID: <20100907132720.2E7A8EE9B2@mail.python.org>
Author: brian.curtin
Date: Tue Sep 7 15:27:20 2010
New Revision: 84583
Log:
Merged revisions 84582 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84582 | brian.curtin | 2010-09-07 08:24:38 -0500 (Tue, 07 Sep 2010) | 3 lines
Adjust #8956 to add the bad signal number to the exception message.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/subprocess.py
Modified: python/branches/release27-maint/Lib/subprocess.py
==============================================================================
--- python/branches/release27-maint/Lib/subprocess.py (original)
+++ python/branches/release27-maint/Lib/subprocess.py Tue Sep 7 15:27:20 2010
@@ -993,7 +993,7 @@
elif sig == signal.CTRL_BREAK_EVENT:
os.kill(self.pid, signal.CTRL_BREAK_EVENT)
else:
- raise ValueError("Unsupported signal")
+ raise ValueError("Unsupported signal: {}".format(sig))
def terminate(self):
"""Terminates the process
From brian.curtin at gmail.com Tue Sep 7 15:28:40 2010
From: brian.curtin at gmail.com (Brian Curtin)
Date: Tue, 7 Sep 2010 08:28:40 -0500
Subject: [Python-checkins] [Python-Dev] r84559 -
python/branches/py3k/Lib/subprocess.py
In-Reply-To:
References: <20100906162929.8439CEE9C7@mail.python.org>
Message-ID:
On Tue, Sep 7, 2010 at 08:19, Nick Coghlan wrote:
> On Tue, Sep 7, 2010 at 11:05 PM, Brian Curtin
> wrote:
> > Sure, seems reasonable to me.
> > Does """raise ValueError("Unsupported signal: {}".format(sig))""" look
> fine,
> > or is there a more preferred format when displaying bad values in
> exception
> > messages?
>
> No, that's about what I was thinking as well. When all we have is an
> error code (or similar number), it's difficult to make the associated
> error message particularly pretty.
>
> Cheers,
> Nick.
Made the adjustment in r84582 (py3k) and r84583 (release27-maint). Thanks
for the suggestion.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From python-checkins at python.org Tue Sep 7 16:52:43 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 16:52:43 +0200 (CEST)
Subject: [Python-checkins] r84584 - in python/branches/py3k: Misc/NEWS
configure configure.in pyconfig.h.in setup.py
Message-ID: <20100907145243.1341AEEA76@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 16:52:42 2010
New Revision: 84584
Log:
Issue #4026: Make the fcntl extension build under AIX.
Patch by S?bastien Sabl?.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/configure
python/branches/py3k/configure.in
python/branches/py3k/pyconfig.h.in
python/branches/py3k/setup.py
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 7 16:52:42 2010
@@ -52,6 +52,12 @@
guaranteed to exist in all Python implementations and the names of hash
algorithms available in the current process.
+Build
+-----
+
+- Issue #4026: Make the fcntl extension build under AIX. Patch by S?bastien
+ Sabl?.
+
What's New in Python 3.2 Alpha 2?
=================================
Modified: python/branches/py3k/configure
==============================================================================
--- python/branches/py3k/configure (original)
+++ python/branches/py3k/configure Tue Sep 7 16:52:42 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 84477 .
+# From configure.in Revision: 84512 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 3.2.
#
@@ -9588,6 +9588,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock" >&5
$as_echo_n "checking for flock... " >&6; }
+have_flock=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -9605,14 +9606,84 @@
$as_echo "#define HAVE_FLOCK 1" >>confdefs.h
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
+ have_flock=yes
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_flock" >&5
+$as_echo "$have_flock" >&6; }
+
+if test "$have_flock" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if flock requires additional libraries." >&5
+$as_echo_n "checking if flock requires additional libraries.... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include
+
+int
+main ()
+{
+void *p = flock; flock(0, 0)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
+$as_echo_n "checking for flock in -lbsd... " >&6; }
+if test "${ac_cv_lib_bsd_flock+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char flock ();
+int
+main ()
+{
+return flock ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bsd_flock=yes
+else
+ ac_cv_lib_bsd_flock=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5
+$as_echo "$ac_cv_lib_bsd_flock" >&6; }
+if test "x$ac_cv_lib_bsd_flock" = x""yes; then :
+
+
+$as_echo "#define FLOCK_NEEDS_LIBBSD 1" >>confdefs.h
+
+
+fi
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5
$as_echo_n "checking for getpagesize... " >&6; }
@@ -14226,8 +14297,8 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
# Files that config.status was made for.
-config_files="$ac_config_files"
-config_headers="$ac_config_headers"
+config_files="`echo $ac_config_files`"
+config_headers="`echo $ac_config_headers`"
_ACEOF
Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in (original)
+++ python/branches/py3k/configure.in Tue Sep 7 16:52:42 2010
@@ -2642,13 +2642,27 @@
])
AC_MSG_CHECKING(for flock)
+have_flock=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include
]], [[void* p = flock]])],
[AC_DEFINE(HAVE_FLOCK, 1, Define if you have the 'flock' function.)
- AC_MSG_RESULT(yes)],
- [AC_MSG_RESULT(no)
+ have_flock=yes
])
+AC_MSG_RESULT($have_flock)
+
+if test "$have_flock" = yes ; then
+ AC_MSG_CHECKING(if flock requires additional libraries.)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include
+ ]], [[void *p = flock; flock(0, 0)]])],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT(yes)
+ AC_CHECK_LIB(bsd,flock, [
+ AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
+ ])
+ ])
+fi
AC_MSG_CHECKING(for getpagesize)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
Modified: python/branches/py3k/pyconfig.h.in
==============================================================================
--- python/branches/py3k/pyconfig.h.in (original)
+++ python/branches/py3k/pyconfig.h.in Tue Sep 7 16:52:42 2010
@@ -30,6 +30,9 @@
/* Define if --enable-ipv6 is specified */
#undef ENABLE_IPV6
+/* Define if flock needs to be linked with bsd library */
+#undef FLOCK_NEEDS_LIBBSD
+
/* Define if getpgrp() must be called as getpgrp(0). */
#undef GETPGRP_HAVE_ARG
Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py (original)
+++ python/branches/py3k/setup.py Tue Sep 7 16:52:42 2010
@@ -499,7 +499,11 @@
# supported...)
# fcntl(2) and ioctl(2)
- exts.append( Extension('fcntl', ['fcntlmodule.c']) )
+ libs = []
+ if (config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)):
+ # May be necessary on AIX for flock function
+ libs = ['bsd']
+ exts.append( Extension('fcntl', ['fcntlmodule.c'], libraries=libs) )
# pwd(3)
exts.append( Extension('pwd', ['pwdmodule.c']) )
# grp(3)
From python-checkins at python.org Tue Sep 7 16:55:24 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 16:55:24 +0200 (CEST)
Subject: [Python-checkins] r84585 - in python/branches/release27-maint:
Misc/NEWS configure configure.in pyconfig.h.in setup.py
Message-ID: <20100907145524.E9A68EEA78@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 16:55:24 2010
New Revision: 84585
Log:
Merged revisions 84584 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84584 | antoine.pitrou | 2010-09-07 16:52:42 +0200 (mar., 07 sept. 2010) | 4 lines
Issue #4026: Make the fcntl extension build under AIX.
Patch by S?bastien Sabl?.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/configure
python/branches/release27-maint/configure.in
python/branches/release27-maint/pyconfig.h.in
python/branches/release27-maint/setup.py
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Tue Sep 7 16:55:24 2010
@@ -275,6 +275,9 @@
Build
-----
+- Issue #4026: Make the fcntl extension build under AIX. Patch by S?bastien
+ Sabl?.
+
- Issue #3101: Helper functions _add_one_to_index_C() and
_add_one_to_index_F() become _Py_add_one_to_index_C() and
_Py_add_one_to_index_F(), respectively.
Modified: python/branches/release27-maint/configure
==============================================================================
--- python/branches/release27-maint/configure (original)
+++ python/branches/release27-maint/configure Tue Sep 7 16:55:24 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 81582 .
+# From configure.in Revision: 84368 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 2.7.
#
@@ -9742,6 +9742,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock" >&5
$as_echo_n "checking for flock... " >&6; }
+have_flock=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -9759,14 +9760,84 @@
$as_echo "#define HAVE_FLOCK 1" >>confdefs.h
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
+ have_flock=yes
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_flock" >&5
+$as_echo "$have_flock" >&6; }
+
+if test "$have_flock" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if flock requires additional libraries." >&5
+$as_echo_n "checking if flock requires additional libraries.... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include
+
+int
+main ()
+{
+void *p = flock; flock(0, 0)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
+$as_echo_n "checking for flock in -lbsd... " >&6; }
+if test "${ac_cv_lib_bsd_flock+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char flock ();
+int
+main ()
+{
+return flock ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bsd_flock=yes
+else
+ ac_cv_lib_bsd_flock=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5
+$as_echo "$ac_cv_lib_bsd_flock" >&6; }
+if test "x$ac_cv_lib_bsd_flock" = x""yes; then :
+
+
+$as_echo "#define FLOCK_NEEDS_LIBBSD 1" >>confdefs.h
+
+
+fi
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5
$as_echo_n "checking for getpagesize... " >&6; }
Modified: python/branches/release27-maint/configure.in
==============================================================================
--- python/branches/release27-maint/configure.in (original)
+++ python/branches/release27-maint/configure.in Tue Sep 7 16:55:24 2010
@@ -2775,13 +2775,27 @@
])
AC_MSG_CHECKING(for flock)
+have_flock=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include
]], [[void* p = flock]])],
[AC_DEFINE(HAVE_FLOCK, 1, Define if you have the 'flock' function.)
- AC_MSG_RESULT(yes)],
- [AC_MSG_RESULT(no)
+ have_flock=yes
])
+AC_MSG_RESULT($have_flock)
+
+if test "$have_flock" = yes ; then
+ AC_MSG_CHECKING(if flock requires additional libraries.)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+ #include
+ ]], [[void *p = flock; flock(0, 0)]])],
+ [AC_MSG_RESULT(no)],
+ [AC_MSG_RESULT(yes)
+ AC_CHECK_LIB(bsd,flock, [
+ AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
+ ])
+ ])
+fi
AC_MSG_CHECKING(for getpagesize)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
Modified: python/branches/release27-maint/pyconfig.h.in
==============================================================================
--- python/branches/release27-maint/pyconfig.h.in (original)
+++ python/branches/release27-maint/pyconfig.h.in Tue Sep 7 16:55:24 2010
@@ -36,6 +36,9 @@
/* Define if --enable-ipv6 is specified */
#undef ENABLE_IPV6
+/* Define if flock needs to be linked with bsd library */
+#undef FLOCK_NEEDS_LIBBSD
+
/* Define if getpgrp() must be called as getpgrp(0). */
#undef GETPGRP_HAVE_ARG
Modified: python/branches/release27-maint/setup.py
==============================================================================
--- python/branches/release27-maint/setup.py (original)
+++ python/branches/release27-maint/setup.py Tue Sep 7 16:55:24 2010
@@ -529,7 +529,11 @@
# supported...)
# fcntl(2) and ioctl(2)
- exts.append( Extension('fcntl', ['fcntlmodule.c']) )
+ libs = []
+ if (config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)):
+ # May be necessary on AIX for flock function
+ libs = ['bsd']
+ exts.append( Extension('fcntl', ['fcntlmodule.c'], libraries=libs) )
# pwd(3)
exts.append( Extension('pwd', ['pwdmodule.c']) )
# grp(3)
From python-checkins at python.org Tue Sep 7 16:58:51 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 16:58:51 +0200 (CEST)
Subject: [Python-checkins] r84586 - in python/branches/release31-maint:
Misc/NEWS configure configure.in pyconfig.h.in setup.py
Message-ID: <20100907145851.02D35EEA88@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 16:58:50 2010
New Revision: 84586
Log:
Merged revisions 84584 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84584 | antoine.pitrou | 2010-09-07 16:52:42 +0200 (mar., 07 sept. 2010) | 4 lines
Issue #4026: Make the fcntl extension build under AIX.
Patch by S?bastien Sabl?.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/configure
python/branches/release31-maint/configure.in
python/branches/release31-maint/pyconfig.h.in
python/branches/release31-maint/setup.py
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Tue Sep 7 16:58:50 2010
@@ -535,6 +535,9 @@
Build
-----
+- Issue #4026: Make the fcntl extension build under AIX. Patch by S?bastien
+ Sabl?.
+
- Issue #3101: Helper functions _add_one_to_index_C() and
_add_one_to_index_F() become _Py_add_one_to_index_C() and
_Py_add_one_to_index_F(), respectively.
Modified: python/branches/release31-maint/configure
==============================================================================
--- python/branches/release31-maint/configure (original)
+++ python/branches/release31-maint/configure Tue Sep 7 16:58:50 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 82963 .
+# From configure.in Revision: 84367 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 3.1.
#
@@ -9410,6 +9410,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock" >&5
$as_echo_n "checking for flock... " >&6; }
+have_flock=no
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -9426,16 +9427,89 @@
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
+
$as_echo "#define HAVE_FLOCK 1" >>confdefs.h
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
+ have_flock=yes
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_flock" >&5
+$as_echo "$have_flock" >&6; }
+
+if test "$have_flock" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if flock requires additional libraries." >&5
+$as_echo_n "checking if flock requires additional libraries.... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include "confdefs.h"
+ #include
+
+int
+main ()
+{
+flock(0, 0)
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
+$as_echo_n "checking for flock in -lbsd... " >&6; }
+if test "${ac_cv_lib_bsd_flock+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lbsd $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char flock ();
+int
+main ()
+{
+return flock ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_bsd_flock=yes
+else
+ ac_cv_lib_bsd_flock=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5
+$as_echo "$ac_cv_lib_bsd_flock" >&6; }
+if test "x$ac_cv_lib_bsd_flock" = x""yes; then :
+
+
+$as_echo "#define FLOCK_NEEDS_LIBBSD 1" >>confdefs.h
+
+
+fi
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5
$as_echo_n "checking for getpagesize... " >&6; }
Modified: python/branches/release31-maint/configure.in
==============================================================================
--- python/branches/release31-maint/configure.in (original)
+++ python/branches/release31-maint/configure.in Tue Sep 7 16:58:50 2010
@@ -2642,14 +2642,29 @@
)
AC_MSG_CHECKING(for flock)
+have_flock=no
AC_TRY_COMPILE([
#include "confdefs.h"
#include
-], void* p = flock,
+], void* p = flock, [
AC_DEFINE(HAVE_FLOCK, 1, Define if you have the 'flock' function.)
- AC_MSG_RESULT(yes),
- AC_MSG_RESULT(no)
-)
+ have_flock=yes
+])
+AC_MSG_RESULT($have_flock)
+
+if test "$have_flock" = yes ; then
+ AC_MSG_CHECKING(if flock requires additional libraries.)
+ AC_TRY_LINK([
+ #include "confdefs.h"
+ #include
+ ], [flock(0, 0)],
+ AC_MSG_RESULT(no), [
+ AC_MSG_RESULT(yes)
+ AC_CHECK_LIB(bsd,flock, [
+ AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
+ ])
+ ])
+fi
AC_MSG_CHECKING(for getpagesize)
AC_TRY_COMPILE([
Modified: python/branches/release31-maint/pyconfig.h.in
==============================================================================
--- python/branches/release31-maint/pyconfig.h.in (original)
+++ python/branches/release31-maint/pyconfig.h.in Tue Sep 7 16:58:50 2010
@@ -33,6 +33,9 @@
/* Define if --enable-ipv6 is specified */
#undef ENABLE_IPV6
+/* Define if flock needs to be linked with bsd library */
+#undef FLOCK_NEEDS_LIBBSD
+
/* Define if getpgrp() must be called as getpgrp(0). */
#undef GETPGRP_HAVE_ARG
Modified: python/branches/release31-maint/setup.py
==============================================================================
--- python/branches/release31-maint/setup.py (original)
+++ python/branches/release31-maint/setup.py Tue Sep 7 16:58:50 2010
@@ -489,7 +489,11 @@
# supported...)
# fcntl(2) and ioctl(2)
- exts.append( Extension('fcntl', ['fcntlmodule.c']) )
+ libs = []
+ if (config_h_vars.get('FLOCK_NEEDS_LIBBSD', False)):
+ # May be necessary on AIX for flock function
+ libs = ['bsd']
+ exts.append( Extension('fcntl', ['fcntlmodule.c'], libraries=libs) )
if platform not in ['mac']:
# pwd(3)
exts.append( Extension('pwd', ['pwdmodule.c']) )
From python-checkins at python.org Tue Sep 7 17:00:15 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 17:00:15 +0200 (CEST)
Subject: [Python-checkins] r84587 - in python/branches/py3k/Lib: random.py
test/test_generators.py
Message-ID: <20100907150015.A05F3EEA46@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 17:00:15 2010
New Revision: 84587
Log:
Fix test that depends on a particular implementation of random.choice().
Modified:
python/branches/py3k/Lib/random.py
python/branches/py3k/Lib/test/test_generators.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 17:00:15 2010
@@ -136,7 +136,7 @@
# really unsigned 32-bit ints, so we convert negative ints from
# version 2 to positive longs for version 3.
try:
- internalstate = tuple( x % (2**32) for x in internalstate )
+ internalstate = tuple(x % (2**32) for x in internalstate)
except ValueError as e:
raise TypeError from e
super(Random, self).setstate(internalstate)
@@ -214,10 +214,7 @@
def _randbelow(self, n, int=int, _maxwidth=1<A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->K L->L M->M
-merged I into A
- A->A B->B C->C D->D E->E F->F G->G H->H I->A J->J K->K L->L M->M
-merged D into C
- A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->K L->L M->M
-merged K into H
- A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->L M->M
-merged L into A
- A->A B->B C->C D->C E->E F->F G->G H->H I->A J->J K->H L->A M->M
-merged E into A
- A->A B->B C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M
-merged B into G
- A->A B->G C->C D->C E->A F->F G->G H->H I->A J->J K->H L->A M->M
+merged K into B
+ A->A B->B C->C D->D E->E F->F G->G H->H I->I J->J K->B L->L M->M
merged A into F
- A->F B->G C->C D->C E->F F->F G->G H->H I->F J->J K->H L->F M->M
-merged H into G
- A->F B->G C->C D->C E->F F->F G->G H->G I->F J->J K->G L->F M->M
-merged F into J
- A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->M
+ A->F B->B C->C D->D E->E F->F G->G H->H I->I J->J K->B L->L M->M
+merged E into F
+ A->F B->B C->C D->D E->F F->F G->G H->H I->I J->J K->B L->L M->M
+merged D into C
+ A->F B->B C->C D->C E->F F->F G->G H->H I->I J->J K->B L->L M->M
merged M into C
- A->J B->G C->C D->C E->J F->J G->G H->G I->J J->J K->G L->J M->C
-merged J into G
- A->G B->G C->C D->C E->G F->G G->G H->G I->G J->G K->G L->G M->C
-merged C into G
- A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G
+ A->F B->B C->C D->C E->F F->F G->G H->H I->I J->J K->B L->L M->C
+merged J into B
+ A->F B->B C->C D->C E->F F->F G->G H->H I->I J->B K->B L->L M->C
+merged B into C
+ A->F B->C C->C D->C E->F F->F G->G H->H I->I J->C K->C L->L M->C
+merged F into G
+ A->G B->C C->C D->C E->G F->G G->G H->H I->I J->C K->C L->L M->C
+merged L into C
+ A->G B->C C->C D->C E->G F->G G->G H->H I->I J->C K->C L->C M->C
+merged G into I
+ A->I B->C C->C D->C E->I F->I G->I H->H I->I J->C K->C L->C M->C
+merged I into H
+ A->H B->C C->C D->C E->H F->H G->H H->H I->H J->C K->C L->C M->C
+merged C into H
+ A->H B->H C->H D->H E->H F->H G->H H->H I->H J->H K->H L->H M->H
"""
# Emacs turd '
From python-checkins at python.org Tue Sep 7 17:38:33 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 17:38:33 +0200 (CEST)
Subject: [Python-checkins] r84588 -
python/branches/py3k/Lib/test/test_random.py
Message-ID: <20100907153833.6BE0FEEA7F@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 17:38:33 2010
New Revision: 84588
Log:
Remove invalid test (it was supposed to fail on 64-bit machines.).
Modified:
python/branches/py3k/Lib/test/test_random.py
Modified: python/branches/py3k/Lib/test/test_random.py
==============================================================================
--- python/branches/py3k/Lib/test/test_random.py (original)
+++ python/branches/py3k/Lib/test/test_random.py Tue Sep 7 17:38:33 2010
@@ -244,10 +244,6 @@
self.assertEqual([self.gen.random().hex() for i in range(4)],
['0x1.ac362300d90d2p-1', '0x1.9d16f74365005p-1',
'0x1.1ebb4352e4c4dp-1', '0x1.1a7422abf9c11p-1'])
- self.gen.seed("the quick brown fox", version=1)
- self.assertEqual([self.gen.random().hex() for i in range(4)],
- ['0x1.9ee265c177cdep-2', '0x1.bad51092e3c25p-1',
- '0x1.85ff833f71576p-1', '0x1.87efb37462927p-1'])
self.gen.seed("the quick brown fox", version=2)
self.assertEqual([self.gen.random().hex() for i in range(4)],
['0x1.1294009b9eda4p-2', '0x1.2ff96171b0010p-1',
From python-checkins at python.org Tue Sep 7 18:30:09 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 18:30:09 +0200 (CEST)
Subject: [Python-checkins] r84589 - in python/branches/py3k:
Lib/test/test_ioctl.py Misc/NEWS Modules/fcntlmodule.c
Message-ID: <20100907163009.A47B1EEA03@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 18:30:09 2010
New Revision: 84589
Log:
Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
Modified:
python/branches/py3k/Lib/test/test_ioctl.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/fcntlmodule.c
Modified: python/branches/py3k/Lib/test/test_ioctl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ioctl.py (original)
+++ python/branches/py3k/Lib/test/test_ioctl.py Tue Sep 7 18:30:09 2010
@@ -1,3 +1,4 @@
+import array
import unittest
from test.support import run_unittest, import_module, get_attribute
import os, struct
@@ -34,16 +35,36 @@
rpgrp = struct.unpack("i", r)[0]
self.assertIn(rpgrp, ids)
- def test_ioctl_mutate(self):
- import array
- buf = array.array('i', [0])
+ def _check_ioctl_mutate_len(self, nbytes=None):
+ buf = array.array('i')
+ intsize = buf.itemsize
ids = (os.getpgrp(), os.getsid(0))
- tty = open("/dev/tty", "r")
- r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
+ # A fill value unlikely to be in `ids`
+ fill = -12345
+ if nbytes is not None:
+ # Extend the buffer so that it is exactly `nbytes` bytes long
+ buf.extend([fill] * (nbytes // intsize))
+ self.assertEqual(len(buf) * intsize, nbytes) # sanity check
+ else:
+ buf.append(fill)
+ with open("/dev/tty", "r") as tty:
+ r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
rpgrp = buf[0]
self.assertEquals(r, 0)
self.assertIn(rpgrp, ids)
+ def test_ioctl_mutate(self):
+ self._check_ioctl_mutate_len()
+
+ def test_ioctl_mutate_1024(self):
+ # Issue #9758: a mutable buffer of exactly 1024 bytes wouldn't be
+ # copied back after the system call.
+ self._check_ioctl_mutate_len(1024)
+
+ def test_ioctl_mutate_2048(self):
+ # Test with a larger buffer, just for the record.
+ self._check_ioctl_mutate_len(2048)
+
def test_ioctl_signed_unsigned_code_param(self):
if not pty:
raise unittest.SkipTest('pty module required')
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 7 18:30:09 2010
@@ -13,6 +13,10 @@
Library
-------
+- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
+ and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
+ be updated back after the system call. Original patch by Brian Brazil.
+
- Updates to the random module:
* Document which parts of the module are guaranteed to stay the same
Modified: python/branches/py3k/Modules/fcntlmodule.c
==============================================================================
--- python/branches/py3k/Modules/fcntlmodule.c (original)
+++ python/branches/py3k/Modules/fcntlmodule.c Tue Sep 7 18:30:09 2010
@@ -157,7 +157,7 @@
else {
ret = ioctl(fd, code, arg);
}
- if (mutate_arg && (len < IOCTL_BUFSZ)) {
+ if (mutate_arg && (len <= IOCTL_BUFSZ)) {
memcpy(str, buf, len);
}
PyBuffer_Release(&pstr); /* No further access to str below this point */
From python-checkins at python.org Tue Sep 7 18:32:28 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 18:32:28 +0200 (CEST)
Subject: [Python-checkins] r84590 - in python/branches/release31-maint:
Lib/test/test_ioctl.py Misc/NEWS Modules/fcntlmodule.c
Message-ID: <20100907163228.3B7A3EEA03@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 18:32:28 2010
New Revision: 84590
Log:
Merged revisions 84589 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84589 | antoine.pitrou | 2010-09-07 18:30:09 +0200 (mar., 07 sept. 2010) | 5 lines
Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_ioctl.py
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Modules/fcntlmodule.c
Modified: python/branches/release31-maint/Lib/test/test_ioctl.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_ioctl.py (original)
+++ python/branches/release31-maint/Lib/test/test_ioctl.py Tue Sep 7 18:32:28 2010
@@ -1,3 +1,4 @@
+import array
import unittest
from test.support import run_unittest, import_module, get_attribute
import os, struct
@@ -34,16 +35,36 @@
rpgrp = struct.unpack("i", r)[0]
self.assertTrue(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
- def test_ioctl_mutate(self):
- import array
- buf = array.array('i', [0])
+ def _check_ioctl_mutate_len(self, nbytes=None):
+ buf = array.array('i')
+ intsize = buf.itemsize
ids = (os.getpgrp(), os.getsid(0))
- tty = open("/dev/tty", "r")
- r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
+ # A fill value unlikely to be in `ids`
+ fill = -12345
+ if nbytes is not None:
+ # Extend the buffer so that it is exactly `nbytes` bytes long
+ buf.extend([fill] * (nbytes // intsize))
+ self.assertEqual(len(buf) * intsize, nbytes) # sanity check
+ else:
+ buf.append(fill)
+ with open("/dev/tty", "r") as tty:
+ r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
rpgrp = buf[0]
self.assertEquals(r, 0)
self.assertTrue(rpgrp in ids, "%s not in %s" % (rpgrp, ids))
+ def test_ioctl_mutate(self):
+ self._check_ioctl_mutate_len()
+
+ def test_ioctl_mutate_1024(self):
+ # Issue #9758: a mutable buffer of exactly 1024 bytes wouldn't be
+ # copied back after the system call.
+ self._check_ioctl_mutate_len(1024)
+
+ def test_ioctl_mutate_2048(self):
+ # Test with a larger buffer, just for the record.
+ self._check_ioctl_mutate_len(2048)
+
def test_ioctl_signed_unsigned_code_param(self):
if not pty:
raise unittest.SkipTest('pty module required')
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Tue Sep 7 18:32:28 2010
@@ -105,6 +105,10 @@
Library
-------
+- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
+ and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
+ be updated back after the system call. Original patch by Brian Brazil.
+
- Issue #6656: fix locale.format_string to handle escaped percents
and mappings.
Modified: python/branches/release31-maint/Modules/fcntlmodule.c
==============================================================================
--- python/branches/release31-maint/Modules/fcntlmodule.c (original)
+++ python/branches/release31-maint/Modules/fcntlmodule.c Tue Sep 7 18:32:28 2010
@@ -157,7 +157,7 @@
else {
ret = ioctl(fd, code, arg);
}
- if (mutate_arg && (len < IOCTL_BUFSZ)) {
+ if (mutate_arg && (len <= IOCTL_BUFSZ)) {
memcpy(str, buf, len);
}
PyBuffer_Release(&pstr); /* No further access to str below this point */
From python-checkins at python.org Tue Sep 7 18:34:48 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 18:34:48 +0200 (CEST)
Subject: [Python-checkins] r84591 - in python/branches/release27-maint:
Lib/test/test_ioctl.py Misc/NEWS Modules/fcntlmodule.c
Message-ID: <20100907163448.18881EEA03@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 18:34:47 2010
New Revision: 84591
Log:
Merged revisions 84589 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84589 | antoine.pitrou | 2010-09-07 18:30:09 +0200 (mar., 07 sept. 2010) | 5 lines
Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_ioctl.py
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Modules/fcntlmodule.c
Modified: python/branches/release27-maint/Lib/test/test_ioctl.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_ioctl.py (original)
+++ python/branches/release27-maint/Lib/test/test_ioctl.py Tue Sep 7 18:34:47 2010
@@ -1,3 +1,4 @@
+import array
import unittest
from test.test_support import run_unittest, import_module, get_attribute
import os, struct
@@ -34,16 +35,36 @@
rpgrp = struct.unpack("i", r)[0]
self.assertIn(rpgrp, ids)
- def test_ioctl_mutate(self):
- import array
- buf = array.array('i', [0])
+ def _check_ioctl_mutate_len(self, nbytes=None):
+ buf = array.array('i')
+ intsize = buf.itemsize
ids = (os.getpgrp(), os.getsid(0))
- tty = open("/dev/tty", "r")
- r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
+ # A fill value unlikely to be in `ids`
+ fill = -12345
+ if nbytes is not None:
+ # Extend the buffer so that it is exactly `nbytes` bytes long
+ buf.extend([fill] * (nbytes // intsize))
+ self.assertEqual(len(buf) * intsize, nbytes) # sanity check
+ else:
+ buf.append(fill)
+ with open("/dev/tty", "r") as tty:
+ r = fcntl.ioctl(tty, termios.TIOCGPGRP, buf, 1)
rpgrp = buf[0]
self.assertEquals(r, 0)
self.assertIn(rpgrp, ids)
+ def test_ioctl_mutate(self):
+ self._check_ioctl_mutate_len()
+
+ def test_ioctl_mutate_1024(self):
+ # Issue #9758: a mutable buffer of exactly 1024 bytes wouldn't be
+ # copied back after the system call.
+ self._check_ioctl_mutate_len(1024)
+
+ def test_ioctl_mutate_2048(self):
+ # Test with a larger buffer, just for the record.
+ self._check_ioctl_mutate_len(2048)
+
def test_ioctl_signed_unsigned_code_param(self):
if not pty:
raise unittest.SkipTest('pty module required')
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Tue Sep 7 18:34:47 2010
@@ -36,6 +36,10 @@
Library
-------
+- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
+ and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
+ be updated back after the system call. Original patch by Brian Brazil.
+
- Issue #1100562: Fix deep-copying of objects derived from the list and
dict types. Patch by Michele Orr? and Bj?rn Lindqvist.
Modified: python/branches/release27-maint/Modules/fcntlmodule.c
==============================================================================
--- python/branches/release27-maint/Modules/fcntlmodule.c (original)
+++ python/branches/release27-maint/Modules/fcntlmodule.c Tue Sep 7 18:34:47 2010
@@ -153,7 +153,7 @@
else {
ret = ioctl(fd, code, arg);
}
- if (mutate_arg && (len < IOCTL_BUFSZ)) {
+ if (mutate_arg && (len <= IOCTL_BUFSZ)) {
memcpy(str, buf, len);
}
if (ret < 0) {
From benjamin at python.org Tue Sep 7 19:39:54 2010
From: benjamin at python.org (Benjamin Peterson)
Date: Tue, 7 Sep 2010 12:39:54 -0500
Subject: [Python-checkins] [Python-Dev] r84562 - in
python/branches/py3k: Doc/library/io.rst Lib/_pyio.py
Lib/test/test_memoryio.py Misc/NEWS Modules/_io/_iomodule.c
Modules/_io/_iomodule.h Modules/_io/bytesio.c
In-Reply-To:
References: <20100906184822.26A92FA6F@mail.python.org>
Message-ID:
2010/9/7 Nick Coghlan :
> I've raised an RFE (http://bugs.python.org/issue9789) to point out
> that the need for that GC collect call in there to make the test
> portable to other implementations is rather ugly
Why? You're testing garbage collection, so you should call garbage collection.
--
Regards,
Benjamin
From python-checkins at python.org Tue Sep 7 20:44:12 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 20:44:12 +0200 (CEST)
Subject: [Python-checkins] r84592 -
python/branches/py3k/Doc/library/nntplib.rst
Message-ID: <20100907184412.F0820FDC3@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 20:44:12 2010
New Revision: 84592
Log:
Update nntplib examples to use a public news server.
The example still doesn't work as-is under py3k, due to incomplete
or buggy porting of the nntplib module.
Modified:
python/branches/py3k/Doc/library/nntplib.rst
Modified: python/branches/py3k/Doc/library/nntplib.rst
==============================================================================
--- python/branches/py3k/Doc/library/nntplib.rst (original)
+++ python/branches/py3k/Doc/library/nntplib.rst Tue Sep 7 20:44:12 2010
@@ -18,35 +18,35 @@
Here are two small examples of how it can be used. To list some statistics
about a newsgroup and print the subjects of the last 10 articles::
- >>> s = NNTP('news.cwi.nl')
- >>> resp, count, first, last, name = s.group('comp.lang.python')
+ >>> s = NNTP('news.gmane.org')
+ >>> resp, count, first, last, name = s.group('gmane.comp.python.committers')
>>> print('Group', name, 'has', count, 'articles, range', first, 'to', last)
- Group comp.lang.python has 59 articles, range 3742 to 3803
+ Group gmane.comp.python.committers has 1071 articles, range 1 to 1071
>>> resp, subs = s.xhdr('subject', first + '-' + last)
>>> for id, sub in subs[-10:]: print(id, sub)
...
- 3792 Re: Removing elements from a list while iterating...
- 3793 Re: Who likes Info files?
- 3794 Emacs and doc strings
- 3795 a few questions about the Mac implementation
- 3796 Re: executable python scripts
- 3797 Re: executable python scripts
- 3798 Re: a few questions about the Mac implementation
- 3799 Re: PROPOSAL: A Generic Python Object Interface for Python C Modules
- 3802 Re: executable python scripts
- 3803 Re: \POSIX{} wait and SIGCHLD
+ 1062 Re: Mercurial Status?
+ 1063 Re: [python-committers] (Windows) buildbots on 3.x
+ 1064 Re: Mercurial Status?
+ 1065 Re: Mercurial Status?
+ 1066 Python 2.6.6 status
+ 1067 Commit Privileges for Ask Solem
+ 1068 Re: Commit Privileges for Ask Solem
+ 1069 Re: Commit Privileges for Ask Solem
+ 1070 Re: Commit Privileges for Ask Solem
+ 1071 2.6.6 rc 2
>>> s.quit()
- '205 news.cwi.nl closing connection. Goodbye.'
+ '205 Bye!'
To post an article from a file (this assumes that the article has valid
-headers)::
+headers, and that you have right to post on the particular newsgroup)::
- >>> s = NNTP('news.cwi.nl')
+ >>> s = NNTP('news.gmane.org')
>>> f = open('/tmp/article')
>>> s.post(f)
'240 Article posted successfully.'
>>> s.quit()
- '205 news.cwi.nl closing connection. Goodbye.'
+ '205 Bye!'
The module itself defines the following items:
From python-checkins at python.org Tue Sep 7 20:44:52 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 20:44:52 +0200 (CEST)
Subject: [Python-checkins] r84593 - in python/branches/release31-maint:
Doc/library/nntplib.rst
Message-ID: <20100907184452.6382FFA05@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 20:44:52 2010
New Revision: 84593
Log:
Merged revisions 84592 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84592 | antoine.pitrou | 2010-09-07 20:44:12 +0200 (mar., 07 sept. 2010) | 5 lines
Update nntplib examples to use a public news server.
The example still doesn't work as-is under py3k, due to incomplete
or buggy porting of the nntplib module.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/library/nntplib.rst
Modified: python/branches/release31-maint/Doc/library/nntplib.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/nntplib.rst (original)
+++ python/branches/release31-maint/Doc/library/nntplib.rst Tue Sep 7 20:44:52 2010
@@ -18,35 +18,35 @@
Here are two small examples of how it can be used. To list some statistics
about a newsgroup and print the subjects of the last 10 articles::
- >>> s = NNTP('news.cwi.nl')
- >>> resp, count, first, last, name = s.group('comp.lang.python')
+ >>> s = NNTP('news.gmane.org')
+ >>> resp, count, first, last, name = s.group('gmane.comp.python.committers')
>>> print('Group', name, 'has', count, 'articles, range', first, 'to', last)
- Group comp.lang.python has 59 articles, range 3742 to 3803
+ Group gmane.comp.python.committers has 1071 articles, range 1 to 1071
>>> resp, subs = s.xhdr('subject', first + '-' + last)
>>> for id, sub in subs[-10:]: print(id, sub)
...
- 3792 Re: Removing elements from a list while iterating...
- 3793 Re: Who likes Info files?
- 3794 Emacs and doc strings
- 3795 a few questions about the Mac implementation
- 3796 Re: executable python scripts
- 3797 Re: executable python scripts
- 3798 Re: a few questions about the Mac implementation
- 3799 Re: PROPOSAL: A Generic Python Object Interface for Python C Modules
- 3802 Re: executable python scripts
- 3803 Re: \POSIX{} wait and SIGCHLD
+ 1062 Re: Mercurial Status?
+ 1063 Re: [python-committers] (Windows) buildbots on 3.x
+ 1064 Re: Mercurial Status?
+ 1065 Re: Mercurial Status?
+ 1066 Python 2.6.6 status
+ 1067 Commit Privileges for Ask Solem
+ 1068 Re: Commit Privileges for Ask Solem
+ 1069 Re: Commit Privileges for Ask Solem
+ 1070 Re: Commit Privileges for Ask Solem
+ 1071 2.6.6 rc 2
>>> s.quit()
- '205 news.cwi.nl closing connection. Goodbye.'
+ '205 Bye!'
To post an article from a file (this assumes that the article has valid
-headers)::
+headers, and that you have right to post on the particular newsgroup)::
- >>> s = NNTP('news.cwi.nl')
+ >>> s = NNTP('news.gmane.org')
>>> f = open('/tmp/article')
>>> s.post(f)
'240 Article posted successfully.'
>>> s.quit()
- '205 news.cwi.nl closing connection. Goodbye.'
+ '205 Bye!'
The module itself defines the following items:
From python-checkins at python.org Tue Sep 7 20:46:41 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 20:46:41 +0200 (CEST)
Subject: [Python-checkins] r84594 - in python/branches/release27-maint:
Doc/library/nntplib.rst
Message-ID: <20100907184641.891B2EEA38@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 20:46:41 2010
New Revision: 84594
Log:
Merged revisions 84592 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84592 | antoine.pitrou | 2010-09-07 20:44:12 +0200 (mar., 07 sept. 2010) | 5 lines
Update nntplib examples to use a public news server.
The example still doesn't work as-is under py3k, due to incomplete
or buggy porting of the nntplib module.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Doc/library/nntplib.rst
Modified: python/branches/release27-maint/Doc/library/nntplib.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/nntplib.rst (original)
+++ python/branches/release27-maint/Doc/library/nntplib.rst Tue Sep 7 20:46:41 2010
@@ -18,35 +18,35 @@
Here are two small examples of how it can be used. To list some statistics
about a newsgroup and print the subjects of the last 10 articles::
- >>> s = NNTP('news.cwi.nl')
- >>> resp, count, first, last, name = s.group('comp.lang.python')
+ >>> s = NNTP('news.gmane.org')
+ >>> resp, count, first, last, name = s.group('gmane.comp.python.committers')
>>> print 'Group', name, 'has', count, 'articles, range', first, 'to', last
- Group comp.lang.python has 59 articles, range 3742 to 3803
+ Group gmane.comp.python.committers has 1071 articles, range 1 to 1071
>>> resp, subs = s.xhdr('subject', first + '-' + last)
>>> for id, sub in subs[-10:]: print id, sub
...
- 3792 Re: Removing elements from a list while iterating...
- 3793 Re: Who likes Info files?
- 3794 Emacs and doc strings
- 3795 a few questions about the Mac implementation
- 3796 Re: executable python scripts
- 3797 Re: executable python scripts
- 3798 Re: a few questions about the Mac implementation
- 3799 Re: PROPOSAL: A Generic Python Object Interface for Python C Modules
- 3802 Re: executable python scripts
- 3803 Re: \POSIX{} wait and SIGCHLD
+ 1062 Re: Mercurial Status?
+ 1063 Re: [python-committers] (Windows) buildbots on 3.x
+ 1064 Re: Mercurial Status?
+ 1065 Re: Mercurial Status?
+ 1066 Python 2.6.6 status
+ 1067 Commit Privileges for Ask Solem
+ 1068 Re: Commit Privileges for Ask Solem
+ 1069 Re: Commit Privileges for Ask Solem
+ 1070 Re: Commit Privileges for Ask Solem
+ 1071 2.6.6 rc 2
>>> s.quit()
- '205 news.cwi.nl closing connection. Goodbye.'
+ '205 Bye!'
To post an article from a file (this assumes that the article has valid
-headers)::
+headers, and that you have right to post on the particular newsgroup)::
- >>> s = NNTP('news.cwi.nl')
+ >>> s = NNTP('news.gmane.org')
>>> f = open('/tmp/article')
>>> s.post(f)
'240 Article posted successfully.'
>>> s.quit()
- '205 news.cwi.nl closing connection. Goodbye.'
+ '205 Bye!'
The module itself defines the following items:
From python-checkins at python.org Tue Sep 7 21:19:33 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 21:19:33 +0200 (CEST)
Subject: [Python-checkins] r84595 - python/branches/py3k/Lib/random.py
Message-ID: <20100907191933.C4308F92D@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 21:19:33 2010
New Revision: 84595
Log:
Minor refactoring and cleanup. Extend looping randrange() technique to subclasses.
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 21:19:33 2010
@@ -212,25 +212,33 @@
return self.randrange(a, b+1)
- def _randbelow(self, n, int=int, _maxwidth=1<= n:
r = getrandbits(k)
return r
- if n >= _maxwidth:
+ # There's an overriden random() method but no new getrandbits() method,
+ # so we can only use random() from here.
+ if k > bpf:
_warn("Underlying random() generator does not supply \n"
"enough bits to choose from a population range this large")
- return int(self.random() * n)
+ return int(self.random() * n)
+ random = self.random
+ N = 1 << k
+ r = int(N * random())
+ while r >= n:
+ r = int(N * random())
+ return r
## -------------------- sequence methods -------------------
@@ -249,16 +257,11 @@
float in [0.0, 1.0); by default, the standard random.random.
"""
- if random is None:
- for i in reversed(range(1, len(x))):
- # pick an element in x[:i+1] with which to exchange x[i]
- j = self._randbelow(i+1)
- x[i], x[j] = x[j], x[i]
- else:
- for i in reversed(range(1, len(x))):
- # pick an element in x[:i+1] with which to exchange x[i]
- j = int(random() * (i+1))
- x[i], x[j] = x[j], x[i]
+ randbelow = self._randbelow
+ for i in reversed(range(1, len(x))):
+ # pick an element in x[:i+1] with which to exchange x[i]
+ j = randbelow(i+1) if random is None else int(random() * (i+1))
+ x[i], x[j] = x[j], x[i]
def sample(self, population, k):
"""Chooses k unique random elements from a population sequence or set.
@@ -292,7 +295,7 @@
population = tuple(population)
if not isinstance(population, _collections.Sequence):
raise TypeError("Population must be a sequence or Set. For dicts, use list(d).")
- random = self.random
+ randbelow = self._randbelow
n = len(population)
if not 0 <= k <= n:
raise ValueError("Sample larger than population")
@@ -304,16 +307,16 @@
# An n-length list is smaller than a k-length set
pool = list(population)
for i in range(k): # invariant: non-selected at [0,n-i)
- j = self._randbelow(n-i)
+ j = randbelow(n-i)
result[i] = pool[j]
pool[j] = pool[n-i-1] # move non-selected item into vacancy
else:
selected = set()
selected_add = selected.add
for i in range(k):
- j = self._randbelow(n)
+ j = randbelow(n)
while j in selected:
- j = self._randbelow(n)
+ j = randbelow(n)
selected_add(j)
result[i] = population[j]
return result
From python-checkins at python.org Tue Sep 7 22:04:42 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 7 Sep 2010 22:04:42 +0200 (CEST)
Subject: [Python-checkins] r84596 - python/branches/py3k/Lib/random.py
Message-ID: <20100907200442.EBE13EEA43@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 7 22:04:42 2010
New Revision: 84596
Log:
Neaten-up comments and warning message.
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Tue Sep 7 22:04:42 2010
@@ -221,9 +221,8 @@
getrandbits = self.getrandbits
# Only call self.getrandbits if the original random() builtin method
# has not been overridden or if a new getrandbits() was supplied.
- # This assures that the two methods correspond.
if type(self.random) is BuiltinMethod or type(getrandbits) is Method:
- r = getrandbits(k) # 0 <= r < 2**k
+ r = getrandbits(k) # 0 <= r < 2**k
while r >= n:
r = getrandbits(k)
return r
@@ -231,11 +230,12 @@
# so we can only use random() from here.
if k > bpf:
_warn("Underlying random() generator does not supply \n"
- "enough bits to choose from a population range this large")
+ "enough bits to choose from a population range this large.\n"
+ "To remove the range limitation, add a getrandbits() method.")
return int(self.random() * n)
random = self.random
N = 1 << k
- r = int(N * random())
+ r = int(N * random()) # 0 <= r < 2**k
while r >= n:
r = int(N * random())
return r
From python-checkins at python.org Tue Sep 7 22:42:20 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 22:42:20 +0200 (CEST)
Subject: [Python-checkins] r84597 - in python/branches/py3k/Lib/test:
support.py test_ssl.py
Message-ID: <20100907204220.2B3E9EEA62@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 22:42:19 2010
New Revision: 84597
Log:
Issue #8574: better implementation of test.support.transient_internet().
Original patch by Victor.
Modified:
python/branches/py3k/Lib/test/support.py
python/branches/py3k/Lib/test/test_ssl.py
Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py (original)
+++ python/branches/py3k/Lib/test/support.py Tue Sep 7 22:42:19 2010
@@ -35,7 +35,7 @@
"check_warnings", "CleanImport", "EnvironmentVarGuard",
"TransientResource", "captured_output", "captured_stdout",
"time_out", "socket_peer_reset", "ioerror_peer_reset",
- "run_with_locale", 'temp_umask',
+ "run_with_locale", 'temp_umask', "transient_internet",
"set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner",
"run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
"reap_children", "cpython_only", "check_impl_detail", "get_attribute",
@@ -775,23 +775,47 @@
else:
raise ResourceDenied("an optional resource is not available")
-
# Context managers that raise ResourceDenied when various issues
# with the Internet connection manifest themselves as exceptions.
+# XXX deprecate these and use transient_internet() instead
time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
@contextlib.contextmanager
-def transient_internet():
+def transient_internet(resource_name, *, timeout=30.0, errnos=()):
"""Return a context manager that raises ResourceDenied when various issues
with the Internet connection manifest themselves as exceptions."""
- time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
- socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
- ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
- with time_out, socket_peer_reset, ioerror_peer_reset:
+ denied = ResourceDenied("Resource '%s' is not available" % resource_name)
+ captured_errnos = errnos or (errno.ETIMEDOUT, errno.ECONNRESET)
+
+ def filter_error(err):
+ if (isinstance(err, socket.timeout) or
+ getattr(err, 'errno', None) in captured_errnos):
+ if not verbose:
+ sys.stderr.write(denied.args[0] + "\n")
+ raise denied from err
+
+ old_timeout = socket.getdefaulttimeout()
+ try:
+ if timeout is not None:
+ socket.setdefaulttimeout(timeout)
yield
+ except IOError as err:
+ # socket.error inherits IOError
+ filter_error(err)
+ # urllib.request wraps the original socket.error with IOerror:
+ #
+ # except socket.error as msg:
+ # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
+ if len(err.args) >= 2 and isinstance(err.args[1], socket.error):
+ filter_error(err.args[1])
+ raise
+ # XXX should we catch generic exceptions and look for their
+ # __cause__ or __context__?
+ finally:
+ socket.setdefaulttimeout(old_timeout)
@contextlib.contextmanager
Modified: python/branches/py3k/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ssl.py (original)
+++ python/branches/py3k/Lib/test/test_ssl.py Tue Sep 7 22:42:19 2010
@@ -477,10 +477,10 @@
# NOTE: https://sha256.tbs-internet.com is another possible test host
remote = ("sha2.hboeck.de", 443)
sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=sha256_cert,)
- with support.transient_internet():
+ with support.transient_internet("sha2.hboeck.de"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=sha256_cert,)
try:
s.connect(remote)
if support.verbose:
From python-checkins at python.org Tue Sep 7 23:05:49 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 23:05:49 +0200 (CEST)
Subject: [Python-checkins] r84598 - in python/branches/py3k: Lib/socket.py
Lib/test/test_socket.py Misc/NEWS
Message-ID: <20100907210549.D987EEEA6C@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 23:05:49 2010
New Revision: 84598
Log:
Issue #9792: In case of connection failure, socket.create_connection()
would swallow the exception and raise a new one, making it impossible
to fetch the original errno, or to filter timeout errors. Now the
original error is re-raised.
Modified:
python/branches/py3k/Lib/socket.py
python/branches/py3k/Lib/test/test_socket.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/socket.py
==============================================================================
--- python/branches/py3k/Lib/socket.py (original)
+++ python/branches/py3k/Lib/socket.py Tue Sep 7 23:05:49 2010
@@ -297,8 +297,8 @@
An host of '' or port 0 tells the OS to use the default.
"""
- msg = "getaddrinfo returns an empty list"
host, port = address
+ err = None
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
af, socktype, proto, canonname, sa = res
sock = None
@@ -311,9 +311,12 @@
sock.connect(sa)
return sock
- except error as err:
- msg = err
+ except error as _:
+ err = _
if sock is not None:
sock.close()
- raise error(msg)
+ if err is not None:
+ raise err
+ else:
+ raise error("getaddrinfo returns an empty list")
Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py (original)
+++ python/branches/py3k/Lib/test/test_socket.py Tue Sep 7 23:05:49 2010
@@ -13,6 +13,7 @@
import sys
import os
import array
+import contextlib
from weakref import proxy
import signal
@@ -1203,12 +1204,42 @@
class NetworkConnectionNoServer(unittest.TestCase):
- def testWithoutServer(self):
+ class MockSocket(socket.socket):
+ def connect(self, *args):
+ raise socket.timeout('timed out')
+
+ @contextlib.contextmanager
+ def mocked_socket_module(self):
+ """Return a socket which times out on connect"""
+ old_socket = socket.socket
+ socket.socket = self.MockSocket
+ try:
+ yield
+ finally:
+ socket.socket = old_socket
+
+ def test_connect(self):
port = support.find_unused_port()
- self.assertRaises(
- socket.error,
- lambda: socket.create_connection((HOST, port))
- )
+ cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ with self.assertRaises(socket.error) as cm:
+ cli.connect((HOST, port))
+ self.assertEqual(cm.exception.errno, errno.ECONNREFUSED)
+
+ def test_create_connection(self):
+ # Issue #9792: errors raised by create_connection() should have
+ # a proper errno attribute.
+ port = support.find_unused_port()
+ with self.assertRaises(socket.error) as cm:
+ socket.create_connection((HOST, port))
+ self.assertEqual(cm.exception.errno, errno.ECONNREFUSED)
+
+ def test_create_connection_timeout(self):
+ # Issue #9792: create_connection() should not recast timeout errors
+ # as generic socket errors.
+ with self.mocked_socket_module():
+ with self.assertRaises(socket.timeout):
+ socket.create_connection((HOST, 1234))
+
@unittest.skipUnless(thread, 'Threading required for this test.')
class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 7 23:05:49 2010
@@ -13,6 +13,11 @@
Library
-------
+- Issue #9792: In case of connection failure, socket.create_connection()
+ would swallow the exception and raise a new one, making it impossible
+ to fetch the original errno, or to filter timeout errors. Now the
+ original error is re-raised.
+
- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
From python-checkins at python.org Tue Sep 7 23:09:09 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 23:09:09 +0200 (CEST)
Subject: [Python-checkins] r84599 - in python/branches/py3k/Lib/test:
support.py test_robotparser.py
Message-ID: <20100907210909.C23FFEEA6C@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 23:09:09 2010
New Revision: 84599
Log:
Improve transient_internet() again to detect more network errors,
and use it in test_robotparser. Fixes #8574.
Modified:
python/branches/py3k/Lib/test/support.py
python/branches/py3k/Lib/test/test_robotparser.py
Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py (original)
+++ python/branches/py3k/Lib/test/support.py Tue Sep 7 23:09:09 2010
@@ -787,8 +787,18 @@
def transient_internet(resource_name, *, timeout=30.0, errnos=()):
"""Return a context manager that raises ResourceDenied when various issues
with the Internet connection manifest themselves as exceptions."""
+ default_errnos = [
+ ('ECONNREFUSED', 111),
+ ('ECONNRESET', 104),
+ ('ENETUNREACH', 101),
+ ('ETIMEDOUT', 110),
+ ]
+
denied = ResourceDenied("Resource '%s' is not available" % resource_name)
- captured_errnos = errnos or (errno.ETIMEDOUT, errno.ECONNRESET)
+ captured_errnos = errnos
+ if not captured_errnos:
+ captured_errnos = [getattr(errno, name, num)
+ for (name, num) in default_errnos]
def filter_error(err):
if (isinstance(err, socket.timeout) or
@@ -803,14 +813,20 @@
socket.setdefaulttimeout(timeout)
yield
except IOError as err:
- # socket.error inherits IOError
+ # urllib can wrap original socket errors multiple times (!), we must
+ # unwrap to get at the original error.
+ while True:
+ a = err.args
+ if len(a) >= 1 and isinstance(a[0], IOError):
+ err = a[0]
+ # The error can also be wrapped as args[1]:
+ # except socket.error as msg:
+ # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
+ elif len(a) >= 2 and isinstance(a[1], IOError):
+ err = a[1]
+ else:
+ break
filter_error(err)
- # urllib.request wraps the original socket.error with IOerror:
- #
- # except socket.error as msg:
- # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
- if len(err.args) >= 2 and isinstance(err.args[1], socket.error):
- filter_error(err.args[1])
raise
# XXX should we catch generic exceptions and look for their
# __cause__ or __context__?
Modified: python/branches/py3k/Lib/test/test_robotparser.py
==============================================================================
--- python/branches/py3k/Lib/test/test_robotparser.py (original)
+++ python/branches/py3k/Lib/test/test_robotparser.py Tue Sep 7 23:09:09 2010
@@ -235,23 +235,24 @@
def testPasswordProtectedSite(self):
support.requires('network')
- # XXX it depends on an external resource which could be unavailable
- url = 'http://mueblesmoraleda.com'
- parser = urllib.robotparser.RobotFileParser()
- parser.set_url(url)
- try:
- parser.read()
- except URLError:
- self.skipTest('%s is unavailable' % url)
- self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)
+ with support.transient_internet('mueblesmoraleda.com'):
+ url = 'http://mueblesmoraleda.com'
+ parser = urllib.robotparser.RobotFileParser()
+ parser.set_url(url)
+ try:
+ parser.read()
+ except URLError:
+ self.skipTest('%s is unavailable' % url)
+ self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)
def testPythonOrg(self):
support.requires('network')
- parser = urllib.robotparser.RobotFileParser(
- "http://www.python.org/robots.txt")
- parser.read()
- self.assertTrue(parser.can_fetch("*",
- "http://www.python.org/robots.txt"))
+ with support.transient_internet('www.python.org'):
+ parser = urllib.robotparser.RobotFileParser(
+ "http://www.python.org/robots.txt")
+ parser.read()
+ self.assertTrue(
+ parser.can_fetch("*", "http://www.python.org/robots.txt"))
def test_main():
support.run_unittest(NetworkTestCase)
From python-checkins at python.org Tue Sep 7 23:22:56 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 23:22:56 +0200 (CEST)
Subject: [Python-checkins] r84600 - in python/branches/release31-maint:
Lib/socket.py Lib/test/support.py
Lib/test/test_robotparser.py Lib/test/test_socket.py
Lib/test/test_ssl.py Misc/NEWS
Message-ID: <20100907212256.4EC81EE9EA@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 23:22:56 2010
New Revision: 84600
Log:
Merged revisions 84597-84599 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84597 | antoine.pitrou | 2010-09-07 22:42:19 +0200 (mar., 07 sept. 2010) | 5 lines
Issue #8574: better implementation of test.support.transient_internet().
Original patch by Victor.
........
r84598 | antoine.pitrou | 2010-09-07 23:05:49 +0200 (mar., 07 sept. 2010) | 6 lines
Issue #9792: In case of connection failure, socket.create_connection()
would swallow the exception and raise a new one, making it impossible
to fetch the original errno, or to filter timeout errors. Now the
original error is re-raised.
........
r84599 | antoine.pitrou | 2010-09-07 23:09:09 +0200 (mar., 07 sept. 2010) | 4 lines
Improve transient_internet() again to detect more network errors,
and use it in test_robotparser. Fixes #8574.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/socket.py
python/branches/release31-maint/Lib/test/support.py
python/branches/release31-maint/Lib/test/test_robotparser.py
python/branches/release31-maint/Lib/test/test_socket.py
python/branches/release31-maint/Lib/test/test_ssl.py
python/branches/release31-maint/Misc/NEWS
Modified: python/branches/release31-maint/Lib/socket.py
==============================================================================
--- python/branches/release31-maint/Lib/socket.py (original)
+++ python/branches/release31-maint/Lib/socket.py Tue Sep 7 23:22:56 2010
@@ -287,8 +287,8 @@
is used.
"""
- msg = "getaddrinfo returns an empty list"
host, port = address
+ err = None
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
af, socktype, proto, canonname, sa = res
sock = None
@@ -299,9 +299,12 @@
sock.connect(sa)
return sock
- except error as err:
- msg = err
+ except error as _:
+ err = _
if sock is not None:
sock.close()
- raise error(msg)
+ if err is not None:
+ raise err
+ else:
+ raise error("getaddrinfo returns an empty list")
Modified: python/branches/release31-maint/Lib/test/support.py
==============================================================================
--- python/branches/release31-maint/Lib/test/support.py (original)
+++ python/branches/release31-maint/Lib/test/support.py Tue Sep 7 23:22:56 2010
@@ -17,19 +17,21 @@
import importlib
import collections
-__all__ = ["Error", "TestFailed", "ResourceDenied", "import_module",
- "verbose", "use_resources", "max_memuse", "record_original_stdout",
- "get_original_stdout", "unload", "unlink", "rmtree", "forget",
- "is_resource_enabled", "requires", "find_unused_port", "bind_port",
- "fcmp", "is_jython", "TESTFN", "HOST", "FUZZ", "findfile", "verify",
- "vereq", "sortdict", "check_syntax_error", "open_urlresource",
- "check_warnings", "CleanImport", "EnvironmentVarGuard",
- "TransientResource", "captured_output", "captured_stdout",
- "time_out", "socket_peer_reset", "ioerror_peer_reset",
- "run_with_locale",
- "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner",
- "run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
- "reap_children", "cpython_only", "check_impl_detail", "get_attribute"]
+__all__ = [
+ "Error", "TestFailed", "ResourceDenied", "import_module",
+ "verbose", "use_resources", "max_memuse", "record_original_stdout",
+ "get_original_stdout", "unload", "unlink", "rmtree", "forget",
+ "is_resource_enabled", "requires", "find_unused_port", "bind_port",
+ "fcmp", "is_jython", "TESTFN", "HOST", "FUZZ", "findfile", "verify",
+ "vereq", "sortdict", "check_syntax_error", "open_urlresource",
+ "check_warnings", "CleanImport", "EnvironmentVarGuard",
+ "TransientResource", "captured_output", "captured_stdout",
+ "time_out", "socket_peer_reset", "ioerror_peer_reset",
+ "run_with_locale", "transient_internet",
+ "set_memlimit", "bigmemtest", "bigaddrspacetest", "BasicTestRunner",
+ "run_unittest", "run_doctest", "threading_setup", "threading_cleanup",
+ "reap_children", "cpython_only", "check_impl_detail", "get_attribute",
+ ]
class Error(Exception):
"""Base class for regression test exceptions."""
@@ -604,23 +606,63 @@
else:
raise ResourceDenied("an optional resource is not available")
-
# Context managers that raise ResourceDenied when various issues
# with the Internet connection manifest themselves as exceptions.
+# XXX deprecate these and use transient_internet() instead
time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
@contextlib.contextmanager
-def transient_internet():
+def transient_internet(resource_name, *, timeout=30.0, errnos=()):
"""Return a context manager that raises ResourceDenied when various issues
with the Internet connection manifest themselves as exceptions."""
- time_out = TransientResource(IOError, errno=errno.ETIMEDOUT)
- socket_peer_reset = TransientResource(socket.error, errno=errno.ECONNRESET)
- ioerror_peer_reset = TransientResource(IOError, errno=errno.ECONNRESET)
- with time_out, socket_peer_reset, ioerror_peer_reset:
+ default_errnos = [
+ ('ECONNREFUSED', 111),
+ ('ECONNRESET', 104),
+ ('ENETUNREACH', 101),
+ ('ETIMEDOUT', 110),
+ ]
+
+ denied = ResourceDenied("Resource '%s' is not available" % resource_name)
+ captured_errnos = errnos
+ if not captured_errnos:
+ captured_errnos = [getattr(errno, name, num)
+ for (name, num) in default_errnos]
+
+ def filter_error(err):
+ if (isinstance(err, socket.timeout) or
+ getattr(err, 'errno', None) in captured_errnos):
+ if not verbose:
+ sys.stderr.write(denied.args[0] + "\n")
+ raise denied from err
+
+ old_timeout = socket.getdefaulttimeout()
+ try:
+ if timeout is not None:
+ socket.setdefaulttimeout(timeout)
yield
+ except IOError as err:
+ # urllib can wrap original socket errors multiple times (!), we must
+ # unwrap to get at the original error.
+ while True:
+ a = err.args
+ if len(a) >= 1 and isinstance(a[0], IOError):
+ err = a[0]
+ # The error can also be wrapped as args[1]:
+ # except socket.error as msg:
+ # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
+ elif len(a) >= 2 and isinstance(a[1], IOError):
+ err = a[1]
+ else:
+ break
+ filter_error(err)
+ raise
+ # XXX should we catch generic exceptions and look for their
+ # __cause__ or __context__?
+ finally:
+ socket.setdefaulttimeout(old_timeout)
@contextlib.contextmanager
Modified: python/branches/release31-maint/Lib/test/test_robotparser.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_robotparser.py (original)
+++ python/branches/release31-maint/Lib/test/test_robotparser.py Tue Sep 7 23:22:56 2010
@@ -235,23 +235,24 @@
def testPasswordProtectedSite(self):
support.requires('network')
- # XXX it depends on an external resource which could be unavailable
- url = 'http://mueblesmoraleda.com'
- parser = urllib.robotparser.RobotFileParser()
- parser.set_url(url)
- try:
- parser.read()
- except URLError:
- self.skipTest('%s is unavailable' % url)
- self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)
+ with support.transient_internet('mueblesmoraleda.com'):
+ url = 'http://mueblesmoraleda.com'
+ parser = urllib.robotparser.RobotFileParser()
+ parser.set_url(url)
+ try:
+ parser.read()
+ except URLError:
+ self.skipTest('%s is unavailable' % url)
+ self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)
def testPythonOrg(self):
support.requires('network')
- parser = urllib.robotparser.RobotFileParser(
- "http://www.python.org/robots.txt")
- parser.read()
- self.assertTrue(parser.can_fetch("*",
- "http://www.python.org/robots.txt"))
+ with support.transient_internet('www.python.org'):
+ parser = urllib.robotparser.RobotFileParser(
+ "http://www.python.org/robots.txt")
+ parser.read()
+ self.assertTrue(
+ parser.can_fetch("*", "http://www.python.org/robots.txt"))
def test_main():
support.run_unittest(NetworkTestCase)
Modified: python/branches/release31-maint/Lib/test/test_socket.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_socket.py (original)
+++ python/branches/release31-maint/Lib/test/test_socket.py Tue Sep 7 23:22:56 2010
@@ -14,6 +14,7 @@
import sys
import os
import array
+import contextlib
from weakref import proxy
import signal
@@ -1026,12 +1027,48 @@
class NetworkConnectionNoServer(unittest.TestCase):
- def testWithoutServer(self):
+ class MockSocket(socket.socket):
+ def connect(self, *args):
+ raise socket.timeout('timed out')
+
+ @contextlib.contextmanager
+ def mocked_socket_module(self):
+ """Return a socket which times out on connect"""
+ old_socket = socket.socket
+ socket.socket = self.MockSocket
+ try:
+ yield
+ finally:
+ socket.socket = old_socket
+
+ def test_connect(self):
port = support.find_unused_port()
- self.assertRaises(
- socket.error,
- lambda: socket.create_connection((HOST, port))
- )
+ cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ cli.connect((HOST, port))
+ except socket.error as err:
+ self.assertEqual(err.errno, errno.ECONNREFUSED)
+ else:
+ self.fail("socket.error not raised")
+
+ def test_create_connection(self):
+ # Issue #9792: errors raised by create_connection() should have
+ # a proper errno attribute.
+ port = support.find_unused_port()
+ try:
+ socket.create_connection((HOST, port))
+ except socket.error as err:
+ self.assertEqual(err.errno, errno.ECONNREFUSED)
+ else:
+ self.fail("socket.error not raised")
+
+ def test_create_connection_timeout(self):
+ # Issue #9792: create_connection() should not recast timeout errors
+ # as generic socket errors.
+ with self.mocked_socket_module():
+ with self.assertRaises(socket.timeout):
+ socket.create_connection((HOST, 1234))
+
class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
Modified: python/branches/release31-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release31-maint/Lib/test/test_ssl.py Tue Sep 7 23:22:56 2010
@@ -218,10 +218,10 @@
# NOTE: https://sha256.tbs-internet.com is another possible test host
remote = ("sha2.hboeck.de", 443)
sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=sha256_cert,)
- with support.transient_internet():
+ with support.transient_internet("sha2.hboeck.de"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=sha256_cert,)
try:
s.connect(remote)
if support.verbose:
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Tue Sep 7 23:22:56 2010
@@ -105,6 +105,11 @@
Library
-------
+- Issue #9792: In case of connection failure, socket.create_connection()
+ would swallow the exception and raise a new one, making it impossible
+ to fetch the original errno, or to filter timeout errors. Now the
+ original error is re-raised.
+
- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
From python-checkins at python.org Tue Sep 7 23:31:18 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Tue, 7 Sep 2010 23:31:18 +0200 (CEST)
Subject: [Python-checkins] r84601 - in python/branches/py3k:
Doc/library/os.rst Doc/whatsnew/3.2.rst Lib/test/test_os.py
Misc/ACKS Misc/NEWS Modules/posixmodule.c
Message-ID: <20100907213118.2712CEEA6B@mail.python.org>
Author: amaury.forgeotdarc
Date: Tue Sep 7 23:31:17 2010
New Revision: 84601
Log:
#6394: Add os.getppid() support for Windows.
Modified:
python/branches/py3k/Doc/library/os.rst
python/branches/py3k/Doc/whatsnew/3.2.rst
python/branches/py3k/Lib/test/test_os.py
python/branches/py3k/Misc/ACKS
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/posixmodule.c
Modified: python/branches/py3k/Doc/library/os.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.rst (original)
+++ python/branches/py3k/Doc/library/os.rst Tue Sep 7 23:31:17 2010
@@ -281,10 +281,14 @@
.. index:: single: process; id of parent
- Return the parent's process id.
+ Return the parent's process id. When the parent process has exited, on Unix
+ the id returned is the one of the init process (1), on Windows it is still
+ the same id, which may be already reused by another process.
- Availability: Unix.
+ Availability: Unix, Windows
+ .. versionchanged:: 3.2
+ Added support for Windows.
.. function:: getresuid()
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Tue Sep 7 23:31:17 2010
@@ -312,6 +312,11 @@
(Patch by Adam Jackson; :issue:`7647`.)
+* :func:`os.getppid` is now supported on Windows. Note that it will continue to
+ return the same pid even after the parent process has exited.
+
+ (Patch by Jon Anglin; :issue:`6394`.)
+
* The :func:`shutil.copytree` function has two new options:
* *ignore_dangling_symlinks*: when ``symlinks=False`` so that the function
Modified: python/branches/py3k/Lib/test/test_os.py
==============================================================================
--- python/branches/py3k/Lib/test/test_os.py (original)
+++ python/branches/py3k/Lib/test/test_os.py Tue Sep 7 23:31:17 2010
@@ -1183,6 +1183,17 @@
check('iso-8859-15', b'\xef\xa4', '\xef\u20ac')
+class PidTests(unittest.TestCase):
+ @unittest.skipUnless(hasattr(os, 'getppid'), "test needs os.getppid")
+ def test_getppid(self):
+ p = subprocess.Popen([sys.executable, '-c',
+ 'import os; print(os.getppid())'],
+ stdout=subprocess.PIPE)
+ stdout, _ = p.communicate()
+ # We are the parent of our subprocess
+ self.assertEqual(int(stdout), os.getpid())
+
+
def test_main():
support.run_unittest(
FileTests,
@@ -1200,6 +1211,7 @@
Win32KillTests,
Win32SymlinkTests,
FSEncodingTests,
+ PidTests,
)
if __name__ == "__main__":
Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS (original)
+++ python/branches/py3k/Misc/ACKS Tue Sep 7 23:31:17 2010
@@ -28,6 +28,7 @@
Erik Anders?n
Oliver Andrich
Ross Andrus
+Jon Anglin
?ric Araujo
Jason Asbahr
David Ascher
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 7 23:31:17 2010
@@ -13,6 +13,10 @@
Library
-------
+- Issue #6394: os.getppid() is now supported on Windows. Note that it will
+ still return the id of the parent process after it has exited. This process
+ id may even have been reused by another unrelated process.
+
- Issue #9792: In case of connection failure, socket.create_connection()
would swallow the exception and raise a new one, making it impossible
to fetch the original errno, or to filter timeout errors. Now the
Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Tue Sep 7 23:31:17 2010
@@ -121,6 +121,7 @@
#else
#ifdef _MSC_VER /* Microsoft compiler */
#define HAVE_GETCWD 1
+#define HAVE_GETPPID 1
#define HAVE_SPAWNV 1
#define HAVE_EXECV 1
#define HAVE_PIPE 1
@@ -4363,16 +4364,65 @@
#endif /* HAVE_SETPGRP */
#ifdef HAVE_GETPPID
+
+#ifdef MS_WINDOWS
+#include
+
+static PyObject*
+win32_getppid()
+{
+ HANDLE snapshot;
+ pid_t mypid;
+ PyObject* result = NULL;
+ BOOL have_record;
+ PROCESSENTRY32 pe;
+
+ mypid = getpid(); /* This function never fails */
+
+ snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (snapshot == INVALID_HANDLE_VALUE)
+ return PyErr_SetFromWindowsErr(GetLastError());
+
+ pe.dwSize = sizeof(pe);
+ have_record = Process32First(snapshot, &pe);
+ while (have_record) {
+ if (mypid == (pid_t)pe.th32ProcessID) {
+ /* We could cache the ulong value in a static variable. */
+ result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
+ break;
+ }
+
+ have_record = Process32Next(snapshot, &pe);
+ }
+
+ /* If our loop exits and our pid was not found (result will be NULL)
+ * then GetLastError will return ERROR_NO_MORE_FILES. This is an
+ * error anyway, so let's raise it. */
+ if (!result)
+ result = PyErr_SetFromWindowsErr(GetLastError());
+
+ CloseHandle(snapshot);
+
+ return result;
+}
+#endif /*MS_WINDOWS*/
+
PyDoc_STRVAR(posix_getppid__doc__,
"getppid() -> ppid\n\n\
-Return the parent's process id.");
+Return the parent's process id. If the parent process has already exited,\n\
+Windows machines will still return its id; others systems will return the id\n\
+of the 'init' process (1).");
static PyObject *
posix_getppid(PyObject *self, PyObject *noargs)
{
+#ifdef MS_WINDOWS
+ return win32_getppid();
+#else
return PyLong_FromPid(getppid());
-}
#endif
+}
+#endif /* HAVE_GETPPID */
#ifdef HAVE_GETLOGIN
From python-checkins at python.org Tue Sep 7 23:35:36 2010
From: python-checkins at python.org (eric.araujo)
Date: Tue, 7 Sep 2010 23:35:36 +0200 (CEST)
Subject: [Python-checkins] r84602 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100907213536.21969EEA5A@mail.python.org>
Author: eric.araujo
Date: Tue Sep 7 23:35:35 2010
New Revision: 84602
Log:
Fix typo in whatsnew (#9793)
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Tue Sep 7 23:35:35 2010
@@ -194,7 +194,7 @@
by calling :func:`getattr` and throwing away the results. This is necessary
because dynamic attribute creation is possible using :meth:`__getattribute__`
or :meth:`__getattr__`. If :func:`hasattr` were to just scan instance and class
- dictionaries it would miss the dynmaic methods and make it difficult to
+ dictionaries it would miss the dynamic methods and make it difficult to
implement proxy objects.
(Discovered by Yury Selivanov and fixed by Benjamin Peterson; :issue:`9666`.)
From python-checkins at python.org Tue Sep 7 23:40:25 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 23:40:25 +0200 (CEST)
Subject: [Python-checkins] r84603 - in python/branches/release27-maint:
Lib/socket.py Lib/test/test_robotparser.py
Lib/test/test_socket.py Lib/test/test_ssl.py
Lib/test/test_support.py Lib/test/test_urllib2net.py Misc/NEWS
Message-ID: <20100907214025.CF06CEEA51@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 23:40:25 2010
New Revision: 84603
Log:
Merged revisions 84597-84599 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84597 | antoine.pitrou | 2010-09-07 22:42:19 +0200 (mar., 07 sept. 2010) | 5 lines
Issue #8574: better implementation of test.support.transient_internet().
Original patch by Victor.
........
r84598 | antoine.pitrou | 2010-09-07 23:05:49 +0200 (mar., 07 sept. 2010) | 6 lines
Issue #9792: In case of connection failure, socket.create_connection()
would swallow the exception and raise a new one, making it impossible
to fetch the original errno, or to filter timeout errors. Now the
original error is re-raised.
........
r84599 | antoine.pitrou | 2010-09-07 23:09:09 +0200 (mar., 07 sept. 2010) | 4 lines
Improve transient_internet() again to detect more network errors,
and use it in test_robotparser. Fixes #8574.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/socket.py
python/branches/release27-maint/Lib/test/test_robotparser.py
python/branches/release27-maint/Lib/test/test_socket.py
python/branches/release27-maint/Lib/test/test_ssl.py
python/branches/release27-maint/Lib/test/test_support.py
python/branches/release27-maint/Lib/test/test_urllib2net.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/socket.py
==============================================================================
--- python/branches/release27-maint/Lib/socket.py (original)
+++ python/branches/release27-maint/Lib/socket.py Tue Sep 7 23:40:25 2010
@@ -548,8 +548,8 @@
An host of '' or port 0 tells the OS to use the default.
"""
- msg = "getaddrinfo returns an empty list"
host, port = address
+ err = None
for res in getaddrinfo(host, port, 0, SOCK_STREAM):
af, socktype, proto, canonname, sa = res
sock = None
@@ -562,8 +562,12 @@
sock.connect(sa)
return sock
- except error, msg:
+ except error as _:
+ err = _
if sock is not None:
sock.close()
- raise error, msg
+ if err is not None:
+ raise err
+ else:
+ raise error("getaddrinfo returns an empty list")
Modified: python/branches/release27-maint/Lib/test/test_robotparser.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_robotparser.py (original)
+++ python/branches/release27-maint/Lib/test/test_robotparser.py Tue Sep 7 23:40:25 2010
@@ -232,23 +232,24 @@
def testPasswordProtectedSite(self):
test_support.requires('network')
- # XXX it depends on an external resource which could be unavailable
- url = 'http://mueblesmoraleda.com'
- parser = robotparser.RobotFileParser()
- parser.set_url(url)
- try:
- parser.read()
- except IOError:
- self.skipTest('%s is unavailable' % url)
- self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)
+ with test_support.transient_internet('mueblesmoraleda.com'):
+ url = 'http://mueblesmoraleda.com'
+ parser = robotparser.RobotFileParser()
+ parser.set_url(url)
+ try:
+ parser.read()
+ except IOError:
+ self.skipTest('%s is unavailable' % url)
+ self.assertEqual(parser.can_fetch("*", url+"/robots.txt"), False)
def testPythonOrg(self):
test_support.requires('network')
- parser = robotparser.RobotFileParser(
- "http://www.python.org/robots.txt")
- parser.read()
- self.assertTrue(parser.can_fetch("*",
- "http://www.python.org/robots.txt"))
+ with test_support.transient_internet('www.python.org'):
+ parser = robotparser.RobotFileParser(
+ "http://www.python.org/robots.txt")
+ parser.read()
+ self.assertTrue(
+ parser.can_fetch("*", "http://www.python.org/robots.txt"))
def test_main():
Modified: python/branches/release27-maint/Lib/test/test_socket.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_socket.py (original)
+++ python/branches/release27-maint/Lib/test/test_socket.py Tue Sep 7 23:40:25 2010
@@ -12,6 +12,7 @@
import sys
import os
import array
+import contextlib
from weakref import proxy
import signal
@@ -1048,12 +1049,42 @@
"""
class NetworkConnectionNoServer(unittest.TestCase):
- def testWithoutServer(self):
+ class MockSocket(socket.socket):
+ def connect(self, *args):
+ raise socket.timeout('timed out')
+
+ @contextlib.contextmanager
+ def mocked_socket_module(self):
+ """Return a socket which times out on connect"""
+ old_socket = socket.socket
+ socket.socket = self.MockSocket
+ try:
+ yield
+ finally:
+ socket.socket = old_socket
+
+ def test_connect(self):
port = test_support.find_unused_port()
- self.assertRaises(
- socket.error,
- lambda: socket.create_connection((HOST, port))
- )
+ cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ with self.assertRaises(socket.error) as cm:
+ cli.connect((HOST, port))
+ self.assertEqual(cm.exception.errno, errno.ECONNREFUSED)
+
+ def test_create_connection(self):
+ # Issue #9792: errors raised by create_connection() should have
+ # a proper errno attribute.
+ port = test_support.find_unused_port()
+ with self.assertRaises(socket.error) as cm:
+ socket.create_connection((HOST, port))
+ self.assertEqual(cm.exception.errno, errno.ECONNREFUSED)
+
+ def test_create_connection_timeout(self):
+ # Issue #9792: create_connection() should not recast timeout errors
+ # as generic socket errors.
+ with self.mocked_socket_module():
+ with self.assertRaises(socket.timeout):
+ socket.create_connection((HOST, 1234))
+
@unittest.skipUnless(thread, 'Threading required for this test.')
class NetworkConnectionAttributesTest(SocketTCPTest, ThreadableTest):
Modified: python/branches/release27-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release27-maint/Lib/test/test_ssl.py Tue Sep 7 23:40:25 2010
@@ -287,10 +287,10 @@
# NOTE: https://sha256.tbs-internet.com is another possible test host
remote = ("sha2.hboeck.de", 443)
sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=sha256_cert,)
- with test_support.transient_internet():
+ with test_support.transient_internet("sha2.hboeck.de"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=sha256_cert,)
try:
s.connect(remote)
if test_support.verbose:
Modified: python/branches/release27-maint/Lib/test/test_support.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_support.py (original)
+++ python/branches/release27-maint/Lib/test/test_support.py Tue Sep 7 23:40:25 2010
@@ -750,32 +750,55 @@
raise ResourceDenied("an optional resource is not available")
-_transients = {
- IOError: (errno.ECONNRESET, errno.ETIMEDOUT),
- socket.error: (errno.ECONNRESET,),
- socket.gaierror: [getattr(socket, t)
- for t in ('EAI_NODATA', 'EAI_NONAME')
- if hasattr(socket, t)],
- }
@contextlib.contextmanager
-def transient_internet():
+def transient_internet(resource_name, timeout=30.0, errnos=()):
"""Return a context manager that raises ResourceDenied when various issues
- with the Internet connection manifest themselves as exceptions.
+ with the Internet connection manifest themselves as exceptions."""
+ default_errnos = [
+ ('ECONNREFUSED', 111),
+ ('ECONNRESET', 104),
+ ('ENETUNREACH', 101),
+ ('ETIMEDOUT', 110),
+ ]
+
+ denied = ResourceDenied("Resource '%s' is not available" % resource_name)
+ captured_errnos = errnos
+ if not captured_errnos:
+ captured_errnos = [getattr(errno, name, num)
+ for (name, num) in default_errnos]
+
+ def filter_error(err):
+ if (isinstance(err, socket.timeout) or
+ getattr(err, 'errno', None) in captured_errnos):
+ if not verbose:
+ sys.stderr.write(denied.args[0] + "\n")
+ raise denied
- Errors caught:
- timeout IOError errno = ETIMEDOUT
- socket reset socket.error, IOError errno = ECONNRESET
- dns no data socket.gaierror errno = EAI_NODATA
- dns no name socket.gaierror errno = EAI_NONAME
- """
+ old_timeout = socket.getdefaulttimeout()
try:
+ if timeout is not None:
+ socket.setdefaulttimeout(timeout)
yield
- except tuple(_transients) as err:
- for errtype in _transients:
- if isinstance(err, errtype) and err.errno in _transients[errtype]:
- raise ResourceDenied("could not establish network "
- "connection ({})".format(err))
+ except IOError as err:
+ # urllib can wrap original socket errors multiple times (!), we must
+ # unwrap to get at the original error.
+ while True:
+ a = err.args
+ if len(a) >= 1 and isinstance(a[0], IOError):
+ err = a[0]
+ # The error can also be wrapped as args[1]:
+ # except socket.error as msg:
+ # raise IOError('socket error', msg).with_traceback(sys.exc_info()[2])
+ elif len(a) >= 2 and isinstance(a[1], IOError):
+ err = a[1]
+ else:
+ break
+ filter_error(err)
raise
+ # XXX should we catch generic exceptions and look for their
+ # __cause__ or __context__?
+ finally:
+ socket.setdefaulttimeout(old_timeout)
@contextlib.contextmanager
Modified: python/branches/release27-maint/Lib/test/test_urllib2net.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_urllib2net.py (original)
+++ python/branches/release27-maint/Lib/test/test_urllib2net.py Tue Sep 7 23:40:25 2010
@@ -192,7 +192,7 @@
raise
else:
try:
- with test_support.transient_internet():
+ with test_support.transient_internet(url):
buf = f.read()
debug("read %d bytes" % len(buf))
except socket.timeout:
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Tue Sep 7 23:40:25 2010
@@ -36,6 +36,11 @@
Library
-------
+- Issue #9792: In case of connection failure, socket.create_connection()
+ would swallow the exception and raise a new one, making it impossible
+ to fetch the original errno, or to filter timeout errors. Now the
+ original error is re-raised.
+
- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
From python-checkins at python.org Tue Sep 7 23:43:31 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 23:43:31 +0200 (CEST)
Subject: [Python-checkins] r84604 - python/branches/py3k/Lib/test/support.py
Message-ID: <20100907214331.C67B7EEA64@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 23:43:31 2010
New Revision: 84604
Log:
Also catch some gaierrors
Modified:
python/branches/py3k/Lib/test/support.py
Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py (original)
+++ python/branches/py3k/Lib/test/support.py Tue Sep 7 23:43:31 2010
@@ -793,16 +793,25 @@
('ENETUNREACH', 101),
('ETIMEDOUT', 110),
]
+ default_gai_errnos = [
+ ('EAI_NONAME', -2),
+ ('EAI_NODATA', -5),
+ ]
denied = ResourceDenied("Resource '%s' is not available" % resource_name)
captured_errnos = errnos
+ gai_errnos = []
if not captured_errnos:
captured_errnos = [getattr(errno, name, num)
for (name, num) in default_errnos]
+ gai_errnos = [getattr(socket, name, num)
+ for (name, num) in default_gai_errnos]
def filter_error(err):
+ n = getattr(err, 'errno', None)
if (isinstance(err, socket.timeout) or
- getattr(err, 'errno', None) in captured_errnos):
+ (isinstance(err, socket.gaierror) and n in gai_errnos) or
+ n in captured_errnos):
if not verbose:
sys.stderr.write(denied.args[0] + "\n")
raise denied from err
From python-checkins at python.org Tue Sep 7 23:44:17 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 23:44:17 +0200 (CEST)
Subject: [Python-checkins] r84605 - in python/branches/release31-maint:
Lib/test/support.py
Message-ID: <20100907214417.3EEACEEA66@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 23:44:17 2010
New Revision: 84605
Log:
Merged revisions 84604 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84604 | antoine.pitrou | 2010-09-07 23:43:31 +0200 (mar., 07 sept. 2010) | 3 lines
Also catch some gaierrors
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/support.py
Modified: python/branches/release31-maint/Lib/test/support.py
==============================================================================
--- python/branches/release31-maint/Lib/test/support.py (original)
+++ python/branches/release31-maint/Lib/test/support.py Tue Sep 7 23:44:17 2010
@@ -624,16 +624,25 @@
('ENETUNREACH', 101),
('ETIMEDOUT', 110),
]
+ default_gai_errnos = [
+ ('EAI_NONAME', -2),
+ ('EAI_NODATA', -5),
+ ]
denied = ResourceDenied("Resource '%s' is not available" % resource_name)
captured_errnos = errnos
+ gai_errnos = []
if not captured_errnos:
captured_errnos = [getattr(errno, name, num)
for (name, num) in default_errnos]
+ gai_errnos = [getattr(socket, name, num)
+ for (name, num) in default_gai_errnos]
def filter_error(err):
+ n = getattr(err, 'errno', None)
if (isinstance(err, socket.timeout) or
- getattr(err, 'errno', None) in captured_errnos):
+ (isinstance(err, socket.gaierror) and n in gai_errnos) or
+ n in captured_errnos):
if not verbose:
sys.stderr.write(denied.args[0] + "\n")
raise denied from err
From python-checkins at python.org Tue Sep 7 23:46:05 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 7 Sep 2010 23:46:05 +0200 (CEST)
Subject: [Python-checkins] r84606 - in python/branches/release27-maint:
Lib/test/test_support.py
Message-ID: <20100907214605.A3C6DEEA66@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 7 23:46:05 2010
New Revision: 84606
Log:
Merged revisions 84604 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84604 | antoine.pitrou | 2010-09-07 23:43:31 +0200 (mar., 07 sept. 2010) | 3 lines
Also catch some gaierrors
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_support.py
Modified: python/branches/release27-maint/Lib/test/test_support.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_support.py (original)
+++ python/branches/release27-maint/Lib/test/test_support.py Tue Sep 7 23:46:05 2010
@@ -760,16 +760,25 @@
('ENETUNREACH', 101),
('ETIMEDOUT', 110),
]
+ default_gai_errnos = [
+ ('EAI_NONAME', -2),
+ ('EAI_NODATA', -5),
+ ]
denied = ResourceDenied("Resource '%s' is not available" % resource_name)
captured_errnos = errnos
+ gai_errnos = []
if not captured_errnos:
captured_errnos = [getattr(errno, name, num)
for (name, num) in default_errnos]
+ gai_errnos = [getattr(socket, name, num)
+ for (name, num) in default_gai_errnos]
def filter_error(err):
+ n = getattr(err, 'errno', None)
if (isinstance(err, socket.timeout) or
- getattr(err, 'errno', None) in captured_errnos):
+ (isinstance(err, socket.gaierror) and n in gai_errnos) or
+ n in captured_errnos):
if not verbose:
sys.stderr.write(denied.args[0] + "\n")
raise denied
From barry at python.org Tue Sep 7 23:58:04 2010
From: barry at python.org (Barry Warsaw)
Date: Tue, 7 Sep 2010 17:58:04 -0400
Subject: [Python-checkins] r84536 - sandbox/trunk/release/release.py
In-Reply-To: <20100905182846.4E3DAEEA02@mail.python.org>
References: <20100905182846.4E3DAEEA02@mail.python.org>
Message-ID: <20100907175804.1eba70d7@mission>
On Sep 05, 2010, at 08:28 PM, georg.brandl wrote:
>Author: georg.brandl
>Date: Sun Sep 5 20:28:46 2010
>New Revision: 84536
>
>Log:
>Fix after changing NEWS layout.
>
>Modified:
> sandbox/trunk/release/release.py
>
>Modified: sandbox/trunk/release/release.py
>==============================================================================
>--- sandbox/trunk/release/release.py (original)
>+++ sandbox/trunk/release/release.py Sun Sep 5 20:28:46 2010
>@@ -396,13 +396,13 @@
> with open('Misc/NEWS', encoding="utf-8") as fp:
> lines = fp.readlines()
> for i, line in enumerate(lines):
>- if line.startswith("(editors"):
>+ if line.startswith("Python News"):
> start = i
> if line.startswith("What's"):
> end = i
> break
> with open('Misc/NEWS', 'w', encoding="utf-8") as fp:
>- fp.writelines(lines[:start+1])
>+ fp.writelines(lines[:start+2])
> fp.write(NEWS_TEMPLATE)
> fp.writelines(lines[end-1:])
> print("Please fill in the the name of the next version.")
Will this still work with the Python 2.7 NEWS file?
-Barry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL:
From python-checkins at python.org Wed Sep 8 00:06:17 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 00:06:17 +0200 (CEST)
Subject: [Python-checkins] r84607 - in python/branches/py3k:
Lib/_threading_local.py Lib/test/test_threading_local.py Misc/NEWS
Message-ID: <20100907220617.E2FC8EEA31@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 00:06:17 2010
New Revision: 84607
Log:
Issue #9707: Rewritten reference implementation of threading.local which
is friendlier towards reference cycles. This change is not normally
visible since an optimized C implementation (_thread._local) is used
instead.
Modified:
python/branches/py3k/Lib/_threading_local.py
python/branches/py3k/Lib/test/test_threading_local.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/_threading_local.py
==============================================================================
--- python/branches/py3k/Lib/_threading_local.py (original)
+++ python/branches/py3k/Lib/_threading_local.py Wed Sep 8 00:06:17 2010
@@ -132,6 +132,9 @@
>>> del mydata
"""
+from weakref import ref
+from contextlib import contextmanager
+
__all__ = ["local"]
# We need to use objects from the threading module, but the threading
@@ -139,112 +142,105 @@
# isn't compiled in to the `thread` module. This creates potential problems
# with circular imports. For that reason, we don't import `threading`
# until the bottom of this file (a hack sufficient to worm around the
-# potential problems). Note that almost all platforms do have support for
-# locals in the `thread` module, and there is no circular import problem
+# potential problems). Note that all platforms on CPython do have support
+# for locals in the `thread` module, and there is no circular import problem
# then, so problems introduced by fiddling the order of imports here won't
-# manifest on most boxes.
+# manifest.
-class _localbase(object):
- __slots__ = '_local__key', '_local__args', '_local__lock'
+class _localimpl:
+ """A class managing thread-local dicts"""
+ __slots__ = 'key', 'dicts', 'localargs', 'locallock', '__weakref__'
+
+ def __init__(self):
+ # The key used in the Thread objects' attribute dicts.
+ # We keep it a string for speed but make it unlikely to clash with
+ # a "real" attribute.
+ self.key = '_threading_local._localimpl.' + str(id(self))
+ # { id(Thread) -> (ref(Thread), thread-local dict) }
+ self.dicts = {}
+
+ def get_dict(self):
+ """Return the dict for the current thread. Raises KeyError if none
+ defined."""
+ thread = current_thread()
+ return self.dicts[id(thread)][1]
+
+ def create_dict(self):
+ """Create a new dict for the current thread, and return it."""
+ localdict = {}
+ key = self.key
+ thread = current_thread()
+ idt = id(thread)
+ def local_deleted(_, key=key):
+ # When the localimpl is deleted, remove the thread attribute.
+ thread = wrthread()
+ if thread is not None:
+ del thread.__dict__[key]
+ def thread_deleted(_, idt=idt):
+ # When the thread is deleted, remove the local dict.
+ # Note that this is suboptimal if the thread object gets
+ # caught in a reference loop. We would like to be called
+ # as soon as the OS-level thread ends instead.
+ local = wrlocal()
+ if local is not None:
+ dct = local.dicts.pop(idt)
+ wrlocal = ref(self, local_deleted)
+ wrthread = ref(thread, thread_deleted)
+ thread.__dict__[key] = wrlocal
+ self.dicts[idt] = wrthread, localdict
+ return localdict
+
+
+ at contextmanager
+def _patch(self):
+ impl = object.__getattribute__(self, '_local__impl')
+ try:
+ dct = impl.get_dict()
+ except KeyError:
+ dct = impl.create_dict()
+ args, kw = impl.localargs
+ self.__init__(*args, **kw)
+ with impl.locallock:
+ object.__setattr__(self, '__dict__', dct)
+ yield
- def __new__(cls, *args, **kw):
- self = object.__new__(cls)
- key = '_local__key', 'thread.local.' + str(id(self))
- object.__setattr__(self, '_local__key', key)
- object.__setattr__(self, '_local__args', (args, kw))
- object.__setattr__(self, '_local__lock', RLock())
+class local:
+ __slots__ = '_local__impl', '__dict__'
+
+ def __new__(cls, *args, **kw):
if (args or kw) and (cls.__init__ is object.__init__):
raise TypeError("Initialization arguments are not supported")
-
+ self = object.__new__(cls)
+ impl = _localimpl()
+ impl.localargs = (args, kw)
+ impl.locallock = RLock()
+ object.__setattr__(self, '_local__impl', impl)
# We need to create the thread dict in anticipation of
# __init__ being called, to make sure we don't call it
# again ourselves.
- dict = object.__getattribute__(self, '__dict__')
- current_thread().__dict__[key] = dict
-
+ impl.create_dict()
return self
-def _patch(self):
- key = object.__getattribute__(self, '_local__key')
- d = current_thread().__dict__.get(key)
- if d is None:
- d = {}
- current_thread().__dict__[key] = d
- object.__setattr__(self, '__dict__', d)
-
- # we have a new instance dict, so call out __init__ if we have
- # one
- cls = type(self)
- if cls.__init__ is not object.__init__:
- args, kw = object.__getattribute__(self, '_local__args')
- cls.__init__(self, *args, **kw)
- else:
- object.__setattr__(self, '__dict__', d)
-
-class local(_localbase):
-
def __getattribute__(self, name):
- lock = object.__getattribute__(self, '_local__lock')
- lock.acquire()
- try:
- _patch(self)
+ with _patch(self):
return object.__getattribute__(self, name)
- finally:
- lock.release()
def __setattr__(self, name, value):
if name == '__dict__':
raise AttributeError(
"%r object attribute '__dict__' is read-only"
% self.__class__.__name__)
- lock = object.__getattribute__(self, '_local__lock')
- lock.acquire()
- try:
- _patch(self)
+ with _patch(self):
return object.__setattr__(self, name, value)
- finally:
- lock.release()
def __delattr__(self, name):
if name == '__dict__':
raise AttributeError(
"%r object attribute '__dict__' is read-only"
% self.__class__.__name__)
- lock = object.__getattribute__(self, '_local__lock')
- lock.acquire()
- try:
- _patch(self)
+ with _patch(self):
return object.__delattr__(self, name)
- finally:
- lock.release()
-
- def __del__(self):
- import threading
-
- key = object.__getattribute__(self, '_local__key')
- try:
- # We use the non-locking API since we might already hold the lock
- # (__del__ can be called at any point by the cyclic GC).
- threads = threading._enumerate()
- except:
- # If enumerating the current threads fails, as it seems to do
- # during shutdown, we'll skip cleanup under the assumption
- # that there is nothing to clean up.
- return
-
- for thread in threads:
- try:
- __dict__ = thread.__dict__
- except AttributeError:
- # Thread is dying, rest in peace.
- continue
-
- if key in __dict__:
- try:
- del __dict__[key]
- except KeyError:
- pass # didn't have anything in this thread
from threading import current_thread, RLock
Modified: python/branches/py3k/Lib/test/test_threading_local.py
==============================================================================
--- python/branches/py3k/Lib/test/test_threading_local.py (original)
+++ python/branches/py3k/Lib/test/test_threading_local.py Wed Sep 8 00:06:17 2010
@@ -184,11 +184,6 @@
"""To test that subclasses behave properly."""
self._test_dict_attribute(LocalSubclass)
-
-class ThreadLocalTest(unittest.TestCase, BaseLocalTest):
- _local = _thread._local
-
- # Fails for the pure Python implementation
def test_cycle_collection(self):
class X:
pass
@@ -201,6 +196,10 @@
gc.collect()
self.assertIs(wr(), None)
+
+class ThreadLocalTest(unittest.TestCase, BaseLocalTest):
+ _local = _thread._local
+
class PyThreadingLocalTest(unittest.TestCase, BaseLocalTest):
_local = _threading_local.local
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 8 00:06:17 2010
@@ -13,6 +13,11 @@
Library
-------
+- Issue #9707: Rewritten reference implementation of threading.local which
+ is friendlier towards reference cycles. This change is not normally
+ visible since an optimized C implementation (_thread._local) is used
+ instead.
+
- Issue #6394: os.getppid() is now supported on Windows. Note that it will
still return the id of the parent process after it has exited. This process
id may even have been reused by another unrelated process.
From python-checkins at python.org Wed Sep 8 00:11:52 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 00:11:52 +0200 (CEST)
Subject: [Python-checkins] r84608 -
python/branches/py3k/Lib/distutils/command/build_clib.py
Message-ID: <20100907221152.A9BA1EEA5A@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 00:11:52 2010
New Revision: 84608
Log:
Fix eon-old bug in build_clib options (#1718574)
Modified:
python/branches/py3k/Lib/distutils/command/build_clib.py
Modified: python/branches/py3k/Lib/distutils/command/build_clib.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/build_clib.py (original)
+++ python/branches/py3k/Lib/distutils/command/build_clib.py Wed Sep 8 00:11:52 2010
@@ -32,9 +32,9 @@
description = "build C/C++ libraries used by Python extensions"
user_options = [
- ('build-clib', 'b',
+ ('build-clib=', 'b',
"directory to build C/C++ libraries to"),
- ('build-temp', 't',
+ ('build-temp=', 't',
"directory to put temporary build by-products"),
('debug', 'g',
"compile with debugging information"),
From python-checkins at python.org Wed Sep 8 00:17:04 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 00:17:04 +0200 (CEST)
Subject: [Python-checkins] r84609 - in python/branches/release31-maint:
Lib/distutils/command/build_clib.py
Message-ID: <20100907221704.75535F9E4@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 00:17:04 2010
New Revision: 84609
Log:
Merged revisions 84608 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84608 | eric.araujo | 2010-09-08 00:11:52 +0200 (mer., 08 sept. 2010) | 2 lines
Fix eon-old bug in build_clib options (#1718574)
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/distutils/command/build_clib.py
Modified: python/branches/release31-maint/Lib/distutils/command/build_clib.py
==============================================================================
--- python/branches/release31-maint/Lib/distutils/command/build_clib.py (original)
+++ python/branches/release31-maint/Lib/distutils/command/build_clib.py Wed Sep 8 00:17:04 2010
@@ -32,9 +32,9 @@
description = "build C/C++ libraries used by Python extensions"
user_options = [
- ('build-clib', 'b',
+ ('build-clib=', 'b',
"directory to build C/C++ libraries to"),
- ('build-temp', 't',
+ ('build-temp=', 't',
"directory to put temporary build by-products"),
('debug', 'g',
"compile with debugging information"),
From ncoghlan at gmail.com Wed Sep 8 00:09:13 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Wed, 8 Sep 2010 08:09:13 +1000
Subject: [Python-checkins] [Python-Dev] r84562 - in
python/branches/py3k: Doc/library/io.rst Lib/_pyio.py
Lib/test/test_memoryio.py Misc/NEWS Modules/_io/_iomodule.c
Modules/_io/_iomodule.h Modules/_io/bytesio.c
In-Reply-To:
References: <20100906184822.26A92FA6F@mail.python.org>
Message-ID:
On Wed, Sep 8, 2010 at 3:39 AM, Benjamin Peterson wrote:
> 2010/9/7 Nick Coghlan :
>> I've raised an RFE (http://bugs.python.org/issue9789) to point out
>> that the need for that GC collect call in there to make the test
>> portable to other implementations is rather ugly
>
> Why? You're testing garbage collection, so you should call garbage collection.
Having that test *as well* as a specific release test (to check
implicit as well as explicit release) is a different story (we do that
for generators, files and assorted other things). Having forced GC
invocation be the only way to do explicit release is the part I found
ugly.
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From python-checkins at python.org Wed Sep 8 00:18:34 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 00:18:34 +0200 (CEST)
Subject: [Python-checkins] r84610 - in python/branches/release27-maint:
Lib/distutils/command/build_clib.py
Message-ID: <20100907221834.560C8EEA81@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 00:18:34 2010
New Revision: 84610
Log:
Merged revisions 84608 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84608 | eric.araujo | 2010-09-08 00:11:52 +0200 (mer., 08 sept. 2010) | 2 lines
Fix eon-old bug in build_clib options (#1718574)
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/distutils/command/build_clib.py
Modified: python/branches/release27-maint/Lib/distutils/command/build_clib.py
==============================================================================
--- python/branches/release27-maint/Lib/distutils/command/build_clib.py (original)
+++ python/branches/release27-maint/Lib/distutils/command/build_clib.py Wed Sep 8 00:18:34 2010
@@ -32,9 +32,9 @@
description = "build C/C++ libraries used by Python extensions"
user_options = [
- ('build-clib', 'b',
+ ('build-clib=', 'b',
"directory to build C/C++ libraries to"),
- ('build-temp', 't',
+ ('build-temp=', 't',
"directory to put temporary build by-products"),
('debug', 'g',
"compile with debugging information"),
From python-checkins at python.org Wed Sep 8 01:08:57 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 01:08:57 +0200 (CEST)
Subject: [Python-checkins] r84611 -
python/branches/py3k/Lib/distutils/command/upload.py
Message-ID: <20100907230857.EA997EEA82@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 01:08:57 2010
New Revision: 84611
Log:
Fix incorrect use of Command.announce (#9199)
Modified:
python/branches/py3k/Lib/distutils/command/upload.py
Modified: python/branches/py3k/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/upload.py (original)
+++ python/branches/py3k/Lib/distutils/command/upload.py Wed Sep 8 01:08:57 2010
@@ -194,4 +194,5 @@
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
if self.show_response:
- self.announce('-'*75, r.read(), '-'*75)
+ msg = ''.join('-' * 75, r.read(), '-' * 75)
+ self.announce(msg, log.INFO)
From python-checkins at python.org Wed Sep 8 01:09:45 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 01:09:45 +0200 (CEST)
Subject: [Python-checkins] r84612 - in python/branches/release31-maint:
Lib/distutils/command/upload.py
Message-ID: <20100907230945.04B81EEA0D@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 01:09:44 2010
New Revision: 84612
Log:
Merged revisions 84611 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84611 | eric.araujo | 2010-09-08 01:08:57 +0200 (mer., 08 sept. 2010) | 2 lines
Fix incorrect use of Command.announce (#9199)
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/distutils/command/upload.py
Modified: python/branches/release31-maint/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/release31-maint/Lib/distutils/command/upload.py (original)
+++ python/branches/release31-maint/Lib/distutils/command/upload.py Wed Sep 8 01:09:44 2010
@@ -194,4 +194,5 @@
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
if self.show_response:
- self.announce('-'*75, r.read(), '-'*75)
+ msg = ''.join('-' * 75, r.read(), '-' * 75)
+ self.announce(msg, log.INFO)
From python-checkins at python.org Wed Sep 8 01:12:59 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 01:12:59 +0200 (CEST)
Subject: [Python-checkins] r84613 - in python/branches/release27-maint:
Lib/distutils/command/upload.py
Message-ID: <20100907231259.C8530EEAA2@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 01:12:59 2010
New Revision: 84613
Log:
Merged revisions 84611 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84611 | eric.araujo | 2010-09-08 01:08:57 +0200 (mer., 08 sept. 2010) | 2 lines
Fix incorrect use of Command.announce (#9199)
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/distutils/command/upload.py
Modified: python/branches/release27-maint/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/release27-maint/Lib/distutils/command/upload.py (original)
+++ python/branches/release27-maint/Lib/distutils/command/upload.py Wed Sep 8 01:12:59 2010
@@ -186,4 +186,5 @@
self.announce('Upload failed (%s): %s' % (status, reason),
log.ERROR)
if self.show_response:
- self.announce('-'*75, result.read(), '-'*75)
+ msg = ''.join('-' * 75, r.read(), '-' * 75)
+ self.announce(msg, log.INFO)
From python-checkins at python.org Wed Sep 8 02:00:45 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 02:00:45 +0200 (CEST)
Subject: [Python-checkins] r84614 -
python/branches/py3k/Lib/distutils/command/upload.py
Message-ID: <20100908000045.C3192EE9B8@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 02:00:45 2010
New Revision: 84614
Log:
Follow-up to #9199: Fix str.join use, add newlines.
Thanks to Konrad Delong for writing a test for upload_docs
--show-response in distutils2, letting me catch my mistake.
Modified:
python/branches/py3k/Lib/distutils/command/upload.py
Modified: python/branches/py3k/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/upload.py (original)
+++ python/branches/py3k/Lib/distutils/command/upload.py Wed Sep 8 02:00:45 2010
@@ -194,5 +194,5 @@
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
if self.show_response:
- msg = ''.join('-' * 75, r.read(), '-' * 75)
+ msg = '\n'.join(('-' * 75, r.read(), '-' * 75))
self.announce(msg, log.INFO)
From python-checkins at python.org Wed Sep 8 02:02:01 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 02:02:01 +0200 (CEST)
Subject: [Python-checkins] r84615 - in python/branches/release31-maint:
Lib/distutils/command/upload.py
Message-ID: <20100908000201.05B76E0E8@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 02:02:00 2010
New Revision: 84615
Log:
Merged revisions 84614 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84614 | eric.araujo | 2010-09-08 02:00:45 +0200 (mer., 08 sept. 2010) | 5 lines
Follow-up to #9199: Fix str.join use, add newlines.
Thanks to Konrad Delong for writing a test for upload_docs
--show-response in distutils2, letting me catch my mistake.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/distutils/command/upload.py
Modified: python/branches/release31-maint/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/release31-maint/Lib/distutils/command/upload.py (original)
+++ python/branches/release31-maint/Lib/distutils/command/upload.py Wed Sep 8 02:02:00 2010
@@ -194,5 +194,5 @@
self.announce('Upload failed (%s): %s' % (r.status, r.reason),
log.ERROR)
if self.show_response:
- msg = ''.join('-' * 75, r.read(), '-' * 75)
+ msg = '\n'.join(('-' * 75, r.read(), '-' * 75))
self.announce(msg, log.INFO)
From python-checkins at python.org Wed Sep 8 02:02:29 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 02:02:29 +0200 (CEST)
Subject: [Python-checkins] r84616 - in python/branches/release27-maint:
Lib/distutils/command/upload.py
Message-ID: <20100908000229.67204E0E8@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 02:02:29 2010
New Revision: 84616
Log:
Merged revisions 84614 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84614 | eric.araujo | 2010-09-08 02:00:45 +0200 (mer., 08 sept. 2010) | 5 lines
Follow-up to #9199: Fix str.join use, add newlines.
Thanks to Konrad Delong for writing a test for upload_docs
--show-response in distutils2, letting me catch my mistake.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/distutils/command/upload.py
Modified: python/branches/release27-maint/Lib/distutils/command/upload.py
==============================================================================
--- python/branches/release27-maint/Lib/distutils/command/upload.py (original)
+++ python/branches/release27-maint/Lib/distutils/command/upload.py Wed Sep 8 02:02:29 2010
@@ -186,5 +186,5 @@
self.announce('Upload failed (%s): %s' % (status, reason),
log.ERROR)
if self.show_response:
- msg = ''.join('-' * 75, r.read(), '-' * 75)
+ msg = '\n'.join(('-' * 75, r.read(), '-' * 75))
self.announce(msg, log.INFO)
From python-checkins at python.org Wed Sep 8 02:30:28 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 8 Sep 2010 02:30:28 +0200 (CEST)
Subject: [Python-checkins] r84617 - python/branches/py3k/Lib/random.py
Message-ID: <20100908003028.5F3CFEE98F@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 8 02:30:28 2010
New Revision: 84617
Log:
In the case where only a user supplied random() method is available,
adopt a strategy that makes the fewest calls to random().
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Wed Sep 8 02:30:28 2010
@@ -212,33 +212,33 @@
return self.randrange(a, b+1)
- def _randbelow(self, n, int=int, bpf=BPF, type=type,
+ def _randbelow(self, n, int=int, maxsize=1<= n:
r = getrandbits(k)
return r
# There's an overriden random() method but no new getrandbits() method,
# so we can only use random() from here.
- if k > bpf:
+ random = self.random
+ if n >= maxsize:
_warn("Underlying random() generator does not supply \n"
"enough bits to choose from a population range this large.\n"
"To remove the range limitation, add a getrandbits() method.")
- return int(self.random() * n)
- random = self.random
- N = 1 << k
- r = int(N * random()) # 0 <= r < 2**k
- while r >= n:
- r = int(N * random())
- return r
+ return int(random() * n)
+ rem = maxsize % n
+ limit = (maxsize - rem) / maxsize # int(limit * maxsize) % n == 0
+ r = random()
+ while r >= limit:
+ r = random()
+ return int(r*maxsize) % n
## -------------------- sequence methods -------------------
From solipsis at pitrou.net Wed Sep 8 05:03:05 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Wed, 08 Sep 2010 05:03:05 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84617): sum=0
Message-ID:
py3k results for svn r84617 (hg cset dc1f3b16d26a)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/refloguhmhVy', '-x']
From g.brandl at gmx.net Wed Sep 8 09:41:16 2010
From: g.brandl at gmx.net (Georg Brandl)
Date: Wed, 08 Sep 2010 09:41:16 +0200
Subject: [Python-checkins] r84536 - sandbox/trunk/release/release.py
In-Reply-To: <20100907175804.1eba70d7@mission>
References: <20100905182846.4E3DAEEA02@mail.python.org>
<20100907175804.1eba70d7@mission>
Message-ID:
Am 07.09.2010 23:58, schrieb Barry Warsaw:
> On Sep 05, 2010, at 08:28 PM, georg.brandl wrote:
>
>>Author: georg.brandl
>>Date: Sun Sep 5 20:28:46 2010
>>New Revision: 84536
>>
>>Log:
>>Fix after changing NEWS layout.
>>
>>Modified:
>> sandbox/trunk/release/release.py
>>
>>Modified: sandbox/trunk/release/release.py
>>==============================================================================
>>--- sandbox/trunk/release/release.py (original)
>>+++ sandbox/trunk/release/release.py Sun Sep 5 20:28:46 2010
>>@@ -396,13 +396,13 @@
>> with open('Misc/NEWS', encoding="utf-8") as fp:
>> lines = fp.readlines()
>> for i, line in enumerate(lines):
>>- if line.startswith("(editors"):
>>+ if line.startswith("Python News"):
>> start = i
>> if line.startswith("What's"):
>> end = i
>> break
>> with open('Misc/NEWS', 'w', encoding="utf-8") as fp:
>>- fp.writelines(lines[:start+1])
>>+ fp.writelines(lines[:start+2])
>> fp.write(NEWS_TEMPLATE)
>> fp.writelines(lines[end-1:])
>> print("Please fill in the the name of the next version.")
>
> Will this still work with the Python 2.7 NEWS file?
I intended to backport my removal of NEWS.help, so yes.
Georg
--
Thus spake the Lord: Thou shalt indent with four spaces. No more, no less.
Four shall be the number of spaces thou shalt indent, and the number of thy
indenting shall be four. Eight shalt thou not indent, nor either indent thou
two, excepting that thou then proceed to four. Tabs are right out.
From python-checkins at python.org Wed Sep 8 12:43:45 2010
From: python-checkins at python.org (georg.brandl)
Date: Wed, 8 Sep 2010 12:43:45 +0200 (CEST)
Subject: [Python-checkins] r84619 - python/branches/py3k/Misc/developers.txt
Message-ID: <20100908104345.BA23DEE981@mail.python.org>
Author: georg.brandl
Date: Wed Sep 8 12:43:45 2010
New Revision: 84619
Log:
Add Lukasz.
Modified:
python/branches/py3k/Misc/developers.txt
Modified: python/branches/py3k/Misc/developers.txt
==============================================================================
--- python/branches/py3k/Misc/developers.txt (original)
+++ python/branches/py3k/Misc/developers.txt Wed Sep 8 12:43:45 2010
@@ -20,6 +20,9 @@
Permissions History
-------------------
+- Lukasz Langa was given commit access on Sep 08 2010 by GFB,
+ at suggestion of Antoine Pitrou, for general bug fixing.
+
- Daniel Stutzbach was given commit access on Aug 22 2010 by MvL,
for general bug fixing.
From python-checkins at python.org Wed Sep 8 12:46:15 2010
From: python-checkins at python.org (vinay.sajip)
Date: Wed, 8 Sep 2010 12:46:15 +0200 (CEST)
Subject: [Python-checkins] r84620 - in python/branches/py3k:
Doc/library/logging.rst Lib/logging/handlers.py Misc/NEWS
Message-ID: <20100908104615.8CA63EEAED@mail.python.org>
Author: vinay.sajip
Date: Wed Sep 8 12:46:15 2010
New Revision: 84620
Log:
logging: Added QueueHandler.
Modified:
python/branches/py3k/Doc/library/logging.rst
python/branches/py3k/Lib/logging/handlers.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Wed Sep 8 12:46:15 2010
@@ -594,10 +594,10 @@
In addition to the base :class:`Handler` class, many useful subclasses are
provided:
-#. :class:`StreamHandler` instances send error messages to streams (file-like
+#. :class:`StreamHandler` instances send messages to streams (file-like
objects).
-#. :class:`FileHandler` instances send error messages to disk files.
+#. :class:`FileHandler` instances send messages to disk files.
.. module:: logging.handlers
@@ -606,31 +606,31 @@
directly. Instead, use :class:`RotatingFileHandler` or
:class:`TimedRotatingFileHandler`.
-#. :class:`RotatingFileHandler` instances send error messages to disk
+#. :class:`RotatingFileHandler` instances send messages to disk
files, with support for maximum log file sizes and log file rotation.
-#. :class:`TimedRotatingFileHandler` instances send error messages to
+#. :class:`TimedRotatingFileHandler` instances send messages to
disk files, rotating the log file at certain timed intervals.
-#. :class:`SocketHandler` instances send error messages to TCP/IP
+#. :class:`SocketHandler` instances send messages to TCP/IP
sockets.
-#. :class:`DatagramHandler` instances send error messages to UDP
+#. :class:`DatagramHandler` instances send messages to UDP
sockets.
-#. :class:`SMTPHandler` instances send error messages to a designated
+#. :class:`SMTPHandler` instances send messages to a designated
email address.
-#. :class:`SysLogHandler` instances send error messages to a Unix
+#. :class:`SysLogHandler` instances send messages to a Unix
syslog daemon, possibly on a remote machine.
-#. :class:`NTEventLogHandler` instances send error messages to a
+#. :class:`NTEventLogHandler` instances send messages to a
Windows NT/2000/XP event log.
-#. :class:`MemoryHandler` instances send error messages to a buffer
+#. :class:`MemoryHandler` instances send messages to a buffer
in memory, which is flushed whenever specific criteria are met.
-#. :class:`HTTPHandler` instances send error messages to an HTTP
+#. :class:`HTTPHandler` instances send messages to an HTTP
server using either ``GET`` or ``POST`` semantics.
#. :class:`WatchedFileHandler` instances watch the file they are
@@ -638,6 +638,9 @@
name. This handler is only useful on Unix-like systems; Windows does not
support the underlying mechanism used.
+#. :class:`QueueHandler` instances send messages to a queue, such as
+ those implemented in the :mod:`queue` or :mod:`multiprocessing` modules.
+
.. currentmodule:: logging
#. :class:`NullHandler` instances do nothing with error messages. They are used
@@ -650,6 +653,10 @@
The :class:`NullHandler` class was not present in previous versions.
+.. versionadded:: 3.2
+
+The :class:`QueueHandler` class was not present in previous versions.
+
The :class:`NullHandler`, :class:`StreamHandler` and :class:`FileHandler`
classes are defined in the core logging package. The other handlers are
defined in a sub- module, :mod:`logging.handlers`. (There is also another
@@ -1506,16 +1513,16 @@
threads in a single process *is* supported, logging to a single file from
*multiple processes* is *not* supported, because there is no standard way to
serialize access to a single file across multiple processes in Python. If you
-need to log to a single file from multiple processes, the best way of doing
-this is to have all the processes log to a :class:`SocketHandler`, and have a
-separate process which implements a socket server which reads from the socket
-and logs to file. (If you prefer, you can dedicate one thread in one of the
-existing processes to perform this function.) The following section documents
-this approach in more detail and includes a working socket receiver which can
-be used as a starting point for you to adapt in your own applications.
+need to log to a single file from multiple processes, one way of doing this is
+to have all the processes log to a :class:`SocketHandler`, and have a separate
+process which implements a socket server which reads from the socket and logs
+to file. (If you prefer, you can dedicate one thread in one of the existing
+processes to perform this function.) The following section documents this
+approach in more detail and includes a working socket receiver which can be
+used as a starting point for you to adapt in your own applications.
If you are using a recent version of Python which includes the
-:mod:`multiprocessing` module, you can write your own handler which uses the
+:mod:`multiprocessing` module, you could write your own handler which uses the
:class:`Lock` class from this module to serialize access to the file from
your processes. The existing :class:`FileHandler` and subclasses do not make
use of :mod:`multiprocessing` at present, though they may do so in the future.
@@ -1523,6 +1530,128 @@
working lock functionality on all platforms (see
http://bugs.python.org/issue3770).
+.. currentmodule:: logging.handlers
+
+Alternatively, you can use a ``Queue`` and a :class:`QueueHandler` to send
+all logging events to one of the processes in your multi-process application.
+The following example script demonstrates how you can do this; in the example
+a separate listener process listens for events sent by other processes and logs
+them according to its own logging configuration. Although the example only
+demonstrates one way of doing it (for example, you may want to use a listener
+thread rather than a separate listener process - the implementation would be
+analogous) it does allow for completely different logging configurations for
+the listener and the other processes in your application, and can be used as
+the basis for code meeting your own specific requirements::
+
+ # You'll need these imports in your own code
+ import logging
+ import logging.handlers
+ import multiprocessing
+
+ # Next two import lines for this demo only
+ from random import choice, random
+ import time
+
+ #
+ # Because you'll want to define the logging configurations for listener and workers, the
+ # listener and worker process functions take a configurer parameter which is a callable
+ # for configuring logging for that process. These functions are also passed the queue,
+ # which they use for communication.
+ #
+ # In practice, you can configure the listener however you want, but note that in this
+ # simple example, the listener does not apply level or filter logic to received records.
+ # In practice, you would probably want to do ths logic in the worker processes, to avoid
+ # sending events which would be filtered out between processes.
+ #
+ # The size of the rotated files is made small so you can see the results easily.
+ def listener_configurer():
+ root = logging.getLogger()
+ h = logging.handlers.RotatingFileHandler('/tmp/mptest.log', 'a', 300, 10)
+ f = logging.Formatter('%(asctime)s %(processName)-10s %(name)s %(levelname)-8s %(message)s')
+ h.setFormatter(f)
+ root.addHandler(h)
+
+ # This is the listener process top-level loop: wait for logging events
+ # (LogRecords)on the queue and handle them, quit when you get a None for a
+ # LogRecord.
+ def listener_process(queue, configurer):
+ configurer()
+ while True:
+ try:
+ record = queue.get()
+ if record is None: # We send this as a sentinel to tell the listener to quit.
+ break
+ logger = logging.getLogger(record.name)
+ logger.handle(record) # No level or filter logic applied - just do it!
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ import sys, traceback
+ print >> sys.stderr, 'Whoops! Problem:'
+ traceback.print_exc(file=sys.stderr)
+
+ # Arrays used for random selections in this demo
+
+ LEVELS = [logging.DEBUG, logging.INFO, logging.WARNING,
+ logging.ERROR, logging.CRITICAL]
+
+ LOGGERS = ['a.b.c', 'd.e.f']
+
+ MESSAGES = [
+ 'Random message #1',
+ 'Random message #2',
+ 'Random message #3',
+ ]
+
+ # The worker configuration is done at the start of the worker process run.
+ # Note that on Windows you can't rely on fork semantics, so each process
+ # will run the logging configuration code when it starts.
+ def worker_configurer(queue):
+ h = logging.handlers.QueueHandler(queue) # Just the one handler needed
+ root = logging.getLogger()
+ root.addHandler(h)
+ root.setLevel(logging.DEBUG) # send all messages, for demo; no other level or filter logic applied.
+
+ # This is the worker process top-level loop, which just logs ten events with
+ # random intervening delays before terminating.
+ # The print messages are just so you know it's doing something!
+ def worker_process(queue, configurer):
+ configurer(queue)
+ name = multiprocessing.current_process().name
+ print('Worker started: %s' % name)
+ for i in range(10):
+ time.sleep(random())
+ logger = logging.getLogger(choice(LOGGERS))
+ level = choice(LEVELS)
+ message = choice(MESSAGES)
+ logger.log(level, message)
+ print('Worker finished: %s' % name)
+
+ # Here's where the demo gets orchestrated. Create the queue, create and start
+ # the listener, create ten workers and start them, wait for them to finish,
+ # then send a None to the queue to tell the listener to finish.
+ def main():
+ queue = multiprocessing.Queue(-1)
+ listener = multiprocessing.Process(target=listener_process,
+ args=(queue, listener_configurer))
+ listener.start()
+ workers = []
+ for i in range(10):
+ worker = multiprocessing.Process(target=worker_process,
+ args=(queue, worker_configurer))
+ workers.append(worker)
+ worker.start()
+ for w in workers:
+ w.join()
+ queue.put_nowait(None)
+ listener.join()
+
+ if __name__ == '__main__':
+ main()
+
+
+.. currentmodule:: logging
+
.. _network-logging:
@@ -2458,6 +2587,39 @@
Sends the record to the Web server as a percent-encoded dictionary.
+.. _queue-handler:
+
+
+QueueHandler
+^^^^^^^^^^^^
+
+The :class:`QueueHandler` class, located in the :mod:`logging.handlers` module,
+supports sending logging messages to a queue, such as those implemented in the
+:mod:`queue` or :mod:`multiprocessing` modules.
+
+
+.. class:: QueueHandler(queue)
+
+ Returns a new instance of the :class:`QueueHandler` class. The instance is
+ initialized with the queue to send messages to.
+
+
+ .. method:: emit(record)
+
+ Sends the record to the handler's queue.
+
+ .. method:: enqueue(record)
+
+ Enqueues the record on the queue using ``put_nowait()``; you may
+ want to override this if you want to use blocking behaviour, or a
+ timeout, or a customised queue implementation.
+
+
+.. versionadded:: 3.2
+
+The :class:`QueueHandler` class was not present in previous versions.
+
+
.. _formatter-objects:
Formatter Objects
@@ -2528,6 +2690,8 @@
+-------------------------+-----------------------------------------------+
| ``%(process)d`` | Process ID (if available). |
+-------------------------+-----------------------------------------------+
+| ``%(processName)s`` | Process name (if available). |
++-------------------------+-----------------------------------------------+
| ``%(message)s`` | The logged message, computed as ``msg % |
| | args``. |
+-------------------------+-----------------------------------------------+
Modified: python/branches/py3k/Lib/logging/handlers.py
==============================================================================
--- python/branches/py3k/Lib/logging/handlers.py (original)
+++ python/branches/py3k/Lib/logging/handlers.py Wed Sep 8 12:46:15 2010
@@ -1134,3 +1134,55 @@
self.flush()
self.target = None
BufferingHandler.close(self)
+
+
+class QueueHandler(logging.Handler):
+ """
+ This handler sends events to a queue. Typically, it would be used together
+ with a multiprocessing Queue to centralise logging to file in one process
+ (in a multi-process application), so as to avoid file write contention
+ between processes.
+
+ This code is new in Python 3.2, but this class can be copy pasted into
+ user code for use with earlier Python versions.
+ """
+
+ def __init__(self, queue):
+ """
+ Initialise an instance, using the passed queue.
+ """
+ logging.Handler.__init__(self)
+ self.queue = queue
+
+ def enqueue(self, record):
+ """
+ Enqueue a record.
+
+ The base implementation uses put_nowait. You may want to override
+ this method if you want to use blocking, timeouts or custom queue
+ implementations.
+ """
+ self.queue.put_nowait(record)
+
+ def emit(self, record):
+ """
+ Emit a record.
+
+ Writes the LogRecord to the queue, preparing it for pickling first.
+ """
+ try:
+ # The format operation gets traceback text into record.exc_text
+ # (if there's exception data), and also puts the message into
+ # record.message. We can then use this to replace the original
+ # msg + args, as these might be unpickleable. We also zap the
+ # exc_info attribute, as it's no longer needed and, if not None,
+ # will typically not be pickleable.
+ self.format(record)
+ record.msg = record.message
+ record.args = None
+ record.exc_info = None
+ self.enqueue(record)
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except:
+ self.handleError(record)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 8 12:46:15 2010
@@ -13,6 +13,9 @@
Library
-------
+- Logging: Added QueueHandler class to facilitate logging usage with
+ multiprocessing.
+
- Issue #9707: Rewritten reference implementation of threading.local which
is friendlier towards reference cycles. This change is not normally
visible since an optimized C implementation (_thread._local) is used
From python-checkins at python.org Wed Sep 8 12:51:01 2010
From: python-checkins at python.org (victor.stinner)
Date: Wed, 8 Sep 2010 12:51:01 +0200 (CEST)
Subject: [Python-checkins] r84621 - in python/branches/release27-maint:
Lib/test/test_file2k.py Misc/NEWS Objects/fileobject.c
Message-ID: <20100908105101.755BFEEB05@mail.python.org>
Author: victor.stinner
Date: Wed Sep 8 12:51:01 2010
New Revision: 84621
Log:
Issue #4947: The write() method of sys.stdout and sys.stderr uses their
encoding and errors attributes instead of using utf-8 in strict mode, to get
the same behaviour than the print statement.
Modified:
python/branches/release27-maint/Lib/test/test_file2k.py
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Objects/fileobject.c
Modified: python/branches/release27-maint/Lib/test/test_file2k.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_file2k.py (original)
+++ python/branches/release27-maint/Lib/test/test_file2k.py Wed Sep 8 12:51:01 2010
@@ -619,6 +619,39 @@
finally:
sys.stdout = save_stdout
+ def test_unicode(self):
+ import subprocess
+
+ def get_message(encoding, *code):
+ code = '\n'.join(code)
+ env = os.environ.copy()
+ env['PYTHONIOENCODING'] = encoding
+ process = subprocess.Popen([sys.executable, "-c", code],
+ stdout=subprocess.PIPE, env=env)
+ stdout, stderr = process.communicate()
+ self.assertEqual(process.returncode, 0)
+ return stdout
+
+ def check_message(text, encoding, expected):
+ stdout = get_message(encoding,
+ "import sys",
+ "sys.stdout.write(%r)" % text,
+ "sys.stdout.flush()")
+ self.assertEqual(stdout, expected)
+
+ check_message(u'\u20ac\n', "iso-8859-15", "\xa4\n")
+ check_message(u'\u20ac\n', "utf-16-le", '\xac\x20\n\x00')
+ check_message(u'15\u20ac\n', "iso-8859-1:ignore", "15\n")
+ check_message(u'15\u20ac\n', "iso-8859-1:replace", "15?\n")
+ check_message(u'15\u20ac\n', "iso-8859-1:backslashreplace",
+ "15\\u20ac\n")
+
+ for objtype in ('buffer', 'bytearray'):
+ stdout = get_message('ascii',
+ 'import sys',
+ r'sys.stdout.write(%s("\xe9\n"))' % objtype)
+ self.assertEqual(stdout, "\xe9\n")
+
def test_main():
# Historically, these tests have been sloppy about removing TESTFN.
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Wed Sep 8 12:51:01 2010
@@ -12,6 +12,10 @@
Core and Builtins
-----------------
+- Issue #4947: The write() method of sys.stdout and sys.stderr uses their
+ encoding and errors attributes instead of using utf-8 in strict mode, to get
+ the same behaviour than the print statement.
+
- Issue #9737: Fix a crash when trying to delete a slice or an item from
a memoryview object.
@@ -63,7 +67,7 @@
- Issue #8750: Fixed MutableSet's methods to correctly handle
reflexive operations, namely x -= x and x ^= x.
-- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing
+- Issue #9129: smtpd.py is vulnerable to DoS attacks deriving from missing
error handling when accepting a new connection.
- Issue #658749: asyncore's connect() method now correctly interprets winsock
Modified: python/branches/release27-maint/Objects/fileobject.c
==============================================================================
--- python/branches/release27-maint/Objects/fileobject.c (original)
+++ python/branches/release27-maint/Objects/fileobject.c Wed Sep 8 12:51:01 2010
@@ -1735,8 +1735,10 @@
file_write(PyFileObject *f, PyObject *args)
{
Py_buffer pbuf;
- char *s;
+ const char *s;
Py_ssize_t n, n2;
+ PyObject *encoded = NULL;
+
if (f->f_fp == NULL)
return err_closed();
if (!f->writable)
@@ -1746,14 +1748,41 @@
return NULL;
s = pbuf.buf;
n = pbuf.len;
- } else
- if (!PyArg_ParseTuple(args, "t#", &s, &n))
- return NULL;
+ }
+ else {
+ const char *encoding, *errors;
+ PyObject *text;
+ if (!PyArg_ParseTuple(args, "O", &text))
+ return NULL;
+
+ if (PyString_Check(text)) {
+ s = PyString_AS_STRING(text);
+ n = PyString_GET_SIZE(text);
+ } else if (PyUnicode_Check(text)) {
+ if (f->f_encoding != Py_None)
+ encoding = PyString_AS_STRING(f->f_encoding);
+ else
+ encoding = PyUnicode_GetDefaultEncoding();
+ if (f->f_errors != Py_None)
+ errors = PyString_AS_STRING(f->f_errors);
+ else
+ errors = "strict";
+ encoded = PyUnicode_AsEncodedString(text, encoding, errors);
+ if (encoded == NULL)
+ return NULL;
+ s = PyString_AS_STRING(encoded);
+ n = PyString_GET_SIZE(encoded);
+ } else {
+ if (PyObject_AsCharBuffer(text, &s, &n))
+ return NULL;
+ }
+ }
f->f_softspace = 0;
FILE_BEGIN_ALLOW_THREADS(f)
errno = 0;
n2 = fwrite(s, 1, n, f->f_fp);
FILE_END_ALLOW_THREADS(f)
+ Py_XDECREF(encoded);
if (f->f_binary)
PyBuffer_Release(&pbuf);
if (n2 != n) {
From python-checkins at python.org Wed Sep 8 13:45:16 2010
From: python-checkins at python.org (victor.stinner)
Date: Wed, 8 Sep 2010 13:45:16 +0200 (CEST)
Subject: [Python-checkins] r84622 -
python/branches/release27-maint/Lib/test/test_file2k.py
Message-ID: <20100908114516.6AB9BEE99C@mail.python.org>
Author: victor.stinner
Date: Wed Sep 8 13:45:16 2010
New Revision: 84622
Log:
StdoutTests.test_unicode(): avoid newlines to fix the test on windows
* Add also a test for utf-8
* Add some comments
* Flush stdout for the buffer API tests
Modified:
python/branches/release27-maint/Lib/test/test_file2k.py
Modified: python/branches/release27-maint/Lib/test/test_file2k.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_file2k.py (original)
+++ python/branches/release27-maint/Lib/test/test_file2k.py Wed Sep 8 13:45:16 2010
@@ -639,18 +639,23 @@
"sys.stdout.flush()")
self.assertEqual(stdout, expected)
- check_message(u'\u20ac\n', "iso-8859-15", "\xa4\n")
- check_message(u'\u20ac\n', "utf-16-le", '\xac\x20\n\x00')
- check_message(u'15\u20ac\n', "iso-8859-1:ignore", "15\n")
- check_message(u'15\u20ac\n', "iso-8859-1:replace", "15?\n")
- check_message(u'15\u20ac\n', "iso-8859-1:backslashreplace",
- "15\\u20ac\n")
+ # test the encoding
+ check_message(u'15\u20ac', "iso-8859-15", "15\xa4")
+ check_message(u'15\u20ac', "utf-8", '15\xe2\x82\xac')
+ check_message(u'15\u20ac', "utf-16-le", '1\x005\x00\xac\x20')
+ # test the error handler
+ check_message(u'15\u20ac', "iso-8859-1:ignore", "15")
+ check_message(u'15\u20ac', "iso-8859-1:replace", "15?")
+ check_message(u'15\u20ac', "iso-8859-1:backslashreplace", "15\\u20ac")
+
+ # test the buffer API
for objtype in ('buffer', 'bytearray'):
stdout = get_message('ascii',
'import sys',
- r'sys.stdout.write(%s("\xe9\n"))' % objtype)
- self.assertEqual(stdout, "\xe9\n")
+ r'sys.stdout.write(%s("\xe9"))' % objtype,
+ 'sys.stdout.flush()')
+ self.assertEqual(stdout, "\xe9")
def test_main():
From python-checkins at python.org Wed Sep 8 14:37:10 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 14:37:10 +0200 (CEST)
Subject: [Python-checkins] r84623 - in python/branches/py3k: Misc/NEWS
Python/pystate.c
Message-ID: <20100908123710.C2BE5F275@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 14:37:10 2010
New Revision: 84623
Log:
Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
thread-local storage key.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Python/pystate.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 8 14:37:10 2010
@@ -10,6 +10,9 @@
Core and Builtins
-----------------
+- Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
+ thread-local storage key.
+
Library
-------
Modified: python/branches/py3k/Python/pystate.c
==============================================================================
--- python/branches/py3k/Python/pystate.c (original)
+++ python/branches/py3k/Python/pystate.c Wed Sep 8 14:37:10 2010
@@ -340,7 +340,7 @@
Py_FatalError("PyThreadState_Delete: tstate is still current");
tstate_delete_common(tstate);
#ifdef WITH_THREAD
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+ if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
#endif /* WITH_THREAD */
}
@@ -357,7 +357,7 @@
"PyThreadState_DeleteCurrent: no current tstate");
_Py_atomic_store_relaxed(&_PyThreadState_Current, NULL);
tstate_delete_common(tstate);
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+ if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
PyEval_ReleaseLock();
}
@@ -580,7 +580,6 @@
_PyGILState_Fini(void)
{
PyThread_delete_key(autoTLSkey);
- autoTLSkey = 0;
autoInterpreterState = NULL;
}
@@ -592,10 +591,10 @@
static void
_PyGILState_NoteThreadState(PyThreadState* tstate)
{
- /* If autoTLSkey is 0, this must be the very first threadstate created
- in Py_Initialize(). Don't do anything for now (we'll be back here
- when _PyGILState_Init is called). */
- if (!autoTLSkey)
+ /* If autoTLSkey isn't initialized, this must be the very first
+ threadstate created in Py_Initialize(). Don't do anything for now
+ (we'll be back here when _PyGILState_Init is called). */
+ if (!autoInterpreterState)
return;
/* Stick the thread state for this thread in thread local storage.
@@ -623,7 +622,7 @@
PyThreadState *
PyGILState_GetThisThreadState(void)
{
- if (autoInterpreterState == NULL || autoTLSkey == 0)
+ if (autoInterpreterState == NULL)
return NULL;
return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
}
From python-checkins at python.org Wed Sep 8 14:39:01 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 14:39:01 +0200 (CEST)
Subject: [Python-checkins] r84624 -
python/branches/release31-maint/Misc/maintainers.rst
Message-ID: <20100908123901.11140F275@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 14:39:00 2010
New Revision: 84624
Log:
Synchronize maintainers.rst
Modified:
python/branches/release31-maint/Misc/maintainers.rst
Modified: python/branches/release31-maint/Misc/maintainers.rst
==============================================================================
--- python/branches/release31-maint/Misc/maintainers.rst (original)
+++ python/branches/release31-maint/Misc/maintainers.rst Wed Sep 8 14:39:00 2010
@@ -52,8 +52,8 @@
argparse bethard
array
ast
-asynchat josiahcarlson, giampaolo.rodola
-asyncore josiahcarlson, giampaolo.rodola
+asynchat josiahcarlson, giampaolo.rodola, stutzbach
+asyncore josiahcarlson, giampaolo.rodola, stutzbach
atexit
audioop
base64
@@ -72,7 +72,7 @@
code
codecs lemburg, doerwalter
codeop
-collections rhettinger
+collections rhettinger, stutzbach
colorsys
compileall
configparser
@@ -83,7 +83,7 @@
crypt
csv
ctypes theller
-curses andrew.kuchling
+curses akuchling
datetime alexander.belopolsky
dbm
decimal facundobatista, rhettinger, mark.dickinson
@@ -113,7 +113,7 @@
grp
gzip
hashlib
-heapq rhettinger
+heapq rhettinger, stutzbach
hmac
html
http
@@ -123,19 +123,19 @@
imp
importlib brett.cannon
inspect
-io pitrou, benjamin.peterson
+io pitrou, benjamin.peterson, stutzbach
itertools rhettinger
json bob.ippolito (inactive)
keyword
lib2to3 benjamin.peterson
linecache
locale loewis, lemburg
-logging vsajip
+logging vinay.sajip
macpath
-mailbox andrew.kuchling
+mailbox akuchling
mailcap
marshal
-math mark.dickinson, rhettinger
+math mark.dickinson, rhettinger, stutzbach
mimetypes
mmap
modulefinder theller, jvr
@@ -231,7 +231,7 @@
wave
weakref fdrake, pitrou
webbrowser georg.brandl
-winreg brian.curtin*
+winreg brian.curtin*, stutzbach
winsound effbot (inactive)
wsgiref pje
xdrlib
@@ -262,7 +262,7 @@
Platform Maintainers
------------------ -----------
AIX
-Cygwin jlt63
+Cygwin jlt63, stutzbach
FreeBSD
HP-UX
Linux
@@ -290,9 +290,9 @@
GUI
i18n lemburg
import machinery brett.cannon, ncoghlan
-io pitrou, benjamin.peterson
+io pitrou, benjamin.peterson, stutzbach
locale lemburg, loewis
-mathematics mark.dickinson, eric.smith, lemburg
+mathematics mark.dickinson, eric.smith, lemburg, stutzbach
memory management tim_one, lemburg
networking giampaolo.rodola
packaging tarek, lemburg
From python-checkins at python.org Wed Sep 8 14:40:15 2010
From: python-checkins at python.org (eric.araujo)
Date: Wed, 8 Sep 2010 14:40:15 +0200 (CEST)
Subject: [Python-checkins] r84625 -
python/branches/release27-maint/Misc/maintainers.rst
Message-ID: <20100908124015.E4AEFEEB17@mail.python.org>
Author: eric.araujo
Date: Wed Sep 8 14:40:15 2010
New Revision: 84625
Log:
Synchronize maintainers.rst
Modified:
python/branches/release27-maint/Misc/maintainers.rst
Modified: python/branches/release27-maint/Misc/maintainers.rst
==============================================================================
--- python/branches/release27-maint/Misc/maintainers.rst (original)
+++ python/branches/release27-maint/Misc/maintainers.rst Wed Sep 8 14:40:15 2010
@@ -86,7 +86,7 @@
crypt
csv
ctypes theller
-curses andrew.kuchling
+curses akuchling
datetime alexander.belopolsky
dbm
decimal facundobatista, rhettinger, mark.dickinson
@@ -137,7 +137,7 @@
locale loewis, lemburg
logging vinay.sajip
macpath
-mailbox andrew.kuchling
+mailbox akuchling
mailcap
marshal
math mark.dickinson, rhettinger, stutzbach
From python-checkins at python.org Wed Sep 8 14:40:45 2010
From: python-checkins at python.org (senthil.kumaran)
Date: Wed, 8 Sep 2010 14:40:45 +0200 (CEST)
Subject: [Python-checkins] r84626 -
python/branches/release27-maint/Lib/string.py
Message-ID: <20100908124045.E11B9EEA96@mail.python.org>
Author: senthil.kumaran
Date: Wed Sep 8 14:40:45 2010
New Revision: 84626
Log:
Issue5416 - Revert a documentatin change made to explain replace on negative value.
Minor changes to doc: s/maxsplit/maxreplace
Modified:
python/branches/release27-maint/Lib/string.py
Modified: python/branches/release27-maint/Lib/string.py
==============================================================================
--- python/branches/release27-maint/Lib/string.py (original)
+++ python/branches/release27-maint/Lib/string.py Wed Sep 8 14:40:45 2010
@@ -508,16 +508,15 @@
return s.capitalize()
# Substring replacement (global)
-def replace(s, old, new, maxsplit=-1):
- """replace (str, old, new[, maxsplit]) -> string
+def replace(s, old, new, maxreplace=-1):
+ """replace (str, old, new[, maxreplace]) -> string
Return a copy of string str with all occurrences of substring
- old replaced by new. If the optional argument maxsplit is
- given, only the first maxsplit occurrences are replaced. A
- negative value of maxsplit signifies all occurances.
+ old replaced by new. If the optional argument maxreplace is
+ given, only the first maxreplace occurrences are replaced.
"""
- return s.replace(old, new, maxsplit)
+ return s.replace(old, new, maxreplace)
# Try importing optional built-in module "strop" -- if it exists,
From python-checkins at python.org Wed Sep 8 14:40:49 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 14:40:49 +0200 (CEST)
Subject: [Python-checkins] r84627 - in python/branches/release27-maint:
Misc/NEWS Python/pystate.c
Message-ID: <20100908124049.9D9D4EEB04@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 14:40:49 2010
New Revision: 84627
Log:
Merged revisions 84623 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84623 | antoine.pitrou | 2010-09-08 14:37:10 +0200 (mer., 08 sept. 2010) | 4 lines
Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
thread-local storage key.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Python/pystate.c
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Wed Sep 8 14:40:49 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
+ thread-local storage key.
+
- Issue #4947: The write() method of sys.stdout and sys.stderr uses their
encoding and errors attributes instead of using utf-8 in strict mode, to get
the same behaviour than the print statement.
Modified: python/branches/release27-maint/Python/pystate.c
==============================================================================
--- python/branches/release27-maint/Python/pystate.c (original)
+++ python/branches/release27-maint/Python/pystate.c Wed Sep 8 14:40:49 2010
@@ -298,7 +298,7 @@
Py_FatalError("PyThreadState_Delete: tstate is still current");
tstate_delete_common(tstate);
#ifdef WITH_THREAD
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+ if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
#endif /* WITH_THREAD */
}
@@ -314,7 +314,7 @@
"PyThreadState_DeleteCurrent: no current tstate");
_PyThreadState_Current = NULL;
tstate_delete_common(tstate);
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+ if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
PyEval_ReleaseLock();
}
@@ -534,7 +534,6 @@
_PyGILState_Fini(void)
{
PyThread_delete_key(autoTLSkey);
- autoTLSkey = 0;
autoInterpreterState = NULL;
}
@@ -546,10 +545,10 @@
static void
_PyGILState_NoteThreadState(PyThreadState* tstate)
{
- /* If autoTLSkey is 0, this must be the very first threadstate created
- in Py_Initialize(). Don't do anything for now (we'll be back here
- when _PyGILState_Init is called). */
- if (!autoTLSkey)
+ /* If autoTLSkey isn't initialized, this must be the very first
+ threadstate created in Py_Initialize(). Don't do anything for now
+ (we'll be back here when _PyGILState_Init is called). */
+ if (!autoInterpreterState)
return;
/* Stick the thread state for this thread in thread local storage.
@@ -577,7 +576,7 @@
PyThreadState *
PyGILState_GetThisThreadState(void)
{
- if (autoInterpreterState == NULL || autoTLSkey == 0)
+ if (autoInterpreterState == NULL)
return NULL;
return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
}
From python-checkins at python.org Wed Sep 8 14:48:12 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 14:48:12 +0200 (CEST)
Subject: [Python-checkins] r84628 - in python/branches/release31-maint:
Misc/NEWS Python/pystate.c
Message-ID: <20100908124812.CADDDEE985@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 14:48:12 2010
New Revision: 84628
Log:
Merged revisions 84623 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84623 | antoine.pitrou | 2010-09-08 14:37:10 +0200 (mer., 08 sept. 2010) | 4 lines
Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
thread-local storage key.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Python/pystate.c
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Wed Sep 8 14:48:12 2010
@@ -12,6 +12,9 @@
Core and Builtins
-----------------
+- Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
+ thread-local storage key.
+
- Issue #9737: Fix a crash when trying to delete a slice or an item from
a memoryview object.
Modified: python/branches/release31-maint/Python/pystate.c
==============================================================================
--- python/branches/release31-maint/Python/pystate.c (original)
+++ python/branches/release31-maint/Python/pystate.c Wed Sep 8 14:48:12 2010
@@ -338,7 +338,7 @@
Py_FatalError("PyThreadState_Delete: tstate is still current");
tstate_delete_common(tstate);
#ifdef WITH_THREAD
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+ if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
#endif /* WITH_THREAD */
}
@@ -354,7 +354,7 @@
"PyThreadState_DeleteCurrent: no current tstate");
_PyThreadState_Current = NULL;
tstate_delete_common(tstate);
- if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
+ if (autoInterpreterState && PyThread_get_key_value(autoTLSkey) == tstate)
PyThread_delete_key_value(autoTLSkey);
PyEval_ReleaseLock();
}
@@ -574,7 +574,6 @@
_PyGILState_Fini(void)
{
PyThread_delete_key(autoTLSkey);
- autoTLSkey = 0;
autoInterpreterState = NULL;
}
@@ -586,10 +585,10 @@
static void
_PyGILState_NoteThreadState(PyThreadState* tstate)
{
- /* If autoTLSkey is 0, this must be the very first threadstate created
- in Py_Initialize(). Don't do anything for now (we'll be back here
- when _PyGILState_Init is called). */
- if (!autoTLSkey)
+ /* If autoTLSkey isn't initialized, this must be the very first
+ threadstate created in Py_Initialize(). Don't do anything for now
+ (we'll be back here when _PyGILState_Init is called). */
+ if (!autoInterpreterState)
return;
/* Stick the thread state for this thread in thread local storage.
@@ -617,7 +616,7 @@
PyThreadState *
PyGILState_GetThisThreadState(void)
{
- if (autoInterpreterState == NULL || autoTLSkey == 0)
+ if (autoInterpreterState == NULL)
return NULL;
return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
}
From python-checkins at python.org Wed Sep 8 14:50:29 2010
From: python-checkins at python.org (senthil.kumaran)
Date: Wed, 8 Sep 2010 14:50:29 +0200 (CEST)
Subject: [Python-checkins] r84629 -
python/branches/py3k/Objects/bytesobject.c
Message-ID: <20100908125029.92BC4EE9AA@mail.python.org>
Author: senthil.kumaran
Date: Wed Sep 8 14:50:29 2010
New Revision: 84629
Log:
Revert the doc change done in r83880. str.replace with negative count value is not a feature.
Modified:
python/branches/py3k/Objects/bytesobject.c
Modified: python/branches/py3k/Objects/bytesobject.c
==============================================================================
--- python/branches/py3k/Objects/bytesobject.c (original)
+++ python/branches/py3k/Objects/bytesobject.c Wed Sep 8 14:50:29 2010
@@ -2131,8 +2131,7 @@
\n\
Return a copy of B with all occurrences of subsection\n\
old replaced by new. If the optional argument count is\n\
-positive, only the first count occurrences are replaced. A\n\
-negative value of count replaces all occurrences");
+given, only first count occurances are replaced.");
static PyObject *
bytes_replace(PyBytesObject *self, PyObject *args)
From python-checkins at python.org Wed Sep 8 15:00:08 2010
From: python-checkins at python.org (senthil.kumaran)
Date: Wed, 8 Sep 2010 15:00:08 +0200 (CEST)
Subject: [Python-checkins] r84630 - in python/branches/release31-maint:
Objects/bytesobject.c
Message-ID: <20100908130008.02A31EEB0D@mail.python.org>
Author: senthil.kumaran
Date: Wed Sep 8 15:00:07 2010
New Revision: 84630
Log:
Merged revisions 84629 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84629 | senthil.kumaran | 2010-09-08 18:20:29 +0530 (Wed, 08 Sep 2010) | 3 lines
Revert the doc change done in r83880. str.replace with negative count value is not a feature.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Objects/bytesobject.c
Modified: python/branches/release31-maint/Objects/bytesobject.c
==============================================================================
--- python/branches/release31-maint/Objects/bytesobject.c (original)
+++ python/branches/release31-maint/Objects/bytesobject.c Wed Sep 8 15:00:07 2010
@@ -2557,8 +2557,7 @@
\n\
Return a copy of B with all occurrences of subsection\n\
old replaced by new. If the optional argument count is\n\
-positive, only the first count occurrences are replaced. A\n\
-negative value of count replaces all occurrences");
+given, only first count occurances are replaced.");
static PyObject *
bytes_replace(PyBytesObject *self, PyObject *args)
From python-checkins at python.org Wed Sep 8 18:22:11 2010
From: python-checkins at python.org (matthias.klose)
Date: Wed, 8 Sep 2010 18:22:11 +0200 (CEST)
Subject: [Python-checkins] r84631 -
python/branches/py3k/Python/dynload_shlib.c
Message-ID: <20100908162211.3E7D3EEAC2@mail.python.org>
Author: matthias.klose
Date: Wed Sep 8 18:22:10 2010
New Revision: 84631
Log:
PEP 3149: Try to load the extension with the SOABI before trying
to load the one without the SOABI in the name.
Modified:
python/branches/py3k/Python/dynload_shlib.c
Modified: python/branches/py3k/Python/dynload_shlib.c
==============================================================================
--- python/branches/py3k/Python/dynload_shlib.c (original)
+++ python/branches/py3k/Python/dynload_shlib.c Wed Sep 8 18:22:10 2010
@@ -52,8 +52,8 @@
{"MODULE.EXE", "rb", C_EXTENSION},
#else /* !__VMS */
{"." SOABI ".so", "rb", C_EXTENSION},
- {".so", "rb", C_EXTENSION},
{"module." SOABI ".so", "rb", C_EXTENSION},
+ {".so", "rb", C_EXTENSION},
{"module.so", "rb", C_EXTENSION},
#endif /* __VMS */
#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */
From python-checkins at python.org Wed Sep 8 20:48:21 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 8 Sep 2010 20:48:21 +0200 (CEST)
Subject: [Python-checkins] r84632 - python/branches/py3k/Lib/random.py
Message-ID: <20100908184821.A874AEEB22@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 8 20:48:21 2010
New Revision: 84632
Log:
* Remove dependency on binascii.hexlify by using int.from_bytes().
* Use the new super() with no arguments.
* Replace pow() call with the ** operator.
* Increase urandom seeding from 16 bytes to 32 bytes.
* Clean-up docstring.
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Wed Sep 8 20:48:21 2010
@@ -42,7 +42,6 @@
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
from os import urandom as _urandom
-from binascii import hexlify as _hexlify
import collections as _collections
__all__ = ["Random","seed","random","uniform","randint","choice","sample",
@@ -97,16 +96,16 @@
None or no argument seeds from current time or from an operating
system specific randomness source if available.
- For version 2 (the default), all of the bits are used if a is a str,
- bytes, or bytearray. For version 1, the hash() of a is used instead.
+ For version 2 (the default), all of the bits are used if *a *is a str,
+ bytes, or bytearray. For version 1, the hash() of *a* is used instead.
- If a is an int, all bits are used.
+ If *a* is an int, all bits are used.
"""
if a is None:
try:
- a = int(_hexlify(_urandom(16)), 16)
+ a = int.from_bytes(_urandom(32), 'big')
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
@@ -114,7 +113,7 @@
if version == 2 and isinstance(a, (str, bytes, bytearray)):
if isinstance(a, str):
a = a.encode("utf8")
- a = int(_hexlify(a), 16)
+ a = int.from_bytes(a, 'big')
super().seed(a)
self.gauss_next = None
@@ -139,7 +138,7 @@
internalstate = tuple(x % (2**32) for x in internalstate)
except ValueError as e:
raise TypeError from e
- super(Random, self).setstate(internalstate)
+ super().setstate(internalstate)
else:
raise ValueError("state with version %s passed to "
"Random.setstate() of version %s" %
@@ -613,7 +612,7 @@
# Jain, pg. 499; bug fix courtesy Bill Arms
u = 1.0 - self.random()
- return alpha * pow(-_log(u), 1.0/beta)
+ return alpha * (-_log(u)) ** (1.0/beta)
## --------------- Operating System Random Source ------------------
@@ -627,7 +626,7 @@
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
- return (int(_hexlify(_urandom(7)), 16) >> 3) * RECIP_BPF
+ return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
def getrandbits(self, k):
"""getrandbits(k) -> x. Generates a long int with k random bits."""
@@ -636,7 +635,7 @@
if k != int(k):
raise TypeError('number of bits should be an integer')
bytes = (k + 7) // 8 # bits / 8 and rounded up
- x = int(_hexlify(_urandom(bytes)), 16)
+ x = int.from_bytes(_urandom(bytes), 'big')
return x >> (bytes * 8 - k) # trim excess bits
def seed(self, *args, **kwds):
From python-checkins at python.org Wed Sep 8 20:58:34 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 8 Sep 2010 20:58:34 +0200 (CEST)
Subject: [Python-checkins] r84633 - python/branches/py3k/Lib/random.py
Message-ID: <20100908185834.26C82EEB38@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 8 20:58:33 2010
New Revision: 84633
Log:
One more conversion from pow() to **.
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Wed Sep 8 20:58:33 2010
@@ -599,7 +599,7 @@
# Jain, pg. 495
u = 1.0 - self.random()
- return 1.0 / pow(u, 1.0/alpha)
+ return 1.0 / u ** (1.0/alpha)
## -------------------- Weibull --------------------
From python-checkins at python.org Wed Sep 8 21:27:59 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 8 Sep 2010 21:27:59 +0200 (CEST)
Subject: [Python-checkins] r84634 - python/branches/py3k/Lib/random.py
Message-ID: <20100908192759.A3750EF07@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 8 21:27:59 2010
New Revision: 84634
Log:
Improve variable name (don't shadow a builtin).
Modified:
python/branches/py3k/Lib/random.py
Modified: python/branches/py3k/Lib/random.py
==============================================================================
--- python/branches/py3k/Lib/random.py (original)
+++ python/branches/py3k/Lib/random.py Wed Sep 8 21:27:59 2010
@@ -634,9 +634,9 @@
raise ValueError('number of bits must be greater than zero')
if k != int(k):
raise TypeError('number of bits should be an integer')
- bytes = (k + 7) // 8 # bits / 8 and rounded up
- x = int.from_bytes(_urandom(bytes), 'big')
- return x >> (bytes * 8 - k) # trim excess bits
+ numbytes = (k + 7) // 8 # bits / 8 and rounded up
+ x = int.from_bytes(_urandom(numbytes), 'big')
+ return x >> (numbytes * 8 - k) # trim excess bits
def seed(self, *args, **kwds):
"Stub method. Not used for a system random number generator."
From python-checkins at python.org Wed Sep 8 22:57:49 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 22:57:49 +0200 (CEST)
Subject: [Python-checkins] r84635 - in python/branches/py3k: Misc/NEWS
Tools/gdb/libpython.py
Message-ID: <20100908205749.14E14FD44@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 22:57:48 2010
New Revision: 84635
Log:
Issue #9188: The gdb extension now handles correctly narrow (UCS2) as well
as wide (UCS4) unicode builds for both the host interpreter (embedded
inside gdb) and the interpreter under test.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Tools/gdb/libpython.py
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Wed Sep 8 22:57:48 2010
@@ -76,6 +76,13 @@
guaranteed to exist in all Python implementations and the names of hash
algorithms available in the current process.
+Tools/Demos
+-----------
+
+- Issue #9188: The gdb extension now handles correctly narrow (UCS2) as well
+ as wide (UCS4) unicode builds for both the host interpreter (embedded
+ inside gdb) and the interpreter under test.
+
Build
-----
Modified: python/branches/py3k/Tools/gdb/libpython.py
==============================================================================
--- python/branches/py3k/Tools/gdb/libpython.py (original)
+++ python/branches/py3k/Tools/gdb/libpython.py Wed Sep 8 22:57:48 2010
@@ -1065,7 +1065,19 @@
if char == u" ":
return True
import unicodedata
- return unicodedata.category(char)[0] not in ("C", "Z")
+ return unicodedata.category(char) not in ("C", "Z")
+
+if sys.maxunicode >= 0x10000:
+ _unichr = unichr
+else:
+ # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb
+ def _unichr(x):
+ if x < 0x10000:
+ return unichr(x)
+ x -= 0x10000
+ ch1 = 0xD800 | (x >> 10)
+ ch2 = 0xDC00 | (x & 0x3FF)
+ return unichr(ch1) + unichr(ch2)
class PyUnicodeObjectPtr(PyObjectPtr):
@@ -1084,11 +1096,33 @@
# Gather a list of ints from the Py_UNICODE array; these are either
# UCS-2 or UCS-4 code points:
- Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
+ if self.char_width() > 2:
+ Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
+ else:
+ # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the
+ # inferior process: we must join surrogate pairs.
+ Py_UNICODEs = []
+ i = 0
+ while i < field_length:
+ ucs = int(field_str[i])
+ i += 1
+ if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
+ Py_UNICODEs.append(ucs)
+ continue
+ # This could be a surrogate pair.
+ ucs2 = int(field_str[i])
+ if ucs2 < 0xDC00 or ucs2 > 0xDFFF:
+ continue
+ code = (ucs & 0x03FF) << 10
+ code |= ucs2 & 0x03FF
+ code += 0x00010000
+ Py_UNICODEs.append(code)
+ i += 1
# Convert the int code points to unicode characters, and generate a
- # local unicode instance:
- result = u''.join([unichr(ucs) for ucs in Py_UNICODEs])
+ # local unicode instance.
+ # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb).
+ result = u''.join([_unichr(ucs) for ucs in Py_UNICODEs])
return result
def write_repr(self, out, visited):
@@ -1137,20 +1171,16 @@
else:
ucs = ch
orig_ucs = None
+ ch2 = None
if self.char_width() == 2:
- # Get code point from surrogate pair
+ # If sizeof(Py_UNICODE) is 2 here (in gdb), join
+ # surrogate pairs before calling _unichr_is_printable.
if (i < len(proxy)
and 0xD800 <= ord(ch) < 0xDC00 \
and 0xDC00 <= ord(proxy[i]) <= 0xDFFF):
ch2 = proxy[i]
- code = (ord(ch) & 0x03FF) << 10
- code |= ord(ch2) & 0x03FF
- code += 0x00010000
- orig_ucs = ucs
- ucs = unichr(code)
+ ucs = ch + ch2
i += 1
- else:
- ch2 = None
printable = _unichr_is_printable(ucs)
if printable:
@@ -1195,7 +1225,7 @@
else:
# Copy characters as-is
out.write(ch)
- if self.char_width() == 2 and (ch2 is not None):
+ if ch2 is not None:
out.write(ch2)
out.write(quote)
From python-checkins at python.org Wed Sep 8 23:07:40 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 23:07:40 +0200 (CEST)
Subject: [Python-checkins] r84636 -
python/branches/py3k/Tools/gdb/libpython.py
Message-ID: <20100908210740.6B606EE9AB@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 23:07:40 2010
New Revision: 84636
Log:
Add a safety limit to the number of unicode characters we fetch
(followup to r84635, suggested by Dave Malcolm).
Modified:
python/branches/py3k/Tools/gdb/libpython.py
Modified: python/branches/py3k/Tools/gdb/libpython.py
==============================================================================
--- python/branches/py3k/Tools/gdb/libpython.py (original)
+++ python/branches/py3k/Tools/gdb/libpython.py Wed Sep 8 23:07:40 2010
@@ -1103,7 +1103,8 @@
# inferior process: we must join surrogate pairs.
Py_UNICODEs = []
i = 0
- while i < field_length:
+ limit = safety_limit(field_length)
+ while i < limit:
ucs = int(field_str[i])
i += 1
if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
From python-checkins at python.org Wed Sep 8 23:12:36 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 23:12:36 +0200 (CEST)
Subject: [Python-checkins] r84637 - in python/branches/release27-maint:
Misc/NEWS Tools/gdb/libpython.py
Message-ID: <20100908211236.3FC32EE9A5@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 23:12:36 2010
New Revision: 84637
Log:
Merged revisions 84635-84636 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84635 | antoine.pitrou | 2010-09-08 22:57:48 +0200 (mer., 08 sept. 2010) | 5 lines
Issue #9188: The gdb extension now handles correctly narrow (UCS2) as well
as wide (UCS4) unicode builds for both the host interpreter (embedded
inside gdb) and the interpreter under test.
........
r84636 | antoine.pitrou | 2010-09-08 23:07:40 +0200 (mer., 08 sept. 2010) | 4 lines
Add a safety limit to the number of unicode characters we fetch
(followup to r84635, suggested by Dave Malcolm).
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Tools/gdb/libpython.py
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Wed Sep 8 23:12:36 2010
@@ -288,6 +288,13 @@
- Issue #7567: Don't call `setupterm' twice.
+Tools/Demos
+-----------
+
+- Issue #9188: The gdb extension now handles correctly narrow (UCS2) as well
+ as wide (UCS4) unicode builds for both the host interpreter (embedded
+ inside gdb) and the interpreter under test.
+
Build
-----
Modified: python/branches/release27-maint/Tools/gdb/libpython.py
==============================================================================
--- python/branches/release27-maint/Tools/gdb/libpython.py (original)
+++ python/branches/release27-maint/Tools/gdb/libpython.py Wed Sep 8 23:12:36 2010
@@ -1011,6 +1011,18 @@
_typename = 'PyTypeObject'
+if sys.maxunicode >= 0x10000:
+ _unichr = unichr
+else:
+ # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb
+ def _unichr(x):
+ if x < 0x10000:
+ return unichr(x)
+ x -= 0x10000
+ ch1 = 0xD800 | (x >> 10)
+ ch2 = 0xDC00 | (x & 0x3FF)
+ return unichr(ch1) + unichr(ch2)
+
class PyUnicodeObjectPtr(PyObjectPtr):
_typename = 'PyUnicodeObject'
@@ -1027,37 +1039,36 @@
# Gather a list of ints from the Py_UNICODE array; these are either
# UCS-2 or UCS-4 code points:
- Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
+ if self.char_width() > 2:
+ Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
+ else:
+ # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the
+ # inferior process: we must join surrogate pairs.
+ Py_UNICODEs = []
+ i = 0
+ limit = safety_limit(field_length)
+ while i < limit:
+ ucs = int(field_str[i])
+ i += 1
+ if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
+ Py_UNICODEs.append(ucs)
+ continue
+ # This could be a surrogate pair.
+ ucs2 = int(field_str[i])
+ if ucs2 < 0xDC00 or ucs2 > 0xDFFF:
+ continue
+ code = (ucs & 0x03FF) << 10
+ code |= ucs2 & 0x03FF
+ code += 0x00010000
+ Py_UNICODEs.append(code)
+ i += 1
# Convert the int code points to unicode characters, and generate a
- # local unicode instance:
- result = u''.join([unichr(ucs) for ucs in Py_UNICODEs])
+ # local unicode instance.
+ # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb).
+ result = u''.join([_unichr(ucs) for ucs in Py_UNICODEs])
return result
- def write_repr(self, out, visited):
- proxy = self.proxyval(visited)
- if self.char_width() == 2:
- # sizeof(Py_UNICODE)==2: join surrogates
- proxy2 = []
- i = 0
- while i < len(proxy):
- ch = proxy[i]
- i += 1
- if (i < len(proxy)
- and 0xD800 <= ord(ch) < 0xDC00 \
- and 0xDC00 <= ord(proxy[i]) <= 0xDFFF):
- # Get code point from surrogate pair
- ch2 = proxy[i]
- code = (ord(ch) & 0x03FF) << 10
- code |= ord(ch2) & 0x03FF
- code += 0x00010000
- i += 1
- proxy2.append(unichr(code))
- else:
- proxy2.append(ch)
- proxy = u''.join(proxy2)
- out.write(repr(proxy))
-
def int_from_int(gdbval):
return int(str(gdbval))
From python-checkins at python.org Wed Sep 8 23:57:37 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 8 Sep 2010 23:57:37 +0200 (CEST)
Subject: [Python-checkins] r84638 - in python/branches/py3k:
Lib/test/test_gdb.py Tools/gdb/libpython.py
Message-ID: <20100908215737.D506DF831@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 8 23:57:37 2010
New Revision: 84638
Log:
gdb: fix representation of non-printable surrogate pairs, and workaround
a bug in ascii().
Modified:
python/branches/py3k/Lib/test/test_gdb.py
python/branches/py3k/Tools/gdb/libpython.py
Modified: python/branches/py3k/Lib/test/test_gdb.py
==============================================================================
--- python/branches/py3k/Lib/test/test_gdb.py (original)
+++ python/branches/py3k/Lib/test/test_gdb.py Wed Sep 8 23:57:37 2010
@@ -234,7 +234,9 @@
text.encode(encoding)
printable = True
except UnicodeEncodeError:
- self.assertGdbRepr(text, ascii(text))
+ # Workaround ascii() bug on UCS-2 builds: issue #9804
+ asc = "'" + text.encode('unicode-escape').decode('ascii') + "'"
+ self.assertGdbRepr(text, asc)
else:
self.assertGdbRepr(text)
Modified: python/branches/py3k/Tools/gdb/libpython.py
==============================================================================
--- python/branches/py3k/Tools/gdb/libpython.py (original)
+++ python/branches/py3k/Tools/gdb/libpython.py Wed Sep 8 23:57:37 2010
@@ -1171,9 +1171,8 @@
# Non-ASCII characters
else:
ucs = ch
- orig_ucs = None
ch2 = None
- if self.char_width() == 2:
+ if sys.maxunicode < 0x10000:
# If sizeof(Py_UNICODE) is 2 here (in gdb), join
# surrogate pairs before calling _unichr_is_printable.
if (i < len(proxy)
@@ -1183,22 +1182,26 @@
ucs = ch + ch2
i += 1
+ # Unfortuately, Python 2's unicode type doesn't seem
+ # to expose the "isprintable" method
printable = _unichr_is_printable(ucs)
if printable:
try:
ucs.encode(ENCODING)
except UnicodeEncodeError:
printable = False
- if orig_ucs is not None:
- ucs = orig_ucs
- i -= 1
# Map Unicode whitespace and control characters
# (categories Z* and C* except ASCII space)
if not printable:
- # Unfortuately, Python 2's unicode type doesn't seem
- # to expose the "isprintable" method
- code = ord(ucs)
+ if ch2 is not None:
+ # Match Python 3's representation of non-printable
+ # wide characters.
+ code = (ord(ch) & 0x03FF) << 10
+ code |= ord(ch2) & 0x03FF
+ code += 0x00010000
+ else:
+ code = ord(ucs)
# Map 8-bit characters to '\\xhh'
if code <= 0xff:
From python-checkins at python.org Thu Sep 9 00:44:13 2010
From: python-checkins at python.org (giampaolo.rodola)
Date: Thu, 9 Sep 2010 00:44:13 +0200 (CEST)
Subject: [Python-checkins] r84639 - in python/branches/py3k:
Doc/library/socket.rst Doc/whatsnew/3.2.rst Lib/socket.py
Lib/test/test_socket.py
Message-ID: <20100908224413.0E373F79A@mail.python.org>
Author: giampaolo.rodola
Date: Thu Sep 9 00:44:12 2010
New Revision: 84639
Log:
Fix issue 9794: adds context manager protocol to socket.socket so that socket.create_connection() can be used with the 'with' statement.
Modified:
python/branches/py3k/Doc/library/socket.rst
python/branches/py3k/Doc/whatsnew/3.2.rst
python/branches/py3k/Lib/socket.py
python/branches/py3k/Lib/test/test_socket.py
Modified: python/branches/py3k/Doc/library/socket.rst
==============================================================================
--- python/branches/py3k/Doc/library/socket.rst (original)
+++ python/branches/py3k/Doc/library/socket.rst Thu Sep 9 00:44:12 2010
@@ -213,6 +213,9 @@
.. versionchanged:: 3.2
*source_address* was added.
+ .. versionchanged:: 3.2
+ support for the :keyword:`with` statement was added.
+
.. function:: getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Thu Sep 9 00:44:12 2010
@@ -389,6 +389,12 @@
(Contributed by Giampaolo Rodol?; :issue:`8807`.)
+* :func:`socket.create_connection` now supports the context manager protocol
+ to unconditionally consume :exc:`socket.error` exceptions and to close the
+ socket when done.
+
+ (Contributed by Giampaolo Rodol?; :issue:`9794`.)
+
Multi-threading
===============
Modified: python/branches/py3k/Lib/socket.py
==============================================================================
--- python/branches/py3k/Lib/socket.py (original)
+++ python/branches/py3k/Lib/socket.py Thu Sep 9 00:44:12 2010
@@ -93,6 +93,13 @@
self._io_refs = 0
self._closed = False
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ if not self._closed:
+ self.close()
+
def __repr__(self):
"""Wrap __repr__() to reveal the real class name."""
s = _socket.socket.__repr__(self)
Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py (original)
+++ python/branches/py3k/Lib/test/test_socket.py Thu Sep 9 00:44:12 2010
@@ -1595,6 +1595,49 @@
self.cli.close()
+ at unittest.skipUnless(thread, 'Threading required for this test.')
+class ContextManagersTest(ThreadedTCPSocketTest):
+
+ def _testSocketClass(self):
+ # base test
+ with socket.socket() as sock:
+ self.assertFalse(sock._closed)
+ self.assertTrue(sock._closed)
+ # close inside with block
+ with socket.socket() as sock:
+ sock.close()
+ self.assertTrue(sock._closed)
+ # exception inside with block
+ with socket.socket() as sock:
+ self.assertRaises(socket.error, sock.sendall, b'foo')
+ self.assertTrue(sock._closed)
+
+ def testCreateConnectionBase(self):
+ conn, addr = self.serv.accept()
+ data = conn.recv(1024)
+ conn.sendall(data)
+
+ def _testCreateConnectionBase(self):
+ address = self.serv.getsockname()
+ with socket.create_connection(address) as sock:
+ self.assertFalse(sock._closed)
+ sock.sendall(b'foo')
+ self.assertEqual(sock.recv(1024), b'foo')
+ self.assertTrue(sock._closed)
+
+ def testCreateConnectionClose(self):
+ conn, addr = self.serv.accept()
+ data = conn.recv(1024)
+ conn.sendall(data)
+
+ def _testCreateConnectionClose(self):
+ address = self.serv.getsockname()
+ with socket.create_connection(address) as sock:
+ sock.close()
+ self.assertTrue(sock._closed)
+ self.assertRaises(socket.error, sock.sendall, b'foo')
+
+
def test_main():
tests = [GeneralModuleTests, BasicTCPTest, TCPCloserTest, TCPTimeoutTest,
TestExceptions, BufferIOTest, BasicTCPTest2, BasicUDPTest, UDPTimeoutTest ]
@@ -1609,6 +1652,7 @@
NetworkConnectionNoServer,
NetworkConnectionAttributesTest,
NetworkConnectionBehaviourTest,
+ ContextManagersTest,
])
if hasattr(socket, "socketpair"):
tests.append(BasicSocketPairTest)
From python-checkins at python.org Thu Sep 9 03:40:50 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 9 Sep 2010 03:40:50 +0200 (CEST)
Subject: [Python-checkins] r84640 - python/branches/py3k/Doc/library/cmd.rst
Message-ID: <20100909014050.39A7AEE9E3@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 9 03:40:50 2010
New Revision: 84640
Log:
Add a working example for the cmd module.
Modified:
python/branches/py3k/Doc/library/cmd.rst
Modified: python/branches/py3k/Doc/library/cmd.rst
==============================================================================
--- python/branches/py3k/Doc/library/cmd.rst (original)
+++ python/branches/py3k/Doc/library/cmd.rst Thu Sep 9 03:40:50 2010
@@ -203,3 +203,165 @@
:mod:`readline`, on systems that support it, the interpreter will automatically
support :program:`Emacs`\ -like line editing and command-history keystrokes.)
+Cmd Example
+===========
+
+.. sectionauthor:: Raymond Hettinger
+
+The :mod:`cmd` module is mainly useful for building custom shells that let a
+user work with a program interactively.
+
+This section presents a simple example of how to build a shell around a few of
+the commands in the :mod:`turtle` module.
+
+Basic turtle commands such as :meth:`~turtle.forward` are added to a
+:class:`Cmd` subclass with method named :meth:`do_forward`. The argument is
+converted to a number and dispatched to the turtle module. The docstring is
+used in the help utility provided by the shell.
+
+The example also includes a basic record and playback facility implemented with
+the :meth:`~Cmd.precmd` method which is responsible for converting the input to
+lowercase and writing the commands to a file. The :meth:`do_playback` method
+reads the file and adds the recorded commands to the :attr:`cmdqueue` for
+immediate playback::
+
+ import cmd, sys
+ from turtle import *
+
+ class TurtleShell(cmd.Cmd):
+ intro = 'Welcome to the turtle shell. Type help or ? to list commands.\n'
+ prompt = '(turtle) '
+ file = None
+
+ # ----- basic turtle commands -----
+ def do_forward(self, arg):
+ 'Move the turtle forward by the specified distance: FORWARD 10'
+ forward(*parse(arg))
+ def do_right(self, arg):
+ 'Turn turtle right by given number of degrees: RIGHT 20'
+ right(*parse(arg))
+ def do_left(self, arg):
+ 'Turn turtle left by given number of degrees: LEFT 90'
+ right(*parse(arg))
+ def do_goto(self, arg):
+ 'Move turtle to an absolute position with changing orientation. GOTO 100 200'
+ goto(*parse(arg))
+ def do_home(self, arg):
+ 'Return turtle to the home postion: HOME'
+ home()
+ def do_circle(self, arg):
+ 'Draw circle with given radius an options extent and steps: CIRCLE 50'
+ circle(*parse(arg))
+ def do_position(self, arg):
+ 'Print the current turle position: POSITION'
+ print('Current position is %d %d\n' % position())
+ def do_heading(self, arg):
+ 'Print the current turle heading in degrees: HEADING'
+ print('Current heading is %d\n' % (heading(),))
+ def do_color(self, arg):
+ 'Set the color: COLOR BLUE'
+ color(arg.lower())
+ def do_undo(self, arg):
+ 'Undo (repeatedly) the last turtle action(s): UNDO'
+ def do_reset(self, arg):
+ 'Clear the screen and return turtle to center: RESET'
+ reset()
+ def do_bye(self, arg):
+ 'Stop recording, close the turtle window, and exit: BYE'
+ print('Thank you for using Turtle')
+ self.close()
+ bye()
+ sys.exit(0)
+
+ # ----- record and playback -----
+ def do_record(self, arg):
+ 'Save future commands to filename: RECORD rose.cmd'
+ self.file = open(arg, 'w')
+ def do_playback(self, arg):
+ 'Playback commands from a file: PLAYBACK rose.cmd'
+ self.close()
+ cmds = open(arg).read().splitlines()
+ self.cmdqueue.extend(cmds)
+ def precmd(self, line):
+ line = line.lower()
+ if self.file and 'playback' not in line:
+ print(line, file=self.file)
+ return line
+ def close(self):
+ if self.file:
+ self.file.close()
+ self.file = None
+
+ def parse(arg):
+ 'Convert a series of zero or more numbers to an argument tuple'
+ return tuple(map(int, arg.split()))
+
+ if __name__ == '__main__':
+ TurtleShell().cmdloop()
+
+
+Here is a sample session with the turtle shell showing the help functions, using
+blank lines to repeat commands, and the simple record and playback facility::
+
+ Welcome to the turtle shell. Type help or ? to list commands.
+
+ (turtle) ?
+
+ Documented commands (type help ):
+ ========================================
+ bye color goto home playback record right
+ circle forward heading left position reset undo
+
+ Undocumented commands:
+ ======================
+ help
+
+ (turtle) help forward
+ Move the turtle forward by the specified distance: FORWARD 10
+ (turtle) record spiral.cmd
+ (turtle) position
+ Current position is 0 0
+
+ (turtle) heading
+ Current heading is 0
+
+ (turtle) reset
+ (turtle) circle 20
+ (turtle) right 30
+ (turtle) circle 40
+ (turtle) right 30
+ (turtle) circle 60
+ (turtle) right 30
+ (turtle) circle 80
+ (turtle) right 30
+ (turtle) circle 100
+ (turtle) right 30
+ (turtle) circle 120
+ (turtle) right 30
+ (turtle) circle 120
+ (turtle) heading
+ Current heading is 180
+
+ (turtle) forward 100
+ (turtle)
+ (turtle) right 90
+ (turtle) forward 100
+ (turtle)
+ (turtle) right 90
+ (turtle) forward 400
+ (turtle) right 90
+ (turtle) forward 500
+ (turtle) right 90
+ (turtle) forward 400
+ (turtle) right 90
+ (turtle) forward 300
+ (turtle) playback spiral.cmd
+ Current position is 0 0
+
+ Current heading is 0
+
+ Current heading is 180
+
+ (turtle) bye
+ Thank you for using Turtle
+
From solipsis at pitrou.net Thu Sep 9 05:03:23 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Thu, 09 Sep 2010 05:03:23 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84639): sum=0
Message-ID:
py3k results for svn r84639 (hg cset 02bcae26df4d)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog2Wob7S', '-x']
From python-checkins at python.org Thu Sep 9 05:53:22 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 9 Sep 2010 05:53:22 +0200 (CEST)
Subject: [Python-checkins] r84641 - in python/branches/py3k:
Doc/library/cmd.rst Lib/cmd.py Lib/test/test_cmd.py
Message-ID: <20100909035322.BD46EF794@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 9 05:53:22 2010
New Revision: 84641
Log:
Add docstring to cmd.Cmd.do_help()
Modified:
python/branches/py3k/Doc/library/cmd.rst
python/branches/py3k/Lib/cmd.py
python/branches/py3k/Lib/test/test_cmd.py
Modified: python/branches/py3k/Doc/library/cmd.rst
==============================================================================
--- python/branches/py3k/Doc/library/cmd.rst (original)
+++ python/branches/py3k/Doc/library/cmd.rst Thu Sep 9 05:53:22 2010
@@ -312,10 +312,6 @@
bye color goto home playback record right
circle forward heading left position reset undo
- Undocumented commands:
- ======================
- help
-
(turtle) help forward
Move the turtle forward by the specified distance: FORWARD 10
(turtle) record spiral.cmd
Modified: python/branches/py3k/Lib/cmd.py
==============================================================================
--- python/branches/py3k/Lib/cmd.py (original)
+++ python/branches/py3k/Lib/cmd.py Thu Sep 9 05:53:22 2010
@@ -288,6 +288,7 @@
return list(commands | topics)
def do_help(self, arg):
+ 'List available commands with "help" or detailed help with "help cmd".'
if arg:
# XXX check arg syntax
try:
Modified: python/branches/py3k/Lib/test/test_cmd.py
==============================================================================
--- python/branches/py3k/Lib/test/test_cmd.py (original)
+++ python/branches/py3k/Lib/test/test_cmd.py Thu Sep 9 05:53:22 2010
@@ -84,11 +84,11 @@
Documented commands (type help ):
========================================
- add
+ add help
Undocumented commands:
======================
- exit help shell
+ exit shell
Test for the function print_topics():
@@ -125,11 +125,11 @@
Documented commands (type help ):
========================================
- add
+ add help
Undocumented commands:
======================
- exit help shell
+ exit shell
help text for add
Hello from postloop
From python-checkins at python.org Thu Sep 9 06:32:39 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 9 Sep 2010 06:32:39 +0200 (CEST)
Subject: [Python-checkins] r84642 - in python/branches/py3k:
Doc/library/tokenize.rst Lib/tokenize.py
Message-ID: <20100909043239.3BAA4FAD9@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 9 06:32:39 2010
New Revision: 84642
Log:
Improve the repr for the TokenInfo named tuple.
Modified:
python/branches/py3k/Doc/library/tokenize.rst
python/branches/py3k/Lib/tokenize.py
Modified: python/branches/py3k/Doc/library/tokenize.rst
==============================================================================
--- python/branches/py3k/Doc/library/tokenize.rst (original)
+++ python/branches/py3k/Doc/library/tokenize.rst Thu Sep 9 06:32:39 2010
@@ -111,7 +111,7 @@
return fp.read()
-Example of a script re-writer that transforms float literals into Decimal
+Example of a script rewriter that transforms float literals into Decimal
objects::
from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OP
Modified: python/branches/py3k/Lib/tokenize.py
==============================================================================
--- python/branches/py3k/Lib/tokenize.py (original)
+++ python/branches/py3k/Lib/tokenize.py Thu Sep 9 06:32:39 2010
@@ -63,7 +63,9 @@
return result
def __repr__(self):
- return 'TokenInfo(type=%r, string=%r, start=%r, end=%r, line=%r)' % self
+ typ = self[0]
+ return 'TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' % \
+ ((('%d (%s)' % (typ, tok_name[typ])),) + self[1:])
def _asdict(self):
'Return a new dict which maps field names to their values'
@@ -550,3 +552,28 @@
# library that expect to be able to use tokenize with strings
def generate_tokens(readline):
return _tokenize(readline, None)
+
+if __name__ == "__main__":
+ # Quick sanity check
+ s = b'''def parseline(self, line):
+ """Parse the line into a command name and a string containing
+ the arguments. Returns a tuple containing (command, args, line).
+ 'command' and 'args' may be None if the line couldn't be parsed.
+ """
+ line = line.strip()
+ if not line:
+ return None, None, line
+ elif line[0] == '?':
+ line = 'help ' + line[1:]
+ elif line[0] == '!':
+ if hasattr(self, 'do_shell'):
+ line = 'shell ' + line[1:]
+ else:
+ return None, None, line
+ i, n = 0, len(line)
+ while i < n and line[i] in self.identchars: i = i+1
+ cmd, arg = line[:i], line[i:].strip()
+ return cmd, arg, line
+ '''
+ for tok in tokenize(iter(s.splitlines()).__next__):
+ print(tok)
From python-checkins at python.org Thu Sep 9 08:08:36 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu, 9 Sep 2010 08:08:36 +0200 (CEST)
Subject: [Python-checkins] r84643 - in python/branches/py3k/PC/VC6:
pythoncore.dsp readme.txt tcl852.patch
Message-ID: <20100909060836.A2D26F275@mail.python.org>
Author: hirokazu.yamamoto
Date: Thu Sep 9 08:08:36 2010
New Revision: 84643
Log:
Updated VC6 files.
* pythoncore.dsp: updated project file
* readme.txt: removed dead link
* tcl852.patch: fixed patch. it was doubled.
Modified:
python/branches/py3k/PC/VC6/pythoncore.dsp
python/branches/py3k/PC/VC6/readme.txt
python/branches/py3k/PC/VC6/tcl852.patch
Modified: python/branches/py3k/PC/VC6/pythoncore.dsp
==============================================================================
--- python/branches/py3k/PC/VC6/pythoncore.dsp (original)
+++ python/branches/py3k/PC/VC6/pythoncore.dsp Thu Sep 9 08:08:36 2010
@@ -133,6 +133,10 @@
# End Source File
# Begin Source File
+SOURCE=..\..\Modules\_datetimemodule.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Modules\_functoolsmodule.c
# End Source File
# Begin Source File
@@ -185,6 +189,10 @@
# End Source File
# Begin Source File
+SOURCE=..\..\Modules\_time.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Python\_warnings.c
# End Source File
# Begin Source File
@@ -309,7 +317,7 @@
# End Source File
# Begin Source File
-SOURCE=..\..\Modules\datetimemodule.c
+SOURCE=..\..\Python\dynamic_annotations.c
# End Source File
# Begin Source File
@@ -635,6 +643,10 @@
# End Source File
# Begin Source File
+SOURCE=..\..\Python\pytime.c
+# End Source File
+# Begin Source File
+
SOURCE=..\..\Objects\rangeobject.c
# End Source File
# Begin Source File
Modified: python/branches/py3k/PC/VC6/readme.txt
==============================================================================
--- python/branches/py3k/PC/VC6/readme.txt (original)
+++ python/branches/py3k/PC/VC6/readme.txt Thu Sep 9 08:08:36 2010
@@ -2,8 +2,7 @@
-------------------------------------
This directory is used to build Python for Win32 platforms, e.g. Windows
2000 and XP. It requires Microsoft Visual C++ 6.x or 5.x and Platform
-SDK February 2003 Edition (Core SDK). You can download this SDK from
-http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm.
+SDK February 2003 Edition (Core SDK).
(For other Windows platforms and compilers, see ../readme.txt.)
All you need to do is open the workspace "pcbuild.dsw" in MSVC++, select
Modified: python/branches/py3k/PC/VC6/tcl852.patch
==============================================================================
--- python/branches/py3k/PC/VC6/tcl852.patch (original)
+++ python/branches/py3k/PC/VC6/tcl852.patch Thu Sep 9 08:08:36 2010
@@ -9,14 +9,3 @@
typedef struct _stati64 Tcl_StatBuf;
# else
typedef struct _stat64 Tcl_StatBuf;
---- tcl8.5.2\generic\tcl.h Fri Jun 13 03:35:39 2008
-+++ tcl8.5.2\generic\tcl.h Sun Jan 4 16:52:30 2009
-@@ -367,7 +367,7 @@
- typedef struct stati64 Tcl_StatBuf;
- # define TCL_LL_MODIFIER "L"
- # else /* __BORLANDC__ */
--# if _MSC_VER < 1400 && !defined(_M_IX86)
-+# if _MSC_VER < 1400 /*&& !defined(_M_IX86)*/
- typedef struct _stati64 Tcl_StatBuf;
- # else
- typedef struct _stat64 Tcl_StatBuf;
From python-checkins at python.org Thu Sep 9 08:14:23 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu, 9 Sep 2010 08:14:23 +0200 (CEST)
Subject: [Python-checkins] r84644 - in python/branches/py3k: Misc/ACKS
PC/VS7.1/pythoncore.vcproj
Message-ID: <20100909061423.CE919F4A6@mail.python.org>
Author: hirokazu.yamamoto
Date: Thu Sep 9 08:14:23 2010
New Revision: 84644
Log:
Updated VS7.1 project file. (I cannot test this file because I don't have VS7.1)
Modified:
python/branches/py3k/Misc/ACKS
python/branches/py3k/PC/VS7.1/pythoncore.vcproj
Modified: python/branches/py3k/Misc/ACKS
==============================================================================
--- python/branches/py3k/Misc/ACKS (original)
+++ python/branches/py3k/Misc/ACKS Thu Sep 9 08:14:23 2010
@@ -902,6 +902,7 @@
Heiko Wundram
Doug Wyatt
Florent Xicluna
+Hirokazu Yamamoto
Ka-Ping Yee
Bob Yodlowski
Danny Yoo
Modified: python/branches/py3k/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PC/VS7.1/pythoncore.vcproj (original)
+++ python/branches/py3k/PC/VS7.1/pythoncore.vcproj Thu Sep 9 08:14:23 2010
@@ -391,9 +391,15 @@
RelativePath="..\..\Modules\_codecsmodule.c">
+
+
+
+
+ RelativePath="..\..\Modules\_time.c">
+ RelativePath="..\..\Modules\_weakref.c">
@@ -472,6 +478,9 @@
RelativePath="..\..\Objects\bytes_methods.c">
+
+
-
-
-
-
+
+
-
-
+
+
Author: hirokazu.yamamoto
Date: Thu Sep 9 08:24:43 2010
New Revision: 84645
Log:
PCBuild cosmetic fixes.
* pythoncore.vcproj: Fixed indentation
* _multiprocessing.vcproj: Converted ProjectGUID to uppercase. Otherwise,
VS8 _multiprocessing.vcproj created by vs9to8.py was modified every time
loads it in VS8 IDE.
Modified:
python/branches/py3k/PCbuild/_multiprocessing.vcproj
python/branches/py3k/PCbuild/pythoncore.vcproj
Modified: python/branches/py3k/PCbuild/_multiprocessing.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/_multiprocessing.vcproj (original)
+++ python/branches/py3k/PCbuild/_multiprocessing.vcproj Thu Sep 9 08:24:43 2010
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9,00"
Name="_multiprocessing"
- ProjectGUID="{9e48b300-37d1-11dd-8c41-005056c00008}"
+ ProjectGUID="{9E48B300-37D1-11DD-8C41-005056C00008}"
RootNamespace="_multiprocessing"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
Modified: python/branches/py3k/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/py3k/PCbuild/pythoncore.vcproj (original)
+++ python/branches/py3k/PCbuild/pythoncore.vcproj Thu Sep 9 08:24:43 2010
@@ -842,7 +842,10 @@
RelativePath="..\Include\pyarena.h"
>
-
+
+
@@ -1391,10 +1394,10 @@
RelativePath="..\Objects\bytesobject.c"
>
-
-
+
+
From python-checkins at python.org Thu Sep 9 09:15:18 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 9 Sep 2010 09:15:18 +0200 (CEST)
Subject: [Python-checkins] r84646 - python/branches/py3k/Lib/tokenize.py
Message-ID: <20100909071518.94FC7F943@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 9 09:15:18 2010
New Revision: 84646
Log:
Experiment: Let collections.namedtuple() do the work. This should work now that _collections is pre-built. The buildbots will tell us shortly.
Modified:
python/branches/py3k/Lib/tokenize.py
Modified: python/branches/py3k/Lib/tokenize.py
==============================================================================
--- python/branches/py3k/Lib/tokenize.py (original)
+++ python/branches/py3k/Lib/tokenize.py Thu Sep 9 09:15:18 2010
@@ -28,6 +28,7 @@
import sys
from token import *
from codecs import lookup, BOM_UTF8
+import collections
cookie_re = re.compile("coding[:=]\s*([-\w.]+)")
import token
@@ -44,49 +45,12 @@
tok_name[ENCODING] = 'ENCODING'
N_TOKENS += 3
-class TokenInfo(tuple):
- 'TokenInfo(type, string, start, end, line)'
-
- __slots__ = ()
-
- _fields = ('type', 'string', 'start', 'end', 'line')
-
- def __new__(cls, type, string, start, end, line):
- return tuple.__new__(cls, (type, string, start, end, line))
-
- @classmethod
- def _make(cls, iterable, new=tuple.__new__, len=len):
- 'Make a new TokenInfo object from a sequence or iterable'
- result = new(cls, iterable)
- if len(result) != 5:
- raise TypeError('Expected 5 arguments, got %d' % len(result))
- return result
-
+class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')):
def __repr__(self):
- typ = self[0]
+ typ = self.type
return 'TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' % \
((('%d (%s)' % (typ, tok_name[typ])),) + self[1:])
- def _asdict(self):
- 'Return a new dict which maps field names to their values'
- return dict(zip(self._fields, self))
-
- def _replace(self, **kwds):
- 'Return a new TokenInfo object replacing specified fields with new values'
- result = self._make(map(kwds.pop, ('type', 'string', 'start', 'end', 'line'), self))
- if kwds:
- raise ValueError('Got unexpected field names: %r' % kwds.keys())
- return result
-
- def __getnewargs__(self):
- return tuple(self)
-
- type = property(lambda t: t[0])
- string = property(lambda t: t[1])
- start = property(lambda t: t[2])
- end = property(lambda t: t[3])
- line = property(lambda t: t[4])
-
def group(*choices): return '(' + '|'.join(choices) + ')'
def any(*choices): return group(*choices) + '*'
def maybe(*choices): return group(*choices) + '?'
From python-checkins at python.org Thu Sep 9 10:29:05 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 9 Sep 2010 10:29:05 +0200 (CEST)
Subject: [Python-checkins] r84647 - python/branches/py3k/Lib/tokenize.py
Message-ID: <20100909082905.A93C1E4D4@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 9 10:29:05 2010
New Revision: 84647
Log:
A little bit more readable repr method.
Modified:
python/branches/py3k/Lib/tokenize.py
Modified: python/branches/py3k/Lib/tokenize.py
==============================================================================
--- python/branches/py3k/Lib/tokenize.py (original)
+++ python/branches/py3k/Lib/tokenize.py Thu Sep 9 10:29:05 2010
@@ -47,9 +47,9 @@
class TokenInfo(collections.namedtuple('TokenInfo', 'type string start end line')):
def __repr__(self):
- typ = self.type
- return 'TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' % \
- ((('%d (%s)' % (typ, tok_name[typ])),) + self[1:])
+ annotated_type = '%d (%s)' % (self.type, tok_name[self.type])
+ return ('TokenInfo(type=%s, string=%r, start=%r, end=%r, line=%r)' %
+ self._replace(type=annotated_type))
def group(*choices): return '(' + '|'.join(choices) + ')'
def any(*choices): return group(*choices) + '*'
From python-checkins at python.org Thu Sep 9 14:31:00 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Thu, 9 Sep 2010 14:31:00 +0200 (CEST)
Subject: [Python-checkins] r84648 - in python/branches/py3k: Lib/pprint.py
Lib/test/test_pprint.py Misc/NEWS
Message-ID: <20100909123100.795EAF4A6@mail.python.org>
Author: raymond.hettinger
Date: Thu Sep 9 14:31:00 2010
New Revision: 84648
Log:
Have pprint() respect the order in an OrderedDict.
Modified:
python/branches/py3k/Lib/pprint.py
python/branches/py3k/Lib/test/test_pprint.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/pprint.py
==============================================================================
--- python/branches/py3k/Lib/pprint.py (original)
+++ python/branches/py3k/Lib/pprint.py Thu Sep 9 14:31:00 2010
@@ -35,7 +35,7 @@
"""
import sys as _sys
-
+from collections import OrderedDict as _OrderedDict
from io import StringIO as _StringIO
__all__ = ["pprint","pformat","isreadable","isrecursive","saferepr",
@@ -163,7 +163,7 @@
if sepLines:
r = getattr(typ, "__repr__", None)
- if issubclass(typ, dict) and r is dict.__repr__:
+ if issubclass(typ, dict):
write('{')
if self._indent_per_level > 1:
write((self._indent_per_level - 1) * ' ')
@@ -171,7 +171,10 @@
if length:
context[objid] = 1
indent = indent + self._indent_per_level
- items = sorted(object.items(), key=_safe_tuple)
+ if issubclass(typ, _OrderedDict):
+ items = list(object.items())
+ else:
+ items = sorted(object.items(), key=_safe_tuple)
key, ent = items[0]
rep = self._repr(key, context, level)
write(rep)
Modified: python/branches/py3k/Lib/test/test_pprint.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pprint.py (original)
+++ python/branches/py3k/Lib/test/test_pprint.py Thu Sep 9 14:31:00 2010
@@ -3,6 +3,8 @@
import unittest
import test.test_set
import random
+import collections
+import itertools
# list, tuple and dict subclasses that do or don't overwrite __repr__
class list2(list):
@@ -195,6 +197,20 @@
self.assertEqual(pprint.pformat({"xy\tab\n": (3,), 5: [[]], (): {}}),
r"{5: [[]], 'xy\tab\n': (3,), (): {}}")
+ def test_ordered_dict(self):
+ words = 'the quick brown fox jumped over a lazy dog'.split()
+ d = collections.OrderedDict(zip(words, itertools.count()))
+ self.assertEqual(pprint.pformat(d),
+"""\
+{'the': 0,
+ 'quick': 1,
+ 'brown': 2,
+ 'fox': 3,
+ 'jumped': 4,
+ 'over': 5,
+ 'a': 6,
+ 'lazy': 7,
+ 'dog': 8}""")
def test_subclassing(self):
o = {'names with spaces': 'should be presented using repr()',
'others.should.not.be': 'like.this'}
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Thu Sep 9 14:31:00 2010
@@ -16,6 +16,9 @@
Library
-------
+- The pprint module now supports printing OrderedDicts in their given
+ order (formerly, it would sort the keys).
+
- Logging: Added QueueHandler class to facilitate logging usage with
multiprocessing.
From python-checkins at python.org Thu Sep 9 14:59:39 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 14:59:39 +0200 (CEST)
Subject: [Python-checkins] r84649 - in python/branches/py3k:
Doc/library/stdtypes.rst Lib/test/test_memoryview.py
Misc/NEWS Objects/memoryobject.c
Message-ID: <20100909125939.AB4B2EE98D@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 14:59:39 2010
New Revision: 84649
Log:
Issue #9757: memoryview objects get a release() method to release the
underlying buffer (previously this was only done when deallocating the
memoryview), and gain support for the context management protocol.
Modified:
python/branches/py3k/Doc/library/stdtypes.rst
python/branches/py3k/Lib/test/test_memoryview.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/memoryobject.c
Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst (original)
+++ python/branches/py3k/Doc/library/stdtypes.rst Thu Sep 9 14:59:39 2010
@@ -2311,7 +2311,40 @@
Notice how the size of the memoryview object cannot be changed.
- :class:`memoryview` has two methods:
+ :class:`memoryview` has several methods:
+
+ .. method:: release()
+
+ Release the underlying buffer exposed by the memoryview object. Many
+ objects take special actions when a view is held on them (for example,
+ a :class:`bytearray` would temporarily forbid resizing); therefore,
+ calling release() is handy to remove these restrictions (and free any
+ dangling resources) as soon as possible.
+
+ After this method has been called, any further operation on the view
+ raises a :class:`ValueError` (except :meth:`release()` itself which can
+ be called multiple times)::
+
+ >>> m = memoryview(b'abc')
+ >>> m.release()
+ >>> m[0]
+ Traceback (most recent call last):
+ File "", line 1, in
+ ValueError: operation forbidden on released memoryview object
+
+ The context management protocol can be used for a similar effect,
+ using the ``with`` statement::
+
+ >>> with memoryview(b'abc') as m:
+ ... m[0]
+ ...
+ b'a'
+ >>> m[0]
+ Traceback (most recent call last):
+ File "", line 1, in
+ ValueError: operation forbidden on released memoryview object
+
+ .. versionadded:: 3.2
.. method:: tobytes()
Modified: python/branches/py3k/Lib/test/test_memoryview.py
==============================================================================
--- python/branches/py3k/Lib/test/test_memoryview.py (original)
+++ python/branches/py3k/Lib/test/test_memoryview.py Thu Sep 9 14:59:39 2010
@@ -225,6 +225,51 @@
gc.collect()
self.assertTrue(wr() is None, wr())
+ def _check_released(self, m, tp):
+ check = self.assertRaisesRegexp(ValueError, "released")
+ with check: bytes(m)
+ with check: m.tobytes()
+ with check: m.tolist()
+ with check: m[0]
+ with check: m[0] = b'x'
+ with check: len(m)
+ with check: m.format
+ with check: m.itemsize
+ with check: m.ndim
+ with check: m.readonly
+ with check: m.shape
+ with check: m.strides
+ with check:
+ with m:
+ pass
+ # str() and repr() still function
+ self.assertIn("released memory", str(m))
+ self.assertIn("released memory", repr(m))
+ self.assertEqual(m, m)
+ self.assertNotEqual(m, memoryview(tp(self._source)))
+ self.assertNotEqual(m, tp(self._source))
+
+ def test_contextmanager(self):
+ for tp in self._types:
+ b = tp(self._source)
+ m = self._view(b)
+ with m as cm:
+ self.assertIs(cm, m)
+ self._check_released(m, tp)
+ m = self._view(b)
+ # Can release explicitly inside the context manager
+ with m:
+ m.release()
+
+ def test_release(self):
+ for tp in self._types:
+ b = tp(self._source)
+ m = self._view(b)
+ m.release()
+ self._check_released(m, tp)
+ # Can be called a second time (it's a no-op)
+ m.release()
+ self._check_released(m, tp)
# Variations on source objects for the buffer: bytes-like objects, then arrays
# with itemsize > 1.
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Thu Sep 9 14:59:39 2010
@@ -10,6 +10,10 @@
Core and Builtins
-----------------
+- Issue #9757: memoryview objects get a release() method to release the
+ underlying buffer (previously this was only done when deallocating the
+ memoryview), and gain support for the context management protocol.
+
- Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
thread-local storage key.
Modified: python/branches/py3k/Objects/memoryobject.c
==============================================================================
--- python/branches/py3k/Objects/memoryobject.c (original)
+++ python/branches/py3k/Objects/memoryobject.c Thu Sep 9 14:59:39 2010
@@ -3,6 +3,23 @@
#include "Python.h"
+#define IS_RELEASED(memobj) \
+ (((PyMemoryViewObject *) memobj)->view.buf == NULL)
+
+#define CHECK_RELEASED(memobj) \
+ if (IS_RELEASED(memobj)) { \
+ PyErr_SetString(PyExc_ValueError, \
+ "operation forbidden on released memoryview object"); \
+ return NULL; \
+ }
+
+#define CHECK_RELEASED_INT(memobj) \
+ if (IS_RELEASED(memobj)) { \
+ PyErr_SetString(PyExc_ValueError, \
+ "operation forbidden on released memoryview object"); \
+ return -1; \
+ }
+
static Py_ssize_t
get_shape0(Py_buffer *buf)
{
@@ -34,6 +51,7 @@
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
{
int res = 0;
+ CHECK_RELEASED_INT(self);
/* XXX for whatever reason fixing the flags seems necessary */
if (self->view.readonly)
flags &= ~PyBUF_WRITABLE;
@@ -330,12 +348,14 @@
static PyObject *
memory_format_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyUnicode_FromString(self->view.format);
}
static PyObject *
memory_itemsize_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyLong_FromSsize_t(self->view.itemsize);
}
@@ -366,30 +386,35 @@
static PyObject *
memory_shape_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
}
static PyObject *
memory_strides_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
}
static PyObject *
memory_suboffsets_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
}
static PyObject *
memory_readonly_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyBool_FromLong(self->view.readonly);
}
static PyObject *
memory_ndim_get(PyMemoryViewObject *self)
{
+ CHECK_RELEASED(self);
return PyLong_FromLong(self->view.ndim);
}
@@ -408,6 +433,7 @@
static PyObject *
memory_tobytes(PyMemoryViewObject *mem, PyObject *noargs)
{
+ CHECK_RELEASED(mem);
return PyObject_CallFunctionObjArgs(
(PyObject *) &PyBytes_Type, mem, NULL);
}
@@ -423,6 +449,7 @@
PyObject *res, *item;
char *buf;
+ CHECK_RELEASED(mem);
if (strcmp(view->format, "B") || view->itemsize != 1) {
PyErr_SetString(PyExc_NotImplementedError,
"tolist() only supports byte views");
@@ -449,17 +476,9 @@
return res;
}
-static PyMethodDef memory_methods[] = {
- {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
- {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
- {NULL, NULL} /* sentinel */
-};
-
-
static void
-memory_dealloc(PyMemoryViewObject *self)
+do_release(PyMemoryViewObject *self)
{
- _PyObject_GC_UNTRACK(self);
if (self->view.obj != NULL) {
if (self->base && PyTuple_Check(self->base)) {
/* Special case when first element is generic object
@@ -484,19 +503,57 @@
}
Py_CLEAR(self->base);
}
+ self->view.obj = NULL;
+ self->view.buf = NULL;
+}
+
+static PyObject *
+memory_enter(PyObject *self, PyObject *args)
+{
+ CHECK_RELEASED(self);
+ Py_INCREF(self);
+ return self;
+}
+
+static PyObject *
+memory_exit(PyObject *self, PyObject *args)
+{
+ do_release((PyMemoryViewObject *) self);
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef memory_methods[] = {
+ {"release", memory_exit, METH_NOARGS},
+ {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
+ {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
+ {"__enter__", memory_enter, METH_NOARGS},
+ {"__exit__", memory_exit, METH_VARARGS},
+ {NULL, NULL} /* sentinel */
+};
+
+
+static void
+memory_dealloc(PyMemoryViewObject *self)
+{
+ _PyObject_GC_UNTRACK(self);
+ do_release(self);
PyObject_GC_Del(self);
}
static PyObject *
memory_repr(PyMemoryViewObject *self)
{
- return PyUnicode_FromFormat("", self);
+ if (IS_RELEASED(self))
+ return PyUnicode_FromFormat("", self);
+ else
+ return PyUnicode_FromFormat("", self);
}
/* Sequence methods */
static Py_ssize_t
memory_length(PyMemoryViewObject *self)
{
+ CHECK_RELEASED_INT(self);
return get_shape0(&self->view);
}
@@ -508,6 +565,7 @@
{
Py_buffer *view = &(self->view);
+ CHECK_RELEASED(self);
if (view->ndim == 0) {
PyErr_SetString(PyExc_IndexError,
"invalid indexing of 0-dim memory");
@@ -557,6 +615,7 @@
Py_buffer *view;
view = &(self->view);
+ CHECK_RELEASED(self);
if (view->ndim == 0) {
if (key == Py_Ellipsis ||
(PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
@@ -626,6 +685,7 @@
Py_buffer *view = &(self->view);
char *srcbuf, *destbuf;
+ CHECK_RELEASED_INT(self);
if (view->readonly) {
PyErr_SetString(PyExc_TypeError,
"cannot modify read-only memory");
@@ -718,6 +778,11 @@
ww.obj = NULL;
if (op != Py_EQ && op != Py_NE)
goto _notimpl;
+ if ((PyMemoryView_Check(v) && IS_RELEASED(v)) ||
+ (PyMemoryView_Check(w) && IS_RELEASED(w))) {
+ equal = (v == w);
+ goto _end;
+ }
if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
PyErr_Clear();
goto _notimpl;
From python-checkins at python.org Thu Sep 9 15:31:47 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 15:31:47 +0200 (CEST)
Subject: [Python-checkins] r84650 - python/branches/py3k/Lib/test/test_ssl.py
Message-ID: <20100909133147.278ABEE990@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 15:31:46 2010
New Revision: 84650
Log:
Use transient_internet() where appropriate in test_ssl
(svn.python.org is sometimes unavailable)
Modified:
python/branches/py3k/Lib/test/test_ssl.py
Modified: python/branches/py3k/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ssl.py (original)
+++ python/branches/py3k/Lib/test/test_ssl.py Thu Sep 9 15:31:46 2010
@@ -305,63 +305,59 @@
class NetworkedTests(unittest.TestCase):
- def setUp(self):
- self.old_timeout = socket.getdefaulttimeout()
- socket.setdefaulttimeout(30)
-
- def tearDown(self):
- socket.setdefaulttimeout(self.old_timeout)
def test_connect(self):
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_NONE)
- try:
- s.connect(("svn.python.org", 443))
- self.assertEqual({}, s.getpeercert())
- finally:
- s.close()
+ with support.transient_internet("svn.python.org"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_NONE)
+ try:
+ s.connect(("svn.python.org", 443))
+ self.assertEqual({}, s.getpeercert())
+ finally:
+ s.close()
- # this should fail because we have no verification certs
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED)
- self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
- s.connect, ("svn.python.org", 443))
- s.close()
-
- # this should succeed because we specify the root cert
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
- try:
- s.connect(("svn.python.org", 443))
- self.assertTrue(s.getpeercert())
- finally:
+ # this should fail because we have no verification certs
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED)
+ self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
+ s.connect, ("svn.python.org", 443))
s.close()
+ # this should succeed because we specify the root cert
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+ try:
+ s.connect(("svn.python.org", 443))
+ self.assertTrue(s.getpeercert())
+ finally:
+ s.close()
+
def test_connect_with_context(self):
- # Same as test_connect, but with a separately created context
- ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- s = ctx.wrap_socket(socket.socket(socket.AF_INET))
- s.connect(("svn.python.org", 443))
- try:
- self.assertEqual({}, s.getpeercert())
- finally:
- s.close()
- # This should fail because we have no verification certs
- ctx.verify_mode = ssl.CERT_REQUIRED
- s = ctx.wrap_socket(socket.socket(socket.AF_INET))
- self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
- s.connect, ("svn.python.org", 443))
- s.close()
- # This should succeed because we specify the root cert
- ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
- s = ctx.wrap_socket(socket.socket(socket.AF_INET))
- s.connect(("svn.python.org", 443))
- try:
- cert = s.getpeercert()
- self.assertTrue(cert)
- finally:
+ with support.transient_internet("svn.python.org"):
+ # Same as test_connect, but with a separately created context
+ ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ s = ctx.wrap_socket(socket.socket(socket.AF_INET))
+ s.connect(("svn.python.org", 443))
+ try:
+ self.assertEqual({}, s.getpeercert())
+ finally:
+ s.close()
+ # This should fail because we have no verification certs
+ ctx.verify_mode = ssl.CERT_REQUIRED
+ s = ctx.wrap_socket(socket.socket(socket.AF_INET))
+ self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
+ s.connect, ("svn.python.org", 443))
s.close()
+ # This should succeed because we specify the root cert
+ ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
+ s = ctx.wrap_socket(socket.socket(socket.AF_INET))
+ s.connect(("svn.python.org", 443))
+ try:
+ cert = s.getpeercert()
+ self.assertTrue(cert)
+ finally:
+ s.close()
def test_connect_capath(self):
# Verify server certificates using the `capath` argument
@@ -369,104 +365,109 @@
# OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
# contain both versions of each certificate (same content, different
# filename) for this test to be portable across OpenSSL releases.
- ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- ctx.verify_mode = ssl.CERT_REQUIRED
- ctx.load_verify_locations(capath=CAPATH)
- s = ctx.wrap_socket(socket.socket(socket.AF_INET))
- s.connect(("svn.python.org", 443))
- try:
- cert = s.getpeercert()
- self.assertTrue(cert)
- finally:
- s.close()
- # Same with a bytes `capath` argument
- ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
- ctx.verify_mode = ssl.CERT_REQUIRED
- ctx.load_verify_locations(capath=BYTES_CAPATH)
- s = ctx.wrap_socket(socket.socket(socket.AF_INET))
- s.connect(("svn.python.org", 443))
- try:
- cert = s.getpeercert()
- self.assertTrue(cert)
- finally:
- s.close()
+ with support.transient_internet("svn.python.org"):
+ ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ ctx.verify_mode = ssl.CERT_REQUIRED
+ ctx.load_verify_locations(capath=CAPATH)
+ s = ctx.wrap_socket(socket.socket(socket.AF_INET))
+ s.connect(("svn.python.org", 443))
+ try:
+ cert = s.getpeercert()
+ self.assertTrue(cert)
+ finally:
+ s.close()
+ # Same with a bytes `capath` argument
+ ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ ctx.verify_mode = ssl.CERT_REQUIRED
+ ctx.load_verify_locations(capath=BYTES_CAPATH)
+ s = ctx.wrap_socket(socket.socket(socket.AF_INET))
+ s.connect(("svn.python.org", 443))
+ try:
+ cert = s.getpeercert()
+ self.assertTrue(cert)
+ finally:
+ s.close()
@unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
def test_makefile_close(self):
# Issue #5238: creating a file-like object with makefile() shouldn't
# delay closing the underlying "real socket" (here tested with its
# file descriptor, hence skipping the test under Windows).
- ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
- ss.connect(("svn.python.org", 443))
- fd = ss.fileno()
- f = ss.makefile()
- f.close()
- # The fd is still open
- os.read(fd, 0)
- # Closing the SSL socket should close the fd too
- ss.close()
- gc.collect()
- with self.assertRaises(OSError) as e:
+ with support.transient_internet("svn.python.org"):
+ ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
+ ss.connect(("svn.python.org", 443))
+ fd = ss.fileno()
+ f = ss.makefile()
+ f.close()
+ # The fd is still open
os.read(fd, 0)
- self.assertEqual(e.exception.errno, errno.EBADF)
+ # Closing the SSL socket should close the fd too
+ ss.close()
+ gc.collect()
+ with self.assertRaises(OSError) as e:
+ os.read(fd, 0)
+ self.assertEqual(e.exception.errno, errno.EBADF)
def test_non_blocking_handshake(self):
- s = socket.socket(socket.AF_INET)
- s.connect(("svn.python.org", 443))
- s.setblocking(False)
- s = ssl.wrap_socket(s,
- cert_reqs=ssl.CERT_NONE,
- do_handshake_on_connect=False)
- count = 0
- while True:
- try:
- count += 1
- s.do_handshake()
- break
- except ssl.SSLError as err:
- if err.args[0] == ssl.SSL_ERROR_WANT_READ:
- select.select([s], [], [])
- elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
- select.select([], [s], [])
- else:
- raise
- s.close()
- if support.verbose:
- sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
+ with support.transient_internet("svn.python.org"):
+ s = socket.socket(socket.AF_INET)
+ s.connect(("svn.python.org", 443))
+ s.setblocking(False)
+ s = ssl.wrap_socket(s,
+ cert_reqs=ssl.CERT_NONE,
+ do_handshake_on_connect=False)
+ count = 0
+ while True:
+ try:
+ count += 1
+ s.do_handshake()
+ break
+ except ssl.SSLError as err:
+ if err.args[0] == ssl.SSL_ERROR_WANT_READ:
+ select.select([s], [], [])
+ elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
+ select.select([], [s], [])
+ else:
+ raise
+ s.close()
+ if support.verbose:
+ sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
def test_get_server_certificate(self):
- pem = ssl.get_server_certificate(("svn.python.org", 443))
- if not pem:
- self.fail("No server certificate on svn.python.org:443!")
+ with support.transient_internet("svn.python.org"):
+ pem = ssl.get_server_certificate(("svn.python.org", 443))
+ if not pem:
+ self.fail("No server certificate on svn.python.org:443!")
- try:
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
- except ssl.SSLError as x:
- #should fail
- if support.verbose:
- sys.stdout.write("%s\n" % x)
- else:
- self.fail("Got server certificate %s for svn.python.org!" % pem)
+ try:
+ pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
+ except ssl.SSLError as x:
+ #should fail
+ if support.verbose:
+ sys.stdout.write("%s\n" % x)
+ else:
+ self.fail("Got server certificate %s for svn.python.org!" % pem)
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
- if not pem:
- self.fail("No server certificate on svn.python.org:443!")
- if support.verbose:
- sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
+ pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+ if not pem:
+ self.fail("No server certificate on svn.python.org:443!")
+ if support.verbose:
+ sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
def test_ciphers(self):
remote = ("svn.python.org", 443)
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_NONE, ciphers="ALL")
- s.connect(remote)
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
- s.connect(remote)
- # Error checking can happen at instantiation or when connecting
- with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
+ with support.transient_internet(remote[0]):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_NONE, ciphers="ALL")
+ s.connect(remote)
s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
+ cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
s.connect(remote)
+ # Error checking can happen at instantiation or when connecting
+ with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
+ s.connect(remote)
def test_algorithms(self):
# Issue #8484: all algorithms should be available when verifying a
From python-checkins at python.org Thu Sep 9 15:33:34 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 15:33:34 +0200 (CEST)
Subject: [Python-checkins] r84651 - in python/branches/release31-maint:
Lib/test/test_ssl.py
Message-ID: <20100909133334.10077EE990@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 15:33:33 2010
New Revision: 84651
Log:
Merged revisions 84650 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84650 | antoine.pitrou | 2010-09-09 15:31:46 +0200 (jeu., 09 sept. 2010) | 4 lines
Use transient_internet() where appropriate in test_ssl
(svn.python.org is sometimes unavailable)
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_ssl.py
Modified: python/branches/release31-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release31-maint/Lib/test/test_ssl.py Thu Sep 9 15:33:33 2010
@@ -103,106 +103,104 @@
class NetworkedTests(unittest.TestCase):
- def setUp(self):
- self.old_timeout = socket.getdefaulttimeout()
- socket.setdefaulttimeout(30)
-
- def tearDown(self):
- socket.setdefaulttimeout(self.old_timeout)
def test_connect(self):
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_NONE)
- s.connect(("svn.python.org", 443))
- c = s.getpeercert()
- if c:
- self.fail("Peer cert %s shouldn't be here!")
- s.close()
-
- # this should fail because we have no verification certs
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED)
- try:
+ with support.transient_internet("svn.python.org"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_NONE)
s.connect(("svn.python.org", 443))
- except ssl.SSLError:
- pass
- finally:
+ c = s.getpeercert()
+ if c:
+ self.fail("Peer cert %s shouldn't be here!")
s.close()
- # this should succeed because we specify the root cert
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
- try:
- s.connect(("svn.python.org", 443))
- finally:
- s.close()
+ # this should fail because we have no verification certs
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED)
+ try:
+ s.connect(("svn.python.org", 443))
+ except ssl.SSLError:
+ pass
+ finally:
+ s.close()
+
+ # this should succeed because we specify the root cert
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+ try:
+ s.connect(("svn.python.org", 443))
+ finally:
+ s.close()
@unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
def test_makefile_close(self):
# Issue #5238: creating a file-like object with makefile() shouldn't
# delay closing the underlying "real socket" (here tested with its
# file descriptor, hence skipping the test under Windows).
- ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
- ss.connect(("svn.python.org", 443))
- fd = ss.fileno()
- f = ss.makefile()
- f.close()
- # The fd is still open
- os.read(fd, 0)
- # Closing the SSL socket should close the fd too
- ss.close()
- gc.collect()
- try:
+ with support.transient_internet("svn.python.org"):
+ ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
+ ss.connect(("svn.python.org", 443))
+ fd = ss.fileno()
+ f = ss.makefile()
+ f.close()
+ # The fd is still open
os.read(fd, 0)
- except OSError as e:
- self.assertEqual(e.errno, errno.EBADF)
- else:
- self.fail("OSError wasn't raised")
+ # Closing the SSL socket should close the fd too
+ ss.close()
+ gc.collect()
+ try:
+ os.read(fd, 0)
+ except OSError as e:
+ self.assertEqual(e.errno, errno.EBADF)
+ else:
+ self.fail("OSError wasn't raised")
def test_non_blocking_handshake(self):
- s = socket.socket(socket.AF_INET)
- s.connect(("svn.python.org", 443))
- s.setblocking(False)
- s = ssl.wrap_socket(s,
- cert_reqs=ssl.CERT_NONE,
- do_handshake_on_connect=False)
- count = 0
- while True:
- try:
- count += 1
- s.do_handshake()
- break
- except ssl.SSLError as err:
- if err.args[0] == ssl.SSL_ERROR_WANT_READ:
- select.select([s], [], [])
- elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
- select.select([], [s], [])
- else:
- raise
- s.close()
- if support.verbose:
- sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
+ with support.transient_internet("svn.python.org"):
+ s = socket.socket(socket.AF_INET)
+ s.connect(("svn.python.org", 443))
+ s.setblocking(False)
+ s = ssl.wrap_socket(s,
+ cert_reqs=ssl.CERT_NONE,
+ do_handshake_on_connect=False)
+ count = 0
+ while True:
+ try:
+ count += 1
+ s.do_handshake()
+ break
+ except ssl.SSLError as err:
+ if err.args[0] == ssl.SSL_ERROR_WANT_READ:
+ select.select([s], [], [])
+ elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
+ select.select([], [s], [])
+ else:
+ raise
+ s.close()
+ if support.verbose:
+ sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
def test_get_server_certificate(self):
- pem = ssl.get_server_certificate(("svn.python.org", 443))
- if not pem:
- self.fail("No server certificate on svn.python.org:443!")
+ with support.transient_internet("svn.python.org"):
+ pem = ssl.get_server_certificate(("svn.python.org", 443))
+ if not pem:
+ self.fail("No server certificate on svn.python.org:443!")
- try:
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
- except ssl.SSLError as x:
- #should fail
- if support.verbose:
- sys.stdout.write("%s\n" % x)
- else:
- self.fail("Got server certificate %s for svn.python.org!" % pem)
+ try:
+ pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
+ except ssl.SSLError as x:
+ #should fail
+ if support.verbose:
+ sys.stdout.write("%s\n" % x)
+ else:
+ self.fail("Got server certificate %s for svn.python.org!" % pem)
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
- if not pem:
- self.fail("No server certificate on svn.python.org:443!")
- if support.verbose:
- sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
+ pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+ if not pem:
+ self.fail("No server certificate on svn.python.org:443!")
+ if support.verbose:
+ sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
# Test disabled: OPENSSL_VERSION* not available in Python 3.1
def test_algorithms(self):
From python-checkins at python.org Thu Sep 9 15:35:44 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 15:35:44 +0200 (CEST)
Subject: [Python-checkins] r84652 - in python/branches/release27-maint:
Lib/test/test_ssl.py
Message-ID: <20100909133544.7F983EE990@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 15:35:44 2010
New Revision: 84652
Log:
Merged revisions 84650 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84650 | antoine.pitrou | 2010-09-09 15:31:46 +0200 (jeu., 09 sept. 2010) | 4 lines
Use transient_internet() where appropriate in test_ssl
(svn.python.org is sometimes unavailable)
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_ssl.py
Modified: python/branches/release27-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release27-maint/Lib/test/test_ssl.py Thu Sep 9 15:35:44 2010
@@ -181,102 +181,100 @@
class NetworkedTests(unittest.TestCase):
- def setUp(self):
- self.old_timeout = socket.getdefaulttimeout()
- socket.setdefaulttimeout(30)
-
- def tearDown(self):
- socket.setdefaulttimeout(self.old_timeout)
def test_connect(self):
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_NONE)
- s.connect(("svn.python.org", 443))
- c = s.getpeercert()
- if c:
- self.fail("Peer cert %s shouldn't be here!")
- s.close()
-
- # this should fail because we have no verification certs
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED)
- try:
+ with test_support.transient_internet("svn.python.org"):
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_NONE)
s.connect(("svn.python.org", 443))
- except ssl.SSLError:
- pass
- finally:
+ c = s.getpeercert()
+ if c:
+ self.fail("Peer cert %s shouldn't be here!")
s.close()
- # this should succeed because we specify the root cert
- s = ssl.wrap_socket(socket.socket(socket.AF_INET),
- cert_reqs=ssl.CERT_REQUIRED,
- ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
- try:
- s.connect(("svn.python.org", 443))
- finally:
- s.close()
+ # this should fail because we have no verification certs
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED)
+ try:
+ s.connect(("svn.python.org", 443))
+ except ssl.SSLError:
+ pass
+ finally:
+ s.close()
+
+ # this should succeed because we specify the root cert
+ s = ssl.wrap_socket(socket.socket(socket.AF_INET),
+ cert_reqs=ssl.CERT_REQUIRED,
+ ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+ try:
+ s.connect(("svn.python.org", 443))
+ finally:
+ s.close()
@unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
def test_makefile_close(self):
# Issue #5238: creating a file-like object with makefile() shouldn't
# delay closing the underlying "real socket" (here tested with its
# file descriptor, hence skipping the test under Windows).
- ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
- ss.connect(("svn.python.org", 443))
- fd = ss.fileno()
- f = ss.makefile()
- f.close()
- # The fd is still open
- os.read(fd, 0)
- # Closing the SSL socket should close the fd too
- ss.close()
- gc.collect()
- with self.assertRaises(OSError) as e:
+ with test_support.transient_internet("svn.python.org"):
+ ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
+ ss.connect(("svn.python.org", 443))
+ fd = ss.fileno()
+ f = ss.makefile()
+ f.close()
+ # The fd is still open
os.read(fd, 0)
- self.assertEqual(e.exception.errno, errno.EBADF)
+ # Closing the SSL socket should close the fd too
+ ss.close()
+ gc.collect()
+ with self.assertRaises(OSError) as e:
+ os.read(fd, 0)
+ self.assertEqual(e.exception.errno, errno.EBADF)
def test_non_blocking_handshake(self):
- s = socket.socket(socket.AF_INET)
- s.connect(("svn.python.org", 443))
- s.setblocking(False)
- s = ssl.wrap_socket(s,
- cert_reqs=ssl.CERT_NONE,
- do_handshake_on_connect=False)
- count = 0
- while True:
- try:
- count += 1
- s.do_handshake()
- break
- except ssl.SSLError, err:
- if err.args[0] == ssl.SSL_ERROR_WANT_READ:
- select.select([s], [], [])
- elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
- select.select([], [s], [])
- else:
- raise
- s.close()
- if test_support.verbose:
- sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
+ with test_support.transient_internet("svn.python.org"):
+ s = socket.socket(socket.AF_INET)
+ s.connect(("svn.python.org", 443))
+ s.setblocking(False)
+ s = ssl.wrap_socket(s,
+ cert_reqs=ssl.CERT_NONE,
+ do_handshake_on_connect=False)
+ count = 0
+ while True:
+ try:
+ count += 1
+ s.do_handshake()
+ break
+ except ssl.SSLError, err:
+ if err.args[0] == ssl.SSL_ERROR_WANT_READ:
+ select.select([s], [], [])
+ elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
+ select.select([], [s], [])
+ else:
+ raise
+ s.close()
+ if test_support.verbose:
+ sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
def test_get_server_certificate(self):
- pem = ssl.get_server_certificate(("svn.python.org", 443))
- if not pem:
- self.fail("No server certificate on svn.python.org:443!")
+ with test_support.transient_internet("svn.python.org"):
+ pem = ssl.get_server_certificate(("svn.python.org", 443))
+ if not pem:
+ self.fail("No server certificate on svn.python.org:443!")
- try:
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
- except ssl.SSLError:
- #should fail
- pass
- else:
- self.fail("Got server certificate %s for svn.python.org!" % pem)
+ try:
+ pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
+ except ssl.SSLError:
+ #should fail
+ pass
+ else:
+ self.fail("Got server certificate %s for svn.python.org!" % pem)
- pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
- if not pem:
- self.fail("No server certificate on svn.python.org:443!")
- if test_support.verbose:
- sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
+ pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
+ if not pem:
+ self.fail("No server certificate on svn.python.org:443!")
+ if test_support.verbose:
+ sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
def test_algorithms(self):
# Issue #8484: all algorithms should be available when verifying a
From python-checkins at python.org Thu Sep 9 20:33:26 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 20:33:26 +0200 (CEST)
Subject: [Python-checkins] r84653 - in python/branches/py3k: Lib/pickle.py
Lib/test/pickletester.py Lib/test/test_pickle.py Misc/NEWS
Modules/_pickle.c
Message-ID: <20100909183326.B1243FD55@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 20:33:21 2010
New Revision: 84653
Log:
Issue #9410: Various optimizations to the pickle module, leading to
speedups up to 4x (depending on the benchmark). Mostly ported from
Unladen Swallow; initial patch by Alexandre Vassalotti.
Modified:
python/branches/py3k/Lib/pickle.py
python/branches/py3k/Lib/test/pickletester.py
python/branches/py3k/Lib/test/test_pickle.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/_pickle.c
Modified: python/branches/py3k/Lib/pickle.py
==============================================================================
--- python/branches/py3k/Lib/pickle.py (original)
+++ python/branches/py3k/Lib/pickle.py Thu Sep 9 20:33:21 2010
@@ -1287,12 +1287,6 @@
"""
return int.from_bytes(data, byteorder='little', signed=True)
-# Use the faster _pickle if possible
-try:
- from _pickle import *
-except ImportError:
- Pickler, Unpickler = _Pickler, _Unpickler
-
# Shorthands
def dump(obj, file, protocol=None, *, fix_imports=True):
@@ -1316,6 +1310,12 @@
return Unpickler(file, fix_imports=fix_imports,
encoding=encoding, errors=errors).load()
+# Use the faster _pickle if possible
+try:
+ from _pickle import *
+except ImportError:
+ Pickler, Unpickler = _Pickler, _Unpickler
+
# Doctest
def _test():
import doctest
Modified: python/branches/py3k/Lib/test/pickletester.py
==============================================================================
--- python/branches/py3k/Lib/test/pickletester.py (original)
+++ python/branches/py3k/Lib/test/pickletester.py Thu Sep 9 20:33:21 2010
@@ -1068,6 +1068,15 @@
dumped = self.dumps(set([3]), 2)
self.assertEqual(dumped, DATA6)
+ def test_large_pickles(self):
+ # Test the correctness of internal buffering routines when handling
+ # large data.
+ for proto in protocols:
+ data = (1, b'x' * (256 * 1024))
+ dumped = self.dumps(data, proto)
+ loaded = self.loads(dumped)
+ self.assertEqual(loaded, data)
+
# Test classes for reduce_ex
Modified: python/branches/py3k/Lib/test/test_pickle.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pickle.py (original)
+++ python/branches/py3k/Lib/test/test_pickle.py Thu Sep 9 20:33:21 2010
@@ -37,6 +37,18 @@
return u.load()
+class InMemoryPickleTests(AbstractPickleTests):
+
+ pickler = pickle._Pickler
+ unpickler = pickle._Unpickler
+
+ def dumps(self, arg, proto=None):
+ return pickle.dumps(arg, proto)
+
+ def loads(self, buf):
+ return pickle.loads(buf)
+
+
class PyPersPicklerTests(AbstractPersistentPicklerTests):
pickler = pickle._Pickler
@@ -95,7 +107,8 @@
tests.extend([CPicklerTests, CPersPicklerTests,
CDumpPickle_LoadPickle, DumpPickle_CLoadPickle,
PyPicklerUnpicklerObjectTests,
- CPicklerUnpicklerObjectTests])
+ CPicklerUnpicklerObjectTests,
+ InMemoryPickleTests])
support.run_unittest(*tests)
support.run_doctest(pickle)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Thu Sep 9 20:33:21 2010
@@ -20,6 +20,10 @@
Library
-------
+- Issue #9410: Various optimizations to the pickle module, leading to
+ speedups up to 4x (depending on the benchmark). Mostly ported from
+ Unladen Swallow; initial patch by Alexandre Vassalotti.
+
- The pprint module now supports printing OrderedDicts in their given
order (formerly, it would sort the keys).
Modified: python/branches/py3k/Modules/_pickle.c
==============================================================================
--- python/branches/py3k/Modules/_pickle.c (original)
+++ python/branches/py3k/Modules/_pickle.c Thu Sep 9 20:33:21 2010
@@ -10,7 +10,6 @@
DEFAULT_PROTOCOL = 3
};
-
/* Pickle opcodes. These must be kept updated with pickle.py.
Extensive docs are in pickletools.py. */
enum opcode {
@@ -96,9 +95,12 @@
checking for self-referential data-structures. */
FAST_NESTING_LIMIT = 50,
- /* Size of the write buffer of Pickler. Higher values will reduce the
- number of calls to the write() method of the output stream. */
- WRITE_BUF_SIZE = 256,
+ /* Initial size of the write buffer of Pickler. */
+ WRITE_BUF_SIZE = 4096,
+
+ /* Maximum size of the write buffer of Pickler when pickling to a
+ stream. This is ignored for in-memory pickling. */
+ MAX_WRITE_BUF_SIZE = 64 * 1024,
};
/* Exception classes for pickle. These should override the ones defined in
@@ -140,23 +142,19 @@
/* Internal data type used as the unpickling stack. */
typedef struct {
- PyObject_HEAD
- int length; /* number of initial slots in data currently used */
- int size; /* number of slots in data allocated */
+ PyObject_VAR_HEAD
PyObject **data;
+ Py_ssize_t allocated; /* number of slots in data allocated */
} Pdata;
static void
Pdata_dealloc(Pdata *self)
{
- int i;
- PyObject **p;
-
- for (i = self->length, p = self->data; --i >= 0; p++) {
- Py_DECREF(*p);
+ int i = Py_SIZE(self);
+ while (--i >= 0) {
+ Py_DECREF(self->data[i]);
}
- if (self->data)
- PyMem_Free(self->data);
+ PyMem_FREE(self->data);
PyObject_Del(self);
}
@@ -175,9 +173,9 @@
if (!(self = PyObject_New(Pdata, &Pdata_Type)))
return NULL;
- self->size = 8;
- self->length = 0;
- self->data = PyMem_Malloc(self->size * sizeof(PyObject *));
+ Py_SIZE(self) = 0;
+ self->allocated = 8;
+ self->data = PyMem_MALLOC(self->allocated * sizeof(PyObject *));
if (self->data)
return (PyObject *)self;
Py_DECREF(self);
@@ -191,42 +189,40 @@
static int
Pdata_clear(Pdata *self, int clearto)
{
- int i;
- PyObject **p;
+ int i = Py_SIZE(self);
if (clearto < 0)
return stack_underflow();
- if (clearto >= self->length)
+ if (clearto >= i)
return 0;
- for (i = self->length, p = self->data + clearto; --i >= clearto; p++) {
- Py_CLEAR(*p);
+ while (--i >= clearto) {
+ Py_CLEAR(self->data[i]);
}
- self->length = clearto;
-
+ Py_SIZE(self) = clearto;
return 0;
}
static int
Pdata_grow(Pdata *self)
{
- int bigger;
- size_t nbytes;
- PyObject **tmp;
-
- bigger = (self->size << 1) + 1;
- if (bigger <= 0) /* was 0, or new value overflows */
+ PyObject **data = self->data;
+ Py_ssize_t allocated = self->allocated;
+ Py_ssize_t new_allocated;
+
+ new_allocated = (allocated >> 3) + 6;
+ /* check for integer overflow */
+ if (new_allocated > PY_SSIZE_T_MAX - allocated)
goto nomemory;
- if ((int)(size_t)bigger != bigger)
+ new_allocated += allocated;
+ if (new_allocated > (PY_SSIZE_T_MAX / sizeof(PyObject *)))
goto nomemory;
- nbytes = (size_t)bigger * sizeof(PyObject *);
- if (nbytes / sizeof(PyObject *) != (size_t)bigger)
- goto nomemory;
- tmp = PyMem_Realloc(self->data, nbytes);
- if (tmp == NULL)
+ data = PyMem_REALLOC(data, new_allocated * sizeof(PyObject *));
+ if (data == NULL)
goto nomemory;
- self->data = tmp;
- self->size = bigger;
+
+ self->data = data;
+ self->allocated = new_allocated;
return 0;
nomemory:
@@ -241,21 +237,21 @@
static PyObject *
Pdata_pop(Pdata *self)
{
- if (self->length == 0) {
+ if (Py_SIZE(self) == 0) {
PyErr_SetString(UnpicklingError, "bad pickle data");
return NULL;
}
- return self->data[--(self->length)];
+ return self->data[--Py_SIZE(self)];
}
#define PDATA_POP(D, V) do { (V) = Pdata_pop((D)); } while (0)
static int
Pdata_push(Pdata *self, PyObject *obj)
{
- if (self->length == self->size && Pdata_grow(self) < 0) {
+ if (Py_SIZE(self) == self->allocated && Pdata_grow(self) < 0) {
return -1;
}
- self->data[self->length++] = obj;
+ self->data[Py_SIZE(self)++] = obj;
return 0;
}
@@ -274,14 +270,14 @@
PyObject *tuple;
Py_ssize_t len, i, j;
- len = self->length - start;
+ len = Py_SIZE(self) - start;
tuple = PyTuple_New(len);
if (tuple == NULL)
return NULL;
for (i = start, j = 0; j < len; i++, j++)
PyTuple_SET_ITEM(tuple, j, self->data[i]);
- self->length = start;
+ Py_SIZE(self) = start;
return tuple;
}
@@ -291,31 +287,45 @@
PyObject *list;
Py_ssize_t len, i, j;
- len = self->length - start;
+ len = Py_SIZE(self) - start;
list = PyList_New(len);
if (list == NULL)
return NULL;
for (i = start, j = 0; j < len; i++, j++)
PyList_SET_ITEM(list, j, self->data[i]);
- self->length = start;
+ Py_SIZE(self) = start;
return list;
}
+typedef struct {
+ PyObject *me_key;
+ long me_value;
+} PyMemoEntry;
+
+typedef struct {
+ Py_ssize_t mt_mask;
+ Py_ssize_t mt_used;
+ Py_ssize_t mt_allocated;
+ PyMemoEntry *mt_table;
+} PyMemoTable;
+
typedef struct PicklerObject {
PyObject_HEAD
- PyObject *write; /* write() method of the output stream */
- PyObject *memo; /* Memo dictionary, keep track of the seen
+ PyMemoTable *memo; /* Memo table, keep track of the seen
objects to support self-referential objects
- pickling. */
+ pickling. */
PyObject *pers_func; /* persistent_id() method, can be NULL */
PyObject *arg;
+
+ PyObject *write; /* write() method of the output stream. */
+ PyObject *output_buffer; /* Write into a local bytearray buffer before
+ flushing to the stream. */
+ Py_ssize_t output_len; /* Length of output_buffer. */
+ Py_ssize_t max_output_len; /* Allocation size of output_buffer. */
int proto; /* Pickle protocol number, >= 0 */
int bin; /* Boolean, true if proto > 0 */
int buf_size; /* Size of the current buffered pickle data */
- char *write_buf; /* Write buffer, this is to avoid calling the
- write() method of the output stream too
- often. */
int fast; /* Enable fast mode if set to a true value.
The fast mode disable the usage of memo,
therefore speeding the pickling process by
@@ -331,15 +341,23 @@
typedef struct UnpicklerObject {
PyObject_HEAD
Pdata *stack; /* Pickle data stack, store unpickled objects. */
- PyObject *readline; /* readline() method of the output stream */
- PyObject *read; /* read() method of the output stream */
- PyObject *memo; /* Memo dictionary, provide the objects stored
- using the PUT opcodes. */
+
+ /* The unpickler memo is just an array of PyObject *s. Using a dict
+ is unnecessary, since the keys are contiguous ints. */
+ PyObject **memo;
+ Py_ssize_t memo_size;
+
PyObject *arg;
PyObject *pers_func; /* persistent_load() method, can be NULL. */
- PyObject *last_string; /* Reference to the last string read by the
- readline() method. */
- char *buffer; /* Reading buffer. */
+
+ Py_buffer buffer;
+ char *input_buffer;
+ char *input_line;
+ Py_ssize_t input_len;
+ Py_ssize_t next_read_idx;
+ PyObject *read; /* read() method of the input stream. */
+ PyObject *readline; /* readline() method of the input stream. */
+
char *encoding; /* Name of the encoding to be used for
decoding strings pickled using Python
2.x. The default value is "ASCII" */
@@ -362,9 +380,230 @@
static PyTypeObject Unpickler_Type;
+/*************************************************************************
+ A custom hashtable mapping void* to longs. This is used by the pickler for
+ memoization. Using a custom hashtable rather than PyDict allows us to skip
+ a bunch of unnecessary object creation. This makes a huge performance
+ difference. */
+
+#define MT_MINSIZE 8
+#define PERTURB_SHIFT 5
+
+
+static PyMemoTable *
+PyMemoTable_New(void)
+{
+ PyMemoTable *memo = PyMem_MALLOC(sizeof(PyMemoTable));
+ if (memo == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ memo->mt_used = 0;
+ memo->mt_allocated = MT_MINSIZE;
+ memo->mt_mask = MT_MINSIZE - 1;
+ memo->mt_table = PyMem_MALLOC(MT_MINSIZE * sizeof(PyMemoEntry));
+ if (memo->mt_table == NULL) {
+ PyMem_FREE(memo);
+ PyErr_NoMemory();
+ return NULL;
+ }
+ memset(memo->mt_table, 0, MT_MINSIZE * sizeof(PyMemoEntry));
+
+ return memo;
+}
+
+static PyMemoTable *
+PyMemoTable_Copy(PyMemoTable *self)
+{
+ Py_ssize_t i;
+ PyMemoTable *new = PyMemoTable_New();
+ if (new == NULL)
+ return NULL;
+
+ new->mt_used = self->mt_used;
+ new->mt_allocated = self->mt_allocated;
+ new->mt_mask = self->mt_mask;
+ /* The table we get from _New() is probably smaller than we wanted.
+ Free it and allocate one that's the right size. */
+ PyMem_FREE(new->mt_table);
+ new->mt_table = PyMem_MALLOC(self->mt_allocated * sizeof(PyMemoEntry));
+ if (new->mt_table == NULL) {
+ PyMem_FREE(new);
+ return NULL;
+ }
+ for (i = 0; i < self->mt_allocated; i++) {
+ Py_XINCREF(self->mt_table[i].me_key);
+ }
+ memcpy(new->mt_table, self->mt_table,
+ sizeof(PyMemoEntry) * self->mt_allocated);
+
+ return new;
+}
+
+static Py_ssize_t
+PyMemoTable_Size(PyMemoTable *self)
+{
+ return self->mt_used;
+}
+
+static int
+PyMemoTable_Clear(PyMemoTable *self)
+{
+ Py_ssize_t i = self->mt_allocated;
+
+ while (--i >= 0) {
+ Py_XDECREF(self->mt_table[i].me_key);
+ }
+ self->mt_used = 0;
+ memset(self->mt_table, 0, self->mt_allocated * sizeof(PyMemoEntry));
+ return 0;
+}
+
+static void
+PyMemoTable_Del(PyMemoTable *self)
+{
+ if (self == NULL)
+ return;
+ PyMemoTable_Clear(self);
+
+ PyMem_FREE(self->mt_table);
+ PyMem_FREE(self);
+}
+
+/* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup()
+ can be considerably simpler than dictobject.c's lookdict(). */
+static PyMemoEntry *
+_PyMemoTable_Lookup(PyMemoTable *self, PyObject *key)
+{
+ size_t i;
+ size_t perturb;
+ size_t mask = (size_t)self->mt_mask;
+ PyMemoEntry *table = self->mt_table;
+ PyMemoEntry *entry;
+ long hash = (long)key >> 3;
+
+ i = hash & mask;
+ entry = &table[i];
+ if (entry->me_key == NULL || entry->me_key == key)
+ return entry;
+
+ for (perturb = hash; ; perturb >>= PERTURB_SHIFT) {
+ i = (i << 2) + i + perturb + 1;
+ entry = &table[i & mask];
+ if (entry->me_key == NULL || entry->me_key == key)
+ return entry;
+ }
+ assert(0); /* Never reached */
+ return NULL;
+}
+
+/* Returns -1 on failure, 0 on success. */
+static int
+_PyMemoTable_ResizeTable(PyMemoTable *self, Py_ssize_t min_size)
+{
+ PyMemoEntry *oldtable = NULL;
+ PyMemoEntry *oldentry, *newentry;
+ Py_ssize_t new_size = MT_MINSIZE;
+ Py_ssize_t to_process;
+
+ assert(min_size > 0);
+
+ /* Find the smallest valid table size >= min_size. */
+ while (new_size < min_size && new_size > 0)
+ new_size <<= 1;
+ if (new_size <= 0) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ /* new_size needs to be a power of two. */
+ assert((new_size & (new_size - 1)) == 0);
+
+ /* Allocate new table. */
+ oldtable = self->mt_table;
+ self->mt_table = PyMem_MALLOC(new_size * sizeof(PyMemoEntry));
+ if (self->mt_table == NULL) {
+ PyMem_FREE(oldtable);
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->mt_allocated = new_size;
+ self->mt_mask = new_size - 1;
+ memset(self->mt_table, 0, sizeof(PyMemoEntry) * new_size);
+
+ /* Copy entries from the old table. */
+ to_process = self->mt_used;
+ for (oldentry = oldtable; to_process > 0; oldentry++) {
+ if (oldentry->me_key != NULL) {
+ to_process--;
+ /* newentry is a pointer to a chunk of the new
+ mt_table, so we're setting the key:value pair
+ in-place. */
+ newentry = _PyMemoTable_Lookup(self, oldentry->me_key);
+ newentry->me_key = oldentry->me_key;
+ newentry->me_value = oldentry->me_value;
+ }
+ }
+
+ /* Deallocate the old table. */
+ PyMem_FREE(oldtable);
+ return 0;
+}
+
+/* Returns NULL on failure, a pointer to the value otherwise. */
+static long *
+PyMemoTable_Get(PyMemoTable *self, PyObject *key)
+{
+ PyMemoEntry *entry = _PyMemoTable_Lookup(self, key);
+ if (entry->me_key == NULL)
+ return NULL;
+ return &entry->me_value;
+}
+
+/* Returns -1 on failure, 0 on success. */
+static int
+PyMemoTable_Set(PyMemoTable *self, PyObject *key, long value)
+{
+ PyMemoEntry *entry;
+
+ assert(key != NULL);
+
+ entry = _PyMemoTable_Lookup(self, key);
+ if (entry->me_key != NULL) {
+ entry->me_value = value;
+ return 0;
+ }
+ Py_INCREF(key);
+ entry->me_key = key;
+ entry->me_value = value;
+ self->mt_used++;
+
+ /* If we added a key, we can safely resize. Otherwise just return!
+ * If used >= 2/3 size, adjust size. Normally, this quaduples the size.
+ *
+ * Quadrupling the size improves average table sparseness
+ * (reducing collisions) at the cost of some memory. It also halves
+ * the number of expensive resize operations in a growing memo table.
+ *
+ * Very large memo tables (over 50K items) use doubling instead.
+ * This may help applications with severe memory constraints.
+ */
+ if (!(self->mt_used * 3 >= (self->mt_mask + 1) * 2))
+ return 0;
+ return _PyMemoTable_ResizeTable(self,
+ (self->mt_used > 50000 ? 2 : 4) * self->mt_used);
+}
+
+#undef MT_MINSIZE
+#undef PERTURB_SHIFT
+
+/*************************************************************************/
+
/* Helpers for creating the argument tuple passed to functions. This has the
- performance advantage of calling PyTuple_New() only once. */
+ performance advantage of calling PyTuple_New() only once.
+ XXX(avassalotti): Inline directly in _Pickler_FastCall() and
+ _Unpickler_FastCall(). */
#define ARG_TUP(self, obj) do { \
if ((self)->arg || ((self)->arg=PyTuple_New(1))) { \
Py_XDECREF(PyTuple_GET_ITEM((self)->arg, 0)); \
@@ -401,10 +640,9 @@
XXX: And, what is the reference behavior of these? Steal, borrow? At first
glance, it seems to steal the reference of 'arg' and borrow the reference
- of 'func'.
- */
+ of 'func'. */
static PyObject *
-pickler_call(PicklerObject *self, PyObject *func, PyObject *arg)
+_Pickler_FastCall(PicklerObject *self, PyObject *func, PyObject *arg)
{
PyObject *result = NULL;
@@ -416,181 +654,541 @@
return result;
}
+static int
+_Pickler_ClearBuffer(PicklerObject *self)
+{
+ Py_CLEAR(self->output_buffer);
+ self->output_buffer =
+ PyBytes_FromStringAndSize(NULL, self->max_output_len);
+ if (self->output_buffer == NULL)
+ return -1;
+ self->output_len = 0;
+ return 0;
+}
+
static PyObject *
-unpickler_call(UnpicklerObject *self, PyObject *func, PyObject *arg)
+_Pickler_GetString(PicklerObject *self)
{
- PyObject *result = NULL;
+ PyObject *output_buffer = self->output_buffer;
- ARG_TUP(self, arg);
- if (self->arg) {
- result = PyObject_Call(func, self->arg, NULL);
- FREE_ARG_TUP(self);
- }
- return result;
+ assert(self->output_buffer != NULL);
+ self->output_buffer = NULL;
+ /* Resize down to exact size */
+ if (_PyBytes_Resize(&output_buffer, self->output_len) < 0)
+ return NULL;
+ return output_buffer;
}
-static Py_ssize_t
-pickler_write(PicklerObject *self, const char *s, Py_ssize_t n)
+static int
+_Pickler_FlushToFile(PicklerObject *self)
{
- PyObject *data, *result;
+ PyObject *output, *result;
+
+ assert(self->write != NULL);
- if (self->write_buf == NULL) {
- PyErr_SetString(PyExc_SystemError, "invalid write buffer");
+ output = _Pickler_GetString(self);
+ if (output == NULL)
return -1;
- }
- if (s == NULL) {
- if (!(self->buf_size))
- return 0;
- data = PyBytes_FromStringAndSize(self->write_buf, self->buf_size);
- if (data == NULL)
- return -1;
- }
- else {
- if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) {
- if (pickler_write(self, NULL, 0) < 0)
+ result = _Pickler_FastCall(self, self->write, output);
+ Py_XDECREF(result);
+ return (result == NULL) ? -1 : 0;
+}
+
+static int
+_Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t n)
+{
+ Py_ssize_t i, required;
+ char *buffer;
+
+ assert(s != NULL);
+
+ required = self->output_len + n;
+ if (required > self->max_output_len) {
+ if (self->write != NULL && required > MAX_WRITE_BUF_SIZE) {
+ /* XXX This reallocates a new buffer every time, which is a bit
+ wasteful. */
+ if (_Pickler_FlushToFile(self) < 0)
+ return -1;
+ if (_Pickler_ClearBuffer(self) < 0)
return -1;
}
-
- if (n > WRITE_BUF_SIZE) {
- if (!(data = PyBytes_FromStringAndSize(s, n)))
+ if (self->write != NULL && n > MAX_WRITE_BUF_SIZE) {
+ /* we already flushed above, so the buffer is empty */
+ PyObject *result;
+ /* XXX we could spare an intermediate copy and pass
+ a memoryview instead */
+ PyObject *output = PyBytes_FromStringAndSize(s, n);
+ if (s == NULL)
return -1;
+ result = _Pickler_FastCall(self, self->write, output);
+ Py_XDECREF(result);
+ return (result == NULL) ? -1 : 0;
}
else {
- memcpy(self->write_buf + self->buf_size, s, n);
- self->buf_size += n;
- return n;
+ if (self->output_len >= PY_SSIZE_T_MAX / 2 - n) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ self->max_output_len = (self->output_len + n) * 2;
+ if (_PyBytes_Resize(&self->output_buffer, self->max_output_len) < 0)
+ return -1;
}
}
+ buffer = PyBytes_AS_STRING(self->output_buffer);
+ if (n < 8) {
+ /* This is faster than memcpy when the string is short. */
+ for (i = 0; i < n; i++) {
+ buffer[self->output_len + i] = s[i];
+ }
+ }
+ else {
+ memcpy(buffer + self->output_len, s, n);
+ }
+ self->output_len += n;
+ return n;
+}
+
+static PicklerObject *
+_Pickler_New(void)
+{
+ PicklerObject *self;
+
+ self = PyObject_GC_New(PicklerObject, &Pickler_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->pers_func = NULL;
+ self->arg = NULL;
+ self->write = NULL;
+ self->proto = 0;
+ self->bin = 0;
+ self->fast = 0;
+ self->fast_nesting = 0;
+ self->fix_imports = 0;
+ self->fast_memo = NULL;
+
+ self->memo = PyMemoTable_New();
+ if (self->memo == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ self->max_output_len = WRITE_BUF_SIZE;
+ self->output_len = 0;
+ self->output_buffer = PyBytes_FromStringAndSize(NULL,
+ self->max_output_len);
+ if (self->output_buffer == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ return self;
+}
- /* object with write method */
- result = pickler_call(self, self->write, data);
- if (result == NULL)
+static int
+_Pickler_SetProtocol(PicklerObject *self, PyObject *proto_obj,
+ PyObject *fix_imports_obj)
+{
+ long proto = 0;
+ int fix_imports;
+
+ if (proto_obj == NULL || proto_obj == Py_None)
+ proto = DEFAULT_PROTOCOL;
+ else {
+ proto = PyLong_AsLong(proto_obj);
+ if (proto == -1 && PyErr_Occurred())
+ return -1;
+ }
+ if (proto < 0)
+ proto = HIGHEST_PROTOCOL;
+ if (proto > HIGHEST_PROTOCOL) {
+ PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d",
+ HIGHEST_PROTOCOL);
return -1;
+ }
+ fix_imports = PyObject_IsTrue(fix_imports_obj);
+ if (fix_imports == -1)
+ return -1;
+
+ self->proto = proto;
+ self->bin = proto > 0;
+ self->fix_imports = fix_imports && proto < 3;
- Py_DECREF(result);
- self->buf_size = 0;
- return n;
+ return 0;
}
-/* XXX: These read/readline functions ought to be optimized. Buffered I/O
- might help a lot, especially with the new (but much slower) io library.
- On the other hand, the added complexity might not worth it.
- */
+/* Returns -1 (with an exception set) on failure, 0 on success. This may
+ be called once on a freshly created Pickler. */
+static int
+_Pickler_SetOutputStream(PicklerObject *self, PyObject *file)
+{
+ assert(file != NULL);
+ self->write = PyObject_GetAttrString(file, "write");
+ if (self->write == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_SetString(PyExc_TypeError,
+ "file must have a 'write' attribute");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* See documentation for _Pickler_FastCall(). */
+static PyObject *
+_Unpickler_FastCall(UnpicklerObject *self, PyObject *func, PyObject *arg)
+{
+ PyObject *result = NULL;
-/* Read at least n characters from the input stream and set s to the current
- reading position. */
+ ARG_TUP(self, arg);
+ if (self->arg) {
+ result = PyObject_Call(func, self->arg, NULL);
+ FREE_ARG_TUP(self);
+ }
+ return result;
+}
+
+/* Returns the size of the input on success, -1 on failure. This takes its
+ own reference to `input`. */
+static Py_ssize_t
+_Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input)
+{
+ if (self->buffer.buf != NULL)
+ PyBuffer_Release(&self->buffer);
+ if (PyObject_GetBuffer(input, &self->buffer, PyBUF_CONTIG_RO) < 0)
+ return -1;
+ self->input_buffer = self->buffer.buf;
+ self->input_len = self->buffer.len;
+ self->next_read_idx = 0;
+ return self->input_len;
+}
+
+static const Py_ssize_t READ_WHOLE_LINE = -1;
+
+/* If reading from a file, we need to only pull the bytes we need, since there
+ may be multiple pickle objects arranged contiguously in the same input
+ buffer.
+
+ If `n` is READ_WHOLE_LINE, read a whole line. Otherwise, read up to `n`
+ bytes from the input stream/buffer.
+
+ Update the unpickler's input buffer with the newly-read data. Returns -1 on
+ failure; on success, returns the number of bytes read from the file.
+
+ On success, self->input_len will be 0; this is intentional so that when
+ unpickling from a file, the "we've run out of data" code paths will trigger,
+ causing the Unpickler to go back to the file for more data. Use the returned
+ size to tell you how much data you can process. */
static Py_ssize_t
-unpickler_read(UnpicklerObject *self, char **s, Py_ssize_t n)
+_Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n)
{
- PyObject *len;
PyObject *data;
+ Py_ssize_t read_size;
- len = PyLong_FromSsize_t(n);
- if (len == NULL)
- return -1;
+ assert(self->read != NULL);
+ assert(self->next_read_idx == 0);
+
+ if (n == READ_WHOLE_LINE)
+ data = PyObject_Call(self->readline, empty_tuple, NULL);
+ else {
+ PyObject *len = PyLong_FromSsize_t(n);
+ if (len == NULL)
+ return -1;
+ data = _Unpickler_FastCall(self, self->read, len);
+ }
- data = unpickler_call(self, self->read, len);
if (data == NULL)
return -1;
- /* XXX: Should bytearray be supported too? */
- if (!PyBytes_Check(data)) {
- PyErr_SetString(PyExc_ValueError,
- "read() from the underlying stream did not "
- "return bytes");
- Py_DECREF(data);
- return -1;
+ read_size = _Unpickler_SetStringInput(self, data);
+ self->input_len = 0;
+ Py_DECREF(data);
+ return read_size;
+}
+
+/* Read `n` bytes from the unpickler's data source, storing the result in `*s`.
+
+ This should be used for all data reads, rather than accessing the unpickler's
+ input buffer directly. This method deals correctly with reading from input
+ streams, which the input buffer doesn't deal with.
+
+ Note that when reading from a file-like object, self->next_read_idx won't
+ be updated (it should remain at 0 for the entire unpickling process). You
+ should use this function's return value to know how many bytes you can
+ consume.
+
+ Returns -1 (with an exception set) on failure. On success, return the
+ number of chars read. */
+static Py_ssize_t
+_Unpickler_Read(UnpicklerObject *self, char **s, Py_ssize_t n)
+{
+ if (n == 0) {
+ *s = NULL;
+ return 0;
}
- if (PyBytes_GET_SIZE(data) != n) {
- PyErr_SetNone(PyExc_EOFError);
- Py_DECREF(data);
+ /* This condition will always be true if self->read. */
+ if (self->next_read_idx + n > self->input_len) {
+ if (self->read) {
+ Py_ssize_t num_read;
+ assert(self->next_read_idx == self->input_len);
+ num_read = _Unpickler_ReadFromFile(self, n);
+ if (n < 0)
+ return -1;
+ if (num_read == n) {
+ *s = self->input_buffer;
+ return num_read;
+ }
+ }
+ PyErr_Format(PyExc_EOFError, "Ran out of input");
return -1;
}
+ assert(self->read == NULL);
+ *s = self->input_buffer + self->next_read_idx;
+ self->next_read_idx += n;
+ return n;
+}
- Py_XDECREF(self->last_string);
- self->last_string = data;
-
- if (!(*s = PyBytes_AS_STRING(data)))
+static Py_ssize_t
+_Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len,
+ char **result)
+{
+ char *input_line = PyMem_Realloc(self->input_line, len + 1);
+ if (input_line == NULL)
return -1;
- return n;
+ memcpy(input_line, line, len);
+ input_line[len] = '\0';
+ self->input_line = input_line;
+ *result = self->input_line;
+ return len;
}
+/* Read a line from the input stream/buffer. If we run off the end of the input
+ before hitting \n, return the data we found.
+
+ Returns the number of chars read, or -1 on failure. */
static Py_ssize_t
-unpickler_readline(UnpicklerObject *self, char **s)
+_Unpickler_Readline(UnpicklerObject *self, char **result)
{
- PyObject *data;
-
- data = PyObject_CallObject(self->readline, empty_tuple);
- if (data == NULL)
- return -1;
+ Py_ssize_t i, num_read;
- /* XXX: Should bytearray be supported too? */
- if (!PyBytes_Check(data)) {
- PyErr_SetString(PyExc_ValueError,
- "readline() from the underlying stream did not "
- "return bytes");
- return -1;
+ /* This loop will never be entered if self->read is not NULL. */
+ for (i = self->next_read_idx; i < self->input_len; i++) {
+ assert(self->read == NULL);
+ if (self->input_buffer[i] == '\n') {
+ char *line_start = self->input_buffer + self->next_read_idx;
+ num_read = i - self->next_read_idx + 1;
+ self->next_read_idx = i + 1;
+ return _Unpickler_CopyLine(self, line_start, num_read, result);
+ }
+ }
+ if (self->read) {
+ assert(self->next_read_idx == self->input_len);
+ num_read = _Unpickler_ReadFromFile(self, READ_WHOLE_LINE);
+ if (num_read < 0)
+ return -1;
+ *result = self->input_buffer;
+ return num_read;
}
+
+ /* If we get here, we've run off the end of the input string. Return the
+ remaining string and let the caller figure it out. */
+ *result = self->input_buffer + self->next_read_idx;
+ num_read = i - self->next_read_idx;
+ self->next_read_idx = i;
+ return num_read;
+}
+
+/* Returns -1 (with an exception set) on failure, 0 on success. The memo array
+ will be modified in place. */
+static int
+_Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
+{
+ Py_ssize_t i;
+ PyObject **memo;
- Py_XDECREF(self->last_string);
- self->last_string = data;
+ assert(new_size > self->memo_size);
- if (!(*s = PyBytes_AS_STRING(data)))
+ memo = PyMem_REALLOC(self->memo, new_size * sizeof(PyObject *));
+ if (memo == NULL) {
+ PyErr_NoMemory();
return -1;
+ }
+ self->memo = memo;
+ for (i = self->memo_size; i < new_size; i++)
+ self->memo[i] = NULL;
+ self->memo_size = new_size;
+ return 0;
+}
- return PyBytes_GET_SIZE(data);
+/* Returns NULL if idx is out of bounds. */
+static PyObject *
+_Unpickler_MemoGet(UnpicklerObject *self, Py_ssize_t idx)
+{
+ if (idx < 0 || idx >= self->memo_size)
+ return NULL;
+
+ return self->memo[idx];
}
-/* Generate a GET opcode for an object stored in the memo. The 'key' argument
- should be the address of the object as returned by PyLong_FromVoidPtr(). */
+/* Returns -1 (with an exception set) on failure, 0 on success.
+ This takes its own reference to `value`. */
static int
-memo_get(PicklerObject *self, PyObject *key)
+_Unpickler_MemoPut(UnpicklerObject *self, Py_ssize_t idx, PyObject *value)
{
- PyObject *value;
- PyObject *memo_id;
- long x;
- char pdata[30];
- int len;
+ PyObject *old_item;
- value = PyDict_GetItemWithError(self->memo, key);
- if (value == NULL) {
- if (!PyErr_Occurred())
- PyErr_SetObject(PyExc_KeyError, key);
+ if (idx >= self->memo_size) {
+ if (_Unpickler_ResizeMemoList(self, idx * 2) < 0)
+ return -1;
+ assert(idx < self->memo_size);
+ }
+ Py_INCREF(value);
+ old_item = self->memo[idx];
+ self->memo[idx] = value;
+ Py_XDECREF(old_item);
+ return 0;
+}
+
+static PyObject **
+_Unpickler_NewMemo(Py_ssize_t new_size)
+{
+ PyObject **memo = PyMem_MALLOC(new_size * sizeof(PyObject *));
+ if (memo == NULL)
+ return NULL;
+ memset(memo, 0, new_size * sizeof(PyObject *));
+ return memo;
+}
+
+/* Free the unpickler's memo, taking care to decref any items left in it. */
+static void
+_Unpickler_MemoCleanup(UnpicklerObject *self)
+{
+ Py_ssize_t i;
+ PyObject **memo = self->memo;
+
+ if (self->memo == NULL)
+ return;
+ self->memo = NULL;
+ i = self->memo_size;
+ while (--i >= 0) {
+ Py_XDECREF(memo[i]);
+ }
+ PyMem_FREE(memo);
+}
+
+static UnpicklerObject *
+_Unpickler_New(void)
+{
+ UnpicklerObject *self;
+
+ self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type);
+ if (self == NULL)
+ return NULL;
+
+ self->stack = (Pdata *)Pdata_New();
+ if (self->stack == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ memset(&self->buffer, 0, sizeof(Py_buffer));
+
+ self->memo_size = 32;
+ self->memo = _Unpickler_NewMemo(self->memo_size);
+ if (self->memo == NULL) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
+ self->arg = NULL;
+ self->pers_func = NULL;
+ self->input_buffer = NULL;
+ self->input_line = NULL;
+ self->input_len = 0;
+ self->next_read_idx = 0;
+ self->read = NULL;
+ self->readline = NULL;
+ self->encoding = NULL;
+ self->errors = NULL;
+ self->marks = NULL;
+ self->num_marks = 0;
+ self->marks_size = 0;
+ self->proto = 0;
+ self->fix_imports = 0;
+
+ return self;
+}
+
+/* Returns -1 (with an exception set) on failure, 0 on success. This may
+ be called once on a freshly created Pickler. */
+static int
+_Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file)
+{
+ self->read = PyObject_GetAttrString(file, "read");
+ self->readline = PyObject_GetAttrString(file, "readline");
+ if (self->readline == NULL || self->read == NULL) {
+ if (PyErr_ExceptionMatches(PyExc_AttributeError))
+ PyErr_SetString(PyExc_TypeError,
+ "file must have 'read' and 'readline' attributes");
+ Py_CLEAR(self->read);
+ Py_CLEAR(self->readline);
return -1;
}
+ return 0;
+}
+
+/* Returns -1 (with an exception set) on failure, 0 on success. This may
+ be called once on a freshly created Pickler. */
+static int
+_Unpickler_SetInputEncoding(UnpicklerObject *self,
+ const char *encoding,
+ const char *errors)
+{
+ if (encoding == NULL)
+ encoding = "ASCII";
+ if (errors == NULL)
+ errors = "strict";
- memo_id = PyTuple_GetItem(value, 0);
- if (memo_id == NULL)
+ self->encoding = strdup(encoding);
+ self->errors = strdup(errors);
+ if (self->encoding == NULL || self->errors == NULL) {
+ PyErr_NoMemory();
return -1;
+ }
+ return 0;
+}
+
+/* Generate a GET opcode for an object stored in the memo. */
+static int
+memo_get(PicklerObject *self, PyObject *key)
+{
+ long *value;
+ char pdata[30];
+ int len;
- if (!PyLong_Check(memo_id)) {
- PyErr_SetString(PicklingError, "memo id must be an integer");
+ value = PyMemoTable_Get(self->memo, key);
+ if (value == NULL) {
+ PyErr_SetObject(PyExc_KeyError, key);
return -1;
}
- x = PyLong_AsLong(memo_id);
- if (x == -1 && PyErr_Occurred())
- return -1;
if (!self->bin) {
pdata[0] = GET;
- PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", x);
+ PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ld\n", *value);
len = (int)strlen(pdata);
}
else {
- if (x < 256) {
+ if (*value < 256) {
pdata[0] = BINGET;
- pdata[1] = (unsigned char)(x & 0xff);
+ pdata[1] = (unsigned char)(*value & 0xff);
len = 2;
}
- else if (x <= 0xffffffffL) {
+ else if (*value <= 0xffffffffL) {
pdata[0] = LONG_BINGET;
- pdata[1] = (unsigned char)(x & 0xff);
- pdata[2] = (unsigned char)((x >> 8) & 0xff);
- pdata[3] = (unsigned char)((x >> 16) & 0xff);
- pdata[4] = (unsigned char)((x >> 24) & 0xff);
+ pdata[1] = (unsigned char)(*value & 0xff);
+ pdata[2] = (unsigned char)((*value >> 8) & 0xff);
+ pdata[3] = (unsigned char)((*value >> 16) & 0xff);
+ pdata[4] = (unsigned char)((*value >> 24) & 0xff);
len = 5;
}
else { /* unlikely */
@@ -600,7 +1198,7 @@
}
}
- if (pickler_write(self, pdata, len) < 0)
+ if (_Pickler_Write(self, pdata, len) < 0)
return -1;
return 0;
@@ -611,9 +1209,6 @@
static int
memo_put(PicklerObject *self, PyObject *obj)
{
- PyObject *key = NULL;
- PyObject *memo_id = NULL;
- PyObject *tuple = NULL;
long x;
char pdata[30];
int len;
@@ -622,23 +1217,8 @@
if (self->fast)
return 0;
- key = PyLong_FromVoidPtr(obj);
- if (key == NULL)
- goto error;
- if ((x = PyDict_Size(self->memo)) < 0)
- goto error;
- memo_id = PyLong_FromLong(x);
- if (memo_id == NULL)
- goto error;
- tuple = PyTuple_New(2);
- if (tuple == NULL)
- goto error;
-
- Py_INCREF(memo_id);
- PyTuple_SET_ITEM(tuple, 0, memo_id);
- Py_INCREF(obj);
- PyTuple_SET_ITEM(tuple, 1, obj);
- if (PyDict_SetItem(self->memo, key, tuple) < 0)
+ x = PyMemoTable_Size(self->memo);
+ if (PyMemoTable_Set(self->memo, obj, x) < 0)
goto error;
if (!self->bin) {
@@ -667,7 +1247,7 @@
}
}
- if (pickler_write(self, pdata, len) < 0)
+ if (_Pickler_Write(self, pdata, len) < 0)
goto error;
if (0) {
@@ -675,10 +1255,6 @@
status = -1;
}
- Py_XDECREF(key);
- Py_XDECREF(memo_id);
- Py_XDECREF(tuple);
-
return status;
}
@@ -821,7 +1397,7 @@
save_none(PicklerObject *self, PyObject *obj)
{
const char none_op = NONE;
- if (pickler_write(self, &none_op, 1) < 0)
+ if (_Pickler_Write(self, &none_op, 1) < 0)
return -1;
return 0;
@@ -836,10 +1412,10 @@
if (self->proto >= 2) {
const char bool_op = p ? NEWTRUE : NEWFALSE;
- if (pickler_write(self, &bool_op, 1) < 0)
+ if (_Pickler_Write(self, &bool_op, 1) < 0)
return -1;
}
- else if (pickler_write(self, buf[p], len[p]) < 0)
+ else if (_Pickler_Write(self, buf[p], len[p]) < 0)
return -1;
return 0;
@@ -861,7 +1437,7 @@
*/
pdata[0] = LONG; /* use LONG for consistency with pickle.py */
PyOS_snprintf(pdata + 1, sizeof(pdata) - 1, "%ldL\n", x);
- if (pickler_write(self, pdata, strlen(pdata)) < 0)
+ if (_Pickler_Write(self, pdata, strlen(pdata)) < 0)
return -1;
}
else {
@@ -886,7 +1462,7 @@
len = 5;
}
- if (pickler_write(self, pdata, len) < 0)
+ if (_Pickler_Write(self, pdata, len) < 0)
return -1;
}
@@ -922,7 +1498,7 @@
if (sign == 0) {
header[0] = LONG1;
header[1] = 0; /* It's 0 -- an empty bytestring. */
- if (pickler_write(self, header, 2) < 0)
+ if (_Pickler_Write(self, header, 2) < 0)
goto error;
return 0;
}
@@ -983,8 +1559,8 @@
}
size = 5;
}
- if (pickler_write(self, header, size) < 0 ||
- pickler_write(self, (char *)pdata, (int)nbytes) < 0)
+ if (_Pickler_Write(self, header, size) < 0 ||
+ _Pickler_Write(self, (char *)pdata, (int)nbytes) < 0)
goto error;
}
else {
@@ -1002,9 +1578,9 @@
if (string == NULL)
goto error;
- if (pickler_write(self, &long_op, 1) < 0 ||
- pickler_write(self, string, size) < 0 ||
- pickler_write(self, "L\n", 2) < 0)
+ if (_Pickler_Write(self, &long_op, 1) < 0 ||
+ _Pickler_Write(self, string, size) < 0 ||
+ _Pickler_Write(self, "L\n", 2) < 0)
goto error;
}
@@ -1027,7 +1603,7 @@
pdata[0] = BINFLOAT;
if (_PyFloat_Pack8(x, (unsigned char *)&pdata[1], 0) < 0)
return -1;
- if (pickler_write(self, pdata, 9) < 0)
+ if (_Pickler_Write(self, pdata, 9) < 0)
return -1;
}
else {
@@ -1035,7 +1611,7 @@
char *buf = NULL;
char op = FLOAT;
- if (pickler_write(self, &op, 1) < 0)
+ if (_Pickler_Write(self, &op, 1) < 0)
goto done;
buf = PyOS_double_to_string(x, 'g', 17, 0, NULL);
@@ -1044,10 +1620,10 @@
goto done;
}
- if (pickler_write(self, buf, strlen(buf)) < 0)
+ if (_Pickler_Write(self, buf, strlen(buf)) < 0)
goto done;
- if (pickler_write(self, "\n", 1) < 0)
+ if (_Pickler_Write(self, "\n", 1) < 0)
goto done;
result = 0;
@@ -1113,10 +1689,10 @@
return -1; /* string too large */
}
- if (pickler_write(self, header, len) < 0)
+ if (_Pickler_Write(self, header, len) < 0)
return -1;
- if (pickler_write(self, PyBytes_AS_STRING(obj), size) < 0)
+ if (_Pickler_Write(self, PyBytes_AS_STRING(obj), size) < 0)
return -1;
if (memo_put(self, obj) < 0)
@@ -1243,10 +1819,10 @@
pdata[3] = (unsigned char)((size >> 16) & 0xff);
pdata[4] = (unsigned char)((size >> 24) & 0xff);
- if (pickler_write(self, pdata, 5) < 0)
+ if (_Pickler_Write(self, pdata, 5) < 0)
goto error;
- if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
+ if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), size) < 0)
goto error;
}
else {
@@ -1257,14 +1833,14 @@
if (encoded == NULL)
goto error;
- if (pickler_write(self, &unicode_op, 1) < 0)
+ if (_Pickler_Write(self, &unicode_op, 1) < 0)
goto error;
size = PyBytes_GET_SIZE(encoded);
- if (pickler_write(self, PyBytes_AS_STRING(encoded), size) < 0)
+ if (_Pickler_Write(self, PyBytes_AS_STRING(encoded), size) < 0)
goto error;
- if (pickler_write(self, "\n", 1) < 0)
+ if (_Pickler_Write(self, "\n", 1) < 0)
goto error;
}
if (memo_put(self, obj) < 0)
@@ -1307,9 +1883,7 @@
static int
save_tuple(PicklerObject *self, PyObject *obj)
{
- PyObject *memo_key = NULL;
int len, i;
- int status = 0;
const char mark_op = MARK;
const char tuple_op = TUPLE;
@@ -1332,40 +1906,35 @@
pdata[1] = TUPLE;
len = 2;
}
- if (pickler_write(self, pdata, len) < 0)
+ if (_Pickler_Write(self, pdata, len) < 0)
return -1;
return 0;
}
- /* id(tuple) isn't in the memo now. If it shows up there after
+ /* The tuple isn't in the memo now. If it shows up there after
* saving the tuple elements, the tuple must be recursive, in
* which case we'll pop everything we put on the stack, and fetch
* its value from the memo.
*/
- memo_key = PyLong_FromVoidPtr(obj);
- if (memo_key == NULL)
- return -1;
-
if (len <= 3 && self->proto >= 2) {
/* Use TUPLE{1,2,3} opcodes. */
if (store_tuple_elements(self, obj, len) < 0)
- goto error;
+ return -1;
- if (PyDict_GetItem(self->memo, memo_key)) {
+ if (PyMemoTable_Get(self->memo, obj)) {
/* pop the len elements */
for (i = 0; i < len; i++)
- if (pickler_write(self, &pop_op, 1) < 0)
- goto error;
+ if (_Pickler_Write(self, &pop_op, 1) < 0)
+ return -1;
/* fetch from memo */
- if (memo_get(self, memo_key) < 0)
- goto error;
+ if (memo_get(self, obj) < 0)
+ return -1;
- Py_DECREF(memo_key);
return 0;
}
else { /* Not recursive. */
- if (pickler_write(self, len2opcode + len, 1) < 0)
- goto error;
+ if (_Pickler_Write(self, len2opcode + len, 1) < 0)
+ return -1;
}
goto memoize;
}
@@ -1373,49 +1942,42 @@
/* proto < 2 and len > 0, or proto >= 2 and len > 3.
* Generate MARK e1 e2 ... TUPLE
*/
- if (pickler_write(self, &mark_op, 1) < 0)
- goto error;
+ if (_Pickler_Write(self, &mark_op, 1) < 0)
+ return -1;
if (store_tuple_elements(self, obj, len) < 0)
- goto error;
+ return -1;
- if (PyDict_GetItem(self->memo, memo_key)) {
+ if (PyMemoTable_Get(self->memo, obj)) {
/* pop the stack stuff we pushed */
if (self->bin) {
- if (pickler_write(self, &pop_mark_op, 1) < 0)
- goto error;
+ if (_Pickler_Write(self, &pop_mark_op, 1) < 0)
+ return -1;
}
else {
/* Note that we pop one more than len, to remove
* the MARK too.
*/
for (i = 0; i <= len; i++)
- if (pickler_write(self, &pop_op, 1) < 0)
- goto error;
+ if (_Pickler_Write(self, &pop_op, 1) < 0)
+ return -1;
}
/* fetch from memo */
- if (memo_get(self, memo_key) < 0)
- goto error;
+ if (memo_get(self, obj) < 0)
+ return -1;
- Py_DECREF(memo_key);
return 0;
}
else { /* Not recursive. */
- if (pickler_write(self, &tuple_op, 1) < 0)
- goto error;
+ if (_Pickler_Write(self, &tuple_op, 1) < 0)
+ return -1;
}
memoize:
if (memo_put(self, obj) < 0)
- goto error;
-
- if (0) {
- error:
- status = -1;
- }
+ return -1;
- Py_DECREF(memo_key);
- return status;
+ return 0;
}
/* iter is an iterator giving items, and we batch up chunks of
@@ -1455,7 +2017,7 @@
Py_DECREF(obj);
if (i < 0)
return -1;
- if (pickler_write(self, &append_op, 1) < 0)
+ if (_Pickler_Write(self, &append_op, 1) < 0)
return -1;
}
return 0;
@@ -1482,7 +2044,7 @@
/* Only one item to write */
if (save(self, firstitem, 0) < 0)
goto error;
- if (pickler_write(self, &append_op, 1) < 0)
+ if (_Pickler_Write(self, &append_op, 1) < 0)
goto error;
Py_CLEAR(firstitem);
break;
@@ -1491,7 +2053,7 @@
/* More than one item to write */
/* Pump out MARK, items, APPENDS. */
- if (pickler_write(self, &mark_op, 1) < 0)
+ if (_Pickler_Write(self, &mark_op, 1) < 0)
goto error;
if (save(self, firstitem, 0) < 0)
@@ -1517,7 +2079,7 @@
}
}
- if (pickler_write(self, &appends_op, 1) < 0)
+ if (_Pickler_Write(self, &appends_op, 1) < 0)
goto error;
} while (n == BATCHSIZE);
@@ -1529,10 +2091,65 @@
return -1;
}
+/* This is a variant of batch_list() above, specialized for lists (with no
+ * support for list subclasses). Like batch_list(), we batch up chunks of
+ * MARK item item ... item APPENDS
+ * opcode sequences. Calling code should have arranged to first create an
+ * empty list, or list-like object, for the APPENDS to operate on.
+ * Returns 0 on success, -1 on error.
+ *
+ * This version is considerably faster than batch_list(), if less general.
+ *
+ * Note that this only works for protocols > 0.
+ */
+static int
+batch_list_exact(PicklerObject *self, PyObject *obj)
+{
+ PyObject *item = NULL;
+ int this_batch, total;
+
+ const char append_op = APPEND;
+ const char appends_op = APPENDS;
+ const char mark_op = MARK;
+
+ assert(obj != NULL);
+ assert(self->proto > 0);
+ assert(PyList_CheckExact(obj));
+
+ if (PyList_GET_SIZE(obj) == 1) {
+ item = PyList_GET_ITEM(obj, 0);
+ if (save(self, item, 0) < 0)
+ return -1;
+ if (_Pickler_Write(self, &append_op, 1) < 0)
+ return -1;
+ return 0;
+ }
+
+ /* Write in batches of BATCHSIZE. */
+ total = 0;
+ do {
+ this_batch = 0;
+ if (_Pickler_Write(self, &mark_op, 1) < 0)
+ return -1;
+ while (total < PyList_GET_SIZE(obj)) {
+ item = PyList_GET_ITEM(obj, total);
+ if (save(self, item, 0) < 0)
+ return -1;
+ total++;
+ if (++this_batch == BATCHSIZE)
+ break;
+ }
+ if (_Pickler_Write(self, &appends_op, 1) < 0)
+ return -1;
+
+ } while (total < PyList_GET_SIZE(obj));
+
+ return 0;
+}
+
static int
save_list(PicklerObject *self, PyObject *obj)
{
- PyObject *iter;
char header[3];
int len;
int status = 0;
@@ -1551,7 +2168,7 @@
len = 2;
}
- if (pickler_write(self, header, len) < 0)
+ if (_Pickler_Write(self, header, len) < 0)
goto error;
/* Get list length, and bow out early if empty. */
@@ -1562,14 +2179,24 @@
goto error;
if (len != 0) {
- /* Save the list elements. */
- iter = PyObject_GetIter(obj);
- if (iter == NULL)
- goto error;
- status = batch_list(self, iter);
- Py_DECREF(iter);
- }
+ /* Materialize the list elements. */
+ if (PyList_CheckExact(obj) && self->proto > 0) {
+ if (Py_EnterRecursiveCall(" while pickling an object") == 0) {
+ status = batch_list_exact(self, obj);
+ Py_LeaveRecursiveCall();
+ }
+ } else {
+ PyObject *iter = PyObject_GetIter(obj);
+ if (iter == NULL)
+ goto error;
+ if (Py_EnterRecursiveCall(" while pickling an object") == 0) {
+ status = batch_list(self, iter);
+ Py_LeaveRecursiveCall();
+ }
+ Py_DECREF(iter);
+ }
+ }
if (0) {
error:
status = -1;
@@ -1625,7 +2252,7 @@
Py_DECREF(obj);
if (i < 0)
return -1;
- if (pickler_write(self, &setitem_op, 1) < 0)
+ if (_Pickler_Write(self, &setitem_op, 1) < 0)
return -1;
}
return 0;
@@ -1659,7 +2286,7 @@
goto error;
if (save(self, PyTuple_GET_ITEM(firstitem, 1), 0) < 0)
goto error;
- if (pickler_write(self, &setitem_op, 1) < 0)
+ if (_Pickler_Write(self, &setitem_op, 1) < 0)
goto error;
Py_CLEAR(firstitem);
break;
@@ -1668,7 +2295,7 @@
/* More than one item to write */
/* Pump out MARK, items, SETITEMS. */
- if (pickler_write(self, &mark_op, 1) < 0)
+ if (_Pickler_Write(self, &mark_op, 1) < 0)
goto error;
if (save(self, PyTuple_GET_ITEM(firstitem, 0), 0) < 0)
@@ -1684,7 +2311,7 @@
PyErr_SetString(PyExc_TypeError, "dict items "
"iterator must return 2-tuples");
goto error;
- }
+ }
if (save(self, PyTuple_GET_ITEM(obj, 0), 0) < 0 ||
save(self, PyTuple_GET_ITEM(obj, 1), 0) < 0)
goto error;
@@ -1702,7 +2329,7 @@
}
}
- if (pickler_write(self, &setitems_op, 1) < 0)
+ if (_Pickler_Write(self, &setitems_op, 1) < 0)
goto error;
} while (n == BATCHSIZE);
@@ -1746,7 +2373,7 @@
return -1;
if (save(self, value, 0) < 0)
return -1;
- if (pickler_write(self, &setitem_op, 1) < 0)
+ if (_Pickler_Write(self, &setitem_op, 1) < 0)
return -1;
return 0;
}
@@ -1754,7 +2381,7 @@
/* Write in batches of BATCHSIZE. */
do {
i = 0;
- if (pickler_write(self, &mark_op, 1) < 0)
+ if (_Pickler_Write(self, &mark_op, 1) < 0)
return -1;
while (PyDict_Next(obj, &ppos, &key, &value)) {
if (save(self, key, 0) < 0)
@@ -1764,7 +2391,7 @@
if (++i == BATCHSIZE)
break;
}
- if (pickler_write(self, &setitems_op, 1) < 0)
+ if (_Pickler_Write(self, &setitems_op, 1) < 0)
return -1;
if (PyDict_Size(obj) != dict_size) {
PyErr_Format(
@@ -1799,7 +2426,7 @@
len = 2;
}
- if (pickler_write(self, header, len) < 0)
+ if (_Pickler_Write(self, header, len) < 0)
goto error;
/* Get dict size, and bow out early if empty. */
@@ -1962,7 +2589,7 @@
n = 5;
}
- if (pickler_write(self, pdata, n) < 0)
+ if (_Pickler_Write(self, pdata, n) < 0)
goto error;
}
else {
@@ -1973,7 +2600,7 @@
PyObject *(*unicode_encoder)(PyObject *);
gen_global:
- if (pickler_write(self, &global_op, 1) < 0)
+ if (_Pickler_Write(self, &global_op, 1) < 0)
goto error;
/* Since Python 3.0 now supports non-ASCII identifiers, we encode both
@@ -2053,13 +2680,13 @@
"pickle protocol %i", module_name, self->proto);
goto error;
}
- if (pickler_write(self, PyBytes_AS_STRING(encoded),
+ if (_Pickler_Write(self, PyBytes_AS_STRING(encoded),
PyBytes_GET_SIZE(encoded)) < 0) {
Py_DECREF(encoded);
goto error;
}
Py_DECREF(encoded);
- if(pickler_write(self, "\n", 1) < 0)
+ if(_Pickler_Write(self, "\n", 1) < 0)
goto error;
/* Save the name of the module. */
@@ -2071,13 +2698,13 @@
"pickle protocol %i", global_name, self->proto);
goto error;
}
- if (pickler_write(self, PyBytes_AS_STRING(encoded),
+ if (_Pickler_Write(self, PyBytes_AS_STRING(encoded),
PyBytes_GET_SIZE(encoded)) < 0) {
Py_DECREF(encoded);
goto error;
}
Py_DECREF(encoded);
- if(pickler_write(self, "\n", 1) < 0)
+ if(_Pickler_Write(self, "\n", 1) < 0)
goto error;
/* Memoize the object. */
@@ -2106,14 +2733,14 @@
const char binpersid_op = BINPERSID;
Py_INCREF(obj);
- pid = pickler_call(self, func, obj);
+ pid = _Pickler_FastCall(self, func, obj);
if (pid == NULL)
return -1;
if (pid != Py_None) {
if (self->bin) {
if (save(self, pid, 1) < 0 ||
- pickler_write(self, &binpersid_op, 1) < 0)
+ _Pickler_Write(self, &binpersid_op, 1) < 0)
goto error;
}
else {
@@ -2133,9 +2760,9 @@
if (pid_ascii_bytes == NULL)
goto error;
- if (pickler_write(self, &persid_op, 1) < 0 ||
- pickler_write(self, pid_ascii_bytes, size) < 0 ||
- pickler_write(self, "\n", 1) < 0)
+ if (_Pickler_Write(self, &persid_op, 1) < 0 ||
+ _Pickler_Write(self, pid_ascii_bytes, size) < 0 ||
+ _Pickler_Write(self, "\n", 1) < 0)
goto error;
}
status = 1;
@@ -2220,6 +2847,8 @@
if (newobj_str == NULL) {
newobj_str = PyUnicode_InternFromString("__newobj__");
+ if (newobj_str == NULL)
+ return -1;
}
name_str = PyObject_GetAttrString(callable, "__name__");
@@ -2312,13 +2941,13 @@
return -1;
/* Add NEWOBJ opcode. */
- if (pickler_write(self, &newobj_op, 1) < 0)
+ if (_Pickler_Write(self, &newobj_op, 1) < 0)
return -1;
}
else { /* Not using NEWOBJ. */
if (save(self, callable, 0) < 0 ||
save(self, argtup, 0) < 0 ||
- pickler_write(self, &reduce_op, 1) < 0)
+ _Pickler_Write(self, &reduce_op, 1) < 0)
return -1;
}
@@ -2337,7 +2966,7 @@
if (state) {
if (save(self, state, 0) < 0 ||
- pickler_write(self, &build_op, 1) < 0)
+ _Pickler_Write(self, &build_op, 1) < 0)
return -1;
}
@@ -2350,7 +2979,6 @@
PyTypeObject *type;
PyObject *reduce_func = NULL;
PyObject *reduce_value = NULL;
- PyObject *memo_key = NULL;
int status = 0;
if (Py_EnterRecursiveCall(" while pickling an object") < 0)
@@ -2370,11 +2998,10 @@
type = Py_TYPE(obj);
- /* XXX: The old cPickle had an optimization that used switch-case
- statement dispatching on the first letter of the type name. It was
- probably not a bad idea after all. If benchmarks shows that particular
- optimization had some real benefits, it would be nice to add it
- back. */
+ /* The old cPickle had an optimization that used switch-case statement
+ dispatching on the first letter of the type name. This has was removed
+ since benchmarks shown that this optimization was actually slowing
+ things down. */
/* Atom types; these aren't memoized, so don't check the memo. */
@@ -2398,11 +3025,8 @@
/* Check the memo to see if it has the object. If so, generate
a GET (or BINGET) opcode, instead of pickling the object
once again. */
- memo_key = PyLong_FromVoidPtr(obj);
- if (memo_key == NULL)
- goto error;
- if (PyDict_GetItem(self->memo, memo_key)) {
- if (memo_get(self, memo_key) < 0)
+ if (PyMemoTable_Get(self->memo, obj)) {
+ if (memo_get(self, obj) < 0)
goto error;
goto done;
}
@@ -2465,7 +3089,7 @@
*/
Py_INCREF(reduce_func);
Py_INCREF(obj);
- reduce_value = pickler_call(self, reduce_func, obj);
+ reduce_value = _Pickler_FastCall(self, reduce_func, obj);
}
else {
static PyObject *reduce_str = NULL;
@@ -2495,7 +3119,7 @@
PyObject *proto;
proto = PyLong_FromLong(self->proto);
if (proto != NULL) {
- reduce_value = pickler_call(self, reduce_func, proto);
+ reduce_value = _Pickler_FastCall(self, reduce_func, proto);
}
}
else {
@@ -2538,7 +3162,6 @@
}
done:
Py_LeaveRecursiveCall();
- Py_XDECREF(memo_key);
Py_XDECREF(reduce_func);
Py_XDECREF(reduce_value);
@@ -2556,13 +3179,12 @@
header[0] = PROTO;
assert(self->proto >= 0 && self->proto < 256);
header[1] = (unsigned char)self->proto;
- if (pickler_write(self, header, 2) < 0)
+ if (_Pickler_Write(self, header, 2) < 0)
return -1;
}
if (save(self, obj, 0) < 0 ||
- pickler_write(self, &stop_op, 1) < 0 ||
- pickler_write(self, NULL, 0) < 0)
+ _Pickler_Write(self, &stop_op, 1) < 0)
return -1;
return 0;
@@ -2580,7 +3202,7 @@
Pickler_clear_memo(PicklerObject *self)
{
if (self->memo)
- PyDict_Clear(self->memo);
+ PyMemoTable_Clear(self->memo);
Py_RETURN_NONE;
}
@@ -2606,9 +3228,15 @@
if (!PyArg_ParseTuple(args, "O:dump", &obj))
return NULL;
+ if (_Pickler_ClearBuffer(self) < 0)
+ return NULL;
+
if (dump(self, obj) < 0)
return NULL;
+ if (_Pickler_FlushToFile(self) < 0)
+ return NULL;
+
Py_RETURN_NONE;
}
@@ -2625,13 +3253,13 @@
{
PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->output_buffer);
Py_XDECREF(self->write);
- Py_XDECREF(self->memo);
Py_XDECREF(self->pers_func);
Py_XDECREF(self->arg);
Py_XDECREF(self->fast_memo);
- PyMem_Free(self->write_buf);
+ PyMemoTable_Del(self->memo);
Py_TYPE(self)->tp_free((PyObject *)self);
}
@@ -2640,7 +3268,6 @@
Pickler_traverse(PicklerObject *self, visitproc visit, void *arg)
{
Py_VISIT(self->write);
- Py_VISIT(self->memo);
Py_VISIT(self->pers_func);
Py_VISIT(self->arg);
Py_VISIT(self->fast_memo);
@@ -2650,18 +3277,21 @@
static int
Pickler_clear(PicklerObject *self)
{
+ Py_CLEAR(self->output_buffer);
Py_CLEAR(self->write);
- Py_CLEAR(self->memo);
Py_CLEAR(self->pers_func);
Py_CLEAR(self->arg);
Py_CLEAR(self->fast_memo);
- PyMem_Free(self->write_buf);
- self->write_buf = NULL;
-
+ if (self->memo != NULL) {
+ PyMemoTable *memo = self->memo;
+ self->memo = NULL;
+ PyMemoTable_Del(memo);
+ }
return 0;
}
+
PyDoc_STRVAR(Pickler_doc,
"Pickler(file, protocol=None)"
"\n"
@@ -2692,10 +3322,9 @@
static char *kwlist[] = {"file", "protocol", "fix_imports", 0};
PyObject *file;
PyObject *proto_obj = NULL;
- long proto = 0;
- int fix_imports = 1;
+ PyObject *fix_imports = Py_True;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:Pickler",
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:Pickler",
kwlist, &file, &proto_obj, &fix_imports))
return -1;
@@ -2703,44 +3332,31 @@
if (self->write != NULL)
(void)Pickler_clear(self);
- if (proto_obj == NULL || proto_obj == Py_None)
- proto = DEFAULT_PROTOCOL;
- else {
- proto = PyLong_AsLong(proto_obj);
- if (proto == -1 && PyErr_Occurred())
- return -1;
- }
+ if (_Pickler_SetProtocol(self, proto_obj, fix_imports) < 0)
+ return -1;
- if (proto < 0)
- proto = HIGHEST_PROTOCOL;
- if (proto > HIGHEST_PROTOCOL) {
- PyErr_Format(PyExc_ValueError, "pickle protocol must be <= %d",
- HIGHEST_PROTOCOL);
+ if (_Pickler_SetOutputStream(self, file) < 0)
return -1;
+
+ /* memo and output_buffer may have already been created in _Pickler_New */
+ if (self->memo == NULL) {
+ self->memo = PyMemoTable_New();
+ if (self->memo == NULL)
+ return -1;
+ }
+ self->output_len = 0;
+ if (self->output_buffer == NULL) {
+ self->max_output_len = WRITE_BUF_SIZE;
+ self->output_buffer = PyBytes_FromStringAndSize(NULL,
+ self->max_output_len);
+ if (self->output_buffer == NULL)
+ return -1;
}
- self->proto = proto;
- self->bin = proto > 0;
self->arg = NULL;
self->fast = 0;
self->fast_nesting = 0;
self->fast_memo = NULL;
- self->fix_imports = fix_imports && proto < 3;
-
- if (!PyObject_HasAttrString(file, "write")) {
- PyErr_SetString(PyExc_TypeError,
- "file must have a 'write' attribute");
- return -1;
- }
- self->write = PyObject_GetAttrString(file, "write");
- if (self->write == NULL)
- return -1;
- self->buf_size = 0;
- self->write_buf = (char *)PyMem_Malloc(WRITE_BUF_SIZE);
- if (self->write_buf == NULL) {
- PyErr_NoMemory();
- return -1;
- }
self->pers_func = NULL;
if (PyObject_HasAttrString((PyObject *)self, "persistent_id")) {
self->pers_func = PyObject_GetAttrString((PyObject *)self,
@@ -2748,44 +3364,248 @@
if (self->pers_func == NULL)
return -1;
}
- self->memo = PyDict_New();
- if (self->memo == NULL)
- return -1;
+ return 0;
+}
+
+/* Define a proxy object for the Pickler's internal memo object. This is to
+ * avoid breaking code like:
+ * pickler.memo.clear()
+ * and
+ * pickler.memo = saved_memo
+ * Is this a good idea? Not really, but we don't want to break code that uses
+ * it. Note that we don't implement the entire mapping API here. This is
+ * intentional, as these should be treated as black-box implementation details.
+ */
+
+typedef struct {
+ PyObject_HEAD
+ PicklerObject *pickler; /* Pickler whose memo table we're proxying. */
+} PicklerMemoProxyObject;
+
+PyDoc_STRVAR(pmp_clear_doc,
+"memo.clear() -> None. Remove all items from memo.");
+
+static PyObject *
+pmp_clear(PicklerMemoProxyObject *self)
+{
+ if (self->pickler->memo)
+ PyMemoTable_Clear(self->pickler->memo);
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(pmp_copy_doc,
+"memo.copy() -> new_memo. Copy the memo to a new object.");
+
+static PyObject *
+pmp_copy(PicklerMemoProxyObject *self)
+{
+ Py_ssize_t i;
+ PyMemoTable *memo;
+ PyObject *new_memo = PyDict_New();
+ if (new_memo == NULL)
+ return NULL;
+
+ memo = self->pickler->memo;
+ for (i = 0; i < memo->mt_allocated; ++i) {
+ PyMemoEntry entry = memo->mt_table[i];
+ if (entry.me_key != NULL) {
+ int status;
+ PyObject *key, *value;
+
+ key = PyLong_FromVoidPtr(entry.me_key);
+ value = Py_BuildValue("lO", entry.me_value, entry.me_key);
+
+ if (key == NULL || value == NULL) {
+ Py_XDECREF(key);
+ Py_XDECREF(value);
+ goto error;
+ }
+ status = PyDict_SetItem(new_memo, key, value);
+ Py_DECREF(key);
+ Py_DECREF(value);
+ if (status < 0)
+ goto error;
+ }
+ }
+ return new_memo;
+
+ error:
+ Py_XDECREF(new_memo);
+ return NULL;
+}
+
+PyDoc_STRVAR(pmp_reduce_doc,
+"memo.__reduce__(). Pickling support.");
+
+static PyObject *
+pmp_reduce(PicklerMemoProxyObject *self, PyObject *args)
+{
+ PyObject *reduce_value, *dict_args;
+ PyObject *contents = pmp_copy(self);
+ if (contents == NULL)
+ return NULL;
+
+ reduce_value = PyTuple_New(2);
+ if (reduce_value == NULL) {
+ Py_DECREF(contents);
+ return NULL;
+ }
+ dict_args = PyTuple_New(1);
+ if (dict_args == NULL) {
+ Py_DECREF(contents);
+ Py_DECREF(reduce_value);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(dict_args, 0, contents);
+ Py_INCREF((PyObject *)&PyDict_Type);
+ PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type);
+ PyTuple_SET_ITEM(reduce_value, 1, dict_args);
+ return reduce_value;
+}
+
+static PyMethodDef picklerproxy_methods[] = {
+ {"clear", (PyCFunction)pmp_clear, METH_NOARGS, pmp_clear_doc},
+ {"copy", (PyCFunction)pmp_copy, METH_NOARGS, pmp_copy_doc},
+ {"__reduce__", (PyCFunction)pmp_reduce, METH_VARARGS, pmp_reduce_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+PicklerMemoProxy_dealloc(PicklerMemoProxyObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->pickler);
+ PyObject_GC_Del((PyObject *)self);
+}
+static int
+PicklerMemoProxy_traverse(PicklerMemoProxyObject *self,
+ visitproc visit, void *arg)
+{
+ Py_VISIT(self->pickler);
+ return 0;
+}
+
+static int
+PicklerMemoProxy_clear(PicklerMemoProxyObject *self)
+{
+ Py_CLEAR(self->pickler);
return 0;
}
+static PyTypeObject PicklerMemoProxyType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_pickle.PicklerMemoProxy", /*tp_name*/
+ sizeof(PicklerMemoProxyObject), /*tp_basicsize*/
+ 0,
+ (destructor)PicklerMemoProxy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ 0, /* tp_doc */
+ (traverseproc)PicklerMemoProxy_traverse, /* tp_traverse */
+ (inquiry)PicklerMemoProxy_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ picklerproxy_methods, /* tp_methods */
+};
+
+static PyObject *
+PicklerMemoProxy_New(PicklerObject *pickler)
+{
+ PicklerMemoProxyObject *self;
+
+ self = PyObject_GC_New(PicklerMemoProxyObject, &PicklerMemoProxyType);
+ if (self == NULL)
+ return NULL;
+ Py_INCREF(pickler);
+ self->pickler = pickler;
+ PyObject_GC_Track(self);
+ return (PyObject *)self;
+}
+
+/*****************************************************************************/
+
static PyObject *
Pickler_get_memo(PicklerObject *self)
{
- if (self->memo == NULL)
- PyErr_SetString(PyExc_AttributeError, "memo");
- else
- Py_INCREF(self->memo);
- return self->memo;
+ return PicklerMemoProxy_New(self);
}
static int
-Pickler_set_memo(PicklerObject *self, PyObject *value)
+Pickler_set_memo(PicklerObject *self, PyObject *obj)
{
- PyObject *tmp;
+ PyMemoTable *new_memo = NULL;
- if (value == NULL) {
+ if (obj == NULL) {
PyErr_SetString(PyExc_TypeError,
"attribute deletion is not supported");
return -1;
}
- if (!PyDict_Check(value)) {
- PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
+
+ if (Py_TYPE(obj) == &PicklerMemoProxyType) {
+ PicklerObject *pickler =
+ ((PicklerMemoProxyObject *)obj)->pickler;
+
+ new_memo = PyMemoTable_Copy(pickler->memo);
+ if (new_memo == NULL)
+ return -1;
+ }
+ else if (PyDict_Check(obj)) {
+ Py_ssize_t i = 0;
+ PyObject *key, *value;
+
+ new_memo = PyMemoTable_New();
+ if (new_memo == NULL)
+ return -1;
+
+ while (PyDict_Next(obj, &i, &key, &value)) {
+ long memo_id;
+ PyObject *memo_obj;
+
+ if (!PyTuple_Check(value) || Py_SIZE(value) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "'memo' values must be 2-item tuples");
+ goto error;
+ }
+ memo_id = PyLong_AsLong(PyTuple_GET_ITEM(value, 0));
+ if (memo_id == -1 && PyErr_Occurred())
+ goto error;
+ memo_obj = PyTuple_GET_ITEM(value, 1);
+ if (PyMemoTable_Set(new_memo, memo_obj, memo_id) < 0)
+ goto error;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "'memo' attribute must be an PicklerMemoProxy object"
+ "or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
- tmp = self->memo;
- Py_INCREF(value);
- self->memo = value;
- Py_XDECREF(tmp);
+ PyMemoTable_Del(self->memo);
+ self->memo = new_memo;
return 0;
+
+ error:
+ if (new_memo)
+ PyMemoTable_Del(new_memo);
+ return -1;
}
static PyObject *
@@ -2926,21 +3746,22 @@
Py_ssize_t len;
long x;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
errno = 0;
- /* XXX: Should the base argument of strtol() be explicitly set to 10? */
+ /* XXX: Should the base argument of strtol() be explicitly set to 10?
+ XXX(avassalotti): Should this uses PyOS_strtol()? */
x = strtol(s, &endptr, 0);
- if (errno || (*endptr != '\n') || (endptr[1] != '\0')) {
+ if (errno || (*endptr != '\n' && *endptr != '\0')) {
/* Hm, maybe we've got something long. Let's try reading
* it as a Python long object. */
errno = 0;
/* XXX: Same thing about the base here. */
- value = PyLong_FromString(s, NULL, 0);
+ value = PyLong_FromString(s, NULL, 0);
if (value == NULL) {
PyErr_SetString(PyExc_ValueError,
"could not convert string to int");
@@ -3017,7 +3838,7 @@
{
char *s;
- if (unpickler_read(self, &s, 4) < 0)
+ if (_Unpickler_Read(self, &s, 4) < 0)
return -1;
return load_binintx(self, s, 4);
@@ -3028,7 +3849,7 @@
{
char *s;
- if (unpickler_read(self, &s, 1) < 0)
+ if (_Unpickler_Read(self, &s, 1) < 0)
return -1;
return load_binintx(self, s, 1);
@@ -3039,7 +3860,7 @@
{
char *s;
- if (unpickler_read(self, &s, 2) < 0)
+ if (_Unpickler_Read(self, &s, 2) < 0)
return -1;
return load_binintx(self, s, 2);
@@ -3052,7 +3873,7 @@
char *s;
Py_ssize_t len;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
@@ -3061,9 +3882,8 @@
the 'L' before calling PyLong_FromString. In order to maintain
compatibility with Python 3.0.0, we don't actually *require*
the 'L' to be present. */
- if (s[len-2] == 'L') {
+ if (s[len-2] == 'L')
s[len-2] = '\0';
- }
/* XXX: Should the base argument explicitly set to 10? */
value = PyLong_FromString(s, NULL, 0);
if (value == NULL)
@@ -3084,7 +3904,7 @@
char *pdata;
assert(size == 1 || size == 4);
- if (unpickler_read(self, &nbytes, size) < 0)
+ if (_Unpickler_Read(self, &nbytes, size) < 0)
return -1;
size = calc_binint(nbytes, size);
@@ -3099,7 +3919,7 @@
value = PyLong_FromLong(0L);
else {
/* Read the raw little-endian bytes and convert. */
- if (unpickler_read(self, &pdata, size) < 0)
+ if (_Unpickler_Read(self, &pdata, size) < 0)
return -1;
value = _PyLong_FromByteArray((unsigned char *)pdata, (size_t)size,
1 /* little endian */ , 1 /* signed */ );
@@ -3118,7 +3938,7 @@
Py_ssize_t len;
double d;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
@@ -3127,7 +3947,7 @@
d = PyOS_string_to_double(s, &endptr, PyExc_OverflowError);
if (d == -1.0 && PyErr_Occurred())
return -1;
- if ((endptr[0] != '\n') || (endptr[1] != '\0')) {
+ if ((endptr[0] != '\n') && (endptr[0] != '\0')) {
PyErr_SetString(PyExc_ValueError, "could not convert string to float");
return -1;
}
@@ -3137,7 +3957,7 @@
PDATA_PUSH(self->stack, value, -1);
return 0;
- }
+}
static int
load_binfloat(UnpicklerObject *self)
@@ -3146,7 +3966,7 @@
double x;
char *s;
- if (unpickler_read(self, &s, 8) < 0)
+ if (_Unpickler_Read(self, &s, 8) < 0)
return -1;
x = _PyFloat_Unpack8((unsigned char *)s, 0);
@@ -3168,7 +3988,7 @@
Py_ssize_t len;
char *s, *p;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 3)
return bad_readline();
@@ -3218,7 +4038,7 @@
long x;
char *s;
- if (unpickler_read(self, &s, 4) < 0)
+ if (_Unpickler_Read(self, &s, 4) < 0)
return -1;
x = calc_binint(s, 4);
@@ -3228,7 +4048,7 @@
return -1;
}
- if (unpickler_read(self, &s, x) < 0)
+ if (_Unpickler_Read(self, &s, x) < 0)
return -1;
bytes = PyBytes_FromStringAndSize(s, x);
if (bytes == NULL)
@@ -3245,12 +4065,12 @@
unsigned char x;
char *s;
- if (unpickler_read(self, &s, 1) < 0)
+ if (_Unpickler_Read(self, &s, 1) < 0)
return -1;
x = (unsigned char)s[0];
- if (unpickler_read(self, &s, x) < 0)
+ if (_Unpickler_Read(self, &s, x) < 0)
return -1;
bytes = PyBytes_FromStringAndSize(s, x);
@@ -3268,7 +4088,7 @@
long x;
char *s;
- if (unpickler_read(self, &s, 4) < 0)
+ if (_Unpickler_Read(self, &s, 4) < 0)
return -1;
x = calc_binint(s, 4);
@@ -3278,7 +4098,7 @@
return -1;
}
- if (unpickler_read(self, &s, x) < 0)
+ if (_Unpickler_Read(self, &s, x) < 0)
return -1;
/* Convert Python 2.x strings to unicode. */
@@ -3297,12 +4117,12 @@
unsigned char x;
char *s;
- if (unpickler_read(self, &s, 1) < 0)
+ if (_Unpickler_Read(self, &s, 1) < 0)
return -1;
x = (unsigned char)s[0];
- if (unpickler_read(self, &s, x) < 0)
+ if (_Unpickler_Read(self, &s, x) < 0)
return -1;
/* Convert Python 2.x strings to unicode. */
@@ -3321,7 +4141,7 @@
Py_ssize_t len;
char *s;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 1)
return bad_readline();
@@ -3341,7 +4161,7 @@
long size;
char *s;
- if (unpickler_read(self, &s, 4) < 0)
+ if (_Unpickler_Read(self, &s, 4) < 0)
return -1;
size = calc_binint(s, 4);
@@ -3351,7 +4171,7 @@
return -1;
}
- if (unpickler_read(self, &s, size) < 0)
+ if (_Unpickler_Read(self, &s, size) < 0)
return -1;
str = PyUnicode_DecodeUTF8(s, size, "surrogatepass");
@@ -3445,7 +4265,7 @@
if ((i = marker(self)) < 0)
return -1;
- j = self->stack->length;
+ j = Py_SIZE(self->stack);
if ((dict = PyDict_New()) == NULL)
return -1;
@@ -3521,7 +4341,7 @@
if ((i = marker(self)) < 0)
return -1;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
@@ -3533,7 +4353,7 @@
if (module_name == NULL)
return -1;
- if ((len = unpickler_readline(self, &s)) >= 0) {
+ if ((len = _Unpickler_Readline(self, &s)) >= 0) {
if (len < 2)
return bad_readline();
class_name = PyUnicode_DecodeASCII(s, len - 1, "strict");
@@ -3619,7 +4439,7 @@
Py_ssize_t len;
char *s;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
@@ -3627,7 +4447,7 @@
if (!module_name)
return -1;
- if ((len = unpickler_readline(self, &s)) >= 0) {
+ if ((len = _Unpickler_Readline(self, &s)) >= 0) {
if (len < 2) {
Py_DECREF(module_name);
return bad_readline();
@@ -3654,7 +4474,7 @@
char *s;
if (self->pers_func) {
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
@@ -3663,9 +4483,9 @@
if (pid == NULL)
return -1;
- /* Ugh... this does not leak since unpickler_call() steals the
+ /* Ugh... this does not leak since _Unpickler_FastCall() steals the
reference to pid first. */
- pid = unpickler_call(self, self->pers_func, pid);
+ pid = _Unpickler_FastCall(self, self->pers_func, pid);
if (pid == NULL)
return -1;
@@ -3690,9 +4510,9 @@
if (pid == NULL)
return -1;
- /* Ugh... this does not leak since unpickler_call() steals the
+ /* Ugh... this does not leak since _Unpickler_FastCall() steals the
reference to pid first. */
- pid = unpickler_call(self, self->pers_func, pid);
+ pid = _Unpickler_FastCall(self, self->pers_func, pid);
if (pid == NULL)
return -1;
@@ -3710,7 +4530,7 @@
static int
load_pop(UnpicklerObject *self)
{
- int len = self->stack->length;
+ int len = Py_SIZE(self->stack);
/* Note that we split the (pickle.py) stack into two stacks,
* an object stack and a mark stack. We have to be clever and
@@ -3724,7 +4544,7 @@
} else if (len > 0) {
len--;
Py_DECREF(self->stack->data[len]);
- self->stack->length = len;
+ Py_SIZE(self->stack) = len;
} else {
return stack_underflow();
}
@@ -3750,7 +4570,7 @@
PyObject *last;
int len;
- if ((len = self->stack->length) <= 0)
+ if ((len = Py_SIZE(self->stack)) <= 0)
return stack_underflow();
last = self->stack->data[len - 1];
PDATA_APPEND(self->stack, last, -1);
@@ -3761,10 +4581,11 @@
load_get(UnpicklerObject *self)
{
PyObject *key, *value;
+ Py_ssize_t idx;
Py_ssize_t len;
char *s;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
@@ -3772,8 +4593,13 @@
key = PyLong_FromString(s, NULL, 10);
if (key == NULL)
return -1;
+ idx = PyLong_AsSsize_t(key);
+ if (idx == -1 && PyErr_Occurred()) {
+ Py_DECREF(key);
+ return -1;
+ }
- value = PyDict_GetItemWithError(self->memo, key);
+ value = _Unpickler_MemoGet(self, idx);
if (value == NULL) {
if (!PyErr_Occurred())
PyErr_SetObject(PyExc_KeyError, key);
@@ -3789,25 +4615,23 @@
static int
load_binget(UnpicklerObject *self)
{
- PyObject *key, *value;
+ PyObject *value;
+ Py_ssize_t idx;
char *s;
- if (unpickler_read(self, &s, 1) < 0)
+ if (_Unpickler_Read(self, &s, 1) < 0)
return -1;
- /* Here, the unsigned cast is necessary to avoid negative values. */
- key = PyLong_FromLong((long)(unsigned char)s[0]);
- if (key == NULL)
- return -1;
+ idx = Py_CHARMASK(s[0]);
- value = PyDict_GetItemWithError(self->memo, key);
+ value = _Unpickler_MemoGet(self, idx);
if (value == NULL) {
+ PyObject *key = PyLong_FromSsize_t(idx);
if (!PyErr_Occurred())
PyErr_SetObject(PyExc_KeyError, key);
Py_DECREF(key);
return -1;
}
- Py_DECREF(key);
PDATA_APPEND(self->stack, value, -1);
return 0;
@@ -3816,30 +4640,26 @@
static int
load_long_binget(UnpicklerObject *self)
{
- PyObject *key, *value;
+ PyObject *value;
+ Py_ssize_t idx;
char *s;
- long k;
- if (unpickler_read(self, &s, 4) < 0)
+ if (_Unpickler_Read(self, &s, 4) < 0)
return -1;
- k = (long)(unsigned char)s[0];
- k |= (long)(unsigned char)s[1] << 8;
- k |= (long)(unsigned char)s[2] << 16;
- k |= (long)(unsigned char)s[3] << 24;
+ idx = (long)Py_CHARMASK(s[0]);
+ idx |= (long)Py_CHARMASK(s[1]) << 8;
+ idx |= (long)Py_CHARMASK(s[2]) << 16;
+ idx |= (long)Py_CHARMASK(s[3]) << 24;
- key = PyLong_FromLong(k);
- if (key == NULL)
- return -1;
-
- value = PyDict_GetItemWithError(self->memo, key);
+ value = _Unpickler_MemoGet(self, idx);
if (value == NULL) {
+ PyObject *key = PyLong_FromSsize_t(idx);
if (!PyErr_Occurred())
PyErr_SetObject(PyExc_KeyError, key);
Py_DECREF(key);
return -1;
}
- Py_DECREF(key);
PDATA_APPEND(self->stack, value, -1);
return 0;
@@ -3859,7 +4679,7 @@
PyObject *module_name, *class_name;
assert(nbytes == 1 || nbytes == 2 || nbytes == 4);
- if (unpickler_read(self, &codebytes, nbytes) < 0)
+ if (_Unpickler_Read(self, &codebytes, nbytes) < 0)
return -1;
code = calc_binint(codebytes, nbytes);
if (code <= 0) { /* note that 0 is forbidden */
@@ -3920,75 +4740,68 @@
load_put(UnpicklerObject *self)
{
PyObject *key, *value;
+ Py_ssize_t idx;
Py_ssize_t len;
char *s;
- int x;
- if ((len = unpickler_readline(self, &s)) < 0)
+ if ((len = _Unpickler_Readline(self, &s)) < 0)
return -1;
if (len < 2)
return bad_readline();
- if ((x = self->stack->length) <= 0)
+ if (Py_SIZE(self->stack) <= 0)
return stack_underflow();
+ value = self->stack->data[Py_SIZE(self->stack) - 1];
key = PyLong_FromString(s, NULL, 10);
if (key == NULL)
return -1;
- value = self->stack->data[x - 1];
-
- x = PyDict_SetItem(self->memo, key, value);
+ idx = PyLong_AsSsize_t(key);
Py_DECREF(key);
- return x;
+ if (idx == -1 && PyErr_Occurred())
+ return -1;
+
+ return _Unpickler_MemoPut(self, idx, value);
}
static int
load_binput(UnpicklerObject *self)
{
- PyObject *key, *value;
+ PyObject *value;
+ Py_ssize_t idx;
char *s;
- int x;
- if (unpickler_read(self, &s, 1) < 0)
+ if (_Unpickler_Read(self, &s, 1) < 0)
return -1;
- if ((x = self->stack->length) <= 0)
+
+ if (Py_SIZE(self->stack) <= 0)
return stack_underflow();
+ value = self->stack->data[Py_SIZE(self->stack) - 1];
- key = PyLong_FromLong((long)(unsigned char)s[0]);
- if (key == NULL)
- return -1;
- value = self->stack->data[x - 1];
+ idx = Py_CHARMASK(s[0]);
- x = PyDict_SetItem(self->memo, key, value);
- Py_DECREF(key);
- return x;
+ return _Unpickler_MemoPut(self, idx, value);
}
static int
load_long_binput(UnpicklerObject *self)
{
- PyObject *key, *value;
- long k;
+ PyObject *value;
+ Py_ssize_t idx;
char *s;
- int x;
- if (unpickler_read(self, &s, 4) < 0)
+ if (_Unpickler_Read(self, &s, 4) < 0)
return -1;
- if ((x = self->stack->length) <= 0)
- return stack_underflow();
- k = (long)(unsigned char)s[0];
- k |= (long)(unsigned char)s[1] << 8;
- k |= (long)(unsigned char)s[2] << 16;
- k |= (long)(unsigned char)s[3] << 24;
+ if (Py_SIZE(self->stack) <= 0)
+ return stack_underflow();
+ value = self->stack->data[Py_SIZE(self->stack) - 1];
- key = PyLong_FromLong(k);
- if (key == NULL)
- return -1;
- value = self->stack->data[x - 1];
+ idx = (long)Py_CHARMASK(s[0]);
+ idx |= (long)Py_CHARMASK(s[1]) << 8;
+ idx |= (long)Py_CHARMASK(s[2]) << 16;
+ idx |= (long)Py_CHARMASK(s[3]) << 24;
- x = PyDict_SetItem(self->memo, key, value);
- Py_DECREF(key);
- return x;
+ return _Unpickler_MemoPut(self, idx, value);
}
static int
@@ -3998,7 +4811,7 @@
PyObject *list;
int len, i;
- len = self->stack->length;
+ len = Py_SIZE(self->stack);
if (x > len || x <= 0)
return stack_underflow();
if (len == x) /* nothing to do */
@@ -4028,15 +4841,15 @@
PyObject *result;
value = self->stack->data[i];
- result = unpickler_call(self, append_func, value);
+ result = _Unpickler_FastCall(self, append_func, value);
if (result == NULL) {
Pdata_clear(self->stack, i + 1);
- self->stack->length = x;
+ Py_SIZE(self->stack) = x;
return -1;
}
Py_DECREF(result);
}
- self->stack->length = x;
+ Py_SIZE(self->stack) = x;
}
return 0;
@@ -4045,7 +4858,7 @@
static int
load_append(UnpicklerObject *self)
{
- return do_append(self, self->stack->length - 1);
+ return do_append(self, Py_SIZE(self->stack) - 1);
}
static int
@@ -4062,7 +4875,7 @@
int len, i;
int status = 0;
- len = self->stack->length;
+ len = Py_SIZE(self->stack);
if (x > len || x <= 0)
return stack_underflow();
if (len == x) /* nothing to do */
@@ -4093,7 +4906,7 @@
static int
load_setitem(UnpicklerObject *self)
{
- return do_setitems(self, self->stack->length - 2);
+ return do_setitems(self, Py_SIZE(self->stack) - 2);
}
static int
@@ -4112,14 +4925,14 @@
/* Stack is ... instance, state. We want to leave instance at
* the stack top, possibly mutated via instance.__setstate__(state).
*/
- if (self->stack->length < 2)
+ if (Py_SIZE(self->stack) < 2)
return stack_underflow();
PDATA_POP(self->stack, state);
if (state == NULL)
return -1;
- inst = self->stack->data[self->stack->length - 1];
+ inst = self->stack->data[Py_SIZE(self->stack) - 1];
setstate = PyObject_GetAttrString(inst, "__setstate__");
if (setstate == NULL) {
@@ -4134,9 +4947,9 @@
PyObject *result;
/* The explicit __setstate__ is responsible for everything. */
- /* Ugh... this does not leak since unpickler_call() steals the
+ /* Ugh... this does not leak since _Unpickler_FastCall() steals the
reference to state first. */
- result = unpickler_call(self, setstate, state);
+ result = _Unpickler_FastCall(self, setstate, state);
Py_DECREF(setstate);
if (result == NULL)
return -1;
@@ -4249,7 +5062,7 @@
self->marks_size = (Py_ssize_t)alloc;
}
- self->marks[self->num_marks++] = self->stack->length;
+ self->marks[self->num_marks++] = Py_SIZE(self->stack);
return 0;
}
@@ -4287,7 +5100,7 @@
char *s;
int i;
- if (unpickler_read(self, &s, 1) < 0)
+ if (_Unpickler_Read(self, &s, 1) < 0)
return -1;
i = (unsigned char)s[0];
@@ -4308,7 +5121,7 @@
char *s;
self->num_marks = 0;
- if (self->stack->length)
+ if (Py_SIZE(self->stack))
Pdata_clear(self->stack, 0);
/* Convenient macros for the dispatch while-switch loop just below. */
@@ -4319,7 +5132,7 @@
case opcode: if (load_func(self, (arg)) < 0) break; continue;
while (1) {
- if (unpickler_read(self, &s, 1) < 0)
+ if (_Unpickler_Read(self, &s, 1) < 0)
break;
switch ((enum opcode)s[0]) {
@@ -4543,13 +5356,17 @@
PyObject_GC_UnTrack((PyObject *)self);
Py_XDECREF(self->readline);
Py_XDECREF(self->read);
- Py_XDECREF(self->memo);
Py_XDECREF(self->stack);
Py_XDECREF(self->pers_func);
Py_XDECREF(self->arg);
- Py_XDECREF(self->last_string);
+ if (self->buffer.buf != NULL) {
+ PyBuffer_Release(&self->buffer);
+ self->buffer.buf = NULL;
+ }
+ _Unpickler_MemoCleanup(self);
PyMem_Free(self->marks);
+ PyMem_Free(self->input_line);
free(self->encoding);
free(self->errors);
@@ -4561,11 +5378,9 @@
{
Py_VISIT(self->readline);
Py_VISIT(self->read);
- Py_VISIT(self->memo);
Py_VISIT(self->stack);
Py_VISIT(self->pers_func);
Py_VISIT(self->arg);
- Py_VISIT(self->last_string);
return 0;
}
@@ -4574,14 +5389,19 @@
{
Py_CLEAR(self->readline);
Py_CLEAR(self->read);
- Py_CLEAR(self->memo);
Py_CLEAR(self->stack);
Py_CLEAR(self->pers_func);
Py_CLEAR(self->arg);
- Py_CLEAR(self->last_string);
+ if (self->buffer.buf != NULL) {
+ PyBuffer_Release(&self->buffer);
+ self->buffer.buf = NULL;
+ }
+ _Unpickler_MemoCleanup(self);
PyMem_Free(self->marks);
self->marks = NULL;
+ PyMem_Free(self->input_line);
+ self->input_line = NULL;
free(self->encoding);
self->encoding = NULL;
free(self->errors);
@@ -4618,7 +5438,7 @@
{
static char *kwlist[] = {"file", "fix_imports", "encoding", "errors", 0};
PyObject *file;
- int fix_imports = 1;
+ PyObject *fix_imports = Py_True;
char *encoding = NULL;
char *errors = NULL;
@@ -4637,7 +5457,7 @@
extra careful in the other Unpickler methods, since a subclass could
forget to call Unpickler.__init__() thus breaking our internal
invariants. */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iss:Unpickler", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oss:Unpickler", kwlist,
&file, &fix_imports, &encoding, &errors))
return -1;
@@ -4645,22 +5465,15 @@
if (self->read != NULL)
(void)Unpickler_clear(self);
- self->read = PyObject_GetAttrString(file, "read");
- self->readline = PyObject_GetAttrString(file, "readline");
- if (self->readline == NULL || self->read == NULL)
+ if (_Unpickler_SetInputStream(self, file) < 0)
return -1;
- if (encoding == NULL)
- encoding = "ASCII";
- if (errors == NULL)
- errors = "strict";
+ if (_Unpickler_SetInputEncoding(self, encoding, errors) < 0)
+ return -1;
- self->encoding = strdup(encoding);
- self->errors = strdup(errors);
- if (self->encoding == NULL || self->errors == NULL) {
- PyErr_NoMemory();
+ self->fix_imports = PyObject_IsTrue(fix_imports);
+ if (self->fix_imports == -1)
return -1;
- }
if (PyObject_HasAttrString((PyObject *)self, "persistent_load")) {
self->pers_func = PyObject_GetAttrString((PyObject *)self,
@@ -4676,49 +5489,269 @@
if (self->stack == NULL)
return -1;
- self->memo = PyDict_New();
+ self->memo_size = 32;
+ self->memo = _Unpickler_NewMemo(self->memo_size);
if (self->memo == NULL)
return -1;
- self->last_string = NULL;
self->arg = NULL;
self->proto = 0;
- self->fix_imports = fix_imports;
return 0;
}
+/* Define a proxy object for the Unpickler's internal memo object. This is to
+ * avoid breaking code like:
+ * unpickler.memo.clear()
+ * and
+ * unpickler.memo = saved_memo
+ * Is this a good idea? Not really, but we don't want to break code that uses
+ * it. Note that we don't implement the entire mapping API here. This is
+ * intentional, as these should be treated as black-box implementation details.
+ *
+ * We do, however, have to implement pickling/unpickling support because of
+ * real-world code like cvs2svn.
+ */
+
+typedef struct {
+ PyObject_HEAD
+ UnpicklerObject *unpickler;
+} UnpicklerMemoProxyObject;
+
+PyDoc_STRVAR(ump_clear_doc,
+"memo.clear() -> None. Remove all items from memo.");
+
+static PyObject *
+ump_clear(UnpicklerMemoProxyObject *self)
+{
+ _Unpickler_MemoCleanup(self->unpickler);
+ self->unpickler->memo = _Unpickler_NewMemo(self->unpickler->memo_size);
+ if (self->unpickler->memo == NULL)
+ return NULL;
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(ump_copy_doc,
+"memo.copy() -> new_memo. Copy the memo to a new object.");
+
+static PyObject *
+ump_copy(UnpicklerMemoProxyObject *self)
+{
+ Py_ssize_t i;
+ PyObject *new_memo = PyDict_New();
+ if (new_memo == NULL)
+ return NULL;
+
+ for (i = 0; i < self->unpickler->memo_size; i++) {
+ int status;
+ PyObject *key, *value;
+
+ value = self->unpickler->memo[i];
+ if (value == NULL)
+ continue;
+
+ key = PyLong_FromSsize_t(i);
+ if (key == NULL)
+ goto error;
+ status = PyDict_SetItem(new_memo, key, value);
+ Py_DECREF(key);
+ if (status < 0)
+ goto error;
+ }
+ return new_memo;
+
+error:
+ Py_DECREF(new_memo);
+ return NULL;
+}
+
+PyDoc_STRVAR(ump_reduce_doc,
+"memo.__reduce__(). Pickling support.");
+
+static PyObject *
+ump_reduce(UnpicklerMemoProxyObject *self, PyObject *args)
+{
+ PyObject *reduce_value;
+ PyObject *constructor_args;
+ PyObject *contents = ump_copy(self);
+ if (contents == NULL)
+ return NULL;
+
+ reduce_value = PyTuple_New(2);
+ if (reduce_value == NULL) {
+ Py_DECREF(contents);
+ return NULL;
+ }
+ constructor_args = PyTuple_New(1);
+ if (constructor_args == NULL) {
+ Py_DECREF(contents);
+ Py_DECREF(reduce_value);
+ return NULL;
+ }
+ PyTuple_SET_ITEM(constructor_args, 0, contents);
+ Py_INCREF((PyObject *)&PyDict_Type);
+ PyTuple_SET_ITEM(reduce_value, 0, (PyObject *)&PyDict_Type);
+ PyTuple_SET_ITEM(reduce_value, 1, constructor_args);
+ return reduce_value;
+}
+
+static PyMethodDef unpicklerproxy_methods[] = {
+ {"clear", (PyCFunction)ump_clear, METH_NOARGS, ump_clear_doc},
+ {"copy", (PyCFunction)ump_copy, METH_NOARGS, ump_copy_doc},
+ {"__reduce__", (PyCFunction)ump_reduce, METH_VARARGS, ump_reduce_doc},
+ {NULL, NULL} /* sentinel */
+};
+
+static void
+UnpicklerMemoProxy_dealloc(UnpicklerMemoProxyObject *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->unpickler);
+ PyObject_GC_Del((PyObject *)self);
+}
+
+static int
+UnpicklerMemoProxy_traverse(UnpicklerMemoProxyObject *self,
+ visitproc visit, void *arg)
+{
+ Py_VISIT(self->unpickler);
+ return 0;
+}
+
+static int
+UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self)
+{
+ Py_CLEAR(self->unpickler);
+ return 0;
+}
+
+static PyTypeObject UnpicklerMemoProxyType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "_pickle.UnpicklerMemoProxy", /*tp_name*/
+ sizeof(UnpicklerMemoProxyObject), /*tp_basicsize*/
+ 0,
+ (destructor)UnpicklerMemoProxy_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)PyObject_HashNotImplemented, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ PyObject_GenericSetAttr, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ 0, /* tp_doc */
+ (traverseproc)UnpicklerMemoProxy_traverse, /* tp_traverse */
+ (inquiry)UnpicklerMemoProxy_clear, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ unpicklerproxy_methods, /* tp_methods */
+};
+
+static PyObject *
+UnpicklerMemoProxy_New(UnpicklerObject *unpickler)
+{
+ UnpicklerMemoProxyObject *self;
+
+ self = PyObject_GC_New(UnpicklerMemoProxyObject,
+ &UnpicklerMemoProxyType);
+ if (self == NULL)
+ return NULL;
+ Py_INCREF(unpickler);
+ self->unpickler = unpickler;
+ PyObject_GC_Track(self);
+ return (PyObject *)self;
+}
+
+/*****************************************************************************/
+
+
static PyObject *
Unpickler_get_memo(UnpicklerObject *self)
{
- if (self->memo == NULL)
- PyErr_SetString(PyExc_AttributeError, "memo");
- else
- Py_INCREF(self->memo);
- return self->memo;
+ return UnpicklerMemoProxy_New(self);
}
static int
-Unpickler_set_memo(UnpicklerObject *self, PyObject *value)
+Unpickler_set_memo(UnpicklerObject *self, PyObject *obj)
{
- PyObject *tmp;
+ PyObject **new_memo;
+ Py_ssize_t new_memo_size = 0;
+ Py_ssize_t i;
- if (value == NULL) {
+ if (obj == NULL) {
PyErr_SetString(PyExc_TypeError,
"attribute deletion is not supported");
return -1;
}
- if (!PyDict_Check(value)) {
- PyErr_SetString(PyExc_TypeError, "memo must be a dictionary");
+
+ if (Py_TYPE(obj) == &UnpicklerMemoProxyType) {
+ UnpicklerObject *unpickler =
+ ((UnpicklerMemoProxyObject *)obj)->unpickler;
+
+ new_memo_size = unpickler->memo_size;
+ new_memo = _Unpickler_NewMemo(new_memo_size);
+ if (new_memo == NULL)
+ return -1;
+
+ for (i = 0; i < new_memo_size; i++) {
+ Py_XINCREF(unpickler->memo[i]);
+ new_memo[i] = unpickler->memo[i];
+ }
+ }
+ else if (PyDict_Check(obj)) {
+ Py_ssize_t i = 0;
+ PyObject *key, *value;
+
+ new_memo_size = PyDict_Size(obj);
+ new_memo = _Unpickler_NewMemo(new_memo_size);
+ if (new_memo == NULL)
+ return -1;
+
+ while (PyDict_Next(obj, &i, &key, &value)) {
+ Py_ssize_t idx;
+ if (!PyLong_Check(key)) {
+ PyErr_SetString(PyExc_TypeError,
+ "memo key must be integers");
+ goto error;
+ }
+ idx = PyLong_AsSsize_t(key);
+ if (idx == -1 && PyErr_Occurred())
+ goto error;
+ if (_Unpickler_MemoPut(self, idx, value) < 0)
+ goto error;
+ }
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "'memo' attribute must be an UnpicklerMemoProxy object"
+ "or dict, not %.200s", Py_TYPE(obj)->tp_name);
return -1;
}
- tmp = self->memo;
- Py_INCREF(value);
- self->memo = value;
- Py_XDECREF(tmp);
+ _Unpickler_MemoCleanup(self);
+ self->memo_size = new_memo_size;
+ self->memo = new_memo;
return 0;
+
+ error:
+ if (new_memo_size) {
+ i = new_memo_size;
+ while (--i >= 0) {
+ Py_XDECREF(new_memo[i]);
+ }
+ PyMem_FREE(new_memo);
+ }
+ return -1;
}
static PyObject *
@@ -4771,7 +5804,7 @@
(destructor)Unpickler_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
- 0, /*tp_setattr*/
+ 0, /*tp_setattr*/
0, /*tp_reserved*/
0, /*tp_repr*/
0, /*tp_as_number*/
@@ -4806,6 +5839,280 @@
0, /*tp_is_gc*/
};
+PyDoc_STRVAR(pickle_dump_doc,
+"dump(obj, file, protocol=None, *, fix_imports=True) -> None\n"
+"\n"
+"Write a pickled representation of obj to the open file object file. This\n"
+"is equivalent to ``Pickler(file, protocol).dump(obj)``, but may be more\n"
+"efficient.\n"
+"\n"
+"The optional protocol argument tells the pickler to use the given protocol;\n"
+"supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n"
+"backward-incompatible protocol designed for Python 3.0.\n"
+"\n"
+"Specifying a negative protocol version selects the highest protocol version\n"
+"supported. The higher the protocol used, the more recent the version of\n"
+"Python needed to read the pickle produced.\n"
+"\n"
+"The file argument must have a write() method that accepts a single bytes\n"
+"argument. It can thus be a file object opened for binary writing, a\n"
+"io.BytesIO instance, or any other custom object that meets this interface.\n"
+"\n"
+"If fix_imports is True and protocol is less than 3, pickle will try to\n"
+"map the new Python 3.x names to the old module names used in Python 2.x,\n"
+"so that the pickle data stream is readable with Python 2.x.\n");
+
+static PyObject *
+pickle_dump(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"obj", "file", "protocol", "fix_imports", 0};
+ PyObject *obj;
+ PyObject *file;
+ PyObject *proto = NULL;
+ PyObject *fix_imports = Py_True;
+ PicklerObject *pickler;
+
+ /* fix_imports is a keyword-only argument. */
+ if (Py_SIZE(args) > 3) {
+ PyErr_Format(PyExc_TypeError,
+ "pickle.dump() takes at most 3 positional "
+ "argument (%zd given)", Py_SIZE(args));
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO:dump", kwlist,
+ &obj, &file, &proto, &fix_imports))
+ return NULL;
+
+ pickler = _Pickler_New();
+ if (pickler == NULL)
+ return NULL;
+
+ if (_Pickler_SetProtocol(pickler, proto, fix_imports) < 0)
+ goto error;
+
+ if (_Pickler_SetOutputStream(pickler, file) < 0)
+ goto error;
+
+ if (dump(pickler, obj) < 0)
+ goto error;
+
+ if (_Pickler_FlushToFile(pickler) < 0)
+ goto error;
+
+ Py_DECREF(pickler);
+ Py_RETURN_NONE;
+
+ error:
+ Py_XDECREF(pickler);
+ return NULL;
+}
+
+PyDoc_STRVAR(pickle_dumps_doc,
+"dumps(obj, protocol=None, *, fix_imports=True) -> bytes\n"
+"\n"
+"Return the pickled representation of the object as a bytes\n"
+"object, instead of writing it to a file.\n"
+"\n"
+"The optional protocol argument tells the pickler to use the given protocol;\n"
+"supported protocols are 0, 1, 2, 3. The default protocol is 3; a\n"
+"backward-incompatible protocol designed for Python 3.0.\n"
+"\n"
+"Specifying a negative protocol version selects the highest protocol version\n"
+"supported. The higher the protocol used, the more recent the version of\n"
+"Python needed to read the pickle produced.\n"
+"\n"
+"If fix_imports is True and *protocol* is less than 3, pickle will try to\n"
+"map the new Python 3.x names to the old module names used in Python 2.x,\n"
+"so that the pickle data stream is readable with Python 2.x.\n");
+
+static PyObject *
+pickle_dumps(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"obj", "protocol", "fix_imports", 0};
+ PyObject *obj;
+ PyObject *proto = NULL;
+ PyObject *result;
+ PyObject *fix_imports = Py_True;
+ PicklerObject *pickler;
+
+ /* fix_imports is a keyword-only argument. */
+ if (Py_SIZE(args) > 2) {
+ PyErr_Format(PyExc_TypeError,
+ "pickle.dumps() takes at most 2 positional "
+ "argument (%zd given)", Py_SIZE(args));
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO:dumps", kwlist,
+ &obj, &proto, &fix_imports))
+ return NULL;
+
+ pickler = _Pickler_New();
+ if (pickler == NULL)
+ return NULL;
+
+ if (_Pickler_SetProtocol(pickler, proto, fix_imports) < 0)
+ goto error;
+
+ if (dump(pickler, obj) < 0)
+ goto error;
+
+ result = _Pickler_GetString(pickler);
+ Py_DECREF(pickler);
+ return result;
+
+ error:
+ Py_XDECREF(pickler);
+ return NULL;
+}
+
+PyDoc_STRVAR(pickle_load_doc,
+"load(file, *, fix_imports=True, encoding='ASCII', errors='strict') -> object\n"
+"\n"
+"Read a pickled object representation from the open file object file and\n"
+"return the reconstituted object hierarchy specified therein. This is\n"
+"equivalent to ``Unpickler(file).load()``, but may be more efficient.\n"
+"\n"
+"The protocol version of the pickle is detected automatically, so no protocol\n"
+"argument is needed. Bytes past the pickled object's representation are\n"
+"ignored.\n"
+"\n"
+"The argument file must have two methods, a read() method that takes an\n"
+"integer argument, and a readline() method that requires no arguments. Both\n"
+"methods should return bytes. Thus *file* can be a binary file object opened\n"
+"for reading, a BytesIO object, or any other custom object that meets this\n"
+"interface.\n"
+"\n"
+"Optional keyword arguments are fix_imports, encoding and errors,\n"
+"which are used to control compatiblity support for pickle stream generated\n"
+"by Python 2.x. If fix_imports is True, pickle will try to map the old\n"
+"Python 2.x names to the new names used in Python 3.x. The encoding and\n"
+"errors tell pickle how to decode 8-bit string instances pickled by Python\n"
+"2.x; these default to 'ASCII' and 'strict', respectively.\n");
+
+static PyObject *
+pickle_load(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"file", "fix_imports", "encoding", "errors", 0};
+ PyObject *file;
+ PyObject *fix_imports = Py_True;
+ PyObject *result;
+ char *encoding = NULL;
+ char *errors = NULL;
+ UnpicklerObject *unpickler;
+
+ /* fix_imports, encoding and errors are a keyword-only argument. */
+ if (Py_SIZE(args) != 1) {
+ PyErr_Format(PyExc_TypeError,
+ "pickle.load() takes exactly one positional "
+ "argument (%zd given)", Py_SIZE(args));
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oss:load", kwlist,
+ &file, &fix_imports, &encoding, &errors))
+ return NULL;
+
+ unpickler = _Unpickler_New();
+ if (unpickler == NULL)
+ return NULL;
+
+ if (_Unpickler_SetInputStream(unpickler, file) < 0)
+ goto error;
+
+ if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0)
+ goto error;
+
+ unpickler->fix_imports = PyObject_IsTrue(fix_imports);
+ if (unpickler->fix_imports == -1)
+ goto error;
+
+ result = load(unpickler);
+ Py_DECREF(unpickler);
+ return result;
+
+ error:
+ Py_XDECREF(unpickler);
+ return NULL;
+}
+
+PyDoc_STRVAR(pickle_loads_doc,
+"loads(input, *, fix_imports=True, encoding='ASCII', errors='strict') -> object\n"
+"\n"
+"Read a pickled object hierarchy from a bytes object and return the\n"
+"reconstituted object hierarchy specified therein\n"
+"\n"
+"The protocol version of the pickle is detected automatically, so no protocol\n"
+"argument is needed. Bytes past the pickled object's representation are\n"
+"ignored.\n"
+"\n"
+"Optional keyword arguments are fix_imports, encoding and errors, which\n"
+"are used to control compatiblity support for pickle stream generated\n"
+"by Python 2.x. If fix_imports is True, pickle will try to map the old\n"
+"Python 2.x names to the new names used in Python 3.x. The encoding and\n"
+"errors tell pickle how to decode 8-bit string instances pickled by Python\n"
+"2.x; these default to 'ASCII' and 'strict', respectively.\n");
+
+static PyObject *
+pickle_loads(PyObject *self, PyObject *args, PyObject *kwds)
+{
+ static char *kwlist[] = {"input", "fix_imports", "encoding", "errors", 0};
+ PyObject *input;
+ PyObject *fix_imports = Py_True;
+ PyObject *result;
+ char *encoding = NULL;
+ char *errors = NULL;
+ UnpicklerObject *unpickler;
+
+ /* fix_imports, encoding and errors are a keyword-only argument. */
+ if (Py_SIZE(args) != 1) {
+ PyErr_Format(PyExc_TypeError,
+ "pickle.loads() takes exactly one positional "
+ "argument (%zd given)", Py_SIZE(args));
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oss:loads", kwlist,
+ &input, &fix_imports, &encoding, &errors))
+ return NULL;
+
+ unpickler = _Unpickler_New();
+ if (unpickler == NULL)
+ return NULL;
+
+ if (_Unpickler_SetStringInput(unpickler, input) < 0)
+ goto error;
+
+ if (_Unpickler_SetInputEncoding(unpickler, encoding, errors) < 0)
+ goto error;
+
+ unpickler->fix_imports = PyObject_IsTrue(fix_imports);
+ if (unpickler->fix_imports == -1)
+ goto error;
+
+ result = load(unpickler);
+ Py_DECREF(unpickler);
+ return result;
+
+ error:
+ Py_XDECREF(unpickler);
+ return NULL;
+}
+
+
+static struct PyMethodDef pickle_methods[] = {
+ {"dump", (PyCFunction)pickle_dump, METH_VARARGS|METH_KEYWORDS,
+ pickle_dump_doc},
+ {"dumps", (PyCFunction)pickle_dumps, METH_VARARGS|METH_KEYWORDS,
+ pickle_dumps_doc},
+ {"load", (PyCFunction)pickle_load, METH_VARARGS|METH_KEYWORDS,
+ pickle_load_doc},
+ {"loads", (PyCFunction)pickle_loads, METH_VARARGS|METH_KEYWORDS,
+ pickle_loads_doc},
+ {NULL, NULL} /* sentinel */
+};
+
static int
initmodule(void)
{
@@ -4915,7 +6222,7 @@
"_pickle",
pickle_module_doc,
-1,
- NULL,
+ pickle_methods,
NULL,
NULL,
NULL,
@@ -4933,6 +6240,10 @@
return NULL;
if (PyType_Ready(&Pdata_Type) < 0)
return NULL;
+ if (PyType_Ready(&PicklerMemoProxyType) < 0)
+ return NULL;
+ if (PyType_Ready(&UnpicklerMemoProxyType) < 0)
+ return NULL;
/* Create the module and add the functions. */
m = PyModule_Create(&_picklemodule);
From python-checkins at python.org Thu Sep 9 21:57:17 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Thu, 9 Sep 2010 21:57:17 +0200 (CEST)
Subject: [Python-checkins] r84654 - in python/branches/release31-maint:
PCbuild/_multiprocessing.vcproj PCbuild/pythoncore.vcproj
Message-ID: <20100909195717.4A5D7FAEF@mail.python.org>
Author: hirokazu.yamamoto
Date: Thu Sep 9 21:57:17 2010
New Revision: 84654
Log:
Merged revisions 84645 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84645 | hirokazu.yamamoto | 2010-09-09 15:24:43 +0900 | 5 lines
PCBuild cosmetic fixes.
* pythoncore.vcproj: Fixed indentation
* _multiprocessing.vcproj: Converted ProjectGUID to uppercase. Otherwise,
VS8 _multiprocessing.vcproj created by vs9to8.py was modified every time
loads it in VS8 IDE.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/PCbuild/_multiprocessing.vcproj
python/branches/release31-maint/PCbuild/pythoncore.vcproj
Modified: python/branches/release31-maint/PCbuild/_multiprocessing.vcproj
==============================================================================
--- python/branches/release31-maint/PCbuild/_multiprocessing.vcproj (original)
+++ python/branches/release31-maint/PCbuild/_multiprocessing.vcproj Thu Sep 9 21:57:17 2010
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9,00"
Name="_multiprocessing"
- ProjectGUID="{9e48b300-37d1-11dd-8c41-005056c00008}"
+ ProjectGUID="{9E48B300-37D1-11DD-8C41-005056C00008}"
RootNamespace="_multiprocessing"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
Modified: python/branches/release31-maint/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/release31-maint/PCbuild/pythoncore.vcproj (original)
+++ python/branches/release31-maint/PCbuild/pythoncore.vcproj Thu Sep 9 21:57:17 2010
@@ -846,7 +846,10 @@
RelativePath="..\Include\pyarena.h"
>
-
+
+
@@ -1375,10 +1378,10 @@
RelativePath="..\Objects\bytesobject.c"
>
-
-
+
+
From python-checkins at python.org Thu Sep 9 22:30:24 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 22:30:24 +0200 (CEST)
Subject: [Python-checkins] r84655 - in python/branches/py3k:
Lib/test/test_builtin.py Lib/test/test_codeccallbacks.py
Misc/NEWS Python/codecs.c
Message-ID: <20100909203024.17989F538@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 22:30:23 2010
New Revision: 84655
Log:
Issue #9804: ascii() now always represents unicode surrogate pairs as
a single `\UXXXXXXXX`, regardless of whether the character is printable
or not. Also, the "backslashreplace" error handler now joins surrogate
pairs into a single character on UCS-2 builds.
Modified:
python/branches/py3k/Lib/test/test_builtin.py
python/branches/py3k/Lib/test/test_codeccallbacks.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Python/codecs.c
Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py (original)
+++ python/branches/py3k/Lib/test/test_builtin.py Thu Sep 9 22:30:23 2010
@@ -179,6 +179,28 @@
a = {}
a[0] = a
self.assertEqual(ascii(a), '{0: {...}}')
+ # Advanced checks for unicode strings
+ def _check_uni(s):
+ self.assertEqual(ascii(s), repr(s))
+ _check_uni("'")
+ _check_uni('"')
+ _check_uni('"\'')
+ _check_uni('\0')
+ _check_uni('\r\n\t .')
+ # Unprintable non-ASCII characters
+ _check_uni('\x85')
+ _check_uni('\u1fff')
+ _check_uni('\U00012fff')
+ # Lone surrogates
+ _check_uni('\ud800')
+ _check_uni('\udfff')
+ # Issue #9804: surrogates should be joined even for printable
+ # wide characters (UCS-2 builds).
+ self.assertEqual(ascii('\U0001d121'), "'\\U0001d121'")
+ # All together
+ s = "'\0\"\n\r\t abcd\x85?\U00012fff\uD800\U0001D121xxx."
+ self.assertEqual(ascii(s),
+ r"""'\'\x00"\n\r\t abcd\x85\xe9\U00012fff\ud800\U0001d121xxx.'""")
def test_neg(self):
x = -sys.maxsize-1
Modified: python/branches/py3k/Lib/test/test_codeccallbacks.py
==============================================================================
--- python/branches/py3k/Lib/test/test_codeccallbacks.py (original)
+++ python/branches/py3k/Lib/test/test_codeccallbacks.py Thu Sep 9 22:30:23 2010
@@ -577,17 +577,31 @@
UnicodeEncodeError("ascii", "\uffff", 0, 1, "ouch")),
("\\uffff", 1)
)
- if sys.maxunicode>0xffff:
- self.assertEquals(
- codecs.backslashreplace_errors(
- UnicodeEncodeError("ascii", "\U00010000", 0, 1, "ouch")),
- ("\\U00010000", 1)
- )
- self.assertEquals(
- codecs.backslashreplace_errors(
- UnicodeEncodeError("ascii", "\U0010ffff", 0, 1, "ouch")),
- ("\\U0010ffff", 1)
- )
+ # 1 on UCS-4 builds, 2 on UCS-2
+ len_wide = len("\U00010000")
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\U00010000",
+ 0, len_wide, "ouch")),
+ ("\\U00010000", len_wide)
+ )
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\U0010ffff",
+ 0, len_wide, "ouch")),
+ ("\\U0010ffff", len_wide)
+ )
+ # Lone surrogates (regardless of unicode width)
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\ud800", 0, 1, "ouch")),
+ ("\\ud800", 1)
+ )
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\udfff", 0, 1, "ouch")),
+ ("\\udfff", 1)
+ )
def test_badhandlerresults(self):
results = ( 42, "foo", (1,2,3), ("foo", 1, 3), ("foo", None), ("foo",), ("foo", 1, 3), ("foo", None), ("foo",) )
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Thu Sep 9 22:30:23 2010
@@ -10,6 +10,11 @@
Core and Builtins
-----------------
+- Issue #9804: ascii() now always represents unicode surrogate pairs as
+ a single ``\UXXXXXXXX``, regardless of whether the character is printable
+ or not. Also, the "backslashreplace" error handler now joins surrogate
+ pairs into a single character on UCS-2 builds.
+
- Issue #9757: memoryview objects get a release() method to release the
underlying buffer (previously this was only done when deallocating the
memoryview), and gain support for the context management protocol.
Modified: python/branches/py3k/Python/codecs.c
==============================================================================
--- python/branches/py3k/Python/codecs.c (original)
+++ python/branches/py3k/Python/codecs.c Thu Sep 9 22:30:23 2010
@@ -678,6 +678,13 @@
PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
{
+#ifndef Py_UNICODE_WIDE
+#define IS_SURROGATE_PAIR(p, end) \
+ (*p >= 0xD800 && *p <= 0xDBFF && (p + 1) < end && \
+ *(p + 1) >= 0xDC00 && *(p + 1) <= 0xDFFF)
+#else
+#define IS_SURROGATE_PAIR(p, end) 0
+#endif
if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
PyObject *restuple;
PyObject *object;
@@ -702,7 +709,12 @@
else
#endif
if (*p >= 0x100) {
- ressize += 1+1+4;
+ if (IS_SURROGATE_PAIR(p, startp+end)) {
+ ressize += 1+1+8;
+ ++p;
+ }
+ else
+ ressize += 1+1+4;
}
else
ressize += 1+1+2;
@@ -712,9 +724,12 @@
return NULL;
for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
p < startp+end; ++p) {
- Py_UNICODE c = *p;
+ Py_UCS4 c = (Py_UCS4) *p;
*outp++ = '\\';
-#ifdef Py_UNICODE_WIDE
+ if (IS_SURROGATE_PAIR(p, startp+end)) {
+ c = ((*p & 0x3FF) << 10) + (*(p + 1) & 0x3FF) + 0x10000;
+ ++p;
+ }
if (c >= 0x00010000) {
*outp++ = 'U';
*outp++ = hexdigits[(c>>28)&0xf];
@@ -724,9 +739,7 @@
*outp++ = hexdigits[(c>>12)&0xf];
*outp++ = hexdigits[(c>>8)&0xf];
}
- else
-#endif
- if (c >= 0x100) {
+ else if (c >= 0x100) {
*outp++ = 'u';
*outp++ = hexdigits[(c>>12)&0xf];
*outp++ = hexdigits[(c>>8)&0xf];
@@ -746,6 +759,7 @@
wrong_exception_type(exc);
return NULL;
}
+#undef IS_SURROGATE_PAIR
}
/* This handler is declared static until someone demonstrates
From python-checkins at python.org Thu Sep 9 22:33:43 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 22:33:43 +0200 (CEST)
Subject: [Python-checkins] r84656 - in python/branches/release31-maint:
Lib/test/test_builtin.py Lib/test/test_codeccallbacks.py
Misc/NEWS Python/codecs.c
Message-ID: <20100909203343.99E0BF538@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 22:33:43 2010
New Revision: 84656
Log:
Merged revisions 84655 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84655 | antoine.pitrou | 2010-09-09 22:30:23 +0200 (jeu., 09 sept. 2010) | 6 lines
Issue #9804: ascii() now always represents unicode surrogate pairs as
a single `\UXXXXXXXX`, regardless of whether the character is printable
or not. Also, the "backslashreplace" error handler now joins surrogate
pairs into a single character on UCS-2 builds.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_builtin.py
python/branches/release31-maint/Lib/test/test_codeccallbacks.py
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Python/codecs.c
Modified: python/branches/release31-maint/Lib/test/test_builtin.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_builtin.py (original)
+++ python/branches/release31-maint/Lib/test/test_builtin.py Thu Sep 9 22:33:43 2010
@@ -174,6 +174,28 @@
a = {}
a[0] = a
self.assertEqual(ascii(a), '{0: {...}}')
+ # Advanced checks for unicode strings
+ def _check_uni(s):
+ self.assertEqual(ascii(s), repr(s))
+ _check_uni("'")
+ _check_uni('"')
+ _check_uni('"\'')
+ _check_uni('\0')
+ _check_uni('\r\n\t .')
+ # Unprintable non-ASCII characters
+ _check_uni('\x85')
+ _check_uni('\u1fff')
+ _check_uni('\U00012fff')
+ # Lone surrogates
+ _check_uni('\ud800')
+ _check_uni('\udfff')
+ # Issue #9804: surrogates should be joined even for printable
+ # wide characters (UCS-2 builds).
+ self.assertEqual(ascii('\U0001d121'), "'\\U0001d121'")
+ # All together
+ s = "'\0\"\n\r\t abcd\x85?\U00012fff\uD800\U0001D121xxx."
+ self.assertEqual(ascii(s),
+ r"""'\'\x00"\n\r\t abcd\x85\xe9\U00012fff\ud800\U0001d121xxx.'""")
def test_neg(self):
x = -sys.maxsize-1
Modified: python/branches/release31-maint/Lib/test/test_codeccallbacks.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_codeccallbacks.py (original)
+++ python/branches/release31-maint/Lib/test/test_codeccallbacks.py Thu Sep 9 22:33:43 2010
@@ -577,17 +577,31 @@
UnicodeEncodeError("ascii", "\uffff", 0, 1, "ouch")),
("\\uffff", 1)
)
- if sys.maxunicode>0xffff:
- self.assertEquals(
- codecs.backslashreplace_errors(
- UnicodeEncodeError("ascii", "\U00010000", 0, 1, "ouch")),
- ("\\U00010000", 1)
- )
- self.assertEquals(
- codecs.backslashreplace_errors(
- UnicodeEncodeError("ascii", "\U0010ffff", 0, 1, "ouch")),
- ("\\U0010ffff", 1)
- )
+ # 1 on UCS-4 builds, 2 on UCS-2
+ len_wide = len("\U00010000")
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\U00010000",
+ 0, len_wide, "ouch")),
+ ("\\U00010000", len_wide)
+ )
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\U0010ffff",
+ 0, len_wide, "ouch")),
+ ("\\U0010ffff", len_wide)
+ )
+ # Lone surrogates (regardless of unicode width)
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\ud800", 0, 1, "ouch")),
+ ("\\ud800", 1)
+ )
+ self.assertEquals(
+ codecs.backslashreplace_errors(
+ UnicodeEncodeError("ascii", "\udfff", 0, 1, "ouch")),
+ ("\\udfff", 1)
+ )
def test_badhandlerresults(self):
results = ( 42, "foo", (1,2,3), ("foo", 1, 3), ("foo", None), ("foo",), ("foo", 1, 3), ("foo", None), ("foo",) )
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Thu Sep 9 22:33:43 2010
@@ -12,6 +12,11 @@
Core and Builtins
-----------------
+- Issue #9804: ascii() now always represents unicode surrogate pairs as
+ a single ``\UXXXXXXXX``, regardless of whether the character is printable
+ or not. Also, the "backslashreplace" error handler now joins surrogate
+ pairs into a single character on UCS-2 builds.
+
- Issue #9797: pystate.c wrongly assumed that zero couldn't be a valid
thread-local storage key.
Modified: python/branches/release31-maint/Python/codecs.c
==============================================================================
--- python/branches/release31-maint/Python/codecs.c (original)
+++ python/branches/release31-maint/Python/codecs.c Thu Sep 9 22:33:43 2010
@@ -678,6 +678,13 @@
PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
{
+#ifndef Py_UNICODE_WIDE
+#define IS_SURROGATE_PAIR(p, end) \
+ (*p >= 0xD800 && *p <= 0xDBFF && (p + 1) < end && \
+ *(p + 1) >= 0xDC00 && *(p + 1) <= 0xDFFF)
+#else
+#define IS_SURROGATE_PAIR(p, end) 0
+#endif
if (PyObject_IsInstance(exc, PyExc_UnicodeEncodeError)) {
PyObject *restuple;
PyObject *object;
@@ -702,7 +709,12 @@
else
#endif
if (*p >= 0x100) {
- ressize += 1+1+4;
+ if (IS_SURROGATE_PAIR(p, startp+end)) {
+ ressize += 1+1+8;
+ ++p;
+ }
+ else
+ ressize += 1+1+4;
}
else
ressize += 1+1+2;
@@ -712,9 +724,12 @@
return NULL;
for (p = startp+start, outp = PyUnicode_AS_UNICODE(res);
p < startp+end; ++p) {
- Py_UNICODE c = *p;
+ Py_UCS4 c = (Py_UCS4) *p;
*outp++ = '\\';
-#ifdef Py_UNICODE_WIDE
+ if (IS_SURROGATE_PAIR(p, startp+end)) {
+ c = ((*p & 0x3FF) << 10) + (*(p + 1) & 0x3FF) + 0x10000;
+ ++p;
+ }
if (c >= 0x00010000) {
*outp++ = 'U';
*outp++ = hexdigits[(c>>28)&0xf];
@@ -724,9 +739,7 @@
*outp++ = hexdigits[(c>>12)&0xf];
*outp++ = hexdigits[(c>>8)&0xf];
}
- else
-#endif
- if (c >= 0x100) {
+ else if (c >= 0x100) {
*outp++ = 'u';
*outp++ = hexdigits[(c>>12)&0xf];
*outp++ = hexdigits[(c>>8)&0xf];
@@ -746,6 +759,7 @@
wrong_exception_type(exc);
return NULL;
}
+#undef IS_SURROGATE_PAIR
}
/* This handler is declared static until someone demonstrates
From python-checkins at python.org Thu Sep 9 22:40:29 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Thu, 9 Sep 2010 22:40:29 +0200 (CEST)
Subject: [Python-checkins] r84657 - python/branches/py3k/Lib/test/test_gdb.py
Message-ID: <20100909204029.0FE01F80D@mail.python.org>
Author: antoine.pitrou
Date: Thu Sep 9 22:40:28 2010
New Revision: 84657
Log:
Remove workaround
Modified:
python/branches/py3k/Lib/test/test_gdb.py
Modified: python/branches/py3k/Lib/test/test_gdb.py
==============================================================================
--- python/branches/py3k/Lib/test/test_gdb.py (original)
+++ python/branches/py3k/Lib/test/test_gdb.py Thu Sep 9 22:40:28 2010
@@ -234,9 +234,7 @@
text.encode(encoding)
printable = True
except UnicodeEncodeError:
- # Workaround ascii() bug on UCS-2 builds: issue #9804
- asc = "'" + text.encode('unicode-escape').decode('ascii') + "'"
- self.assertGdbRepr(text, asc)
+ self.assertGdbRepr(text, ascii(text))
else:
self.assertGdbRepr(text)
From python-checkins at python.org Thu Sep 9 23:17:58 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Thu, 9 Sep 2010 23:17:58 +0200 (CEST)
Subject: [Python-checkins] r84658 -
python/branches/py3k/Lib/test/test_socket.py
Message-ID: <20100909211758.C2B66F882@mail.python.org>
Author: daniel.stutzbach
Date: Thu Sep 9 23:17:58 2010
New Revision: 84658
Log:
Skip socket tests that require the network, if the network resource is not enabled
Modified:
python/branches/py3k/Lib/test/test_socket.py
Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py (original)
+++ python/branches/py3k/Lib/test/test_socket.py Thu Sep 9 23:17:58 2010
@@ -642,6 +642,8 @@
# only IP addresses are allowed
self.assertRaises(socket.error, socket.getnameinfo, ('mail.python.org',0), 0)
+ @unittest.skipUnless(support.is_resource_enabled('network'),
+ 'network is not enabled')
def test_idna(self):
support.requires('network')
# these should all be successful
From python-checkins at python.org Thu Sep 9 23:18:04 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Thu, 9 Sep 2010 23:18:04 +0200 (CEST)
Subject: [Python-checkins] r84659 - python/branches/py3k/Python/import.c
Message-ID: <20100909211804.A5AE9FA9F@mail.python.org>
Author: daniel.stutzbach
Date: Thu Sep 9 23:18:04 2010
New Revision: 84659
Log:
Fix Issue #9752: MSVC compiler warning due to undefined function
(Patch by Jon Anglin)
Modified:
python/branches/py3k/Python/import.c
Modified: python/branches/py3k/Python/import.c
==============================================================================
--- python/branches/py3k/Python/import.c (original)
+++ python/branches/py3k/Python/import.c Thu Sep 9 23:18:04 2010
@@ -25,6 +25,8 @@
#ifdef MS_WINDOWS
/* for stat.st_mode */
typedef unsigned short mode_t;
+/* for _mkdir */
+#include
#endif
@@ -1134,9 +1136,6 @@
time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS /* since Windows uses different permissions */
mode_t mode = srcstat->st_mode & ~S_IEXEC;
- mode_t dirmode = srcstat->st_mode | S_IEXEC; /* XXX Is this correct
- for Windows?
- 2010-04-07 BAW */
#else
mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH;
mode_t dirmode = (srcstat->st_mode |
@@ -1156,8 +1155,12 @@
}
saved = *dirpath;
*dirpath = '\0';
- /* XXX call os.mkdir() or maybe CreateDirectoryA() on Windows? */
+
+#ifdef MS_WINDOWS
+ if (_mkdir(cpathname) < 0 && errno != EEXIST) {
+#else
if (mkdir(cpathname, dirmode) < 0 && errno != EEXIST) {
+#endif
*dirpath = saved;
if (Py_VerboseFlag)
PySys_WriteStderr(
From python-checkins at python.org Fri Sep 10 04:59:56 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Fri, 10 Sep 2010 04:59:56 +0200 (CEST)
Subject: [Python-checkins] r84660 - in python/branches/release31-maint:
Misc/ACKS PC/VS7.1/pythoncore.vcproj
Message-ID: <20100910025956.3C5C7EE987@mail.python.org>
Author: hirokazu.yamamoto
Date: Fri Sep 10 04:59:55 2010
New Revision: 84660
Log:
Merged revisions 84644 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84644 | hirokazu.yamamoto | 2010-09-09 15:14:23 +0900 | 1 line
Updated VS7.1 project file. (I cannot test this file because I don't have VS7.1)
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/ACKS
python/branches/release31-maint/PC/VS7.1/pythoncore.vcproj
Modified: python/branches/release31-maint/Misc/ACKS
==============================================================================
--- python/branches/release31-maint/Misc/ACKS (original)
+++ python/branches/release31-maint/Misc/ACKS Fri Sep 10 04:59:55 2010
@@ -857,6 +857,7 @@
Thomas Wouters
Heiko Wundram
Doug Wyatt
+Hirokazu Yamamoto
Ka-Ping Yee
Bob Yodlowski
Danny Yoo
Modified: python/branches/release31-maint/PC/VS7.1/pythoncore.vcproj
==============================================================================
--- python/branches/release31-maint/PC/VS7.1/pythoncore.vcproj (original)
+++ python/branches/release31-maint/PC/VS7.1/pythoncore.vcproj Fri Sep 10 04:59:55 2010
@@ -466,6 +466,9 @@
RelativePath="..\..\Objects\boolobject.c">
+
+
-
-
py3k results for svn r84659 (hg cset aa138a707c1b)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogvcjP95', '-x']
From python-checkins at python.org Fri Sep 10 05:08:24 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Fri, 10 Sep 2010 05:08:24 +0200 (CEST)
Subject: [Python-checkins] r84661 - in
python/branches/release27-maint/PCbuild:
_multiprocessing.vcproj pythoncore.vcproj
Message-ID: <20100910030824.5ECD7EE9BD@mail.python.org>
Author: hirokazu.yamamoto
Date: Fri Sep 10 05:08:24 2010
New Revision: 84661
Log:
PCBuild cosmetic fixes.
* pythoncore.vcproj: Removed doubled entries, and sorted entries a bit.
* _multiprocessing.vcproj: Converted ProjectGUID to uppercase. Otherwise,
VS8 _multiprocessing.vcproj created by vs9to8.py was modified every time
loads it in VS8 IDE.
Modified:
python/branches/release27-maint/PCbuild/_multiprocessing.vcproj
python/branches/release27-maint/PCbuild/pythoncore.vcproj
Modified: python/branches/release27-maint/PCbuild/_multiprocessing.vcproj
==============================================================================
--- python/branches/release27-maint/PCbuild/_multiprocessing.vcproj (original)
+++ python/branches/release27-maint/PCbuild/_multiprocessing.vcproj Fri Sep 10 05:08:24 2010
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="9,00"
Name="_multiprocessing"
- ProjectGUID="{9e48b300-37d1-11dd-8c41-005056c00008}"
+ ProjectGUID="{9E48B300-37D1-11DD-8C41-005056C00008}"
RootNamespace="_multiprocessing"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
Modified: python/branches/release27-maint/PCbuild/pythoncore.vcproj
==============================================================================
--- python/branches/release27-maint/PCbuild/pythoncore.vcproj (original)
+++ python/branches/release27-maint/PCbuild/pythoncore.vcproj Fri Sep 10 05:08:24 2010
@@ -683,10 +683,6 @@
>
-
-
@@ -719,6 +715,10 @@
>
+
+
@@ -911,10 +911,6 @@
>
-
-
@@ -1423,10 +1419,6 @@
>
-
-
@@ -1443,10 +1435,6 @@
>
-
-
@@ -1559,6 +1547,10 @@
>
+
+
@@ -1719,6 +1711,10 @@
>
+
+
@@ -1831,10 +1827,6 @@
>
-
-
From python-checkins at python.org Fri Sep 10 05:09:38 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Fri, 10 Sep 2010 05:09:38 +0200 (CEST)
Subject: [Python-checkins] r84662 - in
python/branches/release27-maint/PC/VC6: readme.txt tcl852.patch
Message-ID: <20100910030938.BDC7CEE98A@mail.python.org>
Author: hirokazu.yamamoto
Date: Fri Sep 10 05:09:38 2010
New Revision: 84662
Log:
Updated VC6 files.
* readme.txt: Added PSDK as requirement.
* tcl852.patch: fixed patch. it was doubled.
Modified:
python/branches/release27-maint/PC/VC6/readme.txt
python/branches/release27-maint/PC/VC6/tcl852.patch
Modified: python/branches/release27-maint/PC/VC6/readme.txt
==============================================================================
--- python/branches/release27-maint/PC/VC6/readme.txt (original)
+++ python/branches/release27-maint/PC/VC6/readme.txt Fri Sep 10 05:09:38 2010
@@ -1,7 +1,8 @@
Building Python using VC++ 6.0 or 5.0
-------------------------------------
This directory is used to build Python for Win32 platforms, e.g. Windows
-2000 and XP. It requires Microsoft Visual C++ 6.x or 5.x.
+2000 and XP. It requires Microsoft Visual C++ 6.x or 5.x and Platform
+SDK February 2003 Edition (Core SDK).
(For other Windows platforms and compilers, see ../readme.txt.)
All you need to do is open the workspace "pcbuild.dsw" in MSVC++, select
@@ -39,7 +40,6 @@
pythonw.exe, a variant of python.exe that doesn't pop up a DOS box
_msi
_msi.c. You need to install Windows Installer SDK to build this module.
- http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
_socket
socketmodule.c
_testcapi
Modified: python/branches/release27-maint/PC/VC6/tcl852.patch
==============================================================================
--- python/branches/release27-maint/PC/VC6/tcl852.patch (original)
+++ python/branches/release27-maint/PC/VC6/tcl852.patch Fri Sep 10 05:09:38 2010
@@ -9,14 +9,3 @@
typedef struct _stati64 Tcl_StatBuf;
# else
typedef struct _stat64 Tcl_StatBuf;
---- tcl8.5.2\generic\tcl.h Fri Jun 13 03:35:39 2008
-+++ tcl8.5.2\generic\tcl.h Sun Jan 4 16:52:30 2009
-@@ -367,7 +367,7 @@
- typedef struct stati64 Tcl_StatBuf;
- # define TCL_LL_MODIFIER "L"
- # else /* __BORLANDC__ */
--# if _MSC_VER < 1400 && !defined(_M_IX86)
-+# if _MSC_VER < 1400 /*&& !defined(_M_IX86)*/
- typedef struct _stati64 Tcl_StatBuf;
- # else
- typedef struct _stat64 Tcl_StatBuf;
From python-checkins at python.org Fri Sep 10 05:12:10 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Fri, 10 Sep 2010 05:12:10 +0200 (CEST)
Subject: [Python-checkins] r84663 - in python/branches/release27-maint/Lib:
pydoc_data unittest unittest/test
Message-ID: <20100910031210.E6862EE990@mail.python.org>
Author: hirokazu.yamamoto
Date: Fri Sep 10 05:12:10 2010
New Revision: 84663
Log:
Added svn:ignore (*.pyc, *.pyo)
Modified:
python/branches/release27-maint/Lib/pydoc_data/ (props changed)
python/branches/release27-maint/Lib/unittest/ (props changed)
python/branches/release27-maint/Lib/unittest/test/ (props changed)
From python-checkins at python.org Fri Sep 10 10:25:13 2010
From: python-checkins at python.org (vinay.sajip)
Date: Fri, 10 Sep 2010 10:25:13 +0200 (CEST)
Subject: [Python-checkins] r84664 -
python/branches/py3k/Lib/logging/__init__.py
Message-ID: <20100910082513.8C8D6F4F4@mail.python.org>
Author: vinay.sajip
Date: Fri Sep 10 10:25:13 2010
New Revision: 84664
Log:
logging: Added threading interlock in basicConfig().
Modified:
python/branches/py3k/Lib/logging/__init__.py
Modified: python/branches/py3k/Lib/logging/__init__.py
==============================================================================
--- python/branches/py3k/Lib/logging/__init__.py (original)
+++ python/branches/py3k/Lib/logging/__init__.py Fri Sep 10 10:25:13 2010
@@ -1459,22 +1459,28 @@
using sys.stdout or sys.stderr), whereas FileHandler closes its stream
when the handler is closed.
"""
- if len(root.handlers) == 0:
- filename = kwargs.get("filename")
- if filename:
- mode = kwargs.get("filemode", 'a')
- hdlr = FileHandler(filename, mode)
- else:
- stream = kwargs.get("stream")
- hdlr = StreamHandler(stream)
- fs = kwargs.get("format", BASIC_FORMAT)
- dfs = kwargs.get("datefmt", None)
- fmt = Formatter(fs, dfs)
- hdlr.setFormatter(fmt)
- root.addHandler(hdlr)
- level = kwargs.get("level")
- if level is not None:
- root.setLevel(level)
+ # Add thread safety in case someone mistakenly calls
+ # basicConfig() from multiple threads
+ _acquireLock()
+ try:
+ if len(root.handlers) == 0:
+ filename = kwargs.get("filename")
+ if filename:
+ mode = kwargs.get("filemode", 'a')
+ hdlr = FileHandler(filename, mode)
+ else:
+ stream = kwargs.get("stream")
+ hdlr = StreamHandler(stream)
+ fs = kwargs.get("format", BASIC_FORMAT)
+ dfs = kwargs.get("datefmt", None)
+ fmt = Formatter(fs, dfs)
+ hdlr.setFormatter(fmt)
+ root.addHandler(hdlr)
+ level = kwargs.get("level")
+ if level is not None:
+ root.setLevel(level)
+ finally:
+ _releaseLock()
#---------------------------------------------------------------------------
# Utility functions at module level.
From python-checkins at python.org Fri Sep 10 12:47:25 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Fri, 10 Sep 2010 12:47:25 +0200 (CEST)
Subject: [Python-checkins] r84665 - in python/branches/release27-maint:
Lib/random.py Lib/test/test_random.py Misc/NEWS
Message-ID: <20100910104725.64E8CEE9F6@mail.python.org>
Author: raymond.hettinger
Date: Fri Sep 10 12:47:22 2010
New Revision: 84665
Log:
Issue 9816: Random.jumpahead(n) didn't work well for small values of n.
Modified:
python/branches/release27-maint/Lib/random.py
python/branches/release27-maint/Lib/test/test_random.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/random.py
==============================================================================
--- python/branches/release27-maint/Lib/random.py (original)
+++ python/branches/release27-maint/Lib/random.py Fri Sep 10 12:47:22 2010
@@ -46,6 +46,7 @@
from math import sqrt as _sqrt, acos as _acos, cos as _cos, sin as _sin
from os import urandom as _urandom
from binascii import hexlify as _hexlify
+import hashlib as _hashlib
__all__ = ["Random","seed","random","uniform","randint","choice","sample",
"randrange","shuffle","normalvariate","lognormvariate",
@@ -141,6 +142,18 @@
"Random.setstate() of version %s" %
(version, self.VERSION))
+ def jumpahead(self, n):
+ """Change the internal state to one that is likely far away
+ from the current state. This method will not be in Py3.x,
+ so it is better to simply reseed.
+ """
+ # The super.jumpahead() method uses shuffling to change state,
+ # so it needs a large and "interesting" n to work with. Here,
+ # we use hashing to create a large n for the shuffle.
+ s = repr(n) + repr(self.getstate())
+ n = int(_hashlib.new('sha512', s).hexdigest(), 16)
+ super(Random, self).jumpahead(n)
+
## ---- Methods below this point do not need to be overridden when
## ---- subclassing for the purpose of using a different core generator.
Modified: python/branches/release27-maint/Lib/test/test_random.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_random.py (original)
+++ python/branches/release27-maint/Lib/test/test_random.py Fri Sep 10 12:47:22 2010
@@ -55,8 +55,6 @@
with test_support.check_py3k_warnings(quiet=True):
self.assertRaises(TypeError, self.gen.jumpahead) # needs an arg
- self.assertRaises(TypeError, self.gen.jumpahead, "ick") # wrong type
- self.assertRaises(TypeError, self.gen.jumpahead, 2.3) # wrong type
self.assertRaises(TypeError, self.gen.jumpahead, 2, 3) # too many
def test_sample(self):
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Fri Sep 10 12:47:22 2010
@@ -43,6 +43,10 @@
Library
-------
+- Issue #9816: random.Random.jumpahead(n) did not produce a sufficiently
+ different internal state for small values of n. Fixed by salting the
+ value.
+
- Issue #9792: In case of connection failure, socket.create_connection()
would swallow the exception and raise a new one, making it impossible
to fetch the original errno, or to filter timeout errors. Now the
From python-checkins at python.org Fri Sep 10 13:19:59 2010
From: python-checkins at python.org (victor.stinner)
Date: Fri, 10 Sep 2010 13:19:59 +0200 (CEST)
Subject: [Python-checkins] r84666 - python/branches/py3k/Lib/test/support.py
Message-ID: <20100910111959.6C3AEFD5E@mail.python.org>
Author: victor.stinner
Date: Fri Sep 10 13:19:59 2010
New Revision: 84666
Log:
Issue #9819: fix TESTFN_UNENCODABLE for japanese code page
Modified:
python/branches/py3k/Lib/test/support.py
Modified: python/branches/py3k/Lib/test/support.py
==============================================================================
--- python/branches/py3k/Lib/test/support.py (original)
+++ python/branches/py3k/Lib/test/support.py Fri Sep 10 13:19:59 2010
@@ -394,8 +394,9 @@
if os.name in ('nt', 'ce'):
# skip win32s (0) or Windows 9x/ME (1)
if sys.getwindowsversion().platform >= 2:
- # Japanese characters (I think - from bug 846133)
- TESTFN_UNENCODABLE = TESTFN + "-\u5171\u6709\u3055\u308c\u308b"
+ # Different kinds of characters from various languages to minimize the
+ # probability that the whole name is encodable to MBCS (issue #9819)
+ TESTFN_UNENCODABLE = TESTFN + "-\u5171\u0141\u2661\u0363\uDC80"
try:
TESTFN_UNENCODABLE.encode(TESTFN_ENCODING)
except UnicodeEncodeError:
From python-checkins at python.org Fri Sep 10 13:24:10 2010
From: python-checkins at python.org (victor.stinner)
Date: Fri, 10 Sep 2010 13:24:10 +0200 (CEST)
Subject: [Python-checkins] r84667 - in python/branches/release27-maint:
Lib/test/test_support.py Lib/test/test_unicode_file.py
Message-ID: <20100910112410.71271F9BF@mail.python.org>
Author: victor.stinner
Date: Fri Sep 10 13:24:10 2010
New Revision: 84667
Log:
Recorded merge of revisions 83987 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r83987 | victor.stinner | 2010-08-14 00:23:24 +0200 (sam., 14 ao?t 2010) | 2 lines
Fix a typo: TESTFN_UNENCODEABLE => TESTFN_UNENCODABLE
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_support.py
python/branches/release27-maint/Lib/test/test_unicode_file.py
Modified: python/branches/release27-maint/Lib/test/test_support.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_support.py (original)
+++ python/branches/release27-maint/Lib/test/test_support.py Fri Sep 10 13:24:10 2010
@@ -361,30 +361,30 @@
# 2 latin characters.
TESTFN_UNICODE = unicode("@test-\xe0\xf2", "latin-1")
TESTFN_ENCODING = sys.getfilesystemencoding()
- # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
+ # TESTFN_UNENCODABLE is a filename that should *not* be
# able to be encoded by *either* the default or filesystem encoding.
# This test really only makes sense on Windows NT platforms
# which have special Unicode support in posixmodule.
if (not hasattr(sys, "getwindowsversion") or
sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
- TESTFN_UNICODE_UNENCODEABLE = None
+ TESTFN_UNENCODABLE = None
else:
# Japanese characters (I think - from bug 846133)
- TESTFN_UNICODE_UNENCODEABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
+ TESTFN_UNENCODABLE = eval('u"@test-\u5171\u6709\u3055\u308c\u308b"')
try:
# XXX - Note - should be using TESTFN_ENCODING here - but for
# Windows, "mbcs" currently always operates as if in
# errors=ignore' mode - hence we get '?' characters rather than
# the exception. 'Latin1' operates as we expect - ie, fails.
# See [ 850997 ] mbcs encoding ignores errors
- TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
+ TESTFN_UNENCODABLE.encode("Latin1")
except UnicodeEncodeError:
pass
else:
print \
'WARNING: The filename %r CAN be encoded by the filesystem. ' \
'Unicode filename tests may not be effective' \
- % TESTFN_UNICODE_UNENCODEABLE
+ % TESTFN_UNENCODABLE
# Disambiguate TESTFN for parallel testing, while letting it remain a valid
Modified: python/branches/release27-maint/Lib/test/test_unicode_file.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_unicode_file.py (original)
+++ python/branches/release27-maint/Lib/test/test_unicode_file.py Fri Sep 10 13:24:10 2010
@@ -6,7 +6,7 @@
import unittest
from test.test_support import run_unittest, TESTFN_UNICODE
-from test.test_support import TESTFN_ENCODING, TESTFN_UNICODE_UNENCODEABLE
+from test.test_support import TESTFN_ENCODING, TESTFN_UNENCODABLE
try:
TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING)
except (UnicodeError, TypeError):
@@ -171,8 +171,8 @@
def test_single_files(self):
self._test_single(TESTFN_ENCODED)
self._test_single(TESTFN_UNICODE)
- if TESTFN_UNICODE_UNENCODEABLE is not None:
- self._test_single(TESTFN_UNICODE_UNENCODEABLE)
+ if TESTFN_UNENCODABLE is not None:
+ self._test_single(TESTFN_UNENCODABLE)
def test_equivalent_files(self):
self._test_equivalent(TESTFN_ENCODED, TESTFN_UNICODE)
@@ -188,9 +188,9 @@
self._do_directory(TESTFN_UNICODE+ext, TESTFN_ENCODED+ext, False)
self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext, False)
# Our directory name that can't use a non-unicode name.
- if TESTFN_UNICODE_UNENCODEABLE is not None:
- self._do_directory(TESTFN_UNICODE_UNENCODEABLE+ext,
- TESTFN_UNICODE_UNENCODEABLE+ext,
+ if TESTFN_UNENCODABLE is not None:
+ self._do_directory(TESTFN_UNENCODABLE+ext,
+ TESTFN_UNENCODABLE+ext,
False)
def test_main():
From python-checkins at python.org Fri Sep 10 14:19:38 2010
From: python-checkins at python.org (victor.stinner)
Date: Fri, 10 Sep 2010 14:19:38 +0200 (CEST)
Subject: [Python-checkins] r84668 - in python/branches/release31-maint:
Lib/test/support.py
Message-ID: <20100910121938.215A1EE990@mail.python.org>
Author: victor.stinner
Date: Fri Sep 10 14:19:37 2010
New Revision: 84668
Log:
Merged revisions 84666 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84666 | victor.stinner | 2010-09-10 13:19:59 +0200 (ven., 10 sept. 2010) | 2 lines
Issue #9819: fix TESTFN_UNENCODABLE for japanese code page
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/support.py
Modified: python/branches/release31-maint/Lib/test/support.py
==============================================================================
--- python/branches/release31-maint/Lib/test/support.py (original)
+++ python/branches/release31-maint/Lib/test/support.py Fri Sep 10 14:19:37 2010
@@ -351,8 +351,9 @@
sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
TESTFN_UNICODE_UNENCODEABLE = None
else:
- # Japanese characters (I think - from bug 846133)
- TESTFN_UNICODE_UNENCODEABLE = "@test-\u5171\u6709\u3055\u308c\u308b"
+ # Different kinds of characters from various languages to minimize the
+ # probability that the whole name is encodable to MBCS (issue #9819)
+ TESTFN_UNENCODABLE = TESTFN + "-\u5171\u0141\u2661\u0363\uDC80"
try:
# XXX - Note - should be using TESTFN_ENCODING here - but for
# Windows, "mbcs" currently always operates as if in
From python-checkins at python.org Fri Sep 10 14:24:24 2010
From: python-checkins at python.org (nick.coghlan)
Date: Fri, 10 Sep 2010 14:24:24 +0200 (CEST)
Subject: [Python-checkins] r84669 - python/branches/py3k/Lib/dis.py
Message-ID: <20100910122424.8DD97EE983@mail.python.org>
Author: nick.coghlan
Date: Fri Sep 10 14:24:24 2010
New Revision: 84669
Log:
Fix dis.__all__ for new additions to module in 3.2(spotted by Eli Bendersky)
Modified:
python/branches/py3k/Lib/dis.py
Modified: python/branches/py3k/Lib/dis.py
==============================================================================
--- python/branches/py3k/Lib/dis.py (original)
+++ python/branches/py3k/Lib/dis.py Fri Sep 10 14:24:24 2010
@@ -6,8 +6,8 @@
from opcode import *
from opcode import __all__ as _opcodes_all
-__all__ = ["dis", "disassemble", "distb", "disco",
- "findlinestarts", "findlabels"] + _opcodes_all
+__all__ = ["code_info", "dis", "disassemble", "distb", "disco",
+ "findlinestarts", "findlabels", "show_code"] + _opcodes_all
del _opcodes_all
_have_code = (types.MethodType, types.FunctionType, types.CodeType, type)
From python-checkins at python.org Fri Sep 10 14:32:58 2010
From: python-checkins at python.org (victor.stinner)
Date: Fri, 10 Sep 2010 14:32:58 +0200 (CEST)
Subject: [Python-checkins] r84670 - in python/branches/release31-maint:
Lib/test/support.py Lib/test/test_unicode_file.py
Message-ID: <20100910123258.45B30EE98A@mail.python.org>
Author: victor.stinner
Date: Fri Sep 10 14:32:58 2010
New Revision: 84670
Log:
Recorded merge of revisions 83987 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r83987 | victor.stinner | 2010-08-14 00:23:24 +0200 (sam., 14 ao?t 2010) | 2 lines
Fix a typo: TESTFN_UNENCODEABLE => TESTFN_UNENCODABLE
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/support.py
python/branches/release31-maint/Lib/test/test_unicode_file.py
Modified: python/branches/release31-maint/Lib/test/support.py
==============================================================================
--- python/branches/release31-maint/Lib/test/support.py (original)
+++ python/branches/release31-maint/Lib/test/support.py Fri Sep 10 14:32:58 2010
@@ -343,13 +343,13 @@
# file system encoding, but *not* with the default (ascii) encoding
TESTFN_UNICODE = "@test-\xe0\xf2"
TESTFN_ENCODING = sys.getfilesystemencoding()
- # TESTFN_UNICODE_UNENCODEABLE is a filename that should *not* be
+ # TESTFN_UNENCODABLE is a filename that should *not* be
# able to be encoded by *either* the default or filesystem encoding.
# This test really only makes sense on Windows NT platforms
# which have special Unicode support in posixmodule.
if (not hasattr(sys, "getwindowsversion") or
sys.getwindowsversion()[3] < 2): # 0=win32s or 1=9x/ME
- TESTFN_UNICODE_UNENCODEABLE = None
+ TESTFN_UNENCODABLE = None
else:
# Different kinds of characters from various languages to minimize the
# probability that the whole name is encodable to MBCS (issue #9819)
@@ -360,13 +360,13 @@
# errors=ignore' mode - hence we get '?' characters rather than
# the exception. 'Latin1' operates as we expect - ie, fails.
# See [ 850997 ] mbcs encoding ignores errors
- TESTFN_UNICODE_UNENCODEABLE.encode("Latin1")
+ TESTFN_UNENCODABLE.encode("Latin1")
except UnicodeEncodeError:
pass
else:
print('WARNING: The filename %r CAN be encoded by the filesystem. '
'Unicode filename tests may not be effective'
- % TESTFN_UNICODE_UNENCODEABLE)
+ % TESTFN_UNENCODABLE)
if os.path.isdir(TESTFN):
# a test failed (eg. test_os) without removing TESTFN directory
Modified: python/branches/release31-maint/Lib/test/test_unicode_file.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_unicode_file.py (original)
+++ python/branches/release31-maint/Lib/test/test_unicode_file.py Fri Sep 10 14:32:58 2010
@@ -6,7 +6,7 @@
import unittest
from test.support import run_unittest, TESTFN_UNICODE, rmtree
-from test.support import TESTFN_ENCODING, TESTFN_UNICODE_UNENCODEABLE
+from test.support import TESTFN_ENCODING, TESTFN_UNENCODABLE
try:
TESTFN_UNICODE.encode(TESTFN_ENCODING)
except (UnicodeError, TypeError):
@@ -146,8 +146,8 @@
# _test functions with each of the filename combinations we wish to test
def test_single_files(self):
self._test_single(TESTFN_UNICODE)
- if TESTFN_UNICODE_UNENCODEABLE is not None:
- self._test_single(TESTFN_UNICODE_UNENCODEABLE)
+ if TESTFN_UNENCODABLE is not None:
+ self._test_single(TESTFN_UNENCODABLE)
def test_directories(self):
# For all 'equivalent' combinations:
@@ -156,9 +156,9 @@
ext = ".dir"
self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext, False)
# Our directory name that can't use a non-unicode name.
- if TESTFN_UNICODE_UNENCODEABLE is not None:
- self._do_directory(TESTFN_UNICODE_UNENCODEABLE+ext,
- TESTFN_UNICODE_UNENCODEABLE+ext,
+ if TESTFN_UNENCODABLE is not None:
+ self._do_directory(TESTFN_UNENCODABLE+ext,
+ TESTFN_UNENCODABLE+ext,
False)
def test_main():
From python-checkins at python.org Fri Sep 10 14:32:58 2010
From: python-checkins at python.org (nick.coghlan)
Date: Fri, 10 Sep 2010 14:32:58 +0200 (CEST)
Subject: [Python-checkins] r84671 - python/branches/py3k/Lib/dis.py
Message-ID: <20100910123258.DC5FFEE98A@mail.python.org>
Author: nick.coghlan
Date: Fri Sep 10 14:32:58 2010
New Revision: 84671
Log:
Leave show_code out of __all__ and make it clear that its lack of documentation is deliberate
Modified:
python/branches/py3k/Lib/dis.py
Modified: python/branches/py3k/Lib/dis.py
==============================================================================
--- python/branches/py3k/Lib/dis.py (original)
+++ python/branches/py3k/Lib/dis.py Fri Sep 10 14:32:58 2010
@@ -7,7 +7,7 @@
from opcode import __all__ as _opcodes_all
__all__ = ["code_info", "dis", "disassemble", "distb", "disco",
- "findlinestarts", "findlabels", "show_code"] + _opcodes_all
+ "findlinestarts", "findlabels"] + _opcodes_all
del _opcodes_all
_have_code = (types.MethodType, types.FunctionType, types.CodeType, type)
@@ -140,6 +140,10 @@
lines.append("%4d: %s" % i_n)
return "\n".join(lines)
+# show_code is deliberately undocumented and left out of __all__,
+# since it doesn't offer any real benefit over code_info() above
+# It is only retained because it already existed and was not
+# marked as private in previous versions of Python
def show_code(co):
"""Show details about a code object."""
print(code_info(co))
From python-checkins at python.org Fri Sep 10 16:08:05 2010
From: python-checkins at python.org (nick.coghlan)
Date: Fri, 10 Sep 2010 16:08:05 +0200 (CEST)
Subject: [Python-checkins] r84672 - in python/branches/py3k:
Doc/library/dis.rst Lib/dis.py
Message-ID: <20100910140805.14A1AEF29@mail.python.org>
Author: nick.coghlan
Date: Fri Sep 10 16:08:04 2010
New Revision: 84672
Log:
As per python-dev discussion with Eli, properly document and publish dis.show_code
Modified:
python/branches/py3k/Doc/library/dis.rst
python/branches/py3k/Lib/dis.py
Modified: python/branches/py3k/Doc/library/dis.rst
==============================================================================
--- python/branches/py3k/Doc/library/dis.rst (original)
+++ python/branches/py3k/Doc/library/dis.rst Fri Sep 10 16:08:04 2010
@@ -36,7 +36,7 @@
The :mod:`dis` module defines the following functions and constants:
-.. function:: code_info(x=None)
+.. function:: code_info(x)
Return a formatted multi-line string with detailed code object information
for the supplied function, method, source code string or code object.
@@ -48,6 +48,16 @@
.. versionadded:: 3.2
+.. function:: show_code(x)
+
+ Print detailed code object information for the supplied function, method,
+ source code string or code object to stdout.
+
+ This is a convenient shorthand for ``print(code_info(x))``, intended for
+ interactive exploration at the interpreter prompt.
+
+ .. versionadded:: 3.2
+
.. function:: dis(x=None)
Disassemble the *x* object. *x* can denote either a module, a class, a
Modified: python/branches/py3k/Lib/dis.py
==============================================================================
--- python/branches/py3k/Lib/dis.py (original)
+++ python/branches/py3k/Lib/dis.py Fri Sep 10 16:08:04 2010
@@ -7,7 +7,7 @@
from opcode import __all__ as _opcodes_all
__all__ = ["code_info", "dis", "disassemble", "distb", "disco",
- "findlinestarts", "findlabels"] + _opcodes_all
+ "findlinestarts", "findlabels", "show_code"] + _opcodes_all
del _opcodes_all
_have_code = (types.MethodType, types.FunctionType, types.CodeType, type)
@@ -140,12 +140,8 @@
lines.append("%4d: %s" % i_n)
return "\n".join(lines)
-# show_code is deliberately undocumented and left out of __all__,
-# since it doesn't offer any real benefit over code_info() above
-# It is only retained because it already existed and was not
-# marked as private in previous versions of Python
def show_code(co):
- """Show details about a code object."""
+ """Print details of methods, functions, or code to stdout."""
print(code_info(co))
def disassemble(co, lasti=-1):
From python-checkins at python.org Fri Sep 10 20:11:45 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 10 Sep 2010 20:11:45 +0200 (CEST)
Subject: [Python-checkins] r84673 -
python/branches/py3k/Modules/posixmodule.c
Message-ID: <20100910181145.75DE8EE9FE@mail.python.org>
Author: amaury.forgeotdarc
Date: Fri Sep 10 20:11:45 2010
New Revision: 84673
Log:
Untabify file.
Modified:
python/branches/py3k/Modules/posixmodule.c
Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Fri Sep 10 20:11:45 2010
@@ -8256,12 +8256,12 @@
if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
#endif /* EX_NOTFOUND */
- /* statvfs */
+ /* statvfs */
#ifdef ST_RDONLY
- if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
+ if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1;
#endif /* ST_RDONLY */
#ifdef ST_NOSUID
- if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
+ if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1;
#endif /* ST_NOSUID */
#ifdef HAVE_SPAWNV
From python-checkins at python.org Fri Sep 10 20:39:04 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 10 Sep 2010 20:39:04 +0200 (CEST)
Subject: [Python-checkins] r84674 - in python/branches/py3k: configure
configure.in
Message-ID: <20100910183904.D1BE7EEA26@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 10 20:39:00 2010
New Revision: 84674
Log:
Followup to #4026: better patch for flock detection.
Modified:
python/branches/py3k/configure
python/branches/py3k/configure.in
Modified: python/branches/py3k/configure
==============================================================================
--- python/branches/py3k/configure (original)
+++ python/branches/py3k/configure Fri Sep 10 20:39:00 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 84512 .
+# From configure.in Revision: 84584 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 3.2.
#
@@ -9586,56 +9586,45 @@
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock" >&5
-$as_echo_n "checking for flock... " >&6; }
-have_flock=no
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock declaration" >&5
+$as_echo_n "checking for flock declaration... " >&6; }
+if test "${ac_cv_flock_decl+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
#include
-
int
main ()
{
void* p = flock
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
-
-$as_echo "#define HAVE_FLOCK 1" >>confdefs.h
-
- have_flock=yes
+ ac_cv_flock_decl=yes
+else
+ ac_cv_flock_decl=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_flock" >&5
-$as_echo "$have_flock" >&6; }
-
-if test "$have_flock" = yes ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if flock requires additional libraries." >&5
-$as_echo_n "checking if flock requires additional libraries.... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
- #include
-
-int
-main ()
-{
-void *p = flock; flock(0, 0)
- ;
- return 0;
-}
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flock_decl" >&5
+$as_echo "$ac_cv_flock_decl" >&6; }
+if test "x${ac_cv_flock_decl}" = xyes; then
+ for ac_func in flock
+do :
+ ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock"
+if test "x$ac_cv_func_flock" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOCK 1
_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
$as_echo_n "checking for flock in -lbsd... " >&6; }
if test "${ac_cv_lib_bsd_flock+set}" = set; then :
$as_echo_n "(cached) " >&6
@@ -9672,6 +9661,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5
$as_echo "$ac_cv_lib_bsd_flock" >&6; }
if test "x$ac_cv_lib_bsd_flock" = x""yes; then :
+ $as_echo "#define HAVE_FLOCK 1" >>confdefs.h
$as_echo "#define FLOCK_NEEDS_LIBBSD 1" >>confdefs.h
@@ -9681,8 +9671,8 @@
fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+done
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5
Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in (original)
+++ python/branches/py3k/configure.in Fri Sep 10 20:39:00 2010
@@ -2641,27 +2641,23 @@
[AC_MSG_RESULT(no)
])
-AC_MSG_CHECKING(for flock)
-have_flock=no
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include
-]], [[void* p = flock]])],
- [AC_DEFINE(HAVE_FLOCK, 1, Define if you have the 'flock' function.)
- have_flock=yes
+AC_CACHE_CHECK([for flock declaration], [ac_cv_flock_decl],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include ],
+ [void* p = flock]
+ )],
+ [ac_cv_flock_decl=yes],
+ [ac_cv_flock_decl=no]
+ )
])
-AC_MSG_RESULT($have_flock)
-
-if test "$have_flock" = yes ; then
- AC_MSG_CHECKING(if flock requires additional libraries.)
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #include
- ]], [[void *p = flock; flock(0, 0)]])],
- [AC_MSG_RESULT(no)],
- [AC_MSG_RESULT(yes)
- AC_CHECK_LIB(bsd,flock, [
- AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
- ])
- ])
+if test "x${ac_cv_flock_decl}" = xyes; then
+ AC_CHECK_FUNCS(flock,,
+ AC_CHECK_LIB(bsd,flock,
+ [AC_DEFINE(HAVE_FLOCK)
+ AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
+ ])
+ )
fi
AC_MSG_CHECKING(for getpagesize)
From python-checkins at python.org Fri Sep 10 20:44:45 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 10 Sep 2010 20:44:45 +0200 (CEST)
Subject: [Python-checkins] r84675 - in python/branches/release31-maint:
configure configure.in
Message-ID: <20100910184445.54555EEA29@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 10 20:44:45 2010
New Revision: 84675
Log:
Merged revisions 84674 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84674 | antoine.pitrou | 2010-09-10 20:39:00 +0200 (ven., 10 sept. 2010) | 3 lines
Followup to #4026: better patch for flock detection.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/configure
python/branches/release31-maint/configure.in
Modified: python/branches/release31-maint/configure
==============================================================================
--- python/branches/release31-maint/configure (original)
+++ python/branches/release31-maint/configure Fri Sep 10 20:44:45 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 84367 .
+# From configure.in Revision: 84586 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 3.1.
#
@@ -9408,60 +9408,45 @@
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock" >&5
-$as_echo_n "checking for flock... " >&6; }
-have_flock=no
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock declaration" >&5
+$as_echo_n "checking for flock declaration... " >&6; }
+if test "${ac_cv_flock_decl+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
-#include "confdefs.h"
#include
-
int
main ()
{
void* p = flock
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
-
-
-$as_echo "#define HAVE_FLOCK 1" >>confdefs.h
-
- have_flock=yes
+ ac_cv_flock_decl=yes
+else
+ ac_cv_flock_decl=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_flock" >&5
-$as_echo "$have_flock" >&6; }
-if test "$have_flock" = yes ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if flock requires additional libraries." >&5
-$as_echo_n "checking if flock requires additional libraries.... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
- #include "confdefs.h"
- #include
-
-int
-main ()
-{
-flock(0, 0)
- ;
- return 0;
-}
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flock_decl" >&5
+$as_echo "$ac_cv_flock_decl" >&6; }
+if test "x${ac_cv_flock_decl}" = xyes; then
+ for ac_func in flock
+do :
+ ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock"
+if test "x$ac_cv_func_flock" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOCK 1
_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
$as_echo_n "checking for flock in -lbsd... " >&6; }
if test "${ac_cv_lib_bsd_flock+set}" = set; then :
$as_echo_n "(cached) " >&6
@@ -9498,6 +9483,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5
$as_echo "$ac_cv_lib_bsd_flock" >&6; }
if test "x$ac_cv_lib_bsd_flock" = x""yes; then :
+ $as_echo "#define HAVE_FLOCK 1" >>confdefs.h
$as_echo "#define FLOCK_NEEDS_LIBBSD 1" >>confdefs.h
@@ -9507,8 +9493,8 @@
fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+done
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5
Modified: python/branches/release31-maint/configure.in
==============================================================================
--- python/branches/release31-maint/configure.in (original)
+++ python/branches/release31-maint/configure.in Fri Sep 10 20:44:45 2010
@@ -2641,29 +2641,23 @@
AC_MSG_RESULT(no)
)
-AC_MSG_CHECKING(for flock)
-have_flock=no
-AC_TRY_COMPILE([
-#include "confdefs.h"
-#include
-], void* p = flock, [
- AC_DEFINE(HAVE_FLOCK, 1, Define if you have the 'flock' function.)
- have_flock=yes
+AC_CACHE_CHECK([for flock declaration], [ac_cv_flock_decl],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include ],
+ [void* p = flock]
+ )],
+ [ac_cv_flock_decl=yes],
+ [ac_cv_flock_decl=no]
+ )
])
-AC_MSG_RESULT($have_flock)
-
-if test "$have_flock" = yes ; then
- AC_MSG_CHECKING(if flock requires additional libraries.)
- AC_TRY_LINK([
- #include "confdefs.h"
- #include
- ], [flock(0, 0)],
- AC_MSG_RESULT(no), [
- AC_MSG_RESULT(yes)
- AC_CHECK_LIB(bsd,flock, [
- AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
- ])
- ])
+if test "x${ac_cv_flock_decl}" = xyes; then
+ AC_CHECK_FUNCS(flock,,
+ AC_CHECK_LIB(bsd,flock,
+ [AC_DEFINE(HAVE_FLOCK)
+ AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
+ ])
+ )
fi
AC_MSG_CHECKING(for getpagesize)
From python-checkins at python.org Fri Sep 10 20:47:36 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 10 Sep 2010 20:47:36 +0200 (CEST)
Subject: [Python-checkins] r84676 - in python/branches/release27-maint:
configure configure.in
Message-ID: <20100910184736.6814FEEA32@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 10 20:47:36 2010
New Revision: 84676
Log:
Merged revisions 84674 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84674 | antoine.pitrou | 2010-09-10 20:39:00 +0200 (ven., 10 sept. 2010) | 3 lines
Followup to #4026: better patch for flock detection.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/configure
python/branches/release27-maint/configure.in
Modified: python/branches/release27-maint/configure
==============================================================================
--- python/branches/release27-maint/configure (original)
+++ python/branches/release27-maint/configure Fri Sep 10 20:47:36 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 84368 .
+# From configure.in Revision: 84585 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 2.7.
#
@@ -9740,56 +9740,45 @@
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock" >&5
-$as_echo_n "checking for flock... " >&6; }
-have_flock=no
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock declaration" >&5
+$as_echo_n "checking for flock declaration... " >&6; }
+if test "${ac_cv_flock_decl+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-
#include
-
int
main ()
{
void* p = flock
+
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
-
-$as_echo "#define HAVE_FLOCK 1" >>confdefs.h
-
- have_flock=yes
+ ac_cv_flock_decl=yes
+else
+ ac_cv_flock_decl=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_flock" >&5
-$as_echo "$have_flock" >&6; }
-
-if test "$have_flock" = yes ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if flock requires additional libraries." >&5
-$as_echo_n "checking if flock requires additional libraries.... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
- #include
-
-int
-main ()
-{
-void *p = flock; flock(0, 0)
- ;
- return 0;
-}
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_flock_decl" >&5
+$as_echo "$ac_cv_flock_decl" >&6; }
+if test "x${ac_cv_flock_decl}" = xyes; then
+ for ac_func in flock
+do :
+ ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock"
+if test "x$ac_cv_func_flock" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FLOCK 1
_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for flock in -lbsd" >&5
$as_echo_n "checking for flock in -lbsd... " >&6; }
if test "${ac_cv_lib_bsd_flock+set}" = set; then :
$as_echo_n "(cached) " >&6
@@ -9826,6 +9815,7 @@
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bsd_flock" >&5
$as_echo "$ac_cv_lib_bsd_flock" >&6; }
if test "x$ac_cv_lib_bsd_flock" = x""yes; then :
+ $as_echo "#define HAVE_FLOCK 1" >>confdefs.h
$as_echo "#define FLOCK_NEEDS_LIBBSD 1" >>confdefs.h
@@ -9835,8 +9825,8 @@
fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+done
+
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpagesize" >&5
Modified: python/branches/release27-maint/configure.in
==============================================================================
--- python/branches/release27-maint/configure.in (original)
+++ python/branches/release27-maint/configure.in Fri Sep 10 20:47:36 2010
@@ -2774,27 +2774,23 @@
[AC_MSG_RESULT(no)
])
-AC_MSG_CHECKING(for flock)
-have_flock=no
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include
-]], [[void* p = flock]])],
- [AC_DEFINE(HAVE_FLOCK, 1, Define if you have the 'flock' function.)
- have_flock=yes
+AC_CACHE_CHECK([for flock declaration], [ac_cv_flock_decl],
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [#include ],
+ [void* p = flock]
+ )],
+ [ac_cv_flock_decl=yes],
+ [ac_cv_flock_decl=no]
+ )
])
-AC_MSG_RESULT($have_flock)
-
-if test "$have_flock" = yes ; then
- AC_MSG_CHECKING(if flock requires additional libraries.)
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #include
- ]], [[void *p = flock; flock(0, 0)]])],
- [AC_MSG_RESULT(no)],
- [AC_MSG_RESULT(yes)
- AC_CHECK_LIB(bsd,flock, [
- AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
- ])
- ])
+if test "x${ac_cv_flock_decl}" = xyes; then
+ AC_CHECK_FUNCS(flock,,
+ AC_CHECK_LIB(bsd,flock,
+ [AC_DEFINE(HAVE_FLOCK)
+ AC_DEFINE(FLOCK_NEEDS_LIBBSD, 1, Define if flock needs to be linked with bsd library.)
+ ])
+ )
fi
AC_MSG_CHECKING(for getpagesize)
From python-checkins at python.org Fri Sep 10 20:50:38 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Fri, 10 Sep 2010 20:50:38 +0200 (CEST)
Subject: [Python-checkins] r84677 -
python/branches/py3k/Doc/library/fcntl.rst
Message-ID: <20100910185038.4D427EE9F3@mail.python.org>
Author: benjamin.peterson
Date: Fri Sep 10 20:50:38 2010
New Revision: 84677
Log:
add reference to file object
Modified:
python/branches/py3k/Doc/library/fcntl.rst
Modified: python/branches/py3k/Doc/library/fcntl.rst
==============================================================================
--- python/branches/py3k/Doc/library/fcntl.rst (original)
+++ python/branches/py3k/Doc/library/fcntl.rst Fri Sep 10 20:50:38 2010
@@ -16,8 +16,8 @@
All functions in this module take a file descriptor *fd* as their first
argument. This can be an integer file descriptor, such as returned by
-``sys.stdin.fileno()``, or a file object, such as ``sys.stdin`` itself, which
-provides a :meth:`fileno` which returns a genuine file descriptor.
+``sys.stdin.fileno()``, or a :class:`io.IOBase` object, such as ``sys.stdin``
+itself, which provides a :meth:`fileno` that returns a genuine file descriptor.
The module defines the following functions:
From python-checkins at python.org Fri Sep 10 20:52:37 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Fri, 10 Sep 2010 20:52:37 +0200 (CEST)
Subject: [Python-checkins] r84678 - in python/branches/release31-maint:
Doc/library/fcntl.rst
Message-ID: <20100910185237.1987DEEA1D@mail.python.org>
Author: benjamin.peterson
Date: Fri Sep 10 20:52:36 2010
New Revision: 84678
Log:
Merged revisions 84677 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84677 | benjamin.peterson | 2010-09-10 13:50:38 -0500 (Fri, 10 Sep 2010) | 1 line
add reference to file object
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/library/fcntl.rst
Modified: python/branches/release31-maint/Doc/library/fcntl.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/fcntl.rst (original)
+++ python/branches/release31-maint/Doc/library/fcntl.rst Fri Sep 10 20:52:36 2010
@@ -16,8 +16,8 @@
All functions in this module take a file descriptor *fd* as their first
argument. This can be an integer file descriptor, such as returned by
-``sys.stdin.fileno()``, or a file object, such as ``sys.stdin`` itself, which
-provides a :meth:`fileno` which returns a genuine file descriptor.
+``sys.stdin.fileno()``, or a :class:`io.IOBase` object, such as ``sys.stdin``
+itself, which provides a :meth:`fileno` that returns a genuine file descriptor.
The module defines the following functions:
From python-checkins at python.org Fri Sep 10 21:40:53 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 10 Sep 2010 21:40:53 +0200 (CEST)
Subject: [Python-checkins] r84679 -
python/branches/py3k/Lib/test/test_scope.py
Message-ID: <20100910194053.1F6D8EE990@mail.python.org>
Author: amaury.forgeotdarc
Date: Fri Sep 10 21:40:52 2010
New Revision: 84679
Log:
Use the "if 1:" prefix so that quoted code appears nicely
nested inside the test suite.
def test_me():
exec("""if 1:
...code...
""")
No other change here.
Modified:
python/branches/py3k/Lib/test/test_scope.py
Modified: python/branches/py3k/Lib/test/test_scope.py
==============================================================================
--- python/branches/py3k/Lib/test/test_scope.py (original)
+++ python/branches/py3k/Lib/test/test_scope.py Fri Sep 10 21:40:52 2010
@@ -192,44 +192,44 @@
def testUnoptimizedNamespaces(self):
- check_syntax_error(self, """\
-def unoptimized_clash1(strip):
- def f(s):
- from sys import *
- return getrefcount(s) # ambiguity: free or local
- return f
-""")
-
- check_syntax_error(self, """\
-def unoptimized_clash2():
- from sys import *
- def f(s):
- return getrefcount(s) # ambiguity: global or local
- return f
-""")
-
- check_syntax_error(self, """\
-def unoptimized_clash2():
- from sys import *
- def g():
- def f(s):
- return getrefcount(s) # ambiguity: global or local
- return f
-""")
-
- check_syntax_error(self, """\
-def f(x):
- def g():
- return x
- del x # can't del name
-""")
-
- check_syntax_error(self, """\
-def f():
- def g():
- from sys import *
- return getrefcount # global or local?
-""")
+ check_syntax_error(self, """if 1:
+ def unoptimized_clash1(strip):
+ def f(s):
+ from sys import *
+ return getrefcount(s) # ambiguity: free or local
+ return f
+ """)
+
+ check_syntax_error(self, """if 1:
+ def unoptimized_clash2():
+ from sys import *
+ def f(s):
+ return getrefcount(s) # ambiguity: global or local
+ return f
+ """)
+
+ check_syntax_error(self, """if 1:
+ def unoptimized_clash2():
+ from sys import *
+ def g():
+ def f(s):
+ return getrefcount(s) # ambiguity: global or local
+ return f
+ """)
+
+ check_syntax_error(self, """if 1:
+ def f(x):
+ def g():
+ return x
+ del x # can't del name
+ """)
+
+ check_syntax_error(self, """if 1:
+ def f():
+ def g():
+ from sys import *
+ return getrefcount # global or local?
+ """)
def testLambdas(self):
@@ -273,17 +273,17 @@
self.assertRaises(NameError, errorInInner)
# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
- exec("""
-global_x = 1
-def f():
- global_x += 1
-try:
- f()
-except UnboundLocalError:
- pass
-else:
- fail('scope of global_x not correctly determined')
-""", {'fail': self.fail})
+ exec("""if 1:
+ global_x = 1
+ def f():
+ global_x += 1
+ try:
+ f()
+ except UnboundLocalError:
+ pass
+ else:
+ fail('scope of global_x not correctly determined')
+ """, {'fail': self.fail})
def testComplexDefinitions(self):
@@ -302,88 +302,88 @@
self.assertEqual(makeReturner2(a=11)()['a'], 11)
def testScopeOfGlobalStmt(self):
-# Examples posted by Samuele Pedroni to python-dev on 3/1/2001
+ # Examples posted by Samuele Pedroni to python-dev on 3/1/2001
- exec("""\
-# I
-x = 7
-def f():
- x = 1
- def g():
- global x
- def i():
- def h():
- return x
- return h()
- return i()
- return g()
-self.assertEqual(f(), 7)
-self.assertEqual(x, 7)
-
-# II
-x = 7
-def f():
- x = 1
- def g():
- x = 2
- def i():
- def h():
- return x
- return h()
- return i()
- return g()
-self.assertEqual(f(), 2)
-self.assertEqual(x, 7)
-
-# III
-x = 7
-def f():
- x = 1
- def g():
- global x
- x = 2
- def i():
- def h():
- return x
- return h()
- return i()
- return g()
-self.assertEqual(f(), 2)
-self.assertEqual(x, 2)
-
-# IV
-x = 7
-def f():
- x = 3
- def g():
- global x
- x = 2
- def i():
- def h():
- return x
- return h()
- return i()
- return g()
-self.assertEqual(f(), 2)
-self.assertEqual(x, 2)
-
-# XXX what about global statements in class blocks?
-# do they affect methods?
-
-x = 12
-class Global:
- global x
- x = 13
- def set(self, val):
- x = val
- def get(self):
- return x
-
-g = Global()
-self.assertEqual(g.get(), 13)
-g.set(15)
-self.assertEqual(g.get(), 13)
-""")
+ exec("""if 1:
+ # I
+ x = 7
+ def f():
+ x = 1
+ def g():
+ global x
+ def i():
+ def h():
+ return x
+ return h()
+ return i()
+ return g()
+ self.assertEqual(f(), 7)
+ self.assertEqual(x, 7)
+
+ # II
+ x = 7
+ def f():
+ x = 1
+ def g():
+ x = 2
+ def i():
+ def h():
+ return x
+ return h()
+ return i()
+ return g()
+ self.assertEqual(f(), 2)
+ self.assertEqual(x, 7)
+
+ # III
+ x = 7
+ def f():
+ x = 1
+ def g():
+ global x
+ x = 2
+ def i():
+ def h():
+ return x
+ return h()
+ return i()
+ return g()
+ self.assertEqual(f(), 2)
+ self.assertEqual(x, 2)
+
+ # IV
+ x = 7
+ def f():
+ x = 3
+ def g():
+ global x
+ x = 2
+ def i():
+ def h():
+ return x
+ return h()
+ return i()
+ return g()
+ self.assertEqual(f(), 2)
+ self.assertEqual(x, 2)
+
+ # XXX what about global statements in class blocks?
+ # do they affect methods?
+
+ x = 12
+ class Global:
+ global x
+ x = 13
+ def set(self, val):
+ x = val
+ def get(self):
+ return x
+
+ g = Global()
+ self.assertEqual(g.get(), 13)
+ g.set(15)
+ self.assertEqual(g.get(), 13)
+ """)
def testLeaks(self):
@@ -409,28 +409,28 @@
def testClassAndGlobal(self):
- exec("""\
-def test(x):
- class Foo:
- global x
- def __call__(self, y):
- return x + y
- return Foo()
-
-x = 0
-self.assertEqual(test(6)(2), 8)
-x = -1
-self.assertEqual(test(3)(2), 5)
-
-looked_up_by_load_name = False
-class X:
- # Implicit globals inside classes are be looked up by LOAD_NAME, not
- # LOAD_GLOBAL.
- locals()['looked_up_by_load_name'] = True
- passed = looked_up_by_load_name
+ exec("""if 1:
+ def test(x):
+ class Foo:
+ global x
+ def __call__(self, y):
+ return x + y
+ return Foo()
+
+ x = 0
+ self.assertEqual(test(6)(2), 8)
+ x = -1
+ self.assertEqual(test(3)(2), 5)
+
+ looked_up_by_load_name = False
+ class X:
+ # Implicit globals inside classes are be looked up by LOAD_NAME, not
+ # LOAD_GLOBAL.
+ locals()['looked_up_by_load_name'] = True
+ passed = looked_up_by_load_name
-self.assertTrue(X.passed)
-""")
+ self.assertTrue(X.passed)
+ """)
def testLocalsFunction(self):
@@ -626,22 +626,22 @@
# function to other nested functions in the same block.
# This test verifies that a global statement in the first
# function does not affect the second function.
- CODE = """def f():
- y = 1
- def g():
- global y
- return y
- def h():
- return y + 1
- return g, h
-y = 9
-g, h = f()
-result9 = g()
-result2 = h()
-"""
local_ns = {}
global_ns = {}
- exec(CODE, local_ns, global_ns)
+ exec("""if 1:
+ def f():
+ y = 1
+ def g():
+ global y
+ return y
+ def h():
+ return y + 1
+ return g, h
+ y = 9
+ g, h = f()
+ result9 = g()
+ result2 = h()
+ """, local_ns, global_ns)
self.assertEqual(2, global_ns["result2"])
self.assertEqual(9, global_ns["result9"])
From python-checkins at python.org Fri Sep 10 21:44:45 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 10 Sep 2010 21:44:45 +0200 (CEST)
Subject: [Python-checkins] r84680 - in python/branches/py3k:
Lib/distutils/command/build_ext.py Makefile.pre.in Misc/NEWS
Modules/ld_so_aix Modules/ld_so_aix.in configure configure.in
Message-ID: <20100910194445.1C71AEE995@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 10 21:44:44 2010
New Revision: 84680
Log:
Issue #941346: Improve the build process under AIX and allow Python to
be built as a shared library. Patch by S?bastien Sabl?.
Added:
python/branches/py3k/Modules/ld_so_aix.in
Removed:
python/branches/py3k/Modules/ld_so_aix
Modified:
python/branches/py3k/Lib/distutils/command/build_ext.py
python/branches/py3k/Makefile.pre.in
python/branches/py3k/Misc/NEWS
python/branches/py3k/configure
python/branches/py3k/configure.in
Modified: python/branches/py3k/Lib/distutils/command/build_ext.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/build_ext.py (original)
+++ python/branches/py3k/Lib/distutils/command/build_ext.py Fri Sep 10 21:44:44 2010
@@ -748,6 +748,9 @@
elif sys.platform == 'darwin':
# Don't use the default code below
return ext.libraries
+ elif sys.platform[:3] == 'aix':
+ # Don't use the default code below
+ return ext.libraries
else:
from distutils import sysconfig
if sysconfig.get_config_var('Py_ENABLE_SHARED'):
Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in (original)
+++ python/branches/py3k/Makefile.pre.in Fri Sep 10 21:44:44 2010
@@ -446,10 +446,10 @@
libpython$(VERSION).so: $(LIBRARY_OBJS)
if test $(INSTSONAME) != $(LDLIBRARY); then \
- $(LDSHARED) $(PY_LDFLAGS) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+ $(BLDSHARED) $(PY_LDFLAGS) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
$(LN) -f $(INSTSONAME) $@; \
else \
- $(LDSHARED) $(PY_LDFLAGS) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+ $(BLDSHARED) $(PY_LDFLAGS) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
fi
libpython$(VERSION).dylib: $(LIBRARY_OBJS)
@@ -1220,7 +1220,7 @@
done
-rm -f core Makefile Makefile.pre config.status \
Modules/Setup Modules/Setup.local Modules/Setup.config \
- Misc/python.pc
+ Modules/ld_so_aix Misc/python.pc
-rm -f python*-gdb.py
-rm -f pybuilddir.txt
find $(srcdir) '(' -name '*.fdc' -o -name '*~' \
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 10 21:44:44 2010
@@ -102,6 +102,9 @@
Build
-----
+- Issue #941346: Improve the build process under AIX and allow Python to
+ be built as a shared library. Patch by S?bastien Sabl?.
+
- Issue #4026: Make the fcntl extension build under AIX. Patch by S?bastien
Sabl?.
Deleted: python/branches/py3k/Modules/ld_so_aix
==============================================================================
--- python/branches/py3k/Modules/ld_so_aix Fri Sep 10 21:44:44 2010
+++ (empty file)
@@ -1,190 +0,0 @@
-#!/bin/sh
-#
-# ========================================================================
-# FILE: ld_so_aix
-# TYPE: executable, uses makexp_aix
-# SYSTEM: AIX
-#
-# DESCRIPTION: Creates a shareable .o from a set of pre-compiled
-# (unshared) .o files
-#
-# USAGE: ld_so_aix [CC] [arguments]
-#
-# ARGUMENTS: Same as for "ld". The following arguments are processed
-# or supplied by this script (those marked with an asterisk
-# can be overriden from command line):
-#
-# Argument Default value
-# (*) -o [OutputFileName] -o shr.o
-# (*) -e [EntryPointLabel] -e init[OutputBaseName]
-# (*) -bE:[ExportFile] -bE:[OutputBaseName].exp
-# (*) -bI:[ImportFile] -bI:./python.exp
-# -bM:[ModuleType] -bM:SRE
-# -bhalt:[Number] -bhalt:4
-# -T[Number] -T512
-# -H[Number] -H512
-# -lm
-#
-# The compiler specific ("-lc" or "-lc_r", "-lpthreads",...)
-# arguments will be automatically passed to "ld" according
-# to the CC command provided as a first argument to this
-# script. Usually, the same CC command was used to produce
-# the pre-compiled .o file(s).
-#
-# NOTES: 1. Since "ld_so_aix" was originally written for building
-# shared modules for the Python interpreter, the -e and
-# -bI default values match Python's conventions. In
-# Python, the entry point for a shared module is based
-# on the module's name (e.g., the "mathmodule" will
-# expect an entry point of "initmath").
-# 2. The script accepts multiple .o or .a input files and
-# creates a single (shared) output file. The export list
-# that is created is based on the output file's basename
-# with the suffix ".exp".
-# 3. The resulting shared object file is left in the
-# current directory.
-# 4. Uncommenting the "echo" lines gives detailed output
-# about the commands executed in the script.
-#
-#
-# HISTORY: Oct-1996 -- Support added for multiple .o files --
-# -- and optional arguments processing. --
-# Chris Myers (myers at tc.cornell.edu), Keith Kwok
-# (kkwok at tc.cornell.edu) and Vladimir Marangozov
-#
-# Aug-6-1996 -- Take care of the compiler specific --
-# -- args by leaving CC to invoke "ld". --
-# Vladimir Marangozov
-#
-# Jul-1-1996 -- Make sure to use /usr/ccs/bin/ld --
-# -- Use makexp_aix for the export list. --
-# Vladimir Marangozov (Vladimir.Marangozov at imag.fr)
-#
-# Manus Hand (mhand at csn.net) -- Initial code -- 6/24/96
-# ========================================================================
-#
-
-usage="Usage: ld_so_aix [CC command] [ld arguments]"
-if test ! -n "$*"; then
- echo $usage; exit 2
-fi
-
-makexp=`dirname $0`/makexp_aix
-
-# Check for existence of compiler.
-CC=$1; shift
-whichcc=`which $CC`
-
-if test ! -x "$whichcc"; then
- echo "ld_so_aix: Compiler '$CC' not found; exiting."
- exit 2
-fi
-
-if test ! -n "$*"; then
- echo $usage; exit 2
-fi
-
-# Default import file for Python
-# Can be overriden by providing a -bI: argument.
-impfile="./python.exp"
-
-# Parse arguments
-while test -n "$1"
-do
- case "$1" in
- -e | -Wl,-e)
- if test -z "$2"; then
- echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2
- else
- shift; entry=$1
- fi
- ;;
- -e* | -Wl,-e*)
- entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"`
- ;;
- -o)
- if test -z "$2"; then
- echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2
- else
- shift; objfile=$1
- fi
- ;;
- -o*)
- objfile=`echo $1 | sed "s/-o//"`
- ;;
- -bI:* | -Wl,-bI:*)
- impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"`
- ;;
- -bE:* | -Wl,-bE:*)
- expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"`
- ;;
- *.o | *.a)
- objs="$objs $1"
- args="$args $1"
- ;;
- -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm)
- ;;
- *)
- args="$args $1"
- ;;
- esac
- shift
-done
-
-
-if test -z "$objs"; then
- echo "ld_so_aix: No input files; exiting."
- exit 2
-elif test ! -r "$impfile"; then
- echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting."
- exit 2
-fi
-
-# If -o wasn't specified, assume "-o shr.o"
-if test -z "$objfile"; then
- objfile=shr.o
-fi
-
-filename=`basename $objfile | sed "s/\.[^.]*$//"`
-
-# If -bE: wasn't specified, assume "-bE:$filename.exp"
-if test -z "$expfile"; then
- expfile="$filename.exp"
-fi
-
-# Default entry symbol for Python modules = init[modulename]
-# Can be overriden by providing a -e argument.
-if test -z "$entry"; then
- entry=init`echo $filename | sed "s/module.*//"`
-fi
-
-#echo "ld_so_aix: Debug info section"
-#echo " -> output file : $objfile"
-#echo " -> import file : $impfile"
-#echo " -> export file : $expfile"
-#echo " -> entry point : $entry"
-#echo " -> object files: $objs"
-#echo " -> CC arguments: $args"
-
-CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4"
-CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -lm -o $objfile"
-# Note: to use dynamic libraries like libtcl8.4.so and libtk8.4.so
-# you may need to replace the second CCOPT line above with the following:
-# CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -brtl -bnortllib -lm -o $objfile"
-
-CCARGS="$args"
-
-# Export list generation.
-#echo $makexp $expfile "$objfile" $objs
-$makexp $expfile "$objfile" $objs
-
-# Perform the link.
-#echo $CC $CCOPT $CCARGS
-$CC $CCOPT $CCARGS
-retval=$?
-
-# Delete the module's export list file.
-# Comment this line if you need it.
-rm -f $expfile
-
-exit $retval
Added: python/branches/py3k/Modules/ld_so_aix.in
==============================================================================
--- (empty file)
+++ python/branches/py3k/Modules/ld_so_aix.in Fri Sep 10 21:44:44 2010
@@ -0,0 +1,194 @@
+#!/bin/sh
+#
+# ========================================================================
+# FILE: ld_so_aix
+# TYPE: executable, uses makexp_aix
+# SYSTEM: AIX
+#
+# DESCRIPTION: Creates a shareable .o from a set of pre-compiled
+# (unshared) .o files
+#
+# USAGE: ld_so_aix [CC] [arguments]
+#
+# ARGUMENTS: Same as for "ld". The following arguments are processed
+# or supplied by this script (those marked with an asterisk
+# can be overriden from command line):
+#
+# Argument Default value
+# (*) -o [OutputFileName] -o shr.o
+# (*) -e [EntryPointLabel] -e init[OutputBaseName]
+# (*) -bE:[ExportFile] -bE:[OutputBaseName].exp
+# (*) -bI:[ImportFile] -bI:./python.exp
+# -bM:[ModuleType] -bM:SRE
+# -bhalt:[Number] -bhalt:4
+# -T[Number] -T512
+# -H[Number] -H512
+# -lm
+#
+# The compiler specific ("-lc" or "-lc_r", "-lpthreads",...)
+# arguments will be automatically passed to "ld" according
+# to the CC command provided as a first argument to this
+# script. Usually, the same CC command was used to produce
+# the pre-compiled .o file(s).
+#
+# NOTES: 1. Since "ld_so_aix" was originally written for building
+# shared modules for the Python interpreter, the -e and
+# -bI default values match Python's conventions. In
+# Python, the entry point for a shared module is based
+# on the module's name (e.g., the "mathmodule" will
+# expect an entry point of "initmath").
+# 2. The script accepts multiple .o or .a input files and
+# creates a single (shared) output file. The export list
+# that is created is based on the output file's basename
+# with the suffix ".exp".
+# 3. The resulting shared object file is left in the
+# current directory.
+# 4. Uncommenting the "echo" lines gives detailed output
+# about the commands executed in the script.
+#
+#
+# HISTORY: Oct-1996 -- Support added for multiple .o files --
+# -- and optional arguments processing. --
+# Chris Myers (myers at tc.cornell.edu), Keith Kwok
+# (kkwok at tc.cornell.edu) and Vladimir Marangozov
+#
+# Aug-6-1996 -- Take care of the compiler specific --
+# -- args by leaving CC to invoke "ld". --
+# Vladimir Marangozov
+#
+# Jul-1-1996 -- Make sure to use /usr/ccs/bin/ld --
+# -- Use makexp_aix for the export list. --
+# Vladimir Marangozov (Vladimir.Marangozov at imag.fr)
+#
+# Manus Hand (mhand at csn.net) -- Initial code -- 6/24/96
+# ========================================================================
+#
+
+usage="Usage: ld_so_aix [CC command] [ld arguments]"
+if test ! -n "$*"; then
+ echo $usage; exit 2
+fi
+
+makexp=`dirname $0`/makexp_aix
+
+# Check for existence of compiler.
+CC=$1; shift
+whichcc=`which $CC`
+
+if test ! -x "$whichcc"; then
+ echo "ld_so_aix: Compiler '$CC' not found; exiting."
+ exit 2
+fi
+
+if test ! -n "$*"; then
+ echo $usage; exit 2
+fi
+
+# Default import file for Python
+# Can be overriden by providing a -bI: argument.
+impfile="./python.exp"
+
+# Parse arguments
+while test -n "$1"
+do
+ case "$1" in
+ -e | -Wl,-e)
+ if test -z "$2"; then
+ echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2
+ else
+ shift; entry=$1
+ fi
+ ;;
+ -e* | -Wl,-e*)
+ entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"`
+ ;;
+ -o)
+ if test -z "$2"; then
+ echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2
+ else
+ shift; objfile=$1
+ fi
+ ;;
+ -o*)
+ objfile=`echo $1 | sed "s/-o//"`
+ ;;
+ -bI:* | -Wl,-bI:*)
+ impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"`
+ ;;
+ -bE:* | -Wl,-bE:*)
+ expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"`
+ ;;
+ *.o | *.a)
+ objs="$objs $1"
+ args="$args $1"
+ ;;
+ -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm)
+ ;;
+ *)
+ args="$args $1"
+ ;;
+ esac
+ shift
+done
+
+if test "$objfile" = "libpython at VERSION@.so"; then
+ ldsocoremode="true"
+fi
+
+if test -z "$objs"; then
+ echo "ld_so_aix: No input files; exiting."
+ exit 2
+elif test ! -r "$impfile" -a -z "$ldsocoremode"; then
+ echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting."
+ exit 2
+fi
+
+# If -o wasn't specified, assume "-o shr.o"
+if test -z "$objfile"; then
+ objfile=shr.o
+fi
+
+filename=`basename $objfile | sed "s/\.[^.]*$//"`
+
+# If -bE: wasn't specified, assume "-bE:$filename.exp"
+if test -z "$expfile"; then
+ expfile="$filename.exp"
+fi
+
+# Default entry symbol for Python modules = init[modulename]
+# Can be overriden by providing a -e argument.
+if test -z "$entry"; then
+ entry=PyInit_`echo $filename | sed "s/module.*//"`
+fi
+
+#echo "ld_so_aix: Debug info section"
+#echo " -> output file : $objfile"
+#echo " -> import file : $impfile"
+#echo " -> export file : $expfile"
+#echo " -> entry point : $entry"
+#echo " -> object files: $objs"
+#echo " -> CC arguments: $args"
+
+if test -z "$ldsocoremode"; then
+ CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4"
+else
+ CCOPT="-Wl,-bnoentry -Wl,-bE:$expfile -Wl,-bhalt:4"
+fi
+CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -Wl,-brtl -Wl,-bnortllib -lm -o $objfile"
+
+CCARGS="$args"
+
+# Export list generation.
+#echo $makexp $expfile "$objfile" $objs
+$makexp $expfile "$objfile" $objs
+
+# Perform the link.
+#echo $CC $CCOPT $CCARGS
+$CC $CCOPT $CCARGS
+retval=$?
+
+# Delete the module's export list file.
+# Comment this line if you need it.
+rm -f $expfile
+
+exit $retval
Modified: python/branches/py3k/configure
==============================================================================
--- python/branches/py3k/configure (original)
+++ python/branches/py3k/configure Fri Sep 10 21:44:44 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 84584 .
+# From configure.in Revision: 84674 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 3.2.
#
@@ -4929,6 +4929,10 @@
BLDLIBRARY='-L. -lpython$(VERSION)'
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
;;
+ AIX*)
+ LDLIBRARY='libpython$(VERSION).so'
+ RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+ ;;
esac
else # shared is disabled
@@ -7484,7 +7488,7 @@
then
case $ac_sys_system/$ac_sys_release in
AIX*)
- BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp"
+ BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp -L\$(srcdir)"
LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp"
;;
IRIX/5*) LDSHARED="ld -shared";;
@@ -13756,6 +13760,8 @@
# generate output files
ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc"
+ac_config_files="$ac_config_files Modules/ld_so_aix"
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -14448,6 +14454,7 @@
"Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;;
"Modules/Setup.config") CONFIG_FILES="$CONFIG_FILES Modules/Setup.config" ;;
"Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;;
+ "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@@ -14987,6 +14994,11 @@
esac
+
+ case $ac_file$ac_mode in
+ "Modules/ld_so_aix":F) chmod +x Modules/ld_so_aix ;;
+
+ esac
done # for ac_tag
Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in (original)
+++ python/branches/py3k/configure.in Fri Sep 10 21:44:44 2010
@@ -766,6 +766,10 @@
BLDLIBRARY='-L. -lpython$(VERSION)'
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
;;
+ AIX*)
+ LDLIBRARY='libpython$(VERSION).so'
+ RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+ ;;
esac
else # shared is disabled
@@ -1665,7 +1669,7 @@
then
case $ac_sys_system/$ac_sys_release in
AIX*)
- BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp"
+ BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp -L\$(srcdir)"
LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp"
;;
IRIX/5*) LDSHARED="ld -shared";;
@@ -4247,6 +4251,7 @@
# generate output files
AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc)
+AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
AC_OUTPUT
echo "creating Modules/Setup"
From python-checkins at python.org Fri Sep 10 21:47:43 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 10 Sep 2010 21:47:43 +0200 (CEST)
Subject: [Python-checkins] r84681 -
python/branches/py3k/Lib/test/test_syntax.py
Message-ID: <20100910194743.58F90EE995@mail.python.org>
Author: amaury.forgeotdarc
Date: Fri Sep 10 21:47:43 2010
New Revision: 84681
Log:
The "if 1": trick seems cleaner that the one with regular expressions.
Use it here again.
Modified:
python/branches/py3k/Lib/test/test_syntax.py
Modified: python/branches/py3k/Lib/test/test_syntax.py
==============================================================================
--- python/branches/py3k/Lib/test/test_syntax.py (original)
+++ python/branches/py3k/Lib/test/test_syntax.py Fri Sep 10 21:47:43 2010
@@ -550,13 +550,13 @@
def test_global_err_then_warn(self):
# Bug tickler: The SyntaxError raised for one global statement
# shouldn't be clobbered by a SyntaxWarning issued for a later one.
- source = re.sub('(?m)^ *:', '', """\
- :def error(a):
- : global a # SyntaxError
- :def warning():
- : b = 1
- : global b # SyntaxWarning
- :""")
+ source = """if 1:
+ def error(a):
+ global a # SyntaxError
+ def warning():
+ b = 1
+ global b # SyntaxWarning
+ """
warnings.filterwarnings(action='ignore', category=SyntaxWarning)
self._check_error(source, "global")
warnings.filters.pop(0)
@@ -565,12 +565,12 @@
self._check_error("break", "outside loop")
def test_delete_deref(self):
- source = re.sub('(?m)^ *:', '', """\
- :def foo(x):
- : def bar():
- : print(x)
- : del x
- :""")
+ source = """if 1:
+ def foo(x):
+ def bar():
+ print(x)
+ del x
+ """
self._check_error(source, "nested scope")
def test_unexpected_indent(self):
From python-checkins at python.org Fri Sep 10 21:55:20 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 10 Sep 2010 21:55:20 +0200 (CEST)
Subject: [Python-checkins] r84682 - in python/branches/release31-maint:
Lib/distutils/command/build_ext.py Makefile.pre.in Misc/NEWS
Modules/ld_so_aix Modules/ld_so_aix.in configure configure.in
Message-ID: <20100910195520.3D354EE9A0@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 10 21:55:19 2010
New Revision: 84682
Log:
Merged revisions 84680 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84680 | antoine.pitrou | 2010-09-10 21:44:44 +0200 (ven., 10 sept. 2010) | 4 lines
Issue #941346: Improve the build process under AIX and allow Python to
be built as a shared library. Patch by S?bastien Sabl?.
........
Added:
python/branches/release31-maint/Modules/ld_so_aix.in
- copied unchanged from r84680, /python/branches/py3k/Modules/ld_so_aix.in
Removed:
python/branches/release31-maint/Modules/ld_so_aix
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/distutils/command/build_ext.py
python/branches/release31-maint/Makefile.pre.in
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/configure
python/branches/release31-maint/configure.in
Modified: python/branches/release31-maint/Lib/distutils/command/build_ext.py
==============================================================================
--- python/branches/release31-maint/Lib/distutils/command/build_ext.py (original)
+++ python/branches/release31-maint/Lib/distutils/command/build_ext.py Fri Sep 10 21:55:19 2010
@@ -748,6 +748,9 @@
elif sys.platform == 'darwin':
# Don't use the default code below
return ext.libraries
+ elif sys.platform[:3] == 'aix':
+ # Don't use the default code below
+ return ext.libraries
else:
from distutils import sysconfig
if sysconfig.get_config_var('Py_ENABLE_SHARED'):
Modified: python/branches/release31-maint/Makefile.pre.in
==============================================================================
--- python/branches/release31-maint/Makefile.pre.in (original)
+++ python/branches/release31-maint/Makefile.pre.in Fri Sep 10 21:55:19 2010
@@ -435,10 +435,10 @@
libpython$(VERSION).so: $(LIBRARY_OBJS)
if test $(INSTSONAME) != $(LDLIBRARY); then \
- $(LDSHARED) $(LDFLAGS) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+ $(BLDSHARED) $(LDFLAGS) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
$(LN) -f $(INSTSONAME) $@; \
else \
- $(LDSHARED) $(LDFLAGS) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+ $(BLDSHARED) $(LDFLAGS) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
fi
libpython$(VERSION).dylib: $(LIBRARY_OBJS)
@@ -1189,7 +1189,7 @@
distclean: clobber
-rm -f core Makefile Makefile.pre config.status \
Modules/Setup Modules/Setup.local Modules/Setup.config \
- Misc/python.pc
+ Modules/ld_so_aix Misc/python.pc
find $(srcdir) '(' -name '*.fdc' -o -name '*~' \
-o -name '[@,#]*' -o -name '*.old' \
-o -name '*.orig' -o -name '*.rej' \
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Fri Sep 10 21:55:19 2010
@@ -552,6 +552,9 @@
Build
-----
+- Issue #941346: Improve the build process under AIX and allow Python to
+ be built as a shared library. Patch by S?bastien Sabl?.
+
- Issue #4026: Make the fcntl extension build under AIX. Patch by S?bastien
Sabl?.
Deleted: python/branches/release31-maint/Modules/ld_so_aix
==============================================================================
--- python/branches/release31-maint/Modules/ld_so_aix Fri Sep 10 21:55:19 2010
+++ (empty file)
@@ -1,190 +0,0 @@
-#!/bin/sh
-#
-# ========================================================================
-# FILE: ld_so_aix
-# TYPE: executable, uses makexp_aix
-# SYSTEM: AIX
-#
-# DESCRIPTION: Creates a shareable .o from a set of pre-compiled
-# (unshared) .o files
-#
-# USAGE: ld_so_aix [CC] [arguments]
-#
-# ARGUMENTS: Same as for "ld". The following arguments are processed
-# or supplied by this script (those marked with an asterisk
-# can be overriden from command line):
-#
-# Argument Default value
-# (*) -o [OutputFileName] -o shr.o
-# (*) -e [EntryPointLabel] -e init[OutputBaseName]
-# (*) -bE:[ExportFile] -bE:[OutputBaseName].exp
-# (*) -bI:[ImportFile] -bI:./python.exp
-# -bM:[ModuleType] -bM:SRE
-# -bhalt:[Number] -bhalt:4
-# -T[Number] -T512
-# -H[Number] -H512
-# -lm
-#
-# The compiler specific ("-lc" or "-lc_r", "-lpthreads",...)
-# arguments will be automatically passed to "ld" according
-# to the CC command provided as a first argument to this
-# script. Usually, the same CC command was used to produce
-# the pre-compiled .o file(s).
-#
-# NOTES: 1. Since "ld_so_aix" was originally written for building
-# shared modules for the Python interpreter, the -e and
-# -bI default values match Python's conventions. In
-# Python, the entry point for a shared module is based
-# on the module's name (e.g., the "mathmodule" will
-# expect an entry point of "initmath").
-# 2. The script accepts multiple .o or .a input files and
-# creates a single (shared) output file. The export list
-# that is created is based on the output file's basename
-# with the suffix ".exp".
-# 3. The resulting shared object file is left in the
-# current directory.
-# 4. Uncommenting the "echo" lines gives detailed output
-# about the commands executed in the script.
-#
-#
-# HISTORY: Oct-1996 -- Support added for multiple .o files --
-# -- and optional arguments processing. --
-# Chris Myers (myers at tc.cornell.edu), Keith Kwok
-# (kkwok at tc.cornell.edu) and Vladimir Marangozov
-#
-# Aug-6-1996 -- Take care of the compiler specific --
-# -- args by leaving CC to invoke "ld". --
-# Vladimir Marangozov
-#
-# Jul-1-1996 -- Make sure to use /usr/ccs/bin/ld --
-# -- Use makexp_aix for the export list. --
-# Vladimir Marangozov (Vladimir.Marangozov at imag.fr)
-#
-# Manus Hand (mhand at csn.net) -- Initial code -- 6/24/96
-# ========================================================================
-#
-
-usage="Usage: ld_so_aix [CC command] [ld arguments]"
-if test ! -n "$*"; then
- echo $usage; exit 2
-fi
-
-makexp=`dirname $0`/makexp_aix
-
-# Check for existence of compiler.
-CC=$1; shift
-whichcc=`which $CC`
-
-if test ! -x "$whichcc"; then
- echo "ld_so_aix: Compiler '$CC' not found; exiting."
- exit 2
-fi
-
-if test ! -n "$*"; then
- echo $usage; exit 2
-fi
-
-# Default import file for Python
-# Can be overriden by providing a -bI: argument.
-impfile="./python.exp"
-
-# Parse arguments
-while test -n "$1"
-do
- case "$1" in
- -e | -Wl,-e)
- if test -z "$2"; then
- echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2
- else
- shift; entry=$1
- fi
- ;;
- -e* | -Wl,-e*)
- entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"`
- ;;
- -o)
- if test -z "$2"; then
- echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2
- else
- shift; objfile=$1
- fi
- ;;
- -o*)
- objfile=`echo $1 | sed "s/-o//"`
- ;;
- -bI:* | -Wl,-bI:*)
- impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"`
- ;;
- -bE:* | -Wl,-bE:*)
- expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"`
- ;;
- *.o | *.a)
- objs="$objs $1"
- args="$args $1"
- ;;
- -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm)
- ;;
- *)
- args="$args $1"
- ;;
- esac
- shift
-done
-
-
-if test -z "$objs"; then
- echo "ld_so_aix: No input files; exiting."
- exit 2
-elif test ! -r "$impfile"; then
- echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting."
- exit 2
-fi
-
-# If -o wasn't specified, assume "-o shr.o"
-if test -z "$objfile"; then
- objfile=shr.o
-fi
-
-filename=`basename $objfile | sed "s/\.[^.]*$//"`
-
-# If -bE: wasn't specified, assume "-bE:$filename.exp"
-if test -z "$expfile"; then
- expfile="$filename.exp"
-fi
-
-# Default entry symbol for Python modules = init[modulename]
-# Can be overriden by providing a -e argument.
-if test -z "$entry"; then
- entry=init`echo $filename | sed "s/module.*//"`
-fi
-
-#echo "ld_so_aix: Debug info section"
-#echo " -> output file : $objfile"
-#echo " -> import file : $impfile"
-#echo " -> export file : $expfile"
-#echo " -> entry point : $entry"
-#echo " -> object files: $objs"
-#echo " -> CC arguments: $args"
-
-CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4"
-CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -lm -o $objfile"
-# Note: to use dynamic libraries like libtcl8.4.so and libtk8.4.so
-# you may need to replace the second CCOPT line above with the following:
-# CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -brtl -bnortllib -lm -o $objfile"
-
-CCARGS="$args"
-
-# Export list generation.
-#echo $makexp $expfile "$objfile" $objs
-$makexp $expfile "$objfile" $objs
-
-# Perform the link.
-#echo $CC $CCOPT $CCARGS
-$CC $CCOPT $CCARGS
-retval=$?
-
-# Delete the module's export list file.
-# Comment this line if you need it.
-rm -f $expfile
-
-exit $retval
Modified: python/branches/release31-maint/configure
==============================================================================
--- python/branches/release31-maint/configure (original)
+++ python/branches/release31-maint/configure Fri Sep 10 21:55:19 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 84586 .
+# From configure.in Revision: 84675 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 3.1.
#
@@ -4870,6 +4870,10 @@
BLDLIBRARY='-L. -lpython$(VERSION)'
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
;;
+ AIX*)
+ LDLIBRARY='libpython$(VERSION).so'
+ RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+ ;;
esac
else # shared is disabled
@@ -7472,7 +7476,7 @@
then
case $ac_sys_system/$ac_sys_release in
AIX*)
- BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp"
+ BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp -L\$(srcdir)"
LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp"
;;
IRIX/5*) LDSHARED="ld -shared";;
@@ -13380,6 +13384,8 @@
# generate output files
ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc"
+ac_config_files="$ac_config_files Modules/ld_so_aix"
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -14072,6 +14078,7 @@
"Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;;
"Modules/Setup.config") CONFIG_FILES="$CONFIG_FILES Modules/Setup.config" ;;
"Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;;
+ "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@@ -14611,6 +14618,11 @@
esac
+
+ case $ac_file$ac_mode in
+ "Modules/ld_so_aix":F) chmod +x Modules/ld_so_aix ;;
+
+ esac
done # for ac_tag
Modified: python/branches/release31-maint/configure.in
==============================================================================
--- python/branches/release31-maint/configure.in (original)
+++ python/branches/release31-maint/configure.in Fri Sep 10 21:55:19 2010
@@ -748,6 +748,10 @@
BLDLIBRARY='-L. -lpython$(VERSION)'
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
;;
+ AIX*)
+ LDLIBRARY='libpython$(VERSION).so'
+ RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+ ;;
esac
else # shared is disabled
@@ -1723,7 +1727,7 @@
then
case $ac_sys_system/$ac_sys_release in
AIX*)
- BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp"
+ BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp -L\$(srcdir)"
LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp"
;;
IRIX/5*) LDSHARED="ld -shared";;
@@ -4106,6 +4110,7 @@
# generate output files
AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc)
+AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
AC_OUTPUT
echo "creating Modules/Setup"
From python-checkins at python.org Fri Sep 10 22:03:17 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Fri, 10 Sep 2010 22:03:17 +0200 (CEST)
Subject: [Python-checkins] r84683 - in python/branches/release27-maint:
Lib/distutils/command/build_ext.py Makefile.pre.in Misc/NEWS
Modules/ld_so_aix Modules/ld_so_aix.in configure configure.in
Message-ID: <20100910200317.8FBAFF46E@mail.python.org>
Author: antoine.pitrou
Date: Fri Sep 10 22:03:17 2010
New Revision: 84683
Log:
Merged revisions 84680 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84680 | antoine.pitrou | 2010-09-10 21:44:44 +0200 (ven., 10 sept. 2010) | 4 lines
Issue #941346: Improve the build process under AIX and allow Python to
be built as a shared library. Patch by S?bastien Sabl?.
........
Added:
python/branches/release27-maint/Modules/ld_so_aix.in
- copied unchanged from r84680, /python/branches/py3k/Modules/ld_so_aix.in
Removed:
python/branches/release27-maint/Modules/ld_so_aix
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/distutils/command/build_ext.py
python/branches/release27-maint/Makefile.pre.in
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/configure
python/branches/release27-maint/configure.in
Modified: python/branches/release27-maint/Lib/distutils/command/build_ext.py
==============================================================================
--- python/branches/release27-maint/Lib/distutils/command/build_ext.py (original)
+++ python/branches/release27-maint/Lib/distutils/command/build_ext.py Fri Sep 10 22:03:17 2010
@@ -753,7 +753,9 @@
elif sys.platform == 'darwin':
# Don't use the default code below
return ext.libraries
-
+ elif sys.platform[:3] == 'aix':
+ # Don't use the default code below
+ return ext.libraries
else:
from distutils import sysconfig
if sysconfig.get_config_var('Py_ENABLE_SHARED'):
Modified: python/branches/release27-maint/Makefile.pre.in
==============================================================================
--- python/branches/release27-maint/Makefile.pre.in (original)
+++ python/branches/release27-maint/Makefile.pre.in Fri Sep 10 22:03:17 2010
@@ -422,10 +422,10 @@
libpython$(VERSION).so: $(LIBRARY_OBJS)
if test $(INSTSONAME) != $(LDLIBRARY); then \
- $(LDSHARED) $(LDFLAGS) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+ $(BLDSHARED) $(LDFLAGS) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
$(LN) -f $(INSTSONAME) $@; \
else \
- $(LDSHARED) $(LDFLAGS) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
+ $(BLDSHARED) $(LDFLAGS) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
fi
libpython$(VERSION).dylib: $(LIBRARY_OBJS)
@@ -1197,7 +1197,7 @@
done
-rm -f core Makefile Makefile.pre config.status \
Modules/Setup Modules/Setup.local Modules/Setup.config \
- Misc/python.pc
+ Modules/ld_so_aix Misc/python.pc
-rm -f python*-gdb.py
find $(srcdir) '(' -name '*.fdc' -o -name '*~' \
-o -name '[@,#]*' -o -name '*.old' \
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Fri Sep 10 22:03:17 2010
@@ -302,6 +302,9 @@
Build
-----
+- Issue #941346: Improve the build process under AIX and allow Python to
+ be built as a shared library. Patch by S?bastien Sabl?.
+
- Issue #4026: Make the fcntl extension build under AIX. Patch by S?bastien
Sabl?.
Deleted: python/branches/release27-maint/Modules/ld_so_aix
==============================================================================
--- python/branches/release27-maint/Modules/ld_so_aix Fri Sep 10 22:03:17 2010
+++ (empty file)
@@ -1,190 +0,0 @@
-#!/bin/sh
-#
-# ========================================================================
-# FILE: ld_so_aix
-# TYPE: executable, uses makexp_aix
-# SYSTEM: AIX
-#
-# DESCRIPTION: Creates a shareable .o from a set of pre-compiled
-# (unshared) .o files
-#
-# USAGE: ld_so_aix [CC] [arguments]
-#
-# ARGUMENTS: Same as for "ld". The following arguments are processed
-# or supplied by this script (those marked with an asterisk
-# can be overriden from command line):
-#
-# Argument Default value
-# (*) -o [OutputFileName] -o shr.o
-# (*) -e [EntryPointLabel] -e init[OutputBaseName]
-# (*) -bE:[ExportFile] -bE:[OutputBaseName].exp
-# (*) -bI:[ImportFile] -bI:./python.exp
-# -bM:[ModuleType] -bM:SRE
-# -bhalt:[Number] -bhalt:4
-# -T[Number] -T512
-# -H[Number] -H512
-# -lm
-#
-# The compiler specific ("-lc" or "-lc_r", "-lpthreads",...)
-# arguments will be automatically passed to "ld" according
-# to the CC command provided as a first argument to this
-# script. Usually, the same CC command was used to produce
-# the pre-compiled .o file(s).
-#
-# NOTES: 1. Since "ld_so_aix" was originally written for building
-# shared modules for the Python interpreter, the -e and
-# -bI default values match Python's conventions. In
-# Python, the entry point for a shared module is based
-# on the module's name (e.g., the "mathmodule" will
-# expect an entry point of "initmath").
-# 2. The script accepts multiple .o or .a input files and
-# creates a single (shared) output file. The export list
-# that is created is based on the output file's basename
-# with the suffix ".exp".
-# 3. The resulting shared object file is left in the
-# current directory.
-# 4. Uncommenting the "echo" lines gives detailed output
-# about the commands executed in the script.
-#
-#
-# HISTORY: Oct-1996 -- Support added for multiple .o files --
-# -- and optional arguments processing. --
-# Chris Myers (myers at tc.cornell.edu), Keith Kwok
-# (kkwok at tc.cornell.edu) and Vladimir Marangozov
-#
-# Aug-6-1996 -- Take care of the compiler specific --
-# -- args by leaving CC to invoke "ld". --
-# Vladimir Marangozov
-#
-# Jul-1-1996 -- Make sure to use /usr/ccs/bin/ld --
-# -- Use makexp_aix for the export list. --
-# Vladimir Marangozov (Vladimir.Marangozov at imag.fr)
-#
-# Manus Hand (mhand at csn.net) -- Initial code -- 6/24/96
-# ========================================================================
-#
-
-usage="Usage: ld_so_aix [CC command] [ld arguments]"
-if test ! -n "$*"; then
- echo $usage; exit 2
-fi
-
-makexp=`dirname $0`/makexp_aix
-
-# Check for existence of compiler.
-CC=$1; shift
-whichcc=`which $CC`
-
-if test ! -x "$whichcc"; then
- echo "ld_so_aix: Compiler '$CC' not found; exiting."
- exit 2
-fi
-
-if test ! -n "$*"; then
- echo $usage; exit 2
-fi
-
-# Default import file for Python
-# Can be overriden by providing a -bI: argument.
-impfile="./python.exp"
-
-# Parse arguments
-while test -n "$1"
-do
- case "$1" in
- -e | -Wl,-e)
- if test -z "$2"; then
- echo "ld_so_aix: The -e flag needs a parameter; exiting."; exit 2
- else
- shift; entry=$1
- fi
- ;;
- -e* | -Wl,-e*)
- entry=`echo $1 | sed -e "s/-Wl,//" -e "s/-e//"`
- ;;
- -o)
- if test -z "$2"; then
- echo "ld_so_aix: The -o flag needs a parameter; exiting."; exit 2
- else
- shift; objfile=$1
- fi
- ;;
- -o*)
- objfile=`echo $1 | sed "s/-o//"`
- ;;
- -bI:* | -Wl,-bI:*)
- impfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bI://"`
- ;;
- -bE:* | -Wl,-bE:*)
- expfile=`echo $1 | sed -e "s/-Wl,//" -e "s/-bE://"`
- ;;
- *.o | *.a)
- objs="$objs $1"
- args="$args $1"
- ;;
- -bM:* | -Wl,-bM:* | -H* | -Wl,-H* | -T* | -Wl,-T* | -lm)
- ;;
- *)
- args="$args $1"
- ;;
- esac
- shift
-done
-
-
-if test -z "$objs"; then
- echo "ld_so_aix: No input files; exiting."
- exit 2
-elif test ! -r "$impfile"; then
- echo "ld_so_aix: Import file '$impfile' not found or not readable; exiting."
- exit 2
-fi
-
-# If -o wasn't specified, assume "-o shr.o"
-if test -z "$objfile"; then
- objfile=shr.o
-fi
-
-filename=`basename $objfile | sed "s/\.[^.]*$//"`
-
-# If -bE: wasn't specified, assume "-bE:$filename.exp"
-if test -z "$expfile"; then
- expfile="$filename.exp"
-fi
-
-# Default entry symbol for Python modules = init[modulename]
-# Can be overriden by providing a -e argument.
-if test -z "$entry"; then
- entry=init`echo $filename | sed "s/module.*//"`
-fi
-
-#echo "ld_so_aix: Debug info section"
-#echo " -> output file : $objfile"
-#echo " -> import file : $impfile"
-#echo " -> export file : $expfile"
-#echo " -> entry point : $entry"
-#echo " -> object files: $objs"
-#echo " -> CC arguments: $args"
-
-CCOPT="-Wl,-e$entry -Wl,-bE:$expfile -Wl,-bI:$impfile -Wl,-bhalt:4"
-CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -lm -o $objfile"
-# Note: to use dynamic libraries like libtcl8.4.so and libtk8.4.so
-# you may need to replace the second CCOPT line above with the following:
-# CCOPT="$CCOPT -Wl,-bM:SRE -Wl,-T512 -Wl,-H512 -brtl -bnortllib -lm -o $objfile"
-
-CCARGS="$args"
-
-# Export list generation.
-#echo $makexp $expfile "$objfile" $objs
-$makexp $expfile "$objfile" $objs
-
-# Perform the link.
-#echo $CC $CCOPT $CCARGS
-$CC $CCOPT $CCARGS
-retval=$?
-
-# Delete the module's export list file.
-# Comment this line if you need it.
-rm -f $expfile
-
-exit $retval
Modified: python/branches/release27-maint/configure
==============================================================================
--- python/branches/release27-maint/configure (original)
+++ python/branches/release27-maint/configure Fri Sep 10 22:03:17 2010
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 84585 .
+# From configure.in Revision: 84676 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.65 for python 2.7.
#
@@ -4950,6 +4950,10 @@
BLDLIBRARY='-L. -lpython$(VERSION)'
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
;;
+ AIX*)
+ LDLIBRARY='libpython$(VERSION).so'
+ RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+ ;;
esac
else # shared is disabled
@@ -7531,7 +7535,7 @@
then
case $ac_sys_system/$ac_sys_release in
AIX*)
- BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp"
+ BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp -L\$(srcdir)"
LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp"
;;
BeOS*)
@@ -13753,6 +13757,8 @@
# generate output files
ac_config_files="$ac_config_files Makefile.pre Modules/Setup.config Misc/python.pc"
+ac_config_files="$ac_config_files Modules/ld_so_aix"
+
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
@@ -14446,6 +14452,7 @@
"Makefile.pre") CONFIG_FILES="$CONFIG_FILES Makefile.pre" ;;
"Modules/Setup.config") CONFIG_FILES="$CONFIG_FILES Modules/Setup.config" ;;
"Misc/python.pc") CONFIG_FILES="$CONFIG_FILES Misc/python.pc" ;;
+ "Modules/ld_so_aix") CONFIG_FILES="$CONFIG_FILES Modules/ld_so_aix" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
@@ -14985,6 +14992,11 @@
esac
+
+ case $ac_file$ac_mode in
+ "Modules/ld_so_aix":F) chmod +x Modules/ld_so_aix ;;
+
+ esac
done # for ac_tag
Modified: python/branches/release27-maint/configure.in
==============================================================================
--- python/branches/release27-maint/configure.in (original)
+++ python/branches/release27-maint/configure.in Fri Sep 10 22:03:17 2010
@@ -823,6 +823,10 @@
BLDLIBRARY='-L. -lpython$(VERSION)'
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
;;
+ AIX*)
+ LDLIBRARY='libpython$(VERSION).so'
+ RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
+ ;;
esac
else # shared is disabled
@@ -1757,7 +1761,7 @@
then
case $ac_sys_system/$ac_sys_release in
AIX*)
- BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp"
+ BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp -L\$(srcdir)"
LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp"
;;
BeOS*)
@@ -4273,6 +4277,7 @@
# generate output files
AC_CONFIG_FILES(Makefile.pre Modules/Setup.config Misc/python.pc)
+AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])
AC_OUTPUT
echo "creating Modules/Setup"
From python-checkins at python.org Fri Sep 10 22:43:53 2010
From: python-checkins at python.org (georg.brandl)
Date: Fri, 10 Sep 2010 22:43:53 +0200 (CEST)
Subject: [Python-checkins] r84684 -
python/branches/py3k/Doc/library/stdtypes.rst
Message-ID: <20100910204353.7E8E0DDAF@mail.python.org>
Author: georg.brandl
Date: Fri Sep 10 22:43:53 2010
New Revision: 84684
Log:
release() is probably not the most important method
Modified:
python/branches/py3k/Doc/library/stdtypes.rst
Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst (original)
+++ python/branches/py3k/Doc/library/stdtypes.rst Fri Sep 10 22:43:53 2010
@@ -2313,6 +2313,24 @@
:class:`memoryview` has several methods:
+ .. method:: tobytes()
+
+ Return the data in the buffer as a bytestring. This is equivalent to
+ calling the :class:`bytes` constructor on the memoryview. ::
+
+ >>> m = memoryview(b"abc")
+ >>> m.tobytes()
+ b'abc'
+ >>> bytes(m)
+ b'abc'
+
+ .. method:: tolist()
+
+ Return the data in the buffer as a list of integers. ::
+
+ >>> memoryview(b'abc').tolist()
+ [97, 98, 99]
+
.. method:: release()
Release the underlying buffer exposed by the memoryview object. Many
@@ -2346,24 +2364,6 @@
.. versionadded:: 3.2
- .. method:: tobytes()
-
- Return the data in the buffer as a bytestring. This is equivalent to
- calling the :class:`bytes` constructor on the memoryview. ::
-
- >>> m = memoryview(b"abc")
- >>> m.tobytes()
- b'abc'
- >>> bytes(m)
- b'abc'
-
- .. method:: tolist()
-
- Return the data in the buffer as a list of integers. ::
-
- >>> memoryview(b'abc').tolist()
- [97, 98, 99]
-
There are also several readonly attributes available:
.. attribute:: format
From python-checkins at python.org Fri Sep 10 23:39:54 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Fri, 10 Sep 2010 23:39:54 +0200 (CEST)
Subject: [Python-checkins] r84685 - in python/branches/py3k:
Doc/library/dis.rst Doc/reference/simple_stmts.rst
Doc/whatsnew/3.2.rst Include/opcode.h Lib/opcode.py
Lib/test/test_exceptions.py Lib/test/test_scope.py
Lib/test/test_syntax.py Misc/NEWS Python/ceval.c
Python/compile.c Python/opcode_targets.h
Message-ID: <20100910213954.0BD48EEA38@mail.python.org>
Author: amaury.forgeotdarc
Date: Fri Sep 10 23:39:53 2010
New Revision: 84685
Log:
#4617: Previously it was illegal to delete a name from the local
namespace if it occurs as a free variable in a nested block. This limitation
of the compiler has been lifted, and a new opcode introduced (DELETE_DEREF).
This sample was valid in 2.6, but fails to compile in 3.x without this change::
>>> def f():
... def print_error():
... print(e)
... try:
... something
... except Exception as e:
... print_error()
... # implicit "del e" here
This sample has always been invalid in Python, and now works::
>>> def outer(x):
... def inner():
... return x
... inner()
... del x
There is no need to bump the PYC magic number: the new opcode is used
for code that did not compile before.
Modified:
python/branches/py3k/Doc/library/dis.rst
python/branches/py3k/Doc/reference/simple_stmts.rst
python/branches/py3k/Doc/whatsnew/3.2.rst
python/branches/py3k/Include/opcode.h
python/branches/py3k/Lib/opcode.py
python/branches/py3k/Lib/test/test_exceptions.py
python/branches/py3k/Lib/test/test_scope.py
python/branches/py3k/Lib/test/test_syntax.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Python/ceval.c
python/branches/py3k/Python/compile.c
python/branches/py3k/Python/opcode_targets.h
Modified: python/branches/py3k/Doc/library/dis.rst
==============================================================================
--- python/branches/py3k/Doc/library/dis.rst (original)
+++ python/branches/py3k/Doc/library/dis.rst Fri Sep 10 23:39:53 2010
@@ -723,6 +723,12 @@
storage.
+.. opcode:: DELETE_DEREF (i)
+
+ Empties the cell contained in slot *i* of the cell and free variable storage.
+ Used by the :keyword:`del` statement.
+
+
.. opcode:: SET_LINENO (lineno)
This opcode is obsolete.
Modified: python/branches/py3k/Doc/reference/simple_stmts.rst
==============================================================================
--- python/branches/py3k/Doc/reference/simple_stmts.rst (original)
+++ python/branches/py3k/Doc/reference/simple_stmts.rst Fri Sep 10 23:39:53 2010
@@ -388,11 +388,6 @@
in the same code block. If the name is unbound, a :exc:`NameError` exception
will be raised.
-.. index:: pair: free; variable
-
-It is illegal to delete a name from the local namespace if it occurs as a free
-variable in a nested block.
-
.. index:: pair: attribute; deletion
Deletion of attribute references, subscriptions and slicings is passed to the
@@ -400,6 +395,10 @@
assignment of an empty slice of the right type (but even this is determined by
the sliced object).
+.. versionchanged:: 3.2
+ Previously it was illegal to delete a name from the local namespace if it
+ occurs as a free variable in a nested block.
+
.. _return:
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Fri Sep 10 23:39:53 2010
@@ -240,6 +240,31 @@
(See :issue:`8188`.)
+* Previously it was illegal to delete a name from the local namespace if it
+ occurs as a free variable in a nested block::
+
+ >>> def outer(x):
+ ... def inner():
+ ... return x
+ ... inner()
+ ... del x
+
+ This is now allowed. Remember that the target of an :keyword:`except` clause
+ is cleared, so this code which used to work with Python 2.6, raised a
+ :exc:`SyntaxError` with Python 3.1 and now works again::
+
+ >>> def f():
+ ... def print_error():
+ ... print(e)
+ ... try:
+ ... something
+ ... except Exception as e:
+ ... print_error()
+ ... # implicit "del e" here
+
+ (See :issue:`4617`.)
+
+
New, Improved, and Deprecated Modules
=====================================
Modified: python/branches/py3k/Include/opcode.h
==============================================================================
--- python/branches/py3k/Include/opcode.h (original)
+++ python/branches/py3k/Include/opcode.h Fri Sep 10 23:39:53 2010
@@ -123,6 +123,7 @@
#define LOAD_CLOSURE 135 /* Load free variable from closure */
#define LOAD_DEREF 136 /* Load and dereference from closure cell */
#define STORE_DEREF 137 /* Store into cell */
+#define DELETE_DEREF 138 /* Delete closure cell */
/* The next 3 opcodes must be contiguous and satisfy
(CALL_FUNCTION_VAR - CALL_FUNCTION) & 3 == 1 */
Modified: python/branches/py3k/Lib/opcode.py
==============================================================================
--- python/branches/py3k/Lib/opcode.py (original)
+++ python/branches/py3k/Lib/opcode.py Fri Sep 10 23:39:53 2010
@@ -161,6 +161,8 @@
hasfree.append(136)
def_op('STORE_DEREF', 137)
hasfree.append(137)
+def_op('DELETE_DEREF', 138)
+hasfree.append(138)
def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8)
Modified: python/branches/py3k/Lib/test/test_exceptions.py
==============================================================================
--- python/branches/py3k/Lib/test/test_exceptions.py (original)
+++ python/branches/py3k/Lib/test/test_exceptions.py Fri Sep 10 23:39:53 2010
@@ -526,6 +526,17 @@
obj = wr()
self.assertTrue(obj is None, "%s" % obj)
+ def test_exception_target_in_nested_scope(self):
+ # issue 4617: This used to raise a SyntaxError
+ # "can not delete variable 'e' referenced in nested scope"
+ def print_error():
+ e
+ try:
+ something
+ except Exception as e:
+ print_error()
+ # implicit "del e" here
+
def test_generator_leaking(self):
# Test that generator exception state doesn't leak into the calling
# frame
Modified: python/branches/py3k/Lib/test/test_scope.py
==============================================================================
--- python/branches/py3k/Lib/test/test_scope.py (original)
+++ python/branches/py3k/Lib/test/test_scope.py Fri Sep 10 23:39:53 2010
@@ -218,13 +218,6 @@
""")
check_syntax_error(self, """if 1:
- def f(x):
- def g():
- return x
- del x # can't del name
- """)
-
- check_syntax_error(self, """if 1:
def f():
def g():
from sys import *
@@ -272,6 +265,28 @@
self.assertRaises(UnboundLocalError, errorInOuter)
self.assertRaises(NameError, errorInInner)
+ def testUnboundLocal_AfterDel(self):
+ # #4617: It is now legal to delete a cell variable.
+ # The following functions must obviously compile,
+ # and give the correct error when accessing the deleted name.
+ def errorInOuter():
+ y = 1
+ del y
+ print(y)
+ def inner():
+ return y
+
+ def errorInInner():
+ def inner():
+ return y
+ y = 1
+ del y
+ inner()
+
+ self.assertRaises(UnboundLocalError, errorInOuter)
+ self.assertRaises(NameError, errorInInner)
+
+ def testUnboundLocal_AugAssign(self):
# test for bug #1501934: incorrect LOAD/STORE_GLOBAL generation
exec("""if 1:
global_x = 1
Modified: python/branches/py3k/Lib/test/test_syntax.py
==============================================================================
--- python/branches/py3k/Lib/test/test_syntax.py (original)
+++ python/branches/py3k/Lib/test/test_syntax.py Fri Sep 10 23:39:53 2010
@@ -564,15 +564,6 @@
def test_break_outside_loop(self):
self._check_error("break", "outside loop")
- def test_delete_deref(self):
- source = """if 1:
- def foo(x):
- def bar():
- print(x)
- del x
- """
- self._check_error(source, "nested scope")
-
def test_unexpected_indent(self):
self._check_error("foo()\n bar()\n", "unexpected indent",
subclass=IndentationError)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 10 23:39:53 2010
@@ -10,6 +10,10 @@
Core and Builtins
-----------------
+- Issue #4617: Previously it was illegal to delete a name from the local
+ namespace if it occurs as a free variable in a nested block. This limitation
+ of the compiler has been lifted, and a new opcode introduced (DELETE_DEREF).
+
- Issue #9804: ascii() now always represents unicode surrogate pairs as
a single ``\UXXXXXXXX``, regardless of whether the character is printable
or not. Also, the "backslashreplace" error handler now joins surrogate
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Fri Sep 10 23:39:53 2010
@@ -135,6 +135,7 @@
static PyObject * import_from(PyObject *, PyObject *);
static int import_all_from(PyObject *, PyObject *);
static void format_exc_check_arg(PyObject *, const char *, PyObject *);
+static void format_exc_unbound(PyCodeObject *co, int oparg);
static PyObject * unicode_concatenate(PyObject *, PyObject *,
PyFrameObject *, unsigned char *);
static PyObject * special_lookup(PyObject *, char *, PyObject **);
@@ -2143,6 +2144,16 @@
);
break;
+ TARGET(DELETE_DEREF)
+ x = freevars[oparg];
+ if (PyCell_GET(x) != NULL) {
+ PyCell_Set(x, NULL);
+ continue;
+ }
+ err = -1;
+ format_exc_unbound(co, oparg);
+ break;
+
TARGET(LOAD_CLOSURE)
x = freevars[oparg];
Py_INCREF(x);
@@ -2158,22 +2169,7 @@
DISPATCH();
}
err = -1;
- /* Don't stomp existing exception */
- if (PyErr_Occurred())
- break;
- if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
- v = PyTuple_GET_ITEM(co->co_cellvars,
- oparg);
- format_exc_check_arg(
- PyExc_UnboundLocalError,
- UNBOUNDLOCAL_ERROR_MSG,
- v);
- } else {
- v = PyTuple_GET_ITEM(co->co_freevars, oparg -
- PyTuple_GET_SIZE(co->co_cellvars));
- format_exc_check_arg(PyExc_NameError,
- UNBOUNDFREE_ERROR_MSG, v);
- }
+ format_exc_unbound(co, oparg);
break;
TARGET(STORE_DEREF)
@@ -4352,6 +4348,28 @@
PyErr_Format(exc, format_str, obj_str);
}
+static void
+format_exc_unbound(PyCodeObject *co, int oparg)
+{
+ PyObject *name;
+ /* Don't stomp existing exception */
+ if (PyErr_Occurred())
+ return;
+ if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
+ name = PyTuple_GET_ITEM(co->co_cellvars,
+ oparg);
+ format_exc_check_arg(
+ PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ name);
+ } else {
+ name = PyTuple_GET_ITEM(co->co_freevars, oparg -
+ PyTuple_GET_SIZE(co->co_cellvars));
+ format_exc_check_arg(PyExc_NameError,
+ UNBOUNDFREE_ERROR_MSG, name);
+ }
+}
+
static PyObject *
unicode_concatenate(PyObject *v, PyObject *w,
PyFrameObject *f, unsigned char *next_instr)
Modified: python/branches/py3k/Python/compile.c
==============================================================================
--- python/branches/py3k/Python/compile.c (original)
+++ python/branches/py3k/Python/compile.c Fri Sep 10 23:39:53 2010
@@ -857,6 +857,8 @@
return 1;
case STORE_DEREF:
return -1;
+ case DELETE_DEREF:
+ return 0;
default:
fprintf(stderr, "opcode = %d\n", opcode);
Py_FatalError("opcode_stack_effect()");
@@ -2506,13 +2508,7 @@
case AugLoad:
case AugStore:
break;
- case Del:
- PyErr_Format(PyExc_SyntaxError,
- "can not delete variable '%S' referenced "
- "in nested scope",
- name);
- Py_DECREF(mangled);
- return 0;
+ case Del: op = DELETE_DEREF; break;
case Param:
default:
PyErr_SetString(PyExc_SystemError,
Modified: python/branches/py3k/Python/opcode_targets.h
==============================================================================
--- python/branches/py3k/Python/opcode_targets.h (original)
+++ python/branches/py3k/Python/opcode_targets.h Fri Sep 10 23:39:53 2010
@@ -137,7 +137,7 @@
&&TARGET_LOAD_CLOSURE,
&&TARGET_LOAD_DEREF,
&&TARGET_STORE_DEREF,
- &&_unknown_opcode,
+ &&TARGET_DELETE_DEREF,
&&_unknown_opcode,
&&TARGET_CALL_FUNCTION_VAR,
&&TARGET_CALL_FUNCTION_KW,
From python-checkins at python.org Fri Sep 10 23:51:44 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Fri, 10 Sep 2010 23:51:44 +0200 (CEST)
Subject: [Python-checkins] r84686 - python/branches/py3k/Python/import.c
Message-ID: <20100910215144.ACBF7EE9F0@mail.python.org>
Author: benjamin.peterson
Date: Fri Sep 10 23:51:44 2010
New Revision: 84686
Log:
bump magic number for DELETE_DEREF
Modified:
python/branches/py3k/Python/import.c
Modified: python/branches/py3k/Python/import.c
==============================================================================
--- python/branches/py3k/Python/import.c (original)
+++ python/branches/py3k/Python/import.c Fri Sep 10 23:51:44 2010
@@ -105,12 +105,13 @@
tag: cpython-32
Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
tag: cpython-32
+ Python 3.2a2 3180 (add DELETE_DEREF)
*/
/* If you change MAGIC, you must change TAG and you must insert the old value
into _PyMagicNumberTags below.
*/
-#define MAGIC (3170 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (3180 | ((long)'\r'<<16) | ((long)'\n'<<24))
#define TAG "cpython-32"
#define CACHEDIR "__pycache__"
/* Current magic word and string tag as globals. */
From python-checkins at python.org Fri Sep 10 23:58:00 2010
From: python-checkins at python.org (victor.stinner)
Date: Fri, 10 Sep 2010 23:58:00 +0200 (CEST)
Subject: [Python-checkins] r84687 - in python/branches/py3k:
Doc/library/sys.rst Include/fileobject.h Lib/test/test_sys.py
Misc/NEWS Python/bltinmodule.c Python/sysmodule.c
Message-ID: <20100910215800.161F3EE9F0@mail.python.org>
Author: victor.stinner
Date: Fri Sep 10 23:57:59 2010
New Revision: 84687
Log:
Issue #9632: Remove sys.setfilesystemencoding() function: use PYTHONFSENCODING
environment variable to set the filesystem encoding at Python startup.
sys.setfilesystemencoding() creates inconsistencies because it is unable to
reencode all filenames in all objects.
Modified:
python/branches/py3k/Doc/library/sys.rst
python/branches/py3k/Include/fileobject.h
python/branches/py3k/Lib/test/test_sys.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Python/bltinmodule.c
python/branches/py3k/Python/sysmodule.c
Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst (original)
+++ python/branches/py3k/Doc/library/sys.rst Fri Sep 10 23:57:59 2010
@@ -724,15 +724,6 @@
:file:`/usr/include/dlfcn.h` using the :program:`h2py` script. Availability:
Unix.
-.. function:: setfilesystemencoding(enc)
-
- Set the encoding used when converting Python strings to file names to *enc*.
- By default, Python tries to determine the encoding it should use automatically
- on Unix; on Windows, it avoids such conversion completely. This function can
- be used when Python's determination of the encoding needs to be overwritten,
- e.g. when not all file names on disk can be decoded using the encoding that
- Python had chosen.
-
.. function:: setprofile(profilefunc)
.. index::
Modified: python/branches/py3k/Include/fileobject.h
==============================================================================
--- python/branches/py3k/Include/fileobject.h (original)
+++ python/branches/py3k/Include/fileobject.h Fri Sep 10 23:57:59 2010
@@ -21,7 +21,6 @@
*/
PyAPI_DATA(const char *) Py_FileSystemDefaultEncoding;
PyAPI_DATA(int) Py_HasFileSystemDefaultEncoding;
-PyAPI_FUNC(int) _Py_SetFileSystemEncoding(PyObject *);
/* Internal API
Modified: python/branches/py3k/Lib/test/test_sys.py
==============================================================================
--- python/branches/py3k/Lib/test/test_sys.py (original)
+++ python/branches/py3k/Lib/test/test_sys.py Fri Sep 10 23:57:59 2010
@@ -630,17 +630,6 @@
env['PYTHONFSENCODING'] = encoding
self.check_fsencoding(get_fsencoding(env), encoding)
- def test_setfilesystemencoding(self):
- old = sys.getfilesystemencoding()
- try:
- sys.setfilesystemencoding("iso-8859-1")
- self.assertEqual(sys.getfilesystemencoding(), "iso-8859-1")
- finally:
- sys.setfilesystemencoding(old)
- try:
- self.assertRaises(LookupError, sys.setfilesystemencoding, "xxx")
- finally:
- sys.setfilesystemencoding(old)
class SizeofTest(unittest.TestCase):
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Fri Sep 10 23:57:59 2010
@@ -29,6 +29,11 @@
Library
-------
+- Issue #9632: Remove sys.setfilesystemencoding() function: use
+ PYTHONFSENCODING environment variable to set the filesystem encoding at
+ Python startup. sys.setfilesystemencoding() creates inconsistencies because
+ it is unable to reencode all filenames in all objects.
+
- Issue #9410: Various optimizations to the pickle module, leading to
speedups up to 4x (depending on the benchmark). Mostly ported from
Unladen Swallow; initial patch by Alexandre Vassalotti.
Modified: python/branches/py3k/Python/bltinmodule.c
==============================================================================
--- python/branches/py3k/Python/bltinmodule.c (original)
+++ python/branches/py3k/Python/bltinmodule.c Fri Sep 10 23:57:59 2010
@@ -33,29 +33,6 @@
int Py_HasFileSystemDefaultEncoding = 1;
#endif
-int
-_Py_SetFileSystemEncoding(PyObject *s)
-{
- PyObject *defenc, *codec;
- if (!PyUnicode_Check(s)) {
- PyErr_BadInternalCall();
- return -1;
- }
- defenc = _PyUnicode_AsDefaultEncodedString(s, NULL);
- if (!defenc)
- return -1;
- codec = _PyCodec_Lookup(PyBytes_AsString(defenc));
- if (codec == NULL)
- return -1;
- Py_DECREF(codec);
- if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding)
- /* A file system encoding was set at run-time */
- free((char*)Py_FileSystemDefaultEncoding);
- Py_FileSystemDefaultEncoding = strdup(PyBytes_AsString(defenc));
- Py_HasFileSystemDefaultEncoding = 0;
- return 0;
-}
-
static PyObject *
builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
{
Modified: python/branches/py3k/Python/sysmodule.c
==============================================================================
--- python/branches/py3k/Python/sysmodule.c (original)
+++ python/branches/py3k/Python/sysmodule.c Fri Sep 10 23:57:59 2010
@@ -199,25 +199,6 @@
);
static PyObject *
-sys_setfilesystemencoding(PyObject *self, PyObject *args)
-{
- PyObject *new_encoding;
- if (!PyArg_ParseTuple(args, "U:setfilesystemencoding", &new_encoding))
- return NULL;
- if (_Py_SetFileSystemEncoding(new_encoding))
- return NULL;
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-PyDoc_STRVAR(setfilesystemencoding_doc,
-"setfilesystemencoding(string) -> None\n\
-\n\
-Set the encoding used to convert Unicode filenames in\n\
-operating system filenames."
-);
-
-static PyObject *
sys_intern(PyObject *self, PyObject *args)
{
PyObject *s;
@@ -1012,8 +993,6 @@
#ifdef USE_MALLOPT
{"mdebug", sys_mdebug, METH_VARARGS},
#endif
- {"setfilesystemencoding", sys_setfilesystemencoding, METH_VARARGS,
- setfilesystemencoding_doc},
{"setcheckinterval", sys_setcheckinterval, METH_VARARGS,
setcheckinterval_doc},
{"getcheckinterval", sys_getcheckinterval, METH_NOARGS,
From python-checkins at python.org Fri Sep 10 23:59:21 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Fri, 10 Sep 2010 23:59:21 +0200 (CEST)
Subject: [Python-checkins] r84688 -
python/branches/py3k/Doc/reference/simple_stmts.rst
Message-ID: <20100910215921.D456BEE9F0@mail.python.org>
Author: benjamin.peterson
Date: Fri Sep 10 23:59:21 2010
New Revision: 84688
Log:
add newline
Modified:
python/branches/py3k/Doc/reference/simple_stmts.rst
Modified: python/branches/py3k/Doc/reference/simple_stmts.rst
==============================================================================
--- python/branches/py3k/Doc/reference/simple_stmts.rst (original)
+++ python/branches/py3k/Doc/reference/simple_stmts.rst Fri Sep 10 23:59:21 2010
@@ -396,6 +396,7 @@
the sliced object).
.. versionchanged:: 3.2
+
Previously it was illegal to delete a name from the local namespace if it
occurs as a free variable in a nested block.
From python-checkins at python.org Sat Sep 11 00:02:31 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 00:02:31 +0200 (CEST)
Subject: [Python-checkins] r84689 - python/branches/py3k/Python/ceval.c
Message-ID: <20100910220231.4C17CFB1E@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 00:02:31 2010
New Revision: 84689
Log:
use DISPATCH() instead of continue
Modified:
python/branches/py3k/Python/ceval.c
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Sat Sep 11 00:02:31 2010
@@ -2148,7 +2148,7 @@
x = freevars[oparg];
if (PyCell_GET(x) != NULL) {
PyCell_Set(x, NULL);
- continue;
+ DISPATCH();
}
err = -1;
format_exc_unbound(co, oparg);
From python-checkins at python.org Sat Sep 11 00:18:17 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 00:18:17 +0200 (CEST)
Subject: [Python-checkins] r84690 - in python/branches/py3k/Lib: os.py
test/test_os.py
Message-ID: <20100910221817.1AA39EEA2C@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 00:18:16 2010
New Revision: 84690
Log:
Issue #8603: Environ.data is now protected -> Environ._data
os.environ.data was a str dict in Python 3.1. In Python 3.2 on UNIX/BSD,
os.environ.data is now a bytes dict: mark it as protected to avoid confusion.
Modified:
python/branches/py3k/Lib/os.py
python/branches/py3k/Lib/test/test_os.py
Modified: python/branches/py3k/Lib/os.py
==============================================================================
--- python/branches/py3k/Lib/os.py (original)
+++ python/branches/py3k/Lib/os.py Sat Sep 11 00:18:16 2010
@@ -420,34 +420,34 @@
self.decodevalue = decodevalue
self.putenv = putenv
self.unsetenv = unsetenv
- self.data = data
+ self._data = data
def __getitem__(self, key):
- value = self.data[self.encodekey(key)]
+ value = self._data[self.encodekey(key)]
return self.decodevalue(value)
def __setitem__(self, key, value):
key = self.encodekey(key)
value = self.encodevalue(value)
self.putenv(key, value)
- self.data[key] = value
+ self._data[key] = value
def __delitem__(self, key):
key = self.encodekey(key)
self.unsetenv(key)
- del self.data[key]
+ del self._data[key]
def __iter__(self):
- for key in self.data:
+ for key in self._data:
yield self.decodekey(key)
def __len__(self):
- return len(self.data)
+ return len(self._data)
def __repr__(self):
return 'environ({{{}}})'.format(', '.join(
('{!r}: {!r}'.format(self.decodekey(key), self.decodevalue(value))
- for key, value in self.data.items())))
+ for key, value in self._data.items())))
def copy(self):
return dict(self)
@@ -521,7 +521,7 @@
return value
# bytes environ
- environb = _Environ(environ.data,
+ environb = _Environ(environ._data,
_check_bytes, bytes,
_check_bytes, bytes,
_putenv, _unsetenv)
Modified: python/branches/py3k/Lib/test/test_os.py
==============================================================================
--- python/branches/py3k/Lib/test/test_os.py (original)
+++ python/branches/py3k/Lib/test/test_os.py Sat Sep 11 00:18:16 2010
@@ -422,7 +422,6 @@
def test___repr__(self):
"""Check that the repr() of os.environ looks like environ({...})."""
env = os.environ
- self.assertTrue(isinstance(env.data, dict))
self.assertEqual(repr(env), 'environ({{{}}})'.format(', '.join(
'{!r}: {!r}'.format(key, value)
for key, value in env.items())))
From python-checkins at python.org Sat Sep 11 00:22:58 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sat, 11 Sep 2010 00:22:58 +0200 (CEST)
Subject: [Python-checkins] r84691 -
python/branches/release27-maint/Modules/ld_so_aix.in
Message-ID: <20100910222258.7910CE4D4@mail.python.org>
Author: antoine.pitrou
Date: Sat Sep 11 00:22:58 2010
New Revision: 84691
Log:
Small fix to ld_so_aix.in for 2.x
Modified:
python/branches/release27-maint/Modules/ld_so_aix.in
Modified: python/branches/release27-maint/Modules/ld_so_aix.in
==============================================================================
--- python/branches/release27-maint/Modules/ld_so_aix.in (original)
+++ python/branches/release27-maint/Modules/ld_so_aix.in Sat Sep 11 00:22:58 2010
@@ -158,7 +158,7 @@
# Default entry symbol for Python modules = init[modulename]
# Can be overriden by providing a -e argument.
if test -z "$entry"; then
- entry=PyInit_`echo $filename | sed "s/module.*//"`
+ entry=init`echo $filename | sed "s/module.*//"`
fi
#echo "ld_so_aix: Debug info section"
From python-checkins at python.org Sat Sep 11 00:25:19 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 00:25:19 +0200 (CEST)
Subject: [Python-checkins] r84692 - in python/branches/py3k:
Lib/test/test_pyexpat.py Modules/pyexpat.c
Message-ID: <20100910222519.62E21EEA33@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 00:25:19 2010
New Revision: 84692
Log:
Issue #9402: pyexpat uses Py_DECREF() instead of PyObject_DEL()
Fix a crash if Python is compiled in pydebug mode.
Modified:
python/branches/py3k/Lib/test/test_pyexpat.py
python/branches/py3k/Modules/pyexpat.c
Modified: python/branches/py3k/Lib/test/test_pyexpat.py
==============================================================================
--- python/branches/py3k/Lib/test/test_pyexpat.py (original)
+++ python/branches/py3k/Lib/test/test_pyexpat.py Sat Sep 11 00:25:19 2010
@@ -221,6 +221,25 @@
# L should have the same string repeated over and over.
self.assertTrue(tag is entry)
+ def test_issue9402(self):
+ # create an ExternalEntityParserCreate with buffer text
+ class ExternalOutputter:
+ def __init__(self, parser):
+ self.parser = parser
+ self.parser_result = None
+
+ def ExternalEntityRefHandler(self, context, base, sysId, pubId):
+ external_parser = self.parser.ExternalEntityParserCreate("")
+ self.parser_result = external_parser.Parse("", 1)
+ return 1
+
+ parser = expat.ParserCreate(namespace_separator='!')
+ parser.buffer_text = 1
+ out = ExternalOutputter(parser)
+ parser.ExternalEntityRefHandler = out.ExternalEntityRefHandler
+ parser.Parse(data, 1)
+ self.assertEquals(out.parser_result, 1)
+
class BufferTextTest(unittest.TestCase):
def setUp(self):
Modified: python/branches/py3k/Modules/pyexpat.c
==============================================================================
--- python/branches/py3k/Modules/pyexpat.c (original)
+++ python/branches/py3k/Modules/pyexpat.c Sat Sep 11 00:25:19 2010
@@ -973,21 +973,7 @@
return NULL;
new_parser->buffer_size = self->buffer_size;
new_parser->buffer_used = 0;
- if (self->buffer != NULL) {
- new_parser->buffer = malloc(new_parser->buffer_size);
- if (new_parser->buffer == NULL) {
-#ifndef Py_TPFLAGS_HAVE_GC
- /* Code for versions 2.0 and 2.1 */
- PyObject_Del(new_parser);
-#else
- /* Code for versions 2.2 and later. */
- PyObject_GC_Del(new_parser);
-#endif
- return PyErr_NoMemory();
- }
- }
- else
- new_parser->buffer = NULL;
+ new_parser->buffer = NULL;
new_parser->ordered_attributes = self->ordered_attributes;
new_parser->specified_attributes = self->specified_attributes;
new_parser->in_callback = 0;
@@ -1003,6 +989,13 @@
PyObject_GC_Init(new_parser);
#endif
+ if (self->buffer != NULL) {
+ new_parser->buffer = malloc(new_parser->buffer_size);
+ if (new_parser->buffer == NULL) {
+ Py_DECREF(new_parser);
+ return PyErr_NoMemory();
+ }
+ }
if (!new_parser->itself) {
Py_DECREF(new_parser);
return PyErr_NoMemory();
From python-checkins at python.org Sat Sep 11 00:47:02 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 00:47:02 +0200 (CEST)
Subject: [Python-checkins] r84693 - python/branches/py3k/Python/ceval.c
Message-ID: <20100910224702.8A4D6EEA37@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 00:47:02 2010
New Revision: 84693
Log:
remove gil_drop_request in --without-threads
Modified:
python/branches/py3k/Python/ceval.c
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Sat Sep 11 00:47:02 2010
@@ -217,16 +217,24 @@
#endif
+#ifdef WITH_THREAD
+#define GIL_REQUEST _Py_atomic_load_relaxed(&gil_drop_request)
+#else
+#define GIL_REQUEST 0
+#endif
+
/* This can set eval_breaker to 0 even though gil_drop_request became
1. We believe this is all right because the eval loop will release
the GIL eventually anyway. */
#define COMPUTE_EVAL_BREAKER() \
_Py_atomic_store_relaxed( \
&eval_breaker, \
- _Py_atomic_load_relaxed(&gil_drop_request) | \
+ GIL_REQUEST | \
_Py_atomic_load_relaxed(&pendingcalls_to_do) | \
pending_async_exc)
+#ifdef WITH_THREAD
+
#define SET_GIL_DROP_REQUEST() \
do { \
_Py_atomic_store_relaxed(&gil_drop_request, 1); \
@@ -239,6 +247,8 @@
COMPUTE_EVAL_BREAKER(); \
} while (0)
+#endif
+
/* Pending calls are only modified under pending_lock */
#define SIGNAL_PENDING_CALLS() \
do { \
@@ -387,7 +397,6 @@
#else
static _Py_atomic_int eval_breaker = {0};
-static _Py_atomic_int gil_drop_request = {0};
static int pending_async_exc = 0;
#endif /* WITH_THREAD */
@@ -1277,8 +1286,8 @@
goto on_error;
}
}
- if (_Py_atomic_load_relaxed(&gil_drop_request)) {
#ifdef WITH_THREAD
+ if (_Py_atomic_load_relaxed(&gil_drop_request)) {
/* Give another thread a chance */
if (PyThreadState_Swap(NULL) != tstate)
Py_FatalError("ceval: tstate mix-up");
@@ -1289,8 +1298,8 @@
take_gil(tstate);
if (PyThreadState_Swap(tstate) != NULL)
Py_FatalError("ceval: orphan tstate");
-#endif
}
+#endif
/* Check for asynchronous exceptions. */
if (tstate->async_exc != NULL) {
x = tstate->async_exc;
From python-checkins at python.org Sat Sep 11 01:13:52 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 01:13:52 +0200 (CEST)
Subject: [Python-checkins] r84694 - python/branches/py3k/Modules/main.c
Message-ID: <20100910231352.45E6EEE98A@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 01:13:52 2010
New Revision: 84694
Log:
Issue #8589: surrogateescape error handler is not available at startup
Py_Main() uses _Py_wchar2char() + PyUnicode_FromWideChar() instead of
PyUnicode_DecodeFSDefault(), because the PyCodec machinery is not ready yet.
Modified:
python/branches/py3k/Modules/main.c
Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c (original)
+++ python/branches/py3k/Modules/main.c Sat Sep 11 01:13:52 2010
@@ -488,7 +488,8 @@
#else
if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
char *buf, *oldloc;
- PyObject *warning;
+ wchar_t *wchar;
+ PyObject *unicode;
/* settle for strtok here as there's no one standard
C89 wcstok */
@@ -500,11 +501,15 @@
oldloc = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, "");
for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
- warning = PyUnicode_DecodeFSDefault(p);
- if (warning != NULL) {
- PySys_AddWarnOptionUnicode(warning);
- Py_DECREF(warning);
- }
+ wchar = _Py_char2wchar(p);
+ if (wchar == NULL)
+ continue;
+ unicode = PyUnicode_FromWideChar(wchar, wcslen(wchar));
+ PyMem_Free(wchar);
+ if (unicode == NULL)
+ continue;
+ PySys_AddWarnOptionUnicode(unicode);
+ Py_DECREF(unicode);
}
setlocale(LC_ALL, oldloc);
free(oldloc);
From python-checkins at python.org Sat Sep 11 01:35:52 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 01:35:52 +0200 (CEST)
Subject: [Python-checkins] r84695 - python/branches/py3k/Lib/functools.py
Message-ID: <20100910233552.58F97EE9CA@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 01:35:52 2010
New Revision: 84695
Log:
add reduce and partial to __all__
Modified:
python/branches/py3k/Lib/functools.py
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Sat Sep 11 01:35:52 2010
@@ -9,7 +9,7 @@
# See C source code for _functools credits/copyright
__all__ = ['update_wrapper', 'wraps', 'WRAPPER_ASSIGNMENTS', 'WRAPPER_UPDATES',
- 'total_ordering', 'cmp_to_key', 'lru_cache']
+ 'total_ordering', 'cmp_to_key', 'lru_cache', 'reduce', 'partial']
from _functools import partial, reduce
from collections import OrderedDict
From python-checkins at python.org Sat Sep 11 01:49:05 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 01:49:05 +0200 (CEST)
Subject: [Python-checkins] r84696 - in python/branches/py3k: Misc/NEWS
Modules/posixmodule.c
Message-ID: <20100910234905.00C70EEA0E@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 01:49:04 2010
New Revision: 84696
Log:
Issue #9579, #9580: Fix os.confstr() for value longer than 255 bytes and encode
the value with filesystem encoding and surrogateescape (instead of utf-8 in
strict mode).
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/posixmodule.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 11 01:49:04 2010
@@ -29,6 +29,10 @@
Library
-------
+- Issue #9579, #9580: Fix os.confstr() for value longer than 255 bytes and
+ encode the value with filesystem encoding and surrogateescape (instead of
+ utf-8 in strict mode).
+
- Issue #9632: Remove sys.setfilesystemencoding() function: use
PYTHONFSENCODING environment variable to set the filesystem encoding at
Python startup. sys.setfilesystemencoding() creates inconsistencies because
Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Sat Sep 11 01:49:04 2010
@@ -6721,32 +6721,34 @@
{
PyObject *result = NULL;
int name;
- char buffer[256];
-
- if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
+ char buffer[255];
int len;
- errno = 0;
- len = confstr(name, buffer, sizeof(buffer));
- if (len == 0) {
- if (errno) {
- posix_error();
- }
- else {
- result = Py_None;
- Py_INCREF(Py_None);
- }
+ if (!PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name))
+ return NULL;
+
+ errno = 0;
+ len = confstr(name, buffer, sizeof(buffer));
+ if (len == 0) {
+ if (errno) {
+ posix_error();
+ return NULL;
}
else {
- if ((unsigned int)len >= sizeof(buffer)) {
- result = PyUnicode_FromStringAndSize(NULL, len-1);
- if (result != NULL)
- confstr(name, _PyUnicode_AsString(result), len);
- }
- else
- result = PyUnicode_FromStringAndSize(buffer, len-1);
+ Py_RETURN_NONE;
}
}
+
+ if ((unsigned int)len >= sizeof(buffer)) {
+ char *buf = PyMem_Malloc(len);
+ if (buf == NULL)
+ return PyErr_NoMemory();
+ confstr(name, buf, len);
+ result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
+ PyMem_Free(buf);
+ }
+ else
+ result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
return result;
}
#endif
From python-checkins at python.org Sat Sep 11 01:50:31 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 01:50:31 +0200 (CEST)
Subject: [Python-checkins] r84697 - python/branches/py3k/Misc/NEWS
Message-ID: <20100910235031.8D601EE990@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 01:50:31 2010
New Revision: 84697
Log:
Issue #9579, #9580: Oops, add the author of the patch
Modified:
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 11 01:50:31 2010
@@ -31,7 +31,7 @@
- Issue #9579, #9580: Fix os.confstr() for value longer than 255 bytes and
encode the value with filesystem encoding and surrogateescape (instead of
- utf-8 in strict mode).
+ utf-8 in strict mode). Patch written by David Watson.
- Issue #9632: Remove sys.setfilesystemencoding() function: use
PYTHONFSENCODING environment variable to set the filesystem encoding at
From python-checkins at python.org Sat Sep 11 01:52:42 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 01:52:42 +0200 (CEST)
Subject: [Python-checkins] r84698 - python/branches/py3k/Python/ceval.c
Message-ID: <20100910235242.68E2AEE990@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 01:52:42 2010
New Revision: 84698
Log:
use Py_REFCNT
Modified:
python/branches/py3k/Python/ceval.c
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Sat Sep 11 01:52:42 2010
@@ -4394,7 +4394,7 @@
return NULL;
}
- if (v->ob_refcnt == 2) {
+ if (Py_REFCNF(v) == 2) {
/* In the common case, there are 2 references to the value
* stored in 'variable' when the += is performed: one on the
* value stack (in 'v') and one still stored in the
@@ -4435,7 +4435,7 @@
}
}
- if (v->ob_refcnt == 1 && !PyUnicode_CHECK_INTERNED(v)) {
+ if (Py_REFCNF(v) == 1 && !PyUnicode_CHECK_INTERNED(v)) {
/* Now we own the last reference to 'v', so we can resize it
* in-place.
*/
From python-checkins at python.org Sat Sep 11 01:53:15 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 01:53:15 +0200 (CEST)
Subject: [Python-checkins] r84699 - python/branches/py3k/Python/ceval.c
Message-ID: <20100910235315.12003EE990@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 01:53:14 2010
New Revision: 84699
Log:
typo
Modified:
python/branches/py3k/Python/ceval.c
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Sat Sep 11 01:53:14 2010
@@ -4394,7 +4394,7 @@
return NULL;
}
- if (Py_REFCNF(v) == 2) {
+ if (Py_REFCNT(v) == 2) {
/* In the common case, there are 2 references to the value
* stored in 'variable' when the += is performed: one on the
* value stack (in 'v') and one still stored in the
@@ -4435,7 +4435,7 @@
}
}
- if (Py_REFCNF(v) == 1 && !PyUnicode_CHECK_INTERNED(v)) {
+ if (Py_REFCNT(v) == 1 && !PyUnicode_CHECK_INTERNED(v)) {
/* Now we own the last reference to 'v', so we can resize it
* in-place.
*/
From python-checkins at python.org Sat Sep 11 02:05:45 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sat, 11 Sep 2010 02:05:45 +0200 (CEST)
Subject: [Python-checkins] r84700 - in python/branches/py3k/Lib:
collections.py functools.py
Message-ID: <20100911000545.1D4A9EEA16@mail.python.org>
Author: raymond.hettinger
Date: Sat Sep 11 02:05:44 2010
New Revision: 84700
Log:
Separate positional arguments from localized globals.
Modified:
python/branches/py3k/Lib/collections.py
python/branches/py3k/Lib/functools.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Sat Sep 11 02:05:44 2010
@@ -47,7 +47,7 @@
self.__map = {}
self.update(*args, **kwds)
- def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
+ def __setitem__(self, key, value, *, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link which goes at the end of the linked
# list, and the inherited dictionary is updated with the new key/value pair.
@@ -57,7 +57,7 @@
last[NEXT] = root[PREV] = self.__map[key] = [last, root, key]
dict_setitem(self, key, value)
- def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
+ def __delitem__(self, key, *, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
# Deleting an existing item uses self.__map to find the link which is
# then removed by updating the links in the predecessor and successor nodes.
@@ -68,7 +68,7 @@
link_prev[NEXT] = link_next
link_next[PREV] = link_prev
- def __iter__(self, NEXT=1, KEY=2):
+ def __iter__(self, *, NEXT=1, KEY=2):
'od.__iter__() <==> iter(od)'
# Traverse the linked list in order.
root = self.__root
@@ -77,7 +77,7 @@
yield curr[KEY]
curr = curr[NEXT]
- def __reversed__(self, PREV=0, KEY=2):
+ def __reversed__(self, *, PREV=0, KEY=2):
'od.__reversed__() <==> reversed(od)'
# Traverse the linked list in reverse order.
root = self.__root
@@ -108,7 +108,7 @@
pass
dict.clear(self)
- def popitem(self, last=True, PREV=0, NEXT=1, KEY=2, dict_pop=dict.pop):
+ def popitem(self, last=True, *, PREV=0, NEXT=1, KEY=2, dict_pop=dict.pop):
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
Pairs are returned in LIFO order if last is true or FIFO order if false.
@@ -173,7 +173,7 @@
def __del__(self):
self.clear() # eliminate cyclical references
- def move_to_end(self, key, last=True, PREV=0, NEXT=1):
+ def move_to_end(self, key, last=True, *, PREV=0, NEXT=1):
'''Move an existing element to the end (or beginning if last==False).
Raises KeyError if the element does not exist.
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Sat Sep 11 02:05:44 2010
@@ -123,8 +123,8 @@
http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
"""
- def decorating_function(user_function, tuple=tuple, sorted=sorted,
- len=len, KeyError=KeyError):
+ def decorating_function(user_function,
+ *, tuple=tuple, sorted=sorted, len=len, KeyError=KeyError):
cache = OrderedDict() # ordered least recent to most recent
cache_popitem = cache.popitem
cache_renew = cache.move_to_end
From python-checkins at python.org Sat Sep 11 02:22:12 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 02:22:12 +0200 (CEST)
Subject: [Python-checkins] r84701 -
python/branches/py3k/Doc/library/os.path.rst
Message-ID: <20100911002212.2E5EFEEA30@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 02:22:12 2010
New Revision: 84701
Log:
Issue #767645: fix os.path.supports_unicode_filenames definition
os.listdir(str) always returns unicode and it can return non-ascii filenames
even if supports_unicode_filenames is False.
Modified:
python/branches/py3k/Doc/library/os.path.rst
Modified: python/branches/py3k/Doc/library/os.path.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.path.rst (original)
+++ python/branches/py3k/Doc/library/os.path.rst Sat Sep 11 02:22:12 2010
@@ -320,5 +320,4 @@
.. data:: supports_unicode_filenames
True if arbitrary Unicode strings can be used as file names (within limitations
- imposed by the file system), and if :func:`os.listdir` returns strings that
- contain characters that cannot be represented by ASCII.
+ imposed by the file system).
From python-checkins at python.org Sat Sep 11 02:23:53 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 02:23:53 +0200 (CEST)
Subject: [Python-checkins] r84702 - in python/branches/release31-maint:
Doc/library/os.path.rst
Message-ID: <20100911002353.47BD9EEA3A@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 02:23:53 2010
New Revision: 84702
Log:
Merged revisions 84701 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84701 | victor.stinner | 2010-09-11 02:22:12 +0200 (sam., 11 sept. 2010) | 5 lines
Issue #767645: fix os.path.supports_unicode_filenames definition
os.listdir(str) always returns unicode and it can return non-ascii filenames
even if supports_unicode_filenames is False.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/library/os.path.rst
Modified: python/branches/release31-maint/Doc/library/os.path.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/os.path.rst (original)
+++ python/branches/release31-maint/Doc/library/os.path.rst Sat Sep 11 02:23:53 2010
@@ -308,5 +308,4 @@
.. data:: supports_unicode_filenames
True if arbitrary Unicode strings can be used as file names (within limitations
- imposed by the file system), and if :func:`os.listdir` returns strings that
- contain characters that cannot be represented by ASCII.
+ imposed by the file system).
From ncoghlan at gmail.com Sat Sep 11 02:28:11 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Sat, 11 Sep 2010 10:28:11 +1000
Subject: [Python-checkins] r84685 - in python/branches/py3k:
Doc/library/dis.rst Doc/reference/simple_stmts.rst Doc/whatsnew/3.2.rst
Include/opcode.h Lib/opcode.py Lib/test/test_exceptions.py
Lib/test/test_scope.py Lib/test/test_syntax.py Misc/NEWS Python
Message-ID:
On Sat, Sep 11, 2010 at 7:39 AM, amaury.forgeotdarc
wrote:
> There is no need to bump the PYC magic number: the new opcode is used
> for code that did not compile before.
If the magic number doesn't change for 3.2, how will 3.1 know it can't
run pyc and pyo files containing these opcodes?
The magic number needs a bump or this change may cause SystemErrors
when older versions attempt to run affected pyc files.
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From benjamin at python.org Sat Sep 11 02:33:10 2010
From: benjamin at python.org (Benjamin Peterson)
Date: Fri, 10 Sep 2010 19:33:10 -0500
Subject: [Python-checkins] r84685 - in python/branches/py3k:
Doc/library/dis.rst Doc/reference/simple_stmts.rst Doc/whatsnew/3.2.rst
Include/opcode.h Lib/opcode.py Lib/test/test_exceptions.py
Lib/test/test_scope.py Lib/test/test_syntax.py Misc/NEWS Python
In-Reply-To:
References:
Message-ID:
2010/9/10 Nick Coghlan :
> On Sat, Sep 11, 2010 at 7:39 AM, amaury.forgeotdarc
> wrote:
>> There is no need to bump the PYC magic number: the new opcode is used
>> for code that did not compile before.
>
> If the magic number doesn't change for 3.2, how will 3.1 know it can't
> run pyc and pyo files containing these opcodes?
The magic number is already bumped since 3.1. However, it's true that
the number should be bumped anyway for good measure.
--
Regards,
Benjamin
From python-checkins at python.org Sat Sep 11 02:39:25 2010
From: python-checkins at python.org (nick.coghlan)
Date: Sat, 11 Sep 2010 02:39:25 +0200 (CEST)
Subject: [Python-checkins] r84703 - python/branches/py3k/Python/import.c
Message-ID: <20100911003925.28CDAD2F3@mail.python.org>
Author: nick.coghlan
Date: Sat Sep 11 02:39:25 2010
New Revision: 84703
Log:
Fix incorrect comment regarding MAGIC and TAG in import.c
Modified:
python/branches/py3k/Python/import.c
Modified: python/branches/py3k/Python/import.c
==============================================================================
--- python/branches/py3k/Python/import.c (original)
+++ python/branches/py3k/Python/import.c Sat Sep 11 02:39:25 2010
@@ -108,8 +108,11 @@
Python 3.2a2 3180 (add DELETE_DEREF)
*/
-/* If you change MAGIC, you must change TAG and you must insert the old value
- into _PyMagicNumberTags below.
+/* MAGIC must change whenever the bytecode emitted by the compiler may no
+ longer be understood by older implementations of the eval loop (usually
+ due to the addition of new opcodes)
+ TAG must change for each major Python release. The magic number will take
+ care of any bytecode changes that occur during development.
*/
#define MAGIC (3180 | ((long)'\r'<<16) | ((long)'\n'<<24))
#define TAG "cpython-32"
From ncoghlan at gmail.com Sat Sep 11 02:43:14 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Sat, 11 Sep 2010 10:43:14 +1000
Subject: [Python-checkins] r84685 - in python/branches/py3k:
Doc/library/dis.rst Doc/reference/simple_stmts.rst Doc/whatsnew/3.2.rst
Include/opcode.h Lib/opcode.py Lib/test/test_exceptions.py
Lib/test/test_scope.py Lib/test/test_syntax.py Misc/NEWS Python
In-Reply-To:
References:
Message-ID:
On Sat, Sep 11, 2010 at 10:33 AM, Benjamin Peterson wrote:
> 2010/9/10 Nick Coghlan :
>> On Sat, Sep 11, 2010 at 7:39 AM, amaury.forgeotdarc
>> wrote:
>>> There is no need to bump the PYC magic number: the new opcode is used
>>> for code that did not compile before.
>>
>> If the magic number doesn't change for 3.2, how will 3.1 know it can't
>> run pyc and pyo files containing these opcodes?
>
> The magic number is already bumped since 3.1. However, it's true that
> the number should be bumped anyway for good measure.
Yeah, I saw your subsequent checkin. I've updated the comment just
above MAGIC and TAG to make it clearer when they should be changed.
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From python-checkins at python.org Sat Sep 11 02:54:47 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 02:54:47 +0200 (CEST)
Subject: [Python-checkins] r84704 - in python/branches/py3k:
Doc/c-api/exceptions.rst Doc/c-api/unicode.rst
Include/pyerrors.h Include/unicodeobject.h
Lib/test/test_unicode.py Misc/NEWS Modules/_testcapimodule.c
Objects/unicodeobject.c
Message-ID: <20100911005447.60845EE9D7@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 02:54:47 2010
New Revision: 84704
Log:
Issue #9738: PyUnicode_FromFormat() and PyErr_Format() raise an error on
a non-ASCII byte in the format string.
Document also the encoding.
Modified:
python/branches/py3k/Doc/c-api/exceptions.rst
python/branches/py3k/Doc/c-api/unicode.rst
python/branches/py3k/Include/pyerrors.h
python/branches/py3k/Include/unicodeobject.h
python/branches/py3k/Lib/test/test_unicode.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/_testcapimodule.c
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Doc/c-api/exceptions.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/exceptions.rst (original)
+++ python/branches/py3k/Doc/c-api/exceptions.rst Sat Sep 11 02:54:47 2010
@@ -146,7 +146,7 @@
.. cfunction:: PyObject* PyErr_Format(PyObject *exception, const char *format, ...)
This function sets the error indicator and returns *NULL*. *exception* should be
- a Python exception (class, not an instance). *format* should be a string,
+ a Python exception (class, not an instance). *format* should be an ASCII-encoded string,
containing format codes, similar to :cfunc:`printf`. The ``width.precision``
before a format code is parsed, but the width part is ignored.
Modified: python/branches/py3k/Doc/c-api/unicode.rst
==============================================================================
--- python/branches/py3k/Doc/c-api/unicode.rst (original)
+++ python/branches/py3k/Doc/c-api/unicode.rst Sat Sep 11 02:54:47 2010
@@ -234,7 +234,7 @@
arguments, calculate the size of the resulting Python unicode string and return
a string with the values formatted into it. The variable arguments must be C
types and must correspond exactly to the format characters in the *format*
- string. The following format characters are allowed:
+ ASCII-encoded string. The following format characters are allowed:
.. % This should be exactly the same as the table in PyErr_Format.
.. % The descriptions for %zd and %zu are wrong, but the truth is complicated
Modified: python/branches/py3k/Include/pyerrors.h
==============================================================================
--- python/branches/py3k/Include/pyerrors.h (original)
+++ python/branches/py3k/Include/pyerrors.h Sat Sep 11 02:54:47 2010
@@ -183,7 +183,11 @@
PyObject *, const Py_UNICODE *);
#endif /* MS_WINDOWS */
-PyAPI_FUNC(PyObject *) PyErr_Format(PyObject *, const char *, ...);
+PyAPI_FUNC(PyObject *) PyErr_Format(
+ PyObject *exception,
+ const char *format, /* ASCII-encoded string */
+ ...
+ );
#ifdef MS_WINDOWS
PyAPI_FUNC(PyObject *) PyErr_SetFromWindowsErrWithFilenameObject(
Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h (original)
+++ python/branches/py3k/Include/unicodeobject.h Sat Sep 11 02:54:47 2010
@@ -550,8 +550,14 @@
register PyObject *obj /* Object */
);
-PyAPI_FUNC(PyObject *) PyUnicode_FromFormatV(const char*, va_list);
-PyAPI_FUNC(PyObject *) PyUnicode_FromFormat(const char*, ...);
+PyAPI_FUNC(PyObject *) PyUnicode_FromFormatV(
+ const char *format, /* ASCII-encoded string */
+ va_list vargs
+ );
+PyAPI_FUNC(PyObject *) PyUnicode_FromFormat(
+ const char *format, /* ASCII-encoded string */
+ ...
+ );
/* Format the object based on the format_spec, as defined in PEP 3101
(Advanced String Formatting). */
Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py (original)
+++ python/branches/py3k/Lib/test/test_unicode.py Sat Sep 11 02:54:47 2010
@@ -1385,6 +1385,20 @@
self.assertEquals("%s" % s, '__str__ overridden')
self.assertEquals("{}".format(s), '__str__ overridden')
+ def test_from_format(self):
+ # Ensure that PyUnicode_FromFormat() raises an error for a non-ascii
+ # format string.
+ from _testcapi import format_unicode
+
+ # ascii format, non-ascii argument
+ text = format_unicode(b'ascii\x7f=%U', 'unicode\xe9')
+ self.assertEqual(text, 'ascii\x7f=unicode\xe9')
+
+ # non-ascii format, ascii argument
+ self.assertRaisesRegexp(ValueError,
+ '^PyUnicode_FromFormatV\(\) expects an ASCII-encoded format '
+ 'string, got a non-ascii byte: 0xe9$',
+ format_unicode, b'unicode\xe9=%s', 'ascii')
def test_main():
support.run_unittest(__name__)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 11 02:54:47 2010
@@ -10,6 +10,9 @@
Core and Builtins
-----------------
+- Issue #9738: PyUnicode_FromFormat() and PyErr_Format() raise an error on
+ a non-ASCII byte in the format string.
+
- Issue #4617: Previously it was illegal to delete a name from the local
namespace if it occurs as a free variable in a nested block. This limitation
of the compiler has been lifted, and a new opcode introduced (DELETE_DEREF).
Modified: python/branches/py3k/Modules/_testcapimodule.c
==============================================================================
--- python/branches/py3k/Modules/_testcapimodule.c (original)
+++ python/branches/py3k/Modules/_testcapimodule.c Sat Sep 11 02:54:47 2010
@@ -2193,6 +2193,17 @@
return NULL;
}
+static PyObject *
+format_unicode(PyObject *self, PyObject *args)
+{
+ const char *format;
+ PyObject *arg;
+ if (!PyArg_ParseTuple(args, "yU", &format, &arg))
+ return NULL;
+ return PyUnicode_FromFormat(format, arg);
+
+}
+
static PyMethodDef TestMethods[] = {
{"raise_exception", raise_exception, METH_VARARGS},
{"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS},
@@ -2272,6 +2283,7 @@
{"make_exception_with_doc", (PyCFunction)make_exception_with_doc,
METH_VARARGS | METH_KEYWORDS},
{"crash_no_current_thread", (PyCFunction)crash_no_current_thread, METH_NOARGS},
+ {"format_unicode", format_unicode, METH_VARARGS},
{NULL, NULL} /* sentinel */
};
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Sat Sep 11 02:54:47 2010
@@ -1102,7 +1102,15 @@
appendstring(p);
goto end;
}
- } else
+ }
+ else if (128 <= (unsigned char)*f) {
+ PyErr_Format(PyExc_ValueError,
+ "PyUnicode_FromFormatV() expects an ASCII-encoded format "
+ "string, got a non-ascii byte: 0x%02x",
+ (unsigned char)*f);
+ goto fail;
+ }
+ else
*s++ = *f;
}
From solipsis at pitrou.net Sat Sep 11 05:12:04 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Sat, 11 Sep 2010 05:12:04 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84704): sum=6
Message-ID:
py3k results for svn r84704 (hg cset 4ffcca0d1896)
--------------------------------------------------
test_unicode leaked [2, 2, 2] references, sum=6
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflog8l0wn3', '-x']
From python-checkins at python.org Sat Sep 11 08:39:58 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 11 Sep 2010 08:39:58 +0200 (CEST)
Subject: [Python-checkins] r84705 - in python/branches/py3k: .bzrignore
.hgignore Modules
Message-ID: <20100911063958.6E9D1EEA04@mail.python.org>
Author: georg.brandl
Date: Sat Sep 11 08:39:58 2010
New Revision: 84705
Log:
Add new generated file to ignoreds.
Modified:
python/branches/py3k/.bzrignore
python/branches/py3k/.hgignore
python/branches/py3k/Modules/ (props changed)
Modified: python/branches/py3k/.bzrignore
==============================================================================
--- python/branches/py3k/.bzrignore (original)
+++ python/branches/py3k/.bzrignore Sat Sep 11 08:39:58 2010
@@ -30,6 +30,7 @@
Modules/Setup.config
Modules/Setup.local
Modules/config.c
+Modules/ld_so_aix
Parser/pgen
Parser/pgen.stamp
Lib/test/data/*
Modified: python/branches/py3k/.hgignore
==============================================================================
--- python/branches/py3k/.hgignore (original)
+++ python/branches/py3k/.hgignore Sat Sep 11 08:39:58 2010
@@ -29,6 +29,7 @@
Modules/Setup.config
Modules/Setup.local
Modules/config.c
+Modules/ld_so_aix$
Parser/pgen$
Parser/pgen.stamp$
^core
From python-checkins at python.org Sat Sep 11 08:41:30 2010
From: python-checkins at python.org (georg.brandl)
Date: Sat, 11 Sep 2010 08:41:30 +0200 (CEST)
Subject: [Python-checkins] r84706 - python/branches/py3k/Modules/pyexpat.c
Message-ID: <20100911064130.967ACEE990@mail.python.org>
Author: georg.brandl
Date: Sat Sep 11 08:41:30 2010
New Revision: 84706
Log:
Remove compatibility code for Python < 2.1, < 2.2 and < 2.4.
Modified:
python/branches/py3k/Modules/pyexpat.c
Modified: python/branches/py3k/Modules/pyexpat.c
==============================================================================
--- python/branches/py3k/Modules/pyexpat.c (original)
+++ python/branches/py3k/Modules/pyexpat.c Sat Sep 11 08:41:30 2010
@@ -258,11 +258,7 @@
value = Py_None;
Py_INCREF(value);
}
-#if PY_VERSION_HEX < 0x02040000
- arg = Py_BuildValue("(OOO)", type, value, traceback);
-#else
arg = PyTuple_Pack(3, type, value, traceback);
-#endif
if (arg == NULL) {
PyErr_Restore(type, value, traceback);
return 0;
@@ -814,11 +810,7 @@
PyTuple_SET_ITEM(arg, 0, bytes);
-#if PY_VERSION_HEX < 0x02020000
- str = PyObject_CallObject(meth, arg);
-#else
str = PyObject_Call(meth, arg, NULL);
-#endif
if (str == NULL)
goto finally;
@@ -961,14 +953,7 @@
return NULL;
}
-#ifndef Py_TPFLAGS_HAVE_GC
- /* Python versions 2.0 and 2.1 */
- new_parser = PyObject_New(xmlparseobject, &Xmlparsetype);
-#else
- /* Python versions 2.2 and later */
new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
-#endif
-
if (new_parser == NULL)
return NULL;
new_parser->buffer_size = self->buffer_size;
@@ -983,11 +968,7 @@
new_parser->handlers = 0;
new_parser->intern = self->intern;
Py_XINCREF(new_parser->intern);
-#ifdef Py_TPFLAGS_HAVE_GC
PyObject_GC_Track(new_parser);
-#else
- PyObject_GC_Init(new_parser);
-#endif
if (self->buffer != NULL) {
new_parser->buffer = malloc(new_parser->buffer_size);
@@ -1158,12 +1139,7 @@
int i;
xmlparseobject *self;
-#ifdef Py_TPFLAGS_HAVE_GC
- /* Code for versions 2.2 and later */
self = PyObject_GC_New(xmlparseobject, &Xmlparsetype);
-#else
- self = PyObject_New(xmlparseobject, &Xmlparsetype);
-#endif
if (self == NULL)
return NULL;
@@ -1183,11 +1159,7 @@
}
self->intern = intern;
Py_XINCREF(self->intern);
-#ifdef Py_TPFLAGS_HAVE_GC
PyObject_GC_Track(self);
-#else
- PyObject_GC_Init(self);
-#endif
if (self->itself == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"XML_ParserCreate failed");
@@ -1216,11 +1188,7 @@
xmlparse_dealloc(xmlparseobject *self)
{
int i;
-#ifdef Py_TPFLAGS_HAVE_GC
PyObject_GC_UnTrack(self);
-#else
- PyObject_GC_Fini(self);
-#endif
if (self->itself != NULL)
XML_ParserFree(self->itself);
self->itself = NULL;
@@ -1240,13 +1208,7 @@
self->buffer = NULL;
}
Py_XDECREF(self->intern);
-#ifndef Py_TPFLAGS_HAVE_GC
- /* Code for versions 2.0 and 2.1 */
- PyObject_Del(self);
-#else
- /* Code for versions 2.2 and later. */
PyObject_GC_Del(self);
-#endif
}
static int
@@ -1571,11 +1533,7 @@
(getattrofunc)xmlparse_getattro, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
-#ifdef Py_TPFLAGS_HAVE_GC
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
-#else
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/
-#endif
Xmlparsetype__doc__, /* tp_doc - Documentation string */
(traverseproc)xmlparse_traverse, /* tp_traverse */
(inquiry)xmlparse_clear, /* tp_clear */
From python-checkins at python.org Sat Sep 11 10:07:42 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sat, 11 Sep 2010 10:07:42 +0200 (CEST)
Subject: [Python-checkins] r84707 - in python/branches/py3k/Lib:
collections.py functools.py
Message-ID: <20100911080742.5B6FEEEA58@mail.python.org>
Author: raymond.hettinger
Date: Sat Sep 11 10:07:42 2010
New Revision: 84707
Log:
Revert r84700 which had an unfortunate performance cost.
Modified:
python/branches/py3k/Lib/collections.py
python/branches/py3k/Lib/functools.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Sat Sep 11 10:07:42 2010
@@ -47,7 +47,7 @@
self.__map = {}
self.update(*args, **kwds)
- def __setitem__(self, key, value, *, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
+ def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link which goes at the end of the linked
# list, and the inherited dictionary is updated with the new key/value pair.
@@ -57,7 +57,7 @@
last[NEXT] = root[PREV] = self.__map[key] = [last, root, key]
dict_setitem(self, key, value)
- def __delitem__(self, key, *, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
+ def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
# Deleting an existing item uses self.__map to find the link which is
# then removed by updating the links in the predecessor and successor nodes.
@@ -68,7 +68,7 @@
link_prev[NEXT] = link_next
link_next[PREV] = link_prev
- def __iter__(self, *, NEXT=1, KEY=2):
+ def __iter__(self, NEXT=1, KEY=2):
'od.__iter__() <==> iter(od)'
# Traverse the linked list in order.
root = self.__root
@@ -77,7 +77,7 @@
yield curr[KEY]
curr = curr[NEXT]
- def __reversed__(self, *, PREV=0, KEY=2):
+ def __reversed__(self, PREV=0, KEY=2):
'od.__reversed__() <==> reversed(od)'
# Traverse the linked list in reverse order.
root = self.__root
@@ -108,7 +108,7 @@
pass
dict.clear(self)
- def popitem(self, last=True, *, PREV=0, NEXT=1, KEY=2, dict_pop=dict.pop):
+ def popitem(self, last=True, PREV=0, NEXT=1, KEY=2, dict_pop=dict.pop):
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
Pairs are returned in LIFO order if last is true or FIFO order if false.
@@ -173,7 +173,7 @@
def __del__(self):
self.clear() # eliminate cyclical references
- def move_to_end(self, key, last=True, *, PREV=0, NEXT=1):
+ def move_to_end(self, key, last=True, PREV=0, NEXT=1):
'''Move an existing element to the end (or beginning if last==False).
Raises KeyError if the element does not exist.
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Sat Sep 11 10:07:42 2010
@@ -123,8 +123,8 @@
http://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used
"""
- def decorating_function(user_function,
- *, tuple=tuple, sorted=sorted, len=len, KeyError=KeyError):
+ def decorating_function(user_function, tuple=tuple, sorted=sorted,
+ len=len, KeyError=KeyError):
cache = OrderedDict() # ordered least recent to most recent
cache_popitem = cache.popitem
cache_renew = cache.move_to_end
From python-checkins at python.org Sat Sep 11 11:06:21 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sat, 11 Sep 2010 11:06:21 +0200 (CEST)
Subject: [Python-checkins] r84708 -
python/branches/release27-maint/Lib/logging/__init__.py
Message-ID: <20100911090621.7E173EEA4F@mail.python.org>
Author: vinay.sajip
Date: Sat Sep 11 11:06:21 2010
New Revision: 84708
Log:
logging: Added threading interlock in basicConfig().
Modified:
python/branches/release27-maint/Lib/logging/__init__.py
Modified: python/branches/release27-maint/Lib/logging/__init__.py
==============================================================================
--- python/branches/release27-maint/Lib/logging/__init__.py (original)
+++ python/branches/release27-maint/Lib/logging/__init__.py Sat Sep 11 11:06:21 2010
@@ -1497,22 +1497,28 @@
using sys.stdout or sys.stderr), whereas FileHandler closes its stream
when the handler is closed.
"""
- if len(root.handlers) == 0:
- filename = kwargs.get("filename")
- if filename:
- mode = kwargs.get("filemode", 'a')
- hdlr = FileHandler(filename, mode)
- else:
- stream = kwargs.get("stream")
- hdlr = StreamHandler(stream)
- fs = kwargs.get("format", BASIC_FORMAT)
- dfs = kwargs.get("datefmt", None)
- fmt = Formatter(fs, dfs)
- hdlr.setFormatter(fmt)
- root.addHandler(hdlr)
- level = kwargs.get("level")
- if level is not None:
- root.setLevel(level)
+ # Add thread safety in case someone mistakenly calls
+ # basicConfig() from multiple threads
+ _acquireLock()
+ try:
+ if len(root.handlers) == 0:
+ filename = kwargs.get("filename")
+ if filename:
+ mode = kwargs.get("filemode", 'a')
+ hdlr = FileHandler(filename, mode)
+ else:
+ stream = kwargs.get("stream")
+ hdlr = StreamHandler(stream)
+ fs = kwargs.get("format", BASIC_FORMAT)
+ dfs = kwargs.get("datefmt", None)
+ fmt = Formatter(fs, dfs)
+ hdlr.setFormatter(fmt)
+ root.addHandler(hdlr)
+ level = kwargs.get("level")
+ if level is not None:
+ root.setLevel(level)
+ finally:
+ _releaseLock()
#---------------------------------------------------------------------------
# Utility functions at module level.
From python-checkins at python.org Sat Sep 11 12:25:28 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sat, 11 Sep 2010 12:25:28 +0200 (CEST)
Subject: [Python-checkins] r84709 - in python/branches:
py3k/Doc/library/logging.rst release27-maint/Doc/library/logging.rst
Message-ID: <20100911102528.49ACBEE9FE@mail.python.org>
Author: vinay.sajip
Date: Sat Sep 11 12:25:28 2010
New Revision: 84709
Log:
Issue #9827: clarified LogRecord documentation.
Modified:
python/branches/py3k/Doc/library/logging.rst
python/branches/release27-maint/Doc/library/logging.rst
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Sat Sep 11 12:25:28 2010
@@ -527,6 +527,7 @@
just "foo".
.. versionadded:: 3.1
+
The :class:`NullHandler` class was not present in previous versions, but is
now included, so that it need not be defined in library code.
@@ -736,7 +737,7 @@
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)
- would print something like ::
+ would print something like::
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
@@ -903,6 +904,7 @@
and 2.2.x, which do not include the :mod:`logging` package in the standard
library.
+.. _logger:
Logger Objects
--------------
@@ -1788,6 +1790,8 @@
the :meth:`makePickle` method and implementing your alternative there, as
well as adapting the above script to use your alternative serialization.
+.. _arbitrary-object-messages:
+
Using arbitrary objects as messages
-----------------------------------
@@ -2705,7 +2709,6 @@
specified, ``'%(message)s'`` is used. If no *datefmt* is specified, the
ISO8601 date format is used.
-
.. method:: format(record)
The record's attribute dictionary is used as the operand to a string
@@ -2781,32 +2784,70 @@
LogRecord Objects
-----------------
-:class:`LogRecord` instances are created every time something is logged. They
-contain all the information pertinent to the event being logged. The main
-information passed in is in msg and args, which are combined using msg % args to
-create the message field of the record. The record also includes information
-such as when the record was created, the source line where the logging call was
-made, and any exception information to be logged.
+:class:`LogRecord` instances are created automatically by the :class:`Logger`
+every time something is logged, and can be created manually via
+:func:`makeLogRecord` (for example, from a pickled event received over the
+wire).
.. class:: LogRecord(name, lvl, pathname, lineno, msg, args, exc_info, func=None)
- Returns an instance of :class:`LogRecord` initialized with interesting
- information. The *name* is the logger name; *lvl* is the numeric level;
- *pathname* is the absolute pathname of the source file in which the logging
- call was made; *lineno* is the line number in that file where the logging
- call is found; *msg* is the user-supplied message (a format string); *args*
- is the tuple which, together with *msg*, makes up the user message; and
- *exc_info* is the exception tuple obtained by calling :func:`sys.exc_info`
- (or :const:`None`, if no exception information is available). The *func* is
- the name of the function from which the logging call was made. If not
- specified, it defaults to ``None``.
+ Contains all the information pertinent to the event being logged.
+
+ The primary information is passed in :attr:`msg` and :attr:`args`, which
+ are combined using ``msg % args`` to create the :attr:`message` field of the
+ record.
+
+ .. attribute:: args
+
+ Tuple of arguments to be used in formatting :attr:`msg`.
+
+ .. attribute:: exc_info
+
+ Exception tuple (? la `sys.exc_info`) or `None` if no exception
+ information is availble.
+
+ .. attribute:: func
+
+ Name of the function of origin (i.e. in which the logging call was made).
+
+ .. attribute:: lineno
+ Line number in the source file of origin.
+
+ .. attribute:: lvl
+
+ Numeric logging level.
+
+ .. attribute:: message
+
+ Bound to the result of :meth:`getMessage` when
+ :meth:`Formatter.format(record)` is invoked.
+
+ .. attribute:: msg
+
+ User-supplied :ref:`format string` or arbitrary object
+ (see :ref:`arbitrary-object-messages`) used in :meth:`getMessage`.
+
+ .. attribute:: name
+
+ Name of the logger that emitted the record.
+
+ .. attribute:: pathname
+
+ Absolute pathname of the source file of origin.
.. method:: getMessage()
Returns the message for this :class:`LogRecord` instance after merging any
- user-supplied arguments with the message.
+ user-supplied arguments with the message. If the user-supplied message
+ argument to the logging call is not a string, :func:`str` is called on it to
+ convert it to a string. This allows use of user-defined classes as
+ messages, whose ``__str__`` method can return the actual format string to
+ be used.
+
+ .. versionchanged:: 2.5
+ *func* was added.
.. _logger-adapter:
Modified: python/branches/release27-maint/Doc/library/logging.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/logging.rst (original)
+++ python/branches/release27-maint/Doc/library/logging.rst Sat Sep 11 12:25:28 2010
@@ -730,7 +730,7 @@
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)
- would print something like ::
+ would print something like::
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
@@ -1679,6 +1679,8 @@
the :meth:`makePickle` method and implementing your alternative there, as
well as adapting the above script to use your alternative serialization.
+.. _arbitrary-object-messages:
+
Using arbitrary objects as messages
-----------------------------------
@@ -2562,6 +2564,8 @@
+-------------------------+-----------------------------------------------+
| ``%(process)d`` | Process ID (if available). |
+-------------------------+-----------------------------------------------+
+| ``%(processName)s`` | Process name (if available). |
++-------------------------+-----------------------------------------------+
| ``%(message)s`` | The logged message, computed as ``msg % |
| | args``. |
+-------------------------+-----------------------------------------------+
@@ -2573,11 +2577,10 @@
.. class:: Formatter([fmt[, datefmt]])
Returns a new instance of the :class:`Formatter` class. The instance is
- initialized with a format string for the message as a whole, as well as a format
- string for the date/time portion of a message. If no *fmt* is specified,
- ``'%(message)s'`` is used. If no *datefmt* is specified, the ISO8601 date format
- is used.
-
+ initialized with a format string for the message as a whole, as well as a
+ format string for the date/time portion of a message. If no *fmt* is
+ specified, ``'%(message)s'`` is used. If no *datefmt* is specified, the
+ ISO8601 date format is used.
.. method:: format(record)
@@ -2633,7 +2636,7 @@
Returns an instance of the :class:`Filter` class. If *name* is specified, it
names a logger which, together with its children, will have its events allowed
- through the filter. If no name is specified, allows every event.
+ through the filter. If *name* is the empty string, allows every event.
.. method:: filter(record)
@@ -2654,35 +2657,71 @@
LogRecord Objects
-----------------
-:class:`LogRecord` instances are created every time something is logged. They
-contain all the information pertinent to the event being logged. The main
-information passed in is in msg and args, which are combined using msg % args to
-create the message field of the record. The record also includes information
-such as when the record was created, the source line where the logging call was
-made, and any exception information to be logged.
-
-
-.. class:: LogRecord(name, lvl, pathname, lineno, msg, args, exc_info [, func])
-
- Returns an instance of :class:`LogRecord` initialized with interesting
- information. The *name* is the logger name; *lvl* is the numeric level;
- *pathname* is the absolute pathname of the source file in which the logging
- call was made; *lineno* is the line number in that file where the logging
- call is found; *msg* is the user-supplied message (a format string); *args*
- is the tuple which, together with *msg*, makes up the user message; and
- *exc_info* is the exception tuple obtained by calling :func:`sys.exc_info`
- (or :const:`None`, if no exception information is available). The *func* is
- the name of the function from which the logging call was made. If not
- specified, it defaults to ``None``.
+:class:`LogRecord` instances are created automatically by the :class:`Logger`
+every time something is logged, and can be created manually via
+:func:`makeLogRecord` (for example, from a pickled event received over the
+wire).
- .. versionchanged:: 2.5
- *func* was added.
+.. class::
+ LogRecord(name, lvl, pathname, lineno, msg, args, exc_info [, func=None])
+
+ Contains all the information pertinent to the event being logged.
+
+ The primary information is passed in :attr:`msg` and :attr:`args`, which
+ are combined using ``msg % args`` to create the :attr:`message` field of the
+ record.
+
+ .. attribute:: args
+
+ Tuple of arguments to be used in formatting :attr:`msg`.
+
+ .. attribute:: exc_info
+
+ Exception tuple (? la `sys.exc_info`) or `None` if no exception
+ information is availble.
+
+ .. attribute:: func
+
+ Name of the function of origin (i.e. in which the logging call was made).
+
+ .. attribute:: lineno
+
+ Line number in the source file of origin.
+
+ .. attribute:: lvl
+
+ Numeric logging level.
+
+ .. attribute:: message
+
+ Bound to the result of :meth:`getMessage` when
+ :meth:`Formatter.format(record)` is invoked.
+
+ .. attribute:: msg
+
+ User-supplied :ref:`format string` or arbitrary object
+ (see :ref:`arbitrary-object-messages`) used in :meth:`getMessage`.
+
+ .. attribute:: name
+
+ Name of the logger that emitted the record.
+
+ .. attribute:: pathname
+
+ Absolute pathname of the source file of origin.
.. method:: getMessage()
Returns the message for this :class:`LogRecord` instance after merging any
- user-supplied arguments with the message.
+ user-supplied arguments with the message. If the user-supplied message
+ argument to the logging call is not a string, :func:`str` is called on it to
+ convert it to a string. This allows use of user-defined classes as
+ messages, whose ``__str__`` method can return the actual format string to
+ be used.
+
+ .. versionchanged:: 2.5
+ *func* was added.
.. _logger-adapter:
From python-checkins at python.org Sat Sep 11 14:52:30 2010
From: python-checkins at python.org (victor.stinner)
Date: Sat, 11 Sep 2010 14:52:30 +0200 (CEST)
Subject: [Python-checkins] r84710 -
python/branches/py3k/Lib/test/test_unicode_file.py
Message-ID: <20100911125230.D3995EEA0E@mail.python.org>
Author: victor.stinner
Date: Sat Sep 11 14:52:30 2010
New Revision: 84710
Log:
Issue #9819: don't try to encode TESTFN_UNICODE on Windows
mbcs (Windows default filesystem encoding) is now strict by default, and
depending on the code page, TESTFN_UNICODE may not be encodable to bytes.
Remove also unused "encoded" argument from _do_directory() method.
Modified:
python/branches/py3k/Lib/test/test_unicode_file.py
Modified: python/branches/py3k/Lib/test/test_unicode_file.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode_file.py (original)
+++ python/branches/py3k/Lib/test/test_unicode_file.py Sat Sep 11 14:52:30 2010
@@ -8,12 +8,13 @@
from test.support import (run_unittest, rmtree,
TESTFN_ENCODING, TESTFN_UNICODE, TESTFN_UNENCODABLE)
-try:
- TESTFN_UNICODE.encode(TESTFN_ENCODING)
-except (UnicodeError, TypeError):
- # Either the file system encoding is None, or the file name
- # cannot be encoded in the file system encoding.
- raise unittest.SkipTest("No Unicode filesystem semantics on this platform.")
+if not os.path.supports_unicode_filenames:
+ try:
+ TESTFN_UNICODE.encode(TESTFN_ENCODING)
+ except (UnicodeError, TypeError):
+ # Either the file system encoding is None, or the file name
+ # cannot be encoded in the file system encoding.
+ raise unittest.SkipTest("No Unicode filesystem semantics on this platform.")
def remove_if_exists(filename):
if os.path.exists(filename):
@@ -90,7 +91,7 @@
shutil.copy2(filename1, filename2 + ".new")
os.unlink(filename1 + ".new")
- def _do_directory(self, make_name, chdir_name, encoded):
+ def _do_directory(self, make_name, chdir_name):
cwd = os.getcwdb()
if os.path.isdir(make_name):
rmtree(make_name)
@@ -98,12 +99,8 @@
try:
os.chdir(chdir_name)
try:
- if not encoded:
- cwd_result = os.getcwd()
- name_result = make_name
- else:
- cwd_result = os.getcwdb().decode(TESTFN_ENCODING)
- name_result = make_name.decode(TESTFN_ENCODING)
+ cwd_result = os.getcwd()
+ name_result = make_name
cwd_result = unicodedata.normalize("NFD", cwd_result)
name_result = unicodedata.normalize("NFD", name_result)
@@ -155,12 +152,11 @@
# Make dir with encoded, chdir with unicode, checkdir with encoded
# (or unicode/encoded/unicode, etc
ext = ".dir"
- self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext, False)
+ self._do_directory(TESTFN_UNICODE+ext, TESTFN_UNICODE+ext)
# Our directory name that can't use a non-unicode name.
if TESTFN_UNENCODABLE is not None:
self._do_directory(TESTFN_UNENCODABLE+ext,
- TESTFN_UNENCODABLE+ext,
- False)
+ TESTFN_UNENCODABLE+ext)
def test_main():
run_unittest(__name__)
From python-checkins at python.org Sat Sep 11 17:28:56 2010
From: python-checkins at python.org (eric.araujo)
Date: Sat, 11 Sep 2010 17:28:56 +0200 (CEST)
Subject: [Python-checkins] r84711 -
python/branches/py3k/Lib/distutils/command/sdist.py
Message-ID: <20100911152856.266D1EE981@mail.python.org>
Author: eric.araujo
Date: Sat Sep 11 17:28:56 2010
New Revision: 84711
Log:
Fix typo in option name
Modified:
python/branches/py3k/Lib/distutils/command/sdist.py
Modified: python/branches/py3k/Lib/distutils/command/sdist.py
==============================================================================
--- python/branches/py3k/Lib/distutils/command/sdist.py (original)
+++ python/branches/py3k/Lib/distutils/command/sdist.py Sat Sep 11 17:28:56 2010
@@ -73,7 +73,7 @@
('dist-dir=', 'd',
"directory to put the source distribution archive(s) in "
"[default: dist]"),
- ('medata-check', None,
+ ('metadata-check', None,
"Ensure that all required elements of meta-data "
"are supplied. Warn if any missing. [default]"),
]
From python-checkins at python.org Sat Sep 11 17:30:19 2010
From: python-checkins at python.org (eric.araujo)
Date: Sat, 11 Sep 2010 17:30:19 +0200 (CEST)
Subject: [Python-checkins] r84712 - in python/branches/release31-maint:
Lib/distutils/command/sdist.py
Message-ID: <20100911153019.BD167EE981@mail.python.org>
Author: eric.araujo
Date: Sat Sep 11 17:30:19 2010
New Revision: 84712
Log:
Merged revisions 84711 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84711 | eric.araujo | 2010-09-11 17:28:56 +0200 (sam., 11 sept. 2010) | 2 lines
Fix typo in option name
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/distutils/command/sdist.py
Modified: python/branches/release31-maint/Lib/distutils/command/sdist.py
==============================================================================
--- python/branches/release31-maint/Lib/distutils/command/sdist.py (original)
+++ python/branches/release31-maint/Lib/distutils/command/sdist.py Sat Sep 11 17:30:19 2010
@@ -73,7 +73,7 @@
('dist-dir=', 'd',
"directory to put the source distribution archive(s) in "
"[default: dist]"),
- ('medata-check', None,
+ ('metadata-check', None,
"Ensure that all required elements of meta-data "
"are supplied. Warn if any missing. [default]"),
]
From python-checkins at python.org Sat Sep 11 17:31:13 2010
From: python-checkins at python.org (eric.araujo)
Date: Sat, 11 Sep 2010 17:31:13 +0200 (CEST)
Subject: [Python-checkins] r84713 - in python/branches/release27-maint:
Lib/distutils/command/sdist.py
Message-ID: <20100911153113.8F169EE990@mail.python.org>
Author: eric.araujo
Date: Sat Sep 11 17:31:13 2010
New Revision: 84713
Log:
Merged revisions 84711 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84711 | eric.araujo | 2010-09-11 17:28:56 +0200 (sam., 11 sept. 2010) | 2 lines
Fix typo in option name
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/distutils/command/sdist.py
Modified: python/branches/release27-maint/Lib/distutils/command/sdist.py
==============================================================================
--- python/branches/release27-maint/Lib/distutils/command/sdist.py (original)
+++ python/branches/release27-maint/Lib/distutils/command/sdist.py Sat Sep 11 17:31:13 2010
@@ -73,7 +73,7 @@
('dist-dir=', 'd',
"directory to put the source distribution archive(s) in "
"[default: dist]"),
- ('medata-check', None,
+ ('metadata-check', None,
"Ensure that all required elements of meta-data "
"are supplied. Warn if any missing. [default]"),
('owner=', 'u',
From python-checkins at python.org Sat Sep 11 18:02:06 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 18:02:06 +0200 (CEST)
Subject: [Python-checkins] r84714 - in python/branches/py3k: Misc/NEWS
Objects/abstract.c
Message-ID: <20100911160206.5F45AEEA6A@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 18:02:03 2010
New Revision: 84714
Log:
check for NULL tp_as_mapping in PySequence_(Get/Set/Del)Slice #9834
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/abstract.c
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sat Sep 11 18:02:03 2010
@@ -108,6 +108,13 @@
guaranteed to exist in all Python implementations and the names of hash
algorithms available in the current process.
+C-API
+-----
+
+- Issue #9834: Don't segfault in PySequence_GetSlice, PySequence_SetSlice, or
+ PySequence_DelSlice when the object doesn't have any mapping operations
+ defined.
+
Tools/Demos
-----------
Modified: python/branches/py3k/Objects/abstract.c
==============================================================================
--- python/branches/py3k/Objects/abstract.c (original)
+++ python/branches/py3k/Objects/abstract.c Sat Sep 11 18:02:03 2010
@@ -1612,7 +1612,7 @@
if (!s) return null_error();
mp = s->ob_type->tp_as_mapping;
- if (mp->mp_subscript) {
+ if (mp && mp->mp_subscript) {
PyObject *res;
PyObject *slice = _PySlice_FromIndices(i1, i2);
if (!slice)
@@ -1690,7 +1690,7 @@
}
mp = s->ob_type->tp_as_mapping;
- if (mp->mp_ass_subscript) {
+ if (mp && mp->mp_ass_subscript) {
int res;
PyObject *slice = _PySlice_FromIndices(i1, i2);
if (!slice)
@@ -1715,7 +1715,7 @@
}
mp = s->ob_type->tp_as_mapping;
- if (mp->mp_ass_subscript) {
+ if (mp && mp->mp_ass_subscript) {
int res;
PyObject *slice = _PySlice_FromIndices(i1, i2);
if (!slice)
From python-checkins at python.org Sat Sep 11 18:03:34 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 18:03:34 +0200 (CEST)
Subject: [Python-checkins] r84715 - in python/branches/release31-maint:
Misc/NEWS Objects/abstract.c
Message-ID: <20100911160334.21157EEA5F@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 18:03:33 2010
New Revision: 84715
Log:
Merged revisions 84714 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84714 | benjamin.peterson | 2010-09-11 11:02:03 -0500 (Sat, 11 Sep 2010) | 1 line
check for NULL tp_as_mapping in PySequence_(Get/Set/Del)Slice #9834
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Objects/abstract.c
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Sat Sep 11 18:03:33 2010
@@ -105,6 +105,10 @@
C-API
-----
+- Issue #9834: Don't segfault in PySequence_GetSlice, PySequence_SetSlice, or
+ PySequence_DelSlice when the object doesn't have any mapping operations
+ defined.
+
- Issue #5753: A new C API function, :cfunc:`PySys_SetArgvEx`, allows
embedders of the interpreter to set sys.argv without also modifying
sys.path. This helps fix `CVE-2008-5983
Modified: python/branches/release31-maint/Objects/abstract.c
==============================================================================
--- python/branches/release31-maint/Objects/abstract.c (original)
+++ python/branches/release31-maint/Objects/abstract.c Sat Sep 11 18:03:33 2010
@@ -1623,7 +1623,7 @@
if (!s) return null_error();
mp = s->ob_type->tp_as_mapping;
- if (mp->mp_subscript) {
+ if (mp && mp->mp_subscript) {
PyObject *res;
PyObject *slice = _PySlice_FromIndices(i1, i2);
if (!slice)
@@ -1701,7 +1701,7 @@
}
mp = s->ob_type->tp_as_mapping;
- if (mp->mp_ass_subscript) {
+ if (mp && mp->mp_ass_subscript) {
int res;
PyObject *slice = _PySlice_FromIndices(i1, i2);
if (!slice)
@@ -1726,7 +1726,7 @@
}
mp = s->ob_type->tp_as_mapping;
- if (mp->mp_ass_subscript) {
+ if (mp && mp->mp_ass_subscript) {
int res;
PyObject *slice = _PySlice_FromIndices(i1, i2);
if (!slice)
From python-checkins at python.org Sat Sep 11 18:23:57 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 18:23:57 +0200 (CEST)
Subject: [Python-checkins] r84716 - in python/branches/release31-maint:
.bzrignore .hgignore Modules
Message-ID: <20100911162357.62697EEA4B@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 18:23:57 2010
New Revision: 84716
Log:
Merged revisions 84705 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84705 | georg.brandl | 2010-09-11 01:39:58 -0500 (Sat, 11 Sep 2010) | 1 line
Add new generated file to ignoreds.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/.bzrignore
python/branches/release31-maint/.hgignore
python/branches/release31-maint/Modules/ (props changed)
Modified: python/branches/release31-maint/.bzrignore
==============================================================================
--- python/branches/release31-maint/.bzrignore (original)
+++ python/branches/release31-maint/.bzrignore Sat Sep 11 18:23:57 2010
@@ -45,6 +45,7 @@
Modules/Setup.config
Modules/Setup.local
Modules/config.c
+Modules/ld_so_aix
Parser/pgen
Lib/lib2to3/Grammar*.pickle
Lib/lib2to3/PatternGrammar*.pickle
Modified: python/branches/release31-maint/.hgignore
==============================================================================
--- python/branches/release31-maint/.hgignore (original)
+++ python/branches/release31-maint/.hgignore Sat Sep 11 18:23:57 2010
@@ -48,7 +48,7 @@
Modules/config.c
Parser/pgen
core
-
+Modules/ld_so_aix$
syntax: glob
libpython*.a
*.o
From python-checkins at python.org Sat Sep 11 18:39:57 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 18:39:57 +0200 (CEST)
Subject: [Python-checkins] r84717 - python/branches/py3k/Objects/object.c
Message-ID: <20100911163957.8526DDF12@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 18:39:57 2010
New Revision: 84717
Log:
fix formatting
Modified:
python/branches/py3k/Objects/object.c
Modified: python/branches/py3k/Objects/object.c
==============================================================================
--- python/branches/py3k/Objects/object.c (original)
+++ python/branches/py3k/Objects/object.c Sat Sep 11 18:39:57 2010
@@ -479,13 +479,13 @@
result = PyObject_CallFunctionObjArgs(func, NULL);
Py_DECREF(func);
if (result == NULL)
- return NULL;
+ return NULL;
if (!PyBytes_Check(result)) {
- PyErr_Format(PyExc_TypeError,
- "__bytes__ returned non-bytes (type %.200s)",
- Py_TYPE(result)->tp_name);
- Py_DECREF(result);
- return NULL;
+ PyErr_Format(PyExc_TypeError,
+ "__bytes__ returned non-bytes (type %.200s)",
+ Py_TYPE(result)->tp_name);
+ Py_DECREF(result);
+ return NULL;
}
return result;
}
From python-checkins at python.org Sat Sep 11 18:40:47 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sat, 11 Sep 2010 18:40:47 +0200 (CEST)
Subject: [Python-checkins] r84718 - in python/branches/release31-maint:
Objects/object.c
Message-ID: <20100911164047.60155EE9A1@mail.python.org>
Author: benjamin.peterson
Date: Sat Sep 11 18:40:47 2010
New Revision: 84718
Log:
Merged revisions 84717 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84717 | benjamin.peterson | 2010-09-11 11:39:57 -0500 (Sat, 11 Sep 2010) | 1 line
fix formatting
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Objects/object.c
Modified: python/branches/release31-maint/Objects/object.c
==============================================================================
--- python/branches/release31-maint/Objects/object.c (original)
+++ python/branches/release31-maint/Objects/object.c Sat Sep 11 18:40:47 2010
@@ -479,13 +479,13 @@
result = PyObject_CallFunctionObjArgs(func, NULL);
Py_DECREF(func);
if (result == NULL)
- return NULL;
+ return NULL;
if (!PyBytes_Check(result)) {
- PyErr_Format(PyExc_TypeError,
- "__bytes__ returned non-bytes (type %.200s)",
- Py_TYPE(result)->tp_name);
- Py_DECREF(result);
- return NULL;
+ PyErr_Format(PyExc_TypeError,
+ "__bytes__ returned non-bytes (type %.200s)",
+ Py_TYPE(result)->tp_name);
+ Py_DECREF(result);
+ return NULL;
}
return result;
}
From python-checkins at python.org Sat Sep 11 20:12:25 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Sep 2010 20:12:25 +0200 (CEST)
Subject: [Python-checkins] r84719 -
python/branches/py3k/Doc/howto/doanddont.rst
Message-ID: <20100911181225.F0DD7EEA2E@mail.python.org>
Author: r.david.murray
Date: Sat Sep 11 20:12:25 2010
New Revision: 84719
Log:
#9608, #8512 : clarify and improve discussion of exceptions in howto.
Modified:
python/branches/py3k/Doc/howto/doanddont.rst
Modified: python/branches/py3k/Doc/howto/doanddont.rst
==============================================================================
--- python/branches/py3k/Doc/howto/doanddont.rst (original)
+++ python/branches/py3k/Doc/howto/doanddont.rst Sat Sep 11 20:12:25 2010
@@ -111,30 +111,40 @@
-------
Python has the ``except:`` clause, which catches all exceptions. Since *every*
-error in Python raises an exception, this makes many programming errors look
-like runtime problems, and hinders the debugging process.
+error in Python raises an exception, using ``except:`` can make many
+programming errors look like runtime problems, which hinders the debugging
+process.
-The following code shows a great example::
+The following code shows a great example of why this is bad::
try:
foo = opne("file") # misspelled "open"
except:
sys.exit("could not open file!")
-The second line triggers a :exc:`NameError` which is caught by the except
-clause. The program will exit, and you will have no idea that this has nothing
-to do with the readability of ``"file"``.
+The second line triggers a :exc:`NameError`, which is caught by the except
+clause. The program will exit, and the error message the program prints will
+make you think the problem is the readability of ``"file"`` when in fact
+the real error has nothing to do with ``"file"``.
-The example above is better written ::
+A better way to write the above is ::
try:
- foo = opne("file") # will be changed to "open" as soon as we run it
+ foo = opne("file")
except IOError:
sys.exit("could not open file")
-There are some situations in which the ``except:`` clause is useful: for
-example, in a framework when running callbacks, it is good not to let any
-callback disturb the framework.
+When this is run, Python will produce a traceback showing the :exc:`NameError`,
+and it will be immediately apparent what needs to be fixed.
+
+.. index:: bare except, except; bare
+
+Because ``except:`` catches *all* exceptions, including :exc:`SystemExit`,
+:exc:`KeyboardInterrupt`, and :exc:`GeneratorExit` (which is not an error and
+should not normally be caught by user code), using a bare ``except:`` is almost
+never a good idea. In situations where you need to catch all "normal" errors,
+such as in a framework that runs callbacks, you can catch the base class for
+all normal exceptions, :exc:`Exception`.
Exceptions
@@ -152,51 +162,60 @@
sys.exit(1)
return open(file).readline()
-Consider the case the file gets deleted between the time the call to
-:func:`os.path.exists` is made and the time :func:`open` is called. That means
-the last line will raise an :exc:`IOError`. The same would happen if *file*
-exists but has no read permission. Since testing this on a normal machine on
-existing and non-existing files make it seem bugless, that means in testing the
-results will seem fine, and the code will get shipped. Then an unhandled
-:exc:`IOError` escapes to the user, who has to watch the ugly traceback.
+Consider the case where the file gets deleted between the time the call to
+:func:`os.path.exists` is made and the time :func:`open` is called. In that
+case the last line will raise an :exc:`IOError`. The same thing would happen
+if *file* exists but has no read permission. Since testing this on a normal
+machine on existent and non-existent files makes it seem bugless, the test
+results will seem fine, and the code will get shipped. Later an unhandled
+:exc:`IOError` (or perhaps some other :exc:`EnvironmentError`) escapes to the
+user, who gets to watch the ugly traceback.
-Here is a better way to do it. ::
+Here is a somewhat better way to do it. ::
def get_status(file):
try:
return open(file).readline()
- except (IOError, OSError):
- print("file not found")
+ except EnvironmentError as err:
+ print("Unable to open file: {}".format(err))
sys.exit(1)
-In this version, \*either\* the file gets opened and the line is read (so it
-works even on flaky NFS or SMB connections), or the message is printed and the
-application aborted.
-
-Still, :func:`get_status` makes too many assumptions --- that it will only be
-used in a short running script, and not, say, in a long running server. Sure,
-the caller could do something like ::
+In this version, *either* the file gets opened and the line is read (so it
+works even on flaky NFS or SMB connections), or an error message is printed
+that provides all the available information on why the open failed, and the
+application is aborted.
+
+However, even this version of :func:`get_status` makes too many assumptions ---
+that it will only be used in a short running script, and not, say, in a long
+running server. Sure, the caller could do something like ::
try:
status = get_status(log)
except SystemExit:
status = None
-So, try to make as few ``except`` clauses in your code --- those will usually be
-a catch-all in the :func:`main`, or inside calls which should always succeed.
+But there is a better way. You should try to use as few ``except`` clauses in
+your code as you can --- the ones you do use will usually be inside calls which
+should always succeed, or a catch-all in a main function.
-So, the best version is probably ::
+So, an even better version of :func:`get_status()` is probably ::
def get_status(file):
return open(file).readline()
-The caller can deal with the exception if it wants (for example, if it tries
+The caller can deal with the exception if it wants (for example, if it tries
several files in a loop), or just let the exception filter upwards to *its*
caller.
-The last version is not very good either --- due to implementation details, the
-file would not be closed when an exception is raised until the handler finishes,
-and perhaps not at all in non-C implementations (e.g., Jython). ::
+But the last version still has a serious problem --- due to implementation
+details in CPython, the file would not be closed when an exception is raised
+until the exception handler finishes; and, worse, in other implementations
+(e.g., Jython) it might not be closed at all regardless of whether or not
+an exception is raised.
+
+The best version of this function uses the ``open()`` call as a context
+manager, which will ensure that the file gets closed as soon as the
+function returns::
def get_status(file):
with open(file) as fp:
From python-checkins at python.org Sat Sep 11 20:20:06 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Sep 2010 20:20:06 +0200 (CEST)
Subject: [Python-checkins] r84720 - in python/branches/release31-maint:
Doc/howto/doanddont.rst
Message-ID: <20100911182006.AF849EEA62@mail.python.org>
Author: r.david.murray
Date: Sat Sep 11 20:20:06 2010
New Revision: 84720
Log:
Merged revisions 84719 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84719 | r.david.murray | 2010-09-11 14:12:25 -0400 (Sat, 11 Sep 2010) | 2 lines
#9608, #8512 : clarify and improve discussion of exceptions in howto.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/howto/doanddont.rst
Modified: python/branches/release31-maint/Doc/howto/doanddont.rst
==============================================================================
--- python/branches/release31-maint/Doc/howto/doanddont.rst (original)
+++ python/branches/release31-maint/Doc/howto/doanddont.rst Sat Sep 11 20:20:06 2010
@@ -111,30 +111,40 @@
-------
Python has the ``except:`` clause, which catches all exceptions. Since *every*
-error in Python raises an exception, this makes many programming errors look
-like runtime problems, and hinders the debugging process.
+error in Python raises an exception, using ``except:`` can make many
+programming errors look like runtime problems, which hinders the debugging
+process.
-The following code shows a great example::
+The following code shows a great example of why this is bad::
try:
foo = opne("file") # misspelled "open"
except:
sys.exit("could not open file!")
-The second line triggers a :exc:`NameError` which is caught by the except
-clause. The program will exit, and you will have no idea that this has nothing
-to do with the readability of ``"file"``.
+The second line triggers a :exc:`NameError`, which is caught by the except
+clause. The program will exit, and the error message the program prints will
+make you think the problem is the readability of ``"file"`` when in fact
+the real error has nothing to do with ``"file"``.
-The example above is better written ::
+A better way to write the above is ::
try:
- foo = opne("file") # will be changed to "open" as soon as we run it
+ foo = opne("file")
except IOError:
sys.exit("could not open file")
-There are some situations in which the ``except:`` clause is useful: for
-example, in a framework when running callbacks, it is good not to let any
-callback disturb the framework.
+When this is run, Python will produce a traceback showing the :exc:`NameError`,
+and it will be immediately apparent what needs to be fixed.
+
+.. index:: bare except, except; bare
+
+Because ``except:`` catches *all* exceptions, including :exc:`SystemExit`,
+:exc:`KeyboardInterrupt`, and :exc:`GeneratorExit` (which is not an error and
+should not normally be caught by user code), using a bare ``except:`` is almost
+never a good idea. In situations where you need to catch all "normal" errors,
+such as in a framework that runs callbacks, you can catch the base class for
+all normal exceptions, :exc:`Exception`.
Exceptions
@@ -152,51 +162,60 @@
sys.exit(1)
return open(file).readline()
-Consider the case the file gets deleted between the time the call to
-:func:`os.path.exists` is made and the time :func:`open` is called. That means
-the last line will throw an :exc:`IOError`. The same would happen if *file*
-exists but has no read permission. Since testing this on a normal machine on
-existing and non-existing files make it seem bugless, that means in testing the
-results will seem fine, and the code will get shipped. Then an unhandled
-:exc:`IOError` escapes to the user, who has to watch the ugly traceback.
+Consider the case where the file gets deleted between the time the call to
+:func:`os.path.exists` is made and the time :func:`open` is called. In that
+case the last line will raise an :exc:`IOError`. The same thing would happen
+if *file* exists but has no read permission. Since testing this on a normal
+machine on existent and non-existent files makes it seem bugless, the test
+results will seem fine, and the code will get shipped. Later an unhandled
+:exc:`IOError` (or perhaps some other :exc:`EnvironmentError`) escapes to the
+user, who gets to watch the ugly traceback.
-Here is a better way to do it. ::
+Here is a somewhat better way to do it. ::
def get_status(file):
try:
return open(file).readline()
- except (IOError, OSError):
- print("file not found")
+ except EnvironmentError as err:
+ print("Unable to open file: {}".format(err))
sys.exit(1)
-In this version, \*either\* the file gets opened and the line is read (so it
-works even on flaky NFS or SMB connections), or the message is printed and the
-application aborted.
-
-Still, :func:`get_status` makes too many assumptions --- that it will only be
-used in a short running script, and not, say, in a long running server. Sure,
-the caller could do something like ::
+In this version, *either* the file gets opened and the line is read (so it
+works even on flaky NFS or SMB connections), or an error message is printed
+that provides all the available information on why the open failed, and the
+application is aborted.
+
+However, even this version of :func:`get_status` makes too many assumptions ---
+that it will only be used in a short running script, and not, say, in a long
+running server. Sure, the caller could do something like ::
try:
status = get_status(log)
except SystemExit:
status = None
-So, try to make as few ``except`` clauses in your code --- those will usually be
-a catch-all in the :func:`main`, or inside calls which should always succeed.
+But there is a better way. You should try to use as few ``except`` clauses in
+your code as you can --- the ones you do use will usually be inside calls which
+should always succeed, or a catch-all in a main function.
-So, the best version is probably ::
+So, an even better version of :func:`get_status()` is probably ::
def get_status(file):
return open(file).readline()
-The caller can deal with the exception if it wants (for example, if it tries
+The caller can deal with the exception if it wants (for example, if it tries
several files in a loop), or just let the exception filter upwards to *its*
caller.
-The last version is not very good either --- due to implementation details, the
-file would not be closed when an exception is raised until the handler finishes,
-and perhaps not at all in non-C implementations (e.g., Jython). ::
+But the last version still has a serious problem --- due to implementation
+details in CPython, the file would not be closed when an exception is raised
+until the exception handler finishes; and, worse, in other implementations
+(e.g., Jython) it might not be closed at all regardless of whether or not
+an exception is raised.
+
+The best version of this function uses the ``open()`` call as a context
+manager, which will ensure that the file gets closed as soon as the
+function returns::
def get_status(file):
with open(file) as fp:
From python-checkins at python.org Sat Sep 11 20:53:33 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Sep 2010 20:53:33 +0200 (CEST)
Subject: [Python-checkins] r84719 - svn:log
Message-ID: <20100911185333.9FB61EEA71@mail.python.org>
Author: r.david.murray
Revision: 84719
Property Name: svn:log
Action: modified
Property diff:
--- old property value
+++ new property value
@@ -1 +1 @@
-#9608, #8512 : clarify and improve discussion of exceptions in howto.
+#9608, #8518 : clarify and improve discussion of exceptions in howto.
From python-checkins at python.org Sat Sep 11 20:54:27 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Sep 2010 20:54:27 +0200 (CEST)
Subject: [Python-checkins] r84720 - svn:log
Message-ID: <20100911185427.36E75FA9F@mail.python.org>
Author: r.david.murray
Revision: 84720
Property Name: svn:log
Action: modified
Property diff:
--- old property value
+++ new property value
@@ -4,5 +4,5 @@
........
r84719 | r.david.murray | 2010-09-11 14:12:25 -0400 (Sat, 11 Sep 2010) | 2 lines
- #9608, #8512 : clarify and improve discussion of exceptions in howto.
+ #9608, #8518 : clarify and improve discussion of exceptions in howto.
........
From python-checkins at python.org Sat Sep 11 20:57:20 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Sep 2010 20:57:20 +0200 (CEST)
Subject: [Python-checkins] r84721 - in python/branches/release27-maint:
Doc/howto/doanddont.rst
Message-ID: <20100911185720.58FACEE9CA@mail.python.org>
Author: r.david.murray
Date: Sat Sep 11 20:57:20 2010
New Revision: 84721
Log:
Merged revisions 84719 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84719 | r.david.murray | 2010-09-11 14:12:25 -0400 (Sat, 11 Sep 2010) | 2 lines
#9608, #8518 : clarify and improve discussion of exceptions in howto.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Doc/howto/doanddont.rst
Modified: python/branches/release27-maint/Doc/howto/doanddont.rst
==============================================================================
--- python/branches/release27-maint/Doc/howto/doanddont.rst (original)
+++ python/branches/release27-maint/Doc/howto/doanddont.rst Sat Sep 11 20:57:20 2010
@@ -144,30 +144,44 @@
-------
Python has the ``except:`` clause, which catches all exceptions. Since *every*
-error in Python raises an exception, this makes many programming errors look
-like runtime problems, and hinders the debugging process.
+error in Python raises an exception, using ``except:`` can make many
+programming errors look like runtime problems, which hinders the debugging
+process.
-The following code shows a great example::
+The following code shows a great example of why this is bad::
try:
foo = opne("file") # misspelled "open"
except:
sys.exit("could not open file!")
-The second line triggers a :exc:`NameError` which is caught by the except
-clause. The program will exit, and you will have no idea that this has nothing
-to do with the readability of ``"file"``.
+The second line triggers a :exc:`NameError`, which is caught by the except
+clause. The program will exit, and the error message the program prints will
+make you think the problem is the readability of ``"file"`` when in fact
+the real error has nothing to do with ``"file"``.
-The example above is better written ::
+A better way to write the above is ::
try:
- foo = opne("file") # will be changed to "open" as soon as we run it
+ foo = opne("file")
except IOError:
sys.exit("could not open file")
-There are some situations in which the ``except:`` clause is useful: for
-example, in a framework when running callbacks, it is good not to let any
-callback disturb the framework.
+When this is run, Python will produce a traceback showing the :exc:`NameError`,
+and it will be immediately apparent what needs to be fixed.
+
+.. index:: bare except, except; bare
+
+Because ``except:`` catches *all* exceptions, including :exc:`SystemExit`,
+:exc:`KeyboardInterrupt`, and :exc:`GeneratorExit` (which is not an error and
+should not normally be caught by user code), using a bare ``except:`` is almost
+never a good idea. In situations where you need to catch all "normal" errors,
+such as in a framework that runs callbacks, you can catch the base class for
+all normal exceptions, :exc:`Exception`. Unfortunately in Python2 it is
+possible for third-party code to raise exceptions that do not inherit from
+:exc:`Exception`, so in Python 2.x there are some cases where you may have to
+use a bare ``except:`` and manually re-raise the exceptions you don't want
+to catch.
Exceptions
@@ -185,51 +199,60 @@
sys.exit(1)
return open(file).readline()
-Consider the case the file gets deleted between the time the call to
-:func:`os.path.exists` is made and the time :func:`open` is called. That means
-the last line will throw an :exc:`IOError`. The same would happen if *file*
-exists but has no read permission. Since testing this on a normal machine on
-existing and non-existing files make it seem bugless, that means in testing the
-results will seem fine, and the code will get shipped. Then an unhandled
-:exc:`IOError` escapes to the user, who has to watch the ugly traceback.
+Consider the case where the file gets deleted between the time the call to
+:func:`os.path.exists` is made and the time :func:`open` is called. In that
+case the last line will raise an :exc:`IOError`. The same thing would happen
+if *file* exists but has no read permission. Since testing this on a normal
+machine on existent and non-existent files makes it seem bugless, the test
+results will seem fine, and the code will get shipped. Later an unhandled
+:exc:`IOError` (or perhaps some other :exc:`EnvironmentError`) escapes to the
+user, who gets to watch the ugly traceback.
-Here is a better way to do it. ::
+Here is a somewhat better way to do it. ::
def get_status(file):
try:
return open(file).readline()
- except (IOError, OSError):
- print "file not found"
+ except EnvironmentError as err:
+ print "Unable to open file: {}".format(err)
sys.exit(1)
-In this version, \*either\* the file gets opened and the line is read (so it
-works even on flaky NFS or SMB connections), or the message is printed and the
-application aborted.
-
-Still, :func:`get_status` makes too many assumptions --- that it will only be
-used in a short running script, and not, say, in a long running server. Sure,
-the caller could do something like ::
+In this version, *either* the file gets opened and the line is read (so it
+works even on flaky NFS or SMB connections), or an error message is printed
+that provides all the available information on why the open failed, and the
+application is aborted.
+
+However, even this version of :func:`get_status` makes too many assumptions ---
+that it will only be used in a short running script, and not, say, in a long
+running server. Sure, the caller could do something like ::
try:
status = get_status(log)
except SystemExit:
status = None
-So, try to make as few ``except`` clauses in your code --- those will usually be
-a catch-all in the :func:`main`, or inside calls which should always succeed.
+But there is a better way. You should try to use as few ``except`` clauses in
+your code as you can --- the ones you do use will usually be inside calls which
+should always succeed, or a catch-all in a main function.
-So, the best version is probably ::
+So, an even better version of :func:`get_status()` is probably ::
def get_status(file):
return open(file).readline()
-The caller can deal with the exception if it wants (for example, if it tries
+The caller can deal with the exception if it wants (for example, if it tries
several files in a loop), or just let the exception filter upwards to *its*
caller.
-The last version is not very good either --- due to implementation details, the
-file would not be closed when an exception is raised until the handler finishes,
-and perhaps not at all in non-C implementations (e.g., Jython). ::
+But the last version still has a serious problem --- due to implementation
+details in CPython, the file would not be closed when an exception is raised
+until the exception handler finishes; and, worse, in other implementations
+(e.g., Jython) it might not be closed at all regardless of whether or not
+an exception is raised.
+
+The best version of this function uses the ``open()`` call as a context
+manager, which will ensure that the file gets closed as soon as the
+function returns::
def get_status(file):
with open(file) as fp:
From python-checkins at python.org Sat Sep 11 21:15:40 2010
From: python-checkins at python.org (r.david.murray)
Date: Sat, 11 Sep 2010 21:15:40 +0200 (CEST)
Subject: [Python-checkins] r84722 -
python/branches/release27-maint/Doc/howto/doanddont.rst
Message-ID: <20100911191540.9FEF3EEA6B@mail.python.org>
Author: r.david.murray
Date: Sat Sep 11 21:15:40 2010
New Revision: 84722
Log:
Fix typo in previous doc commit.
Modified:
python/branches/release27-maint/Doc/howto/doanddont.rst
Modified: python/branches/release27-maint/Doc/howto/doanddont.rst
==============================================================================
--- python/branches/release27-maint/Doc/howto/doanddont.rst (original)
+++ python/branches/release27-maint/Doc/howto/doanddont.rst Sat Sep 11 21:15:40 2010
@@ -177,7 +177,7 @@
should not normally be caught by user code), using a bare ``except:`` is almost
never a good idea. In situations where you need to catch all "normal" errors,
such as in a framework that runs callbacks, you can catch the base class for
-all normal exceptions, :exc:`Exception`. Unfortunately in Python2 it is
+all normal exceptions, :exc:`Exception`. Unfortunately in Python 2.x it is
possible for third-party code to raise exceptions that do not inherit from
:exc:`Exception`, so in Python 2.x there are some cases where you may have to
use a bare ``except:`` and manually re-raise the exceptions you don't want
From python-checkins at python.org Sun Sep 12 00:26:07 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun, 12 Sep 2010 00:26:07 +0200 (CEST)
Subject: [Python-checkins] r84723 - python/branches/release31-maint
Message-ID: <20100911222607.DA620FC4F@mail.python.org>
Author: hirokazu.yamamoto
Date: Sun Sep 12 00:26:07 2010
New Revision: 84723
Log:
Blocked revisions 84643 via svnmerge
........
r84643 | hirokazu.yamamoto | 2010-09-09 15:08:36 +0900 | 4 lines
Updated VC6 files.
* pythoncore.dsp: updated project file
* readme.txt: removed dead link
* tcl852.patch: fixed patch. it was doubled.
........
Modified:
python/branches/release31-maint/ (props changed)
From python-checkins at python.org Sun Sep 12 00:35:24 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun, 12 Sep 2010 00:35:24 +0200 (CEST)
Subject: [Python-checkins] r84724 - python/branches/py3k/Include/pythread.h
Message-ID: <20100911223524.B5514EE985@mail.python.org>
Author: hirokazu.yamamoto
Date: Sun Sep 12 00:35:24 2010
New Revision: 84724
Log:
Issue #9318: Use Py_LL for old compiler.
Modified:
python/branches/py3k/Include/pythread.h
Modified: python/branches/py3k/Include/pythread.h
==============================================================================
--- python/branches/py3k/Include/pythread.h (original)
+++ python/branches/py3k/Include/pythread.h Sun Sep 12 00:35:24 2010
@@ -39,9 +39,9 @@
/* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
#if defined (NT_THREADS)
-#if (0xFFFFFFFFLL * 1000 < PY_TIMEOUT_MAX)
+#if (Py_LL(0xFFFFFFFF) * 1000 < PY_TIMEOUT_MAX)
#undef PY_TIMEOUT_MAX
-#define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000)
+#define PY_TIMEOUT_MAX (Py_LL(0xFFFFFFFF) * 1000)
#endif
#endif
From python-checkins at python.org Sun Sep 12 04:11:46 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 12 Sep 2010 04:11:46 +0200 (CEST)
Subject: [Python-checkins] r84725 - in python/branches/release27-maint:
Lib/collections.py Misc/NEWS
Message-ID: <20100912021146.216FCEE98A@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 12 04:11:45 2010
New Revision: 84725
Log:
Issue #9825: Remove __del__() from OrderedDict.
Modified:
python/branches/release27-maint/Lib/collections.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/collections.py
==============================================================================
--- python/branches/release27-maint/Lib/collections.py (original)
+++ python/branches/release27-maint/Lib/collections.py Sun Sep 12 04:11:45 2010
@@ -173,9 +173,6 @@
all(_imap(_eq, self.iteritems(), other.iteritems()))
return dict.__eq__(self, other)
- def __del__(self):
- self.clear() # eliminate cyclical references
-
################################################################################
### namedtuple
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Sun Sep 12 04:11:45 2010
@@ -43,6 +43,13 @@
Library
-------
+- Issue #9825: removed __del__ from the definition of collections.OrderedDict.
+ This prevents user-created self-referencing ordered dictionaries from
+ becoming permanently uncollectable GC garbage. The downside is that
+ removing __del__ means that the internal doubly-linked list has to wait for
+ GC collection rather than freeing memory immediately when the refcnt drops
+ to zero.
+
- Issue #9816: random.Random.jumpahead(n) did not produce a sufficiently
different internal state for small values of n. Fixed by salting the
value.
From solipsis at pitrou.net Sun Sep 12 05:08:45 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Sun, 12 Sep 2010 05:08:45 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84724): sum=6
Message-ID:
py3k results for svn r84724 (hg cset 05f24bf164ac)
--------------------------------------------------
test_unicode leaked [2, 2, 2] references, sum=6
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflognoNh-a', '-x']
From python-checkins at python.org Sun Sep 12 05:40:54 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 12 Sep 2010 05:40:54 +0200 (CEST)
Subject: [Python-checkins] r84726 -
python/branches/py3k/Objects/unicodeobject.c
Message-ID: <20100912034054.3595AF882@mail.python.org>
Author: benjamin.peterson
Date: Sun Sep 12 05:40:54 2010
New Revision: 84726
Log:
detect non-ascii characters much earlier (plugs ref leak)
Modified:
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Sun Sep 12 05:40:54 2010
@@ -764,6 +764,13 @@
if (*f == 's')
++callcount;
}
+ else if (128 <= (unsigned char)*f) {
+ PyErr_Format(PyExc_ValueError,
+ "PyUnicode_FromFormatV() expects an ASCII-encoded format "
+ "string, got a non-ascii byte: 0x%02x",
+ (unsigned char)*f);
+ return NULL;
+ }
}
/* step 2: allocate memory for the results of
* PyObject_Str()/PyObject_Repr()/PyUnicode_DecodeUTF8() calls */
@@ -1103,13 +1110,6 @@
goto end;
}
}
- else if (128 <= (unsigned char)*f) {
- PyErr_Format(PyExc_ValueError,
- "PyUnicode_FromFormatV() expects an ASCII-encoded format "
- "string, got a non-ascii byte: 0x%02x",
- (unsigned char)*f);
- goto fail;
- }
else
*s++ = *f;
}
From python-checkins at python.org Sun Sep 12 06:12:42 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 12 Sep 2010 06:12:42 +0200 (CEST)
Subject: [Python-checkins] r84727 - in python/branches/py3k:
Lib/collections.py Misc/NEWS
Message-ID: <20100912041242.C927AFA7A@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 12 06:12:42 2010
New Revision: 84727
Log:
Issue #9825: Replace OrderedDict.__del__() with weakrefs.
Modified:
python/branches/py3k/Lib/collections.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Sun Sep 12 06:12:42 2010
@@ -11,12 +11,16 @@
from keyword import iskeyword as _iskeyword
import sys as _sys
import heapq as _heapq
+from weakref import proxy as _proxy
from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
################################################################################
### OrderedDict
################################################################################
+class _Link(object):
+ __slots__ = 'prev', 'next', 'key', '__weakref__'
+
class OrderedDict(dict, MutableMapping):
'Dictionary that remembers insertion order'
# An inherited dict maps keys to values.
@@ -27,7 +31,7 @@
# The internal self.__map dictionary maps keys to links in a doubly linked list.
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
- # Each link is stored as a list of length three: [PREV, NEXT, KEY].
+ # The back links are weakref proxies (to prevent circular references).
def __init__(self, *args, **kwds):
'''Initialize an ordered dictionary. Signature is the same as for
@@ -40,51 +44,53 @@
try:
self.__root
except AttributeError:
- self.__root = root = [None, None, None] # sentinel node
- PREV = 0
- NEXT = 1
- root[PREV] = root[NEXT] = root
+ self.__root = root = _Link() # sentinel node for the doubly linked list
+ root.prev = root.next = root
self.__map = {}
self.update(*args, **kwds)
- def __setitem__(self, key, value, PREV=0, NEXT=1, dict_setitem=dict.__setitem__):
+ def __setitem__(self, key, value,
+ dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
'od.__setitem__(i, y) <==> od[i]=y'
# Setting a new item creates a new link which goes at the end of the linked
# list, and the inherited dictionary is updated with the new key/value pair.
if key not in self:
+ self.__map[key] = link = Link()
root = self.__root
- last = root[PREV]
- last[NEXT] = root[PREV] = self.__map[key] = [last, root, key]
- dict_setitem(self, key, value)
+ last = root.prev
+ link.prev, link.next, link.key = last, root, key
+ last.next = link
+ root.prev = proxy(link)
+ dict.__setitem__(self, key, value)
- def __delitem__(self, key, PREV=0, NEXT=1, dict_delitem=dict.__delitem__):
+ def __delitem__(self, key, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
# Deleting an existing item uses self.__map to find the link which is
# then removed by updating the links in the predecessor and successor nodes.
dict_delitem(self, key)
link = self.__map.pop(key)
- link_prev = link[PREV]
- link_next = link[NEXT]
- link_prev[NEXT] = link_next
- link_next[PREV] = link_prev
+ link_prev = link.prev
+ link_next = link.next
+ link_prev.next = link_next
+ link_next.prev = link_prev
- def __iter__(self, NEXT=1, KEY=2):
+ def __iter__(self):
'od.__iter__() <==> iter(od)'
# Traverse the linked list in order.
root = self.__root
- curr = root[NEXT]
+ curr = root.next
while curr is not root:
- yield curr[KEY]
- curr = curr[NEXT]
+ yield curr.key
+ curr = curr.next
- def __reversed__(self, PREV=0, KEY=2):
+ def __reversed__(self):
'od.__reversed__() <==> reversed(od)'
# Traverse the linked list in reverse order.
root = self.__root
- curr = root[PREV]
+ curr = root.prev
while curr is not root:
- yield curr[KEY]
- curr = curr[PREV]
+ yield curr.key
+ curr = curr.prev
def __reduce__(self):
'Return state information for pickling'
@@ -99,16 +105,12 @@
def clear(self):
'od.clear() -> None. Remove all items from od.'
- try:
- for node in self.__map.values():
- del node[:]
- self.__root[:] = [self.__root, self.__root, None]
- self.__map.clear()
- except AttributeError:
- pass
+ root = self.__root
+ root.prev = root.next = root
+ self.__map.clear()
dict.clear(self)
- def popitem(self, last=True, PREV=0, NEXT=1, KEY=2, dict_pop=dict.pop):
+ def popitem(self, last=True):
'''od.popitem() -> (k, v), return and remove a (key, value) pair.
Pairs are returned in LIFO order if last is true or FIFO order if false.
@@ -116,21 +118,45 @@
if not self:
raise KeyError('dictionary is empty')
root = self.__root
- if last: # link_prev <--> link <--> root
- link = root[PREV]
- link_prev = link[PREV]
- link_prev[NEXT] = root
- root[PREV] = link_prev
- else: # root <--> link <--> link_next
- link = root[NEXT]
- link_next = link[NEXT]
- root[NEXT] = link_next
- link_next[PREV] = root
- key = link[KEY]
+ if last:
+ link = root.prev
+ link_prev = link.prev
+ link_prev.next = root
+ root.prev = link_prev
+ else:
+ link = root.next
+ link_next = link.next
+ root.next = link_next
+ link_next.prev = root
+ key = link.key
del self.__map[key]
- value = dict_pop(self, key)
+ value = dict.pop(self, key)
return key, value
+ def move_to_end(self, key, last=True):
+ '''Move an existing element to the end (or beginning if last==False).
+
+ Raises KeyError if the element does not exist.
+ When last=True, acts like a fast version of self[key]=self.pop(key).
+
+ '''
+ link = self.__map[key]
+ link_prev = link.prev
+ link_next = link.next
+ link_prev.next = link_next
+ link_next.prev = link_prev
+ root = self.__root
+ if last:
+ last = root.prev
+ link.prev = last
+ link.next = root
+ last.next = root.prev = link
+ else:
+ first = root.next
+ link.prev = root
+ link.next = first
+ root.next = first.prev = link
+
setdefault = MutableMapping.setdefault
update = MutableMapping.update
pop = MutableMapping.pop
@@ -170,33 +196,6 @@
all(p==q for p, q in zip(self.items(), other.items()))
return dict.__eq__(self, other)
- def __del__(self):
- self.clear() # eliminate cyclical references
-
- def move_to_end(self, key, last=True, PREV=0, NEXT=1):
- '''Move an existing element to the end (or beginning if last==False).
-
- Raises KeyError if the element does not exist.
- When last=True, acts like a fast version of self[key]=self.pop(key).
-
- '''
- link = self.__map[key]
- link_prev = link[PREV]
- link_next = link[NEXT]
- link_prev[NEXT] = link_next
- link_next[PREV] = link_prev
- root = self.__root
- if last:
- last = root[PREV]
- link[PREV] = last
- link[NEXT] = root
- last[NEXT] = root[PREV] = link
- else:
- first = root[NEXT]
- link[PREV] = root
- link[NEXT] = first
- root[NEXT] = first[PREV] = link
-
################################################################################
### namedtuple
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 12 06:12:42 2010
@@ -32,6 +32,12 @@
Library
-------
+- Issue #9825: Using __del__ in the definition of collections.OrderedDict made
+ it possible for the user to create self-referencing ordered dictionaries
+ which become permanently uncollectable GC garbage. Reinstated the Py3.1
+ approach of using weakref proxies so that reference cycles never get created
+ in the first place.
+
- Issue #9579, #9580: Fix os.confstr() for value longer than 255 bytes and
encode the value with filesystem encoding and surrogateescape (instead of
utf-8 in strict mode). Patch written by David Watson.
From python-checkins at python.org Sun Sep 12 07:15:22 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 12 Sep 2010 07:15:22 +0200 (CEST)
Subject: [Python-checkins] r84728 - in python/branches/py3k:
Lib/collections.py Lib/test/test_collections.py Misc/NEWS
Message-ID: <20100912051522.7D8DAEDAE@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 12 07:15:22 2010
New Revision: 84728
Log:
Issue #9826: Handle recursive repr in collections.OrderedDict.
Modified:
python/branches/py3k/Lib/collections.py
python/branches/py3k/Lib/test/test_collections.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Sun Sep 12 07:15:22 2010
@@ -41,6 +41,7 @@
'''
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
+ self.__in_repr = False # detects recursive repr
try:
self.__root
except AttributeError:
@@ -95,10 +96,10 @@
def __reduce__(self):
'Return state information for pickling'
items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__root
- del self.__map, self.__root
+ tmp = self.__map, self.__root, self.__in_repr
+ del self.__map, self.__root, self.__in_repr
inst_dict = vars(self).copy()
- self.__map, self.__root = tmp
+ self.__map, self.__root, self.__in_repr = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
@@ -167,9 +168,16 @@
def __repr__(self):
'od.__repr__() <==> repr(od)'
+ if self.__in_repr:
+ return '...'
if not self:
return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, list(self.items()))
+ self.__in_repr = True
+ try:
+ result = '%s(%r)' % (self.__class__.__name__, list(self.items()))
+ finally:
+ self.__in_repr = False
+ return result
def copy(self):
'od.copy() -> a shallow copy of od'
Modified: python/branches/py3k/Lib/test/test_collections.py
==============================================================================
--- python/branches/py3k/Lib/test/test_collections.py (original)
+++ python/branches/py3k/Lib/test/test_collections.py Sun Sep 12 07:15:22 2010
@@ -951,6 +951,13 @@
self.assertEqual(eval(repr(od)), od)
self.assertEqual(repr(OrderedDict()), "OrderedDict()")
+ def test_repr_recursive(self):
+ # See issue #9826
+ od = OrderedDict.fromkeys('abc')
+ od['x'] = od
+ self.assertEqual(repr(od),
+ "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
+
def test_setdefault(self):
pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
shuffle(pairs)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 12 07:15:22 2010
@@ -32,6 +32,9 @@
Library
-------
+- Issue #9826: OrderedDict.__repr__ can now handle self-referential
+ values: d['x'] = d.
+
- Issue #9825: Using __del__ in the definition of collections.OrderedDict made
it possible for the user to create self-referencing ordered dictionaries
which become permanently uncollectable GC garbage. Reinstated the Py3.1
From python-checkins at python.org Sun Sep 12 07:28:42 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 12 Sep 2010 07:28:42 +0200 (CEST)
Subject: [Python-checkins] r84729 - in python/branches/release31-maint:
Lib/collections.py Lib/test/test_collections.py Misc/NEWS
Message-ID: <20100912052842.4791DF9D0@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 12 07:28:42 2010
New Revision: 84729
Log:
Issue #9826: Handle recursive repr in collections.OrderedDict.
Modified:
python/branches/release31-maint/Lib/collections.py
python/branches/release31-maint/Lib/test/test_collections.py
python/branches/release31-maint/Misc/NEWS
Modified: python/branches/release31-maint/Lib/collections.py
==============================================================================
--- python/branches/release31-maint/Lib/collections.py (original)
+++ python/branches/release31-maint/Lib/collections.py Sun Sep 12 07:28:42 2010
@@ -43,6 +43,7 @@
'''
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
+ self.__in_repr = False # detects recursive repr
try:
self.__root
except AttributeError:
@@ -100,10 +101,10 @@
def __reduce__(self):
'Return state information for pickling'
items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__root
- del self.__map, self.__root
+ tmp = self.__map, self.__root, self.__in_repr
+ del self.__map, self.__root, self.__in_repr
inst_dict = vars(self).copy()
- self.__map, self.__root = tmp
+ self.__map, self.__root, self.__in_repr = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
@@ -128,9 +129,16 @@
def __repr__(self):
'od.__repr__() <==> repr(od)'
+ if self.__in_repr:
+ return '...'
if not self:
return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, list(self.items()))
+ self.__in_repr = True
+ try:
+ result = '%s(%r)' % (self.__class__.__name__, list(self.items()))
+ finally:
+ self.__in_repr = False
+ return result
def copy(self):
'od.copy() -> a shallow copy of od'
Modified: python/branches/release31-maint/Lib/test/test_collections.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_collections.py (original)
+++ python/branches/release31-maint/Lib/test/test_collections.py Sun Sep 12 07:28:42 2010
@@ -908,6 +908,13 @@
self.assertEqual(eval(repr(od)), od)
self.assertEqual(repr(OrderedDict()), "OrderedDict()")
+ def test_repr_recursive(self):
+ # See issue #9826
+ od = OrderedDict.fromkeys('abc')
+ od['x'] = od
+ self.assertEqual(repr(od),
+ "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
+
def test_setdefault(self):
pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
shuffle(pairs)
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Sun Sep 12 07:28:42 2010
@@ -122,6 +122,9 @@
to fetch the original errno, or to filter timeout errors. Now the
original error is re-raised.
+- Issue #9826: OrderedDict.__repr__ can now handle self-referential
+ values: d['x'] = d.
+
- Issue #9758: When fcntl.ioctl() was called with mutable_flag set to True,
and the passed buffer was exactly 1024 bytes long, the buffer wouldn't
be updated back after the system call. Original patch by Brian Brazil.
From python-checkins at python.org Sun Sep 12 09:51:18 2010
From: python-checkins at python.org (victor.stinner)
Date: Sun, 12 Sep 2010 09:51:18 +0200 (CEST)
Subject: [Python-checkins] r84730 - in python/branches/py3k:
Lib/test/test_unicode.py Objects/unicodeobject.c
Message-ID: <20100912075118.C7C7CF43F@mail.python.org>
Author: victor.stinner
Date: Sun Sep 12 09:51:18 2010
New Revision: 84730
Log:
Issue #9738, #9836: Fix refleak introduced by r84704
Modified:
python/branches/py3k/Lib/test/test_unicode.py
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py (original)
+++ python/branches/py3k/Lib/test/test_unicode.py Sun Sep 12 09:51:18 2010
@@ -1397,7 +1397,7 @@
# non-ascii format, ascii argument
self.assertRaisesRegexp(ValueError,
'^PyUnicode_FromFormatV\(\) expects an ASCII-encoded format '
- 'string, got a non-ascii byte: 0xe9$',
+ 'string, got a non-ASCII byte: 0xe9$',
format_unicode, b'unicode\xe9=%s', 'ascii')
def test_main():
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Sun Sep 12 09:51:18 2010
@@ -767,9 +767,9 @@
else if (128 <= (unsigned char)*f) {
PyErr_Format(PyExc_ValueError,
"PyUnicode_FromFormatV() expects an ASCII-encoded format "
- "string, got a non-ascii byte: 0x%02x",
+ "string, got a non-ASCII byte: 0x%02x",
(unsigned char)*f);
- return NULL;
+ goto fail;
}
}
/* step 2: allocate memory for the results of
From python-checkins at python.org Sun Sep 12 10:00:41 2010
From: python-checkins at python.org (victor.stinner)
Date: Sun, 12 Sep 2010 10:00:41 +0200 (CEST)
Subject: [Python-checkins] r84731 - python/branches/py3k/Modules/main.c
Message-ID: <20100912080041.E8E2EF99B@mail.python.org>
Author: victor.stinner
Date: Sun Sep 12 10:00:41 2010
New Revision: 84731
Log:
Isse #8589: Decode PYTHONWARNINGS from utf-8 on Mac OS X
Instead of the locale encoding.
Modified:
python/branches/py3k/Modules/main.c
Modified: python/branches/py3k/Modules/main.c
==============================================================================
--- python/branches/py3k/Modules/main.c (original)
+++ python/branches/py3k/Modules/main.c Sun Sep 12 10:00:41 2010
@@ -488,7 +488,6 @@
#else
if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
char *buf, *oldloc;
- wchar_t *wchar;
PyObject *unicode;
/* settle for strtok here as there's no one standard
@@ -501,11 +500,16 @@
oldloc = strdup(setlocale(LC_ALL, NULL));
setlocale(LC_ALL, "");
for (p = strtok(buf, ","); p != NULL; p = strtok(NULL, ",")) {
- wchar = _Py_char2wchar(p);
+#ifdef __APPLE__
+ /* Use utf-8 on Mac OS X */
+ unicode = PyUnicode_FromString(p);
+#else
+ wchar_t *wchar = _Py_char2wchar(p);
if (wchar == NULL)
continue;
unicode = PyUnicode_FromWideChar(wchar, wcslen(wchar));
PyMem_Free(wchar);
+#endif
if (unicode == NULL)
continue;
PySys_AddWarnOptionUnicode(unicode);
From python-checkins at python.org Sun Sep 12 13:47:47 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Sep 2010 13:47:47 +0200 (CEST)
Subject: [Python-checkins] r84732 -
python/branches/release31-maint/Doc/library/logging.rst
Message-ID: <20100912114747.7A998F343@mail.python.org>
Author: vinay.sajip
Date: Sun Sep 12 13:47:47 2010
New Revision: 84732
Log:
Issue #9827: clarified LogRecord documentation.
Modified:
python/branches/release31-maint/Doc/library/logging.rst
Modified: python/branches/release31-maint/Doc/library/logging.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/logging.rst (original)
+++ python/branches/release31-maint/Doc/library/logging.rst Sun Sep 12 13:47:47 2010
@@ -540,10 +540,10 @@
In addition to the base :class:`Handler` class, many useful subclasses are
provided:
-#. :class:`StreamHandler` instances send error messages to streams (file-like
+#. :class:`StreamHandler` instances send messages to streams (file-like
objects).
-#. :class:`FileHandler` instances send error messages to disk files.
+#. :class:`FileHandler` instances send messages to disk files.
.. module:: logging.handlers
@@ -552,31 +552,31 @@
directly. Instead, use :class:`RotatingFileHandler` or
:class:`TimedRotatingFileHandler`.
-#. :class:`RotatingFileHandler` instances send error messages to disk
+#. :class:`RotatingFileHandler` instances send messages to disk
files, with support for maximum log file sizes and log file rotation.
-#. :class:`TimedRotatingFileHandler` instances send error messages to
+#. :class:`TimedRotatingFileHandler` instances send messages to
disk files, rotating the log file at certain timed intervals.
-#. :class:`SocketHandler` instances send error messages to TCP/IP
+#. :class:`SocketHandler` instances send messages to TCP/IP
sockets.
-#. :class:`DatagramHandler` instances send error messages to UDP
+#. :class:`DatagramHandler` instances send messages to UDP
sockets.
-#. :class:`SMTPHandler` instances send error messages to a designated
+#. :class:`SMTPHandler` instances send messages to a designated
email address.
-#. :class:`SysLogHandler` instances send error messages to a Unix
+#. :class:`SysLogHandler` instances send messages to a Unix
syslog daemon, possibly on a remote machine.
-#. :class:`NTEventLogHandler` instances send error messages to a
+#. :class:`NTEventLogHandler` instances send messages to a
Windows NT/2000/XP event log.
-#. :class:`MemoryHandler` instances send error messages to a buffer
+#. :class:`MemoryHandler` instances send messages to a buffer
in memory, which is flushed whenever specific criteria are met.
-#. :class:`HTTPHandler` instances send error messages to an HTTP
+#. :class:`HTTPHandler` instances send messages to an HTTP
server using either ``GET`` or ``POST`` semantics.
#. :class:`WatchedFileHandler` instances watch the file they are
@@ -675,7 +675,7 @@
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)
- would print something like ::
+ would print something like::
2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset
@@ -842,6 +842,7 @@
and 2.2.x, which do not include the :mod:`logging` package in the standard
library.
+.. _logger:
Logger Objects
--------------
@@ -1441,16 +1442,16 @@
threads in a single process *is* supported, logging to a single file from
*multiple processes* is *not* supported, because there is no standard way to
serialize access to a single file across multiple processes in Python. If you
-need to log to a single file from multiple processes, the best way of doing
-this is to have all the processes log to a :class:`SocketHandler`, and have a
-separate process which implements a socket server which reads from the socket
-and logs to file. (If you prefer, you can dedicate one thread in one of the
-existing processes to perform this function.) The following section documents
-this approach in more detail and includes a working socket receiver which can
-be used as a starting point for you to adapt in your own applications.
+need to log to a single file from multiple processes, one way of doing this is
+to have all the processes log to a :class:`SocketHandler`, and have a separate
+process which implements a socket server which reads from the socket and logs
+to file. (If you prefer, you can dedicate one thread in one of the existing
+processes to perform this function.) The following section documents this
+approach in more detail and includes a working socket receiver which can be
+used as a starting point for you to adapt in your own applications.
If you are using a recent version of Python which includes the
-:mod:`multiprocessing` module, you can write your own handler which uses the
+:mod:`multiprocessing` module, you could write your own handler which uses the
:class:`Lock` class from this module to serialize access to the file from
your processes. The existing :class:`FileHandler` and subclasses do not make
use of :mod:`multiprocessing` at present, though they may do so in the future.
@@ -1594,6 +1595,8 @@
the :meth:`makePickle` method and implementing your alternative there, as
well as adapting the above script to use your alternative serialization.
+.. _arbitrary-object-messages:
+
Using arbitrary objects as messages
-----------------------------------
@@ -1957,6 +1960,11 @@
The extensions are date-and-time based, using the strftime format
``%Y-%m-%d_%H-%M-%S`` or a leading portion thereof, depending on the
rollover interval.
+
+ When computing the next rollover time for the first time (when the handler
+ is created), the last modification time of an existing log file, or else
+ the current time, is used to compute when the next rotation will occur.
+
If the *utc* argument is true, times in UTC will be used; otherwise
local time is used.
@@ -2452,6 +2460,8 @@
+-------------------------+-----------------------------------------------+
| ``%(process)d`` | Process ID (if available). |
+-------------------------+-----------------------------------------------+
+| ``%(processName)s`` | Process name (if available). |
++-------------------------+-----------------------------------------------+
| ``%(message)s`` | The logged message, computed as ``msg % |
| | args``. |
+-------------------------+-----------------------------------------------+
@@ -2465,7 +2475,6 @@
specified, ``'%(message)s'`` is used. If no *datefmt* is specified, the
ISO8601 date format is used.
-
.. method:: format(record)
The record's attribute dictionary is used as the operand to a string
From python-checkins at python.org Sun Sep 12 13:51:26 2010
From: python-checkins at python.org (vinay.sajip)
Date: Sun, 12 Sep 2010 13:51:26 +0200 (CEST)
Subject: [Python-checkins] r84733 -
python/branches/release31-maint/Doc/library/logging.rst
Message-ID: <20100912115126.920D0F343@mail.python.org>
Author: vinay.sajip
Date: Sun Sep 12 13:51:26 2010
New Revision: 84733
Log:
Issue #9827: clarified LogRecord documentation a little more.
Modified:
python/branches/release31-maint/Doc/library/logging.rst
Modified: python/branches/release31-maint/Doc/library/logging.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/logging.rst (original)
+++ python/branches/release31-maint/Doc/library/logging.rst Sun Sep 12 13:51:26 2010
@@ -2550,27 +2550,58 @@
LogRecord Objects
-----------------
-:class:`LogRecord` instances are created every time something is logged. They
-contain all the information pertinent to the event being logged. The main
-information passed in is in msg and args, which are combined using msg % args to
-create the message field of the record. The record also includes information
-such as when the record was created, the source line where the logging call was
-made, and any exception information to be logged.
+:class:`LogRecord` instances are created automatically by the :class:`Logger`
+every time something is logged, and can be created manually via
+:func:`makeLogRecord` (for example, from a pickled event received over the
+wire).
.. class:: LogRecord(name, lvl, pathname, lineno, msg, args, exc_info, func=None)
- Returns an instance of :class:`LogRecord` initialized with interesting
- information. The *name* is the logger name; *lvl* is the numeric level;
- *pathname* is the absolute pathname of the source file in which the logging
- call was made; *lineno* is the line number in that file where the logging
- call is found; *msg* is the user-supplied message (a format string); *args*
- is the tuple which, together with *msg*, makes up the user message; and
- *exc_info* is the exception tuple obtained by calling :func:`sys.exc_info`
- (or :const:`None`, if no exception information is available). The *func* is
- the name of the function from which the logging call was made. If not
- specified, it defaults to ``None``.
+ Contains all the information pertinent to the event being logged.
+ The primary information is passed in :attr:`msg` and :attr:`args`, which
+ are combined using ``msg % args`` to create the :attr:`message` field of the
+ record.
+
+ .. attribute:: args
+
+ Tuple of arguments to be used in formatting :attr:`msg`.
+
+ .. attribute:: exc_info
+
+ Exception tuple (? la `sys.exc_info`) or `None` if no exception
+ information is availble.
+
+ .. attribute:: func
+
+ Name of the function of origin (i.e. in which the logging call was made).
+
+ .. attribute:: lineno
+
+ Line number in the source file of origin.
+
+ .. attribute:: lvl
+
+ Numeric logging level.
+
+ .. attribute:: message
+
+ Bound to the result of :meth:`getMessage` when
+ :meth:`Formatter.format(record)` is invoked.
+
+ .. attribute:: msg
+
+ User-supplied :ref:`format string` or arbitrary object
+ (see :ref:`arbitrary-object-messages`) used in :meth:`getMessage`.
+
+ .. attribute:: name
+
+ Name of the logger that emitted the record.
+
+ .. attribute:: pathname
+
+ Absolute pathname of the source file of origin.
.. method:: getMessage()
From python-checkins at python.org Sun Sep 12 15:18:01 2010
From: python-checkins at python.org (martin.v.loewis)
Date: Sun, 12 Sep 2010 15:18:01 +0200 (CEST)
Subject: [Python-checkins] r84734 - in tracker/instances:
jython/detectors/patches.py python-dev/detectors/patches.py
security/detectors/patches.py
Message-ID: <20100912131801.BAFAAC3C7@mail.python.org>
Author: martin.v.loewis
Date: Sun Sep 12 15:18:01 2010
New Revision: 84734
Log:
Issue #353: Don't add patch keyword to new issue if it's
already there.
Modified:
tracker/instances/jython/detectors/patches.py
tracker/instances/python-dev/detectors/patches.py
tracker/instances/security/detectors/patches.py
Modified: tracker/instances/jython/detectors/patches.py
==============================================================================
--- tracker/instances/jython/detectors/patches.py (original)
+++ tracker/instances/jython/detectors/patches.py Sun Sep 12 15:18:01 2010
@@ -37,7 +37,8 @@
return
if not newvalues.has_key('keywords'):
newvalues['keywords'] = oldkeywords
- newvalues['keywords'].append(patchid)
+ if patchid not in newvalues['keywords']:
+ newvalues['keywords'].append(patchid)
def init(db):
db.file.audit('create', patches_text_plain)
Modified: tracker/instances/python-dev/detectors/patches.py
==============================================================================
--- tracker/instances/python-dev/detectors/patches.py (original)
+++ tracker/instances/python-dev/detectors/patches.py Sun Sep 12 15:18:01 2010
@@ -37,7 +37,8 @@
return
if not newvalues.has_key('keywords'):
newvalues['keywords'] = oldkeywords
- newvalues['keywords'].append(patchid)
+ if patchid not in newvalues['keywords']:
+ newvalues['keywords'].append(patchid)
def init(db):
db.file.audit('create', patches_text_plain)
Modified: tracker/instances/security/detectors/patches.py
==============================================================================
--- tracker/instances/security/detectors/patches.py (original)
+++ tracker/instances/security/detectors/patches.py Sun Sep 12 15:18:01 2010
@@ -37,7 +37,8 @@
return
if not newvalues.has_key('keywords'):
newvalues['keywords'] = oldkeywords
- newvalues['keywords'].append(patchid)
+ if patchid not in newvalues['keywords']:
+ newvalues['keywords'].append(patchid)
def init(db):
db.file.audit('create', patches_text_plain)
From python-checkins at python.org Sun Sep 12 15:55:02 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 12 Sep 2010 15:55:02 +0200 (CEST)
Subject: [Python-checkins] r84735 - python/branches/py3k/Lib/test/test_nis.py
Message-ID: <20100912135502.BF17BEBDE@mail.python.org>
Author: benjamin.peterson
Date: Sun Sep 12 15:55:02 2010
New Revision: 84735
Log:
reenable test_nis on solaris #3402
Modified:
python/branches/py3k/Lib/test/test_nis.py
Modified: python/branches/py3k/Lib/test/test_nis.py
==============================================================================
--- python/branches/py3k/Lib/test/test_nis.py (original)
+++ python/branches/py3k/Lib/test/test_nis.py Sun Sep 12 15:55:02 2010
@@ -5,8 +5,6 @@
# Skip test if nis module does not exist.
nis = support.import_module('nis')
-if sys.platform.startswith("sunos"):
- raise unittest.SkipTest("test_nis hangs on Solaris")
class NisTests(unittest.TestCase):
def test_maps(self):
From python-checkins at python.org Sun Sep 12 15:58:40 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 12 Sep 2010 15:58:40 +0200 (CEST)
Subject: [Python-checkins] r84736 - in python/branches/release31-maint:
Lib/test/test_nis.py
Message-ID: <20100912135840.2C1EDF045@mail.python.org>
Author: benjamin.peterson
Date: Sun Sep 12 15:58:34 2010
New Revision: 84736
Log:
Merged revisions 84735 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84735 | benjamin.peterson | 2010-09-12 08:55:02 -0500 (Sun, 12 Sep 2010) | 1 line
reenable test_nis on solaris #3402
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_nis.py
Modified: python/branches/release31-maint/Lib/test/test_nis.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_nis.py (original)
+++ python/branches/release31-maint/Lib/test/test_nis.py Sun Sep 12 15:58:34 2010
@@ -4,7 +4,6 @@
# Skip test if nis module does not exist.
nis = support.import_module('nis')
-raise unittest.SkipTest("test_nis hangs on Solaris")
class NisTests(unittest.TestCase):
def test_maps(self):
From python-checkins at python.org Sun Sep 12 16:51:21 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Sep 2010 16:51:21 +0200 (CEST)
Subject: [Python-checkins] r84737 - in python/branches/py3k:
Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS
Message-ID: <20100912145121.18AF1EDAE@mail.python.org>
Author: antoine.pitrou
Date: Sun Sep 12 16:51:20 2010
New Revision: 84737
Log:
Issue #9837: The read() method of ZipExtFile objects (as returned by
ZipFile.open()) could return more bytes than requested.
Modified:
python/branches/py3k/Lib/test/test_zipfile.py
python/branches/py3k/Lib/zipfile.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/test/test_zipfile.py
==============================================================================
--- python/branches/py3k/Lib/test/test_zipfile.py (original)
+++ python/branches/py3k/Lib/test/test_zipfile.py Sun Sep 12 16:51:20 2010
@@ -939,6 +939,26 @@
def test_read_with_bad_crc_deflated(self):
self.check_read_with_bad_crc(zipfile.ZIP_DEFLATED)
+ def check_read_return_size(self, compression):
+ # Issue #9837: ZipExtFile.read() shouldn't return more bytes
+ # than requested.
+ for test_size in (1, 4095, 4096, 4097, 16384):
+ file_size = test_size + 1
+ junk = b''.join(struct.pack('B', randint(0, 255))
+ for x in range(file_size))
+ with zipfile.ZipFile(io.BytesIO(), "w", compression) as zipf:
+ zipf.writestr('foo', junk)
+ with zipf.open('foo', 'r') as fp:
+ buf = fp.read(test_size)
+ self.assertEqual(len(buf), test_size)
+
+ def test_read_return_size_stored(self):
+ self.check_read_return_size(zipfile.ZIP_STORED)
+
+ @skipUnless(zlib, "requires zlib")
+ def test_read_return_size_deflated(self):
+ self.check_read_return_size(zipfile.ZIP_DEFLATED)
+
def tearDown(self):
unlink(TESTFN)
unlink(TESTFN2)
Modified: python/branches/py3k/Lib/zipfile.py
==============================================================================
--- python/branches/py3k/Lib/zipfile.py (original)
+++ python/branches/py3k/Lib/zipfile.py Sun Sep 12 16:51:20 2010
@@ -564,17 +564,20 @@
"""Read and return up to n bytes.
If the argument is omitted, None, or negative, data is read and returned until EOF is reached..
"""
-
buf = b''
- while n < 0 or n is None or n > len(buf):
- data = self.read1(n)
+ if n is None:
+ n = -1
+ while True:
+ if n < 0:
+ data = self.read1(n)
+ elif n > len(buf):
+ data = self.read1(n - len(buf))
+ else:
+ return buf
if len(data) == 0:
return buf
-
buf += data
- return buf
-
def _update_crc(self, newdata, eof):
# Update the CRC using the given data.
if self._expected_crc is None:
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 12 16:51:20 2010
@@ -32,6 +32,9 @@
Library
-------
+- Issue #9837: The read() method of ZipExtFile objects (as returned by
+ ZipFile.open()) could return more bytes than requested.
+
- Issue #9826: OrderedDict.__repr__ can now handle self-referential
values: d['x'] = d.
From python-checkins at python.org Sun Sep 12 16:55:22 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Sep 2010 16:55:22 +0200 (CEST)
Subject: [Python-checkins] r84738 - in python/branches/release31-maint:
Lib/test/test_zipfile.py
Message-ID: <20100912145522.5F8CEF275@mail.python.org>
Author: antoine.pitrou
Date: Sun Sep 12 16:55:22 2010
New Revision: 84738
Log:
Merged revisions 84737 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
Only the tests are merged, 3.1 doesn't exhibit the issue.
........
r84737 | antoine.pitrou | 2010-09-12 16:51:20 +0200 (dim., 12 sept. 2010) | 4 lines
Issue #9837: The read() method of ZipExtFile objects (as returned by
ZipFile.open()) could return more bytes than requested.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/test/test_zipfile.py
Modified: python/branches/release31-maint/Lib/test/test_zipfile.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_zipfile.py (original)
+++ python/branches/release31-maint/Lib/test/test_zipfile.py Sun Sep 12 16:55:22 2010
@@ -879,6 +879,29 @@
def test_read_with_bad_crc_deflated(self):
self.check_read_with_bad_crc(zipfile.ZIP_DEFLATED)
+ def check_read_return_size(self, compression):
+ # Issue #9837: ZipExtFile.read() shouldn't return more bytes
+ # than requested.
+ for test_size in (1, 4095, 4096, 4097, 16384):
+ file_size = test_size + 1
+ junk = b''.join(struct.pack('B', randint(0, 255))
+ for x in range(file_size))
+ zipf = zipfile.ZipFile(io.BytesIO(), "w", compression)
+ try:
+ zipf.writestr('foo', junk)
+ fp = zipf.open('foo', 'r')
+ buf = fp.read(test_size)
+ self.assertEqual(len(buf), test_size)
+ finally:
+ zipf.close()
+
+ def test_read_return_size_stored(self):
+ self.check_read_return_size(zipfile.ZIP_STORED)
+
+ if zlib:
+ def test_read_return_size_deflated(self):
+ self.check_read_return_size(zipfile.ZIP_DEFLATED)
+
def tearDown(self):
support.unlink(TESTFN)
support.unlink(TESTFN2)
From python-checkins at python.org Sun Sep 12 16:56:27 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Sep 2010 16:56:27 +0200 (CEST)
Subject: [Python-checkins] r84739 - in python/branches/release27-maint:
Lib/test/test_zipfile.py Lib/zipfile.py Misc/NEWS
Message-ID: <20100912145627.A85A4DD6C@mail.python.org>
Author: antoine.pitrou
Date: Sun Sep 12 16:56:27 2010
New Revision: 84739
Log:
Merged revisions 84737 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84737 | antoine.pitrou | 2010-09-12 16:51:20 +0200 (dim., 12 sept. 2010) | 4 lines
Issue #9837: The read() method of ZipExtFile objects (as returned by
ZipFile.open()) could return more bytes than requested.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/test/test_zipfile.py
python/branches/release27-maint/Lib/zipfile.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/test/test_zipfile.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_zipfile.py (original)
+++ python/branches/release27-maint/Lib/test/test_zipfile.py Sun Sep 12 16:56:27 2010
@@ -929,6 +929,26 @@
def test_read_with_bad_crc_deflated(self):
self.check_read_with_bad_crc(zipfile.ZIP_DEFLATED)
+ def check_read_return_size(self, compression):
+ # Issue #9837: ZipExtFile.read() shouldn't return more bytes
+ # than requested.
+ for test_size in (1, 4095, 4096, 4097, 16384):
+ file_size = test_size + 1
+ junk = b''.join(struct.pack('B', randint(0, 255))
+ for x in range(file_size))
+ with zipfile.ZipFile(io.BytesIO(), "w", compression) as zipf:
+ zipf.writestr('foo', junk)
+ with zipf.open('foo', 'r') as fp:
+ buf = fp.read(test_size)
+ self.assertEqual(len(buf), test_size)
+
+ def test_read_return_size_stored(self):
+ self.check_read_return_size(zipfile.ZIP_STORED)
+
+ @skipUnless(zlib, "requires zlib")
+ def test_read_return_size_deflated(self):
+ self.check_read_return_size(zipfile.ZIP_DEFLATED)
+
def tearDown(self):
unlink(TESTFN)
unlink(TESTFN2)
Modified: python/branches/release27-maint/Lib/zipfile.py
==============================================================================
--- python/branches/release27-maint/Lib/zipfile.py (original)
+++ python/branches/release27-maint/Lib/zipfile.py Sun Sep 12 16:56:27 2010
@@ -565,17 +565,20 @@
"""Read and return up to n bytes.
If the argument is omitted, None, or negative, data is read and returned until EOF is reached..
"""
-
buf = ''
- while n < 0 or n is None or n > len(buf):
- data = self.read1(n)
+ if n is None:
+ n = -1
+ while True:
+ if n < 0:
+ data = self.read1(n)
+ elif n > len(buf):
+ data = self.read1(n - len(buf))
+ else:
+ return buf
if len(data) == 0:
return buf
-
buf += data
- return buf
-
def _update_crc(self, newdata, eof):
# Update the CRC using the given data.
if self._expected_crc is None:
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Sun Sep 12 16:56:27 2010
@@ -43,6 +43,9 @@
Library
-------
+- Issue #9837: The read() method of ZipExtFile objects (as returned by
+ ZipFile.open()) could return more bytes than requested.
+
- Issue #9825: removed __del__ from the definition of collections.OrderedDict.
This prevents user-created self-referencing ordered dictionaries from
becoming permanently uncollectable GC garbage. The downside is that
From python-checkins at python.org Sun Sep 12 16:57:22 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Sun, 12 Sep 2010 16:57:22 +0200 (CEST)
Subject: [Python-checkins] r84740 - python/branches/release27-maint/Modules
Message-ID: <20100912145722.BAA5EE381@mail.python.org>
Author: antoine.pitrou
Date: Sun Sep 12 16:57:22 2010
New Revision: 84740
Log:
Add Modules/ld_so_aix to svn:ignore
Modified:
python/branches/release27-maint/Modules/ (props changed)
From python-checkins at python.org Sun Sep 12 18:06:18 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun, 12 Sep 2010 18:06:18 +0200 (CEST)
Subject: [Python-checkins] r84741 -
python/branches/py3k/Modules/_ctypes/_ctypes.c
Message-ID: <20100912160618.62E18F860@mail.python.org>
Author: hirokazu.yamamoto
Date: Sun Sep 12 18:06:18 2010
New Revision: 84741
Log:
Fixed refcount bug. I placed Py_INCREF in create_comerror() for compatibility
with Python2.7.
Modified:
python/branches/py3k/Modules/_ctypes/_ctypes.c
Modified: python/branches/py3k/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/py3k/Modules/_ctypes/_ctypes.c (original)
+++ python/branches/py3k/Modules/_ctypes/_ctypes.c Sun Sep 12 18:06:18 2010
@@ -5120,6 +5120,7 @@
PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
if (PyType_Ready(&PyComError_Type) < 0)
return -1;
+ Py_INCREF(&PyComError_Type);
ComError = (PyObject*)&PyComError_Type;
return 0;
}
From python-checkins at python.org Sun Sep 12 18:19:05 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Sun, 12 Sep 2010 18:19:05 +0200 (CEST)
Subject: [Python-checkins] r84742 - in python/branches/release31-maint:
Modules/_ctypes/_ctypes.c
Message-ID: <20100912161905.84945FA7A@mail.python.org>
Author: hirokazu.yamamoto
Date: Sun Sep 12 18:19:05 2010
New Revision: 84742
Log:
Merged revisions 83841,84741 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r83841 | thomas.heller | 2010-08-09 03:16:20 +0900 | 2 lines
Fix issue6869: refcount problem in the _ctypes extension.
........
r84741 | hirokazu.yamamoto | 2010-09-13 01:06:18 +0900 | 2 lines
Fixed refcount bug. I placed Py_INCREF in create_comerror() for compatibility
with Python2.7.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Modules/_ctypes/_ctypes.c
Modified: python/branches/release31-maint/Modules/_ctypes/_ctypes.c
==============================================================================
--- python/branches/release31-maint/Modules/_ctypes/_ctypes.c (original)
+++ python/branches/release31-maint/Modules/_ctypes/_ctypes.c Sun Sep 12 18:19:05 2010
@@ -5134,6 +5134,7 @@
PyComError_Type.tp_base = (PyTypeObject*)PyExc_Exception;
if (PyType_Ready(&PyComError_Type) < 0)
return -1;
+ Py_INCREF(&PyComError_Type);
ComError = (PyObject*)&PyComError_Type;
return 0;
}
@@ -5326,36 +5327,42 @@
Struct_Type.tp_base = &PyCData_Type;
if (PyType_Ready(&Struct_Type) < 0)
return NULL;
+ Py_INCREF(&Struct_Type);
PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
Py_TYPE(&Union_Type) = &UnionType_Type;
Union_Type.tp_base = &PyCData_Type;
if (PyType_Ready(&Union_Type) < 0)
return NULL;
+ Py_INCREF(&Union_Type);
PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
Py_TYPE(&PyCPointer_Type) = &PyCPointerType_Type;
PyCPointer_Type.tp_base = &PyCData_Type;
if (PyType_Ready(&PyCPointer_Type) < 0)
return NULL;
+ Py_INCREF(&PyCPointer_Type);
PyModule_AddObject(m, "_Pointer", (PyObject *)&PyCPointer_Type);
Py_TYPE(&PyCArray_Type) = &PyCArrayType_Type;
PyCArray_Type.tp_base = &PyCData_Type;
if (PyType_Ready(&PyCArray_Type) < 0)
return NULL;
+ Py_INCREF(&PyCArray_Type);
PyModule_AddObject(m, "Array", (PyObject *)&PyCArray_Type);
Py_TYPE(&Simple_Type) = &PyCSimpleType_Type;
Simple_Type.tp_base = &PyCData_Type;
if (PyType_Ready(&Simple_Type) < 0)
return NULL;
+ Py_INCREF(&Simple_Type);
PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
Py_TYPE(&PyCFuncPtr_Type) = &PyCFuncPtrType_Type;
PyCFuncPtr_Type.tp_base = &PyCData_Type;
if (PyType_Ready(&PyCFuncPtr_Type) < 0)
return NULL;
+ Py_INCREF(&PyCFuncPtr_Type);
PyModule_AddObject(m, "CFuncPtr", (PyObject *)&PyCFuncPtr_Type);
/*************************************************
From python-checkins at python.org Sun Sep 12 18:31:58 2010
From: python-checkins at python.org (matthias.klose)
Date: Sun, 12 Sep 2010 18:31:58 +0200 (CEST)
Subject: [Python-checkins] r84743 - in python/branches/py3k: Doc/license.rst
Misc/NEWS Modules/expat/COPYING
Message-ID: <20100912163158.7902EF11D@mail.python.org>
Author: matthias.klose
Date: Sun Sep 12 18:31:58 2010
New Revision: 84743
Log:
- Issue #9817: Add expat COPYING file; add expat, libffi and expat licenses
to Doc/license.rst.
Added:
python/branches/py3k/Modules/expat/COPYING
Modified:
python/branches/py3k/Doc/license.rst
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/license.rst
==============================================================================
--- python/branches/py3k/Doc/license.rst (original)
+++ python/branches/py3k/Doc/license.rst Sun Sep 12 18:31:58 2010
@@ -704,3 +704,92 @@
***************************************************************/
+expat
+-----
+
+The :mod:`pyexpat` extension is built using an included copy of the expat
+sources unless the build is configured :option:`--with-system-expat`::
+
+ Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ and Clark Cooper
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+libffi
+------
+
+The :mod:`_ctypes` extension is built using an included copy of the libffi
+sources unless the build is configured :option:`--with-system-libffi`::
+
+ Copyright (c) 1996-2008 Red Hat, Inc and others.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+
+zlib
+----
+
+The :mod:`zlib` extension is built using an included copy of the zlib
+sources unless the zlib version found on the system is too old to be
+used for the build::
+
+ Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup at gzip.org madler at alumni.caltech.edu
+
+
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 12 18:31:58 2010
@@ -2280,6 +2280,9 @@
Documentation
-------------
+- Issue #9817: Add expat COPYING file; add expat, libffi and expat licenses
+ to Doc/license.rst.
+
- Issue #9524: Document that two CTRL* signals are meant for use only
with os.kill.
Added: python/branches/py3k/Modules/expat/COPYING
==============================================================================
--- (empty file)
+++ python/branches/py3k/Modules/expat/COPYING Sun Sep 12 18:31:58 2010
@@ -0,0 +1,21 @@
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ and Clark Cooper
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
From python-checkins at python.org Sun Sep 12 18:40:53 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Sun, 12 Sep 2010 18:40:53 +0200 (CEST)
Subject: [Python-checkins] r84744 -
python/branches/py3k/Objects/unicodeobject.c
Message-ID: <20100912164053.CB6F9EBDE@mail.python.org>
Author: benjamin.peterson
Date: Sun Sep 12 18:40:53 2010
New Revision: 84744
Log:
use return NULL; it's just as correct
Modified:
python/branches/py3k/Objects/unicodeobject.c
Modified: python/branches/py3k/Objects/unicodeobject.c
==============================================================================
--- python/branches/py3k/Objects/unicodeobject.c (original)
+++ python/branches/py3k/Objects/unicodeobject.c Sun Sep 12 18:40:53 2010
@@ -769,7 +769,7 @@
"PyUnicode_FromFormatV() expects an ASCII-encoded format "
"string, got a non-ASCII byte: 0x%02x",
(unsigned char)*f);
- goto fail;
+ return NULL;
}
}
/* step 2: allocate memory for the results of
From python-checkins at python.org Sun Sep 12 18:50:20 2010
From: python-checkins at python.org (matthias.klose)
Date: Sun, 12 Sep 2010 18:50:20 +0200 (CEST)
Subject: [Python-checkins] r84745 - in python/branches/release31-maint:
Doc/license.rst Misc/NEWS Modules/expat/COPYING
Message-ID: <20100912165020.C37EAEBDE@mail.python.org>
Author: matthias.klose
Date: Sun Sep 12 18:50:20 2010
New Revision: 84745
Log:
Merged revisions 84743 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84743 | matthias.klose | 2010-09-12 18:31:58 +0200 (So, 12 Sep 2010) | 3 lines
- Issue #9817: Add expat COPYING file; add expat, libffi and expat licenses
to Doc/license.rst.
........
Added:
python/branches/release31-maint/Modules/expat/COPYING
- copied unchanged from r84743, /python/branches/py3k/Modules/expat/COPYING
Modified:
python/branches/release31-maint/Doc/license.rst
python/branches/release31-maint/Misc/NEWS
Modified: python/branches/release31-maint/Doc/license.rst
==============================================================================
--- python/branches/release31-maint/Doc/license.rst (original)
+++ python/branches/release31-maint/Doc/license.rst Sun Sep 12 18:50:20 2010
@@ -701,3 +701,92 @@
***************************************************************/
+expat
+-----
+
+The :mod:`pyexpat` extension is built using an included copy of the expat
+sources unless the build is configured :option:`--with-system-expat`::
+
+ Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ and Clark Cooper
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+libffi
+------
+
+The :mod:`_ctypes` extension is built using an included copy of the libffi
+sources unless the build is configured :option:`--with-system-libffi`::
+
+ Copyright (c) 1996-2008 Red Hat, Inc and others.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+
+zlib
+----
+
+The :mod:`zlib` extension is built using an included copy of the zlib
+sources unless the zlib version found on the system is too old to be
+used for the build::
+
+ Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup at gzip.org madler at alumni.caltech.edu
+
+
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Sun Sep 12 18:50:20 2010
@@ -622,6 +622,9 @@
Documentation
-------------
+- Issue #9817: Add expat COPYING file; add expat, libffi and expat licenses
+ to Doc/license.rst.
+
- Issue #9255: Document that the 'test' package is meant for interal Python use
only.
From python-checkins at python.org Sun Sep 12 18:51:29 2010
From: python-checkins at python.org (matthias.klose)
Date: Sun, 12 Sep 2010 18:51:29 +0200 (CEST)
Subject: [Python-checkins] r84746 - in python/branches/release27-maint:
Doc/license.rst Misc/NEWS Modules/expat/COPYING
Message-ID: <20100912165129.B53F7F9D0@mail.python.org>
Author: matthias.klose
Date: Sun Sep 12 18:51:29 2010
New Revision: 84746
Log:
Merged revisions 84743 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84743 | matthias.klose | 2010-09-12 18:31:58 +0200 (So, 12 Sep 2010) | 3 lines
- Issue #9817: Add expat COPYING file; add expat, libffi and expat licenses
to Doc/license.rst.
........
Added:
python/branches/release27-maint/Modules/expat/COPYING
- copied unchanged from r84743, /python/branches/py3k/Modules/expat/COPYING
Modified:
python/branches/release27-maint/Doc/license.rst
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Doc/license.rst
==============================================================================
--- python/branches/release27-maint/Doc/license.rst (original)
+++ python/branches/release27-maint/Doc/license.rst Sun Sep 12 18:51:29 2010
@@ -748,3 +748,92 @@
***************************************************************/
+expat
+-----
+
+The :mod:`pyexpat` extension is built using an included copy of the expat
+sources unless the build is configured :option:`--with-system-expat`::
+
+ Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+ and Clark Cooper
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+libffi
+------
+
+The :mod:`_ctypes` extension is built using an included copy of the libffi
+sources unless the build is configured :option:`--with-system-libffi`::
+
+ Copyright (c) 1996-2008 Red Hat, Inc and others.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+
+
+zlib
+----
+
+The :mod:`zlib` extension is built using an included copy of the zlib
+sources unless the zlib version found on the system is too old to be
+used for the build::
+
+ Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup at gzip.org madler at alumni.caltech.edu
+
+
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Sun Sep 12 18:51:29 2010
@@ -351,6 +351,9 @@
Documentation
-------------
+- Issue #9817: Add expat COPYING file; add expat, libffi and expat licenses
+ to Doc/license.rst.
+
- Issue #9524: Document that two CTRL* signals are meant for use only
with os.kill.
From python-checkins at python.org Sun Sep 12 19:14:26 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 12 Sep 2010 19:14:26 +0200 (CEST)
Subject: [Python-checkins] r84747 - in python/branches/py3k/Misc: NEWS
python-config.in
Message-ID: <20100912171426.CFAABD9B7@mail.python.org>
Author: georg.brandl
Date: Sun Sep 12 19:14:26 2010
New Revision: 84747
Log:
9806: add --extension-suffix option to python-config.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/Misc/python-config.in
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Sun Sep 12 19:14:26 2010
@@ -137,6 +137,10 @@
Build
-----
+- Issue #9806: python-config now has an ``--extension-suffix`` option that
+ outputs the suffix for dynamic libraries including the ABI version name
+ defined by PEP 3149.
+
- Issue #941346: Improve the build process under AIX and allow Python to
be built as a shared library. Patch by S?bastien Sabl?.
Modified: python/branches/py3k/Misc/python-config.in
==============================================================================
--- python/branches/py3k/Misc/python-config.in (original)
+++ python/branches/py3k/Misc/python-config.in Sun Sep 12 19:14:26 2010
@@ -6,7 +6,7 @@
import sysconfig
valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags',
- 'ldflags', 'help']
+ 'ldflags', 'extension-suffix', 'help']
def exit_with_usage(code=1):
print("Usage: {0} [{1}]".format(
@@ -54,3 +54,5 @@
libs.extend(getvar('LINKFORSHARED').split())
print(' '.join(libs))
+ elif opt == '--extension-suffix':
+ print(sysconfig.get_config_var('SO'))
From python-checkins at python.org Sun Sep 12 20:13:47 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 12 Sep 2010 20:13:47 +0200 (CEST)
Subject: [Python-checkins] r84748 - python/branches/py3k/Lib/collections.py
Message-ID: <20100912181347.03FB2E381@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 12 20:13:46 2010
New Revision: 84748
Log:
Use weakrefs for both forward and backward links.
Modified:
python/branches/py3k/Lib/collections.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Sun Sep 12 20:13:46 2010
@@ -31,7 +31,9 @@
# The internal self.__map dictionary maps keys to links in a doubly linked list.
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
- # The back links are weakref proxies (to prevent circular references).
+ # The prev/next links are weakref proxies (to prevent circular references).
+ # Individual links are kept alive by the hard reference in self.__map.
+ # Those hard references disappear when a key is deleted from an OrderedDict.
def __init__(self, *args, **kwds):
'''Initialize an ordered dictionary. Signature is the same as for
@@ -60,8 +62,7 @@
root = self.__root
last = root.prev
link.prev, link.next, link.key = last, root, key
- last.next = link
- root.prev = proxy(link)
+ last.next = root.prev = proxy(link)
dict.__setitem__(self, key, value)
def __delitem__(self, key, dict_delitem=dict.__delitem__):
From python-checkins at python.org Sun Sep 12 20:16:01 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Sun, 12 Sep 2010 20:16:01 +0200 (CEST)
Subject: [Python-checkins] r84749 - python/branches/py3k/Lib/collections.py
Message-ID: <20100912181601.413F0F09D@mail.python.org>
Author: raymond.hettinger
Date: Sun Sep 12 20:16:01 2010
New Revision: 84749
Log:
Put tests in more logical order.
Modified:
python/branches/py3k/Lib/collections.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Sun Sep 12 20:16:01 2010
@@ -169,10 +169,10 @@
def __repr__(self):
'od.__repr__() <==> repr(od)'
- if self.__in_repr:
- return '...'
if not self:
return '%s()' % (self.__class__.__name__,)
+ if self.__in_repr:
+ return '...'
self.__in_repr = True
try:
result = '%s(%r)' % (self.__class__.__name__, list(self.items()))
From python-checkins at python.org Sun Sep 12 22:32:57 2010
From: python-checkins at python.org (victor.stinner)
Date: Sun, 12 Sep 2010 22:32:57 +0200 (CEST)
Subject: [Python-checkins] r84750 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100912203257.3E7CCEE981@mail.python.org>
Author: victor.stinner
Date: Sun Sep 12 22:32:57 2010
New Revision: 84750
Log:
Document changes on mbcs encoding
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Sun Sep 12 22:32:57 2010
@@ -544,3 +544,10 @@
opaque C pointers in Python objects, the :ctype:`PyCapsule` API should be used
instead; the new type has a well-defined interface for passing typing safety
information and a less complicated signature for calling a destructor.
+
+* mbcs encoding doesn't ignore the error handler argument anymore. By default
+ (strict mode), it raises an UnicodeDecodeError on undecodable byte sequence
+ and UnicodeEncodeError on unencodable character. To get the mbcs encoding of
+ Python 3.1, use ``'ignore'`` error handler to decode and ``'replace'`` error
+ handler to encode. mbcs now supports ``'strict'`` and ``'ignore'`` error
+ handlers for decoding, and ``'strict'`` and ``'replace'`` for encoding.
From python-checkins at python.org Sun Sep 12 22:58:19 2010
From: python-checkins at python.org (georg.brandl)
Date: Sun, 12 Sep 2010 22:58:19 +0200 (CEST)
Subject: [Python-checkins] r84751 -
python/branches/py3k/Misc/python-config.in
Message-ID: <20100912205819.CF49EF0F1@mail.python.org>
Author: georg.brandl
Date: Sun Sep 12 22:58:19 2010
New Revision: 84751
Log:
Get rid of tabs.
Modified:
python/branches/py3k/Misc/python-config.in
Modified: python/branches/py3k/Misc/python-config.in
==============================================================================
--- python/branches/py3k/Misc/python-config.in (original)
+++ python/branches/py3k/Misc/python-config.in Sun Sep 12 22:58:19 2010
@@ -55,4 +55,4 @@
print(' '.join(libs))
elif opt == '--extension-suffix':
- print(sysconfig.get_config_var('SO'))
+ print(sysconfig.get_config_var('SO'))
From python-checkins at python.org Mon Sep 13 00:42:57 2010
From: python-checkins at python.org (amaury.forgeotdarc)
Date: Mon, 13 Sep 2010 00:42:57 +0200 (CEST)
Subject: [Python-checkins] r84752 - in python/branches/py3k:
Doc/whatsnew/3.2.rst Include/unicodeobject.h Misc/NEWS
Objects/unicodectype.c Objects/unicodetype_db.h
Tools/unicode/makeunicodedata.py configure configure.in
pyconfig.h.in
Message-ID: <20100912224257.E3472F4F4@mail.python.org>
Author: amaury.forgeotdarc
Date: Mon Sep 13 00:42:57 2010
New Revision: 84752
Log:
#9210: remove --with-wctype-functions configure option.
The internal unicode database is now always used.
(after 5 years: see
http://mail.python.org/pipermail/python-dev/2004-December/050193.html
)
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
python/branches/py3k/Include/unicodeobject.h
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/unicodectype.c
python/branches/py3k/Objects/unicodetype_db.h
python/branches/py3k/Tools/unicode/makeunicodedata.py
python/branches/py3k/configure
python/branches/py3k/configure.in
python/branches/py3k/pyconfig.h.in
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Mon Sep 13 00:42:57 2010
@@ -525,6 +525,11 @@
(Contributed by Antoine Pitrou; :issue:`9203`.)
+* The option ``--with-wctype-functions`` was removed. The built-in unicode
+ database is now used for all functions.
+
+ (Contributed by Amaury Forgeot D'Arc; :issue:`9210`.)
+
Porting to Python 3.2
=====================
Modified: python/branches/py3k/Include/unicodeobject.h
==============================================================================
--- python/branches/py3k/Include/unicodeobject.h (original)
+++ python/branches/py3k/Include/unicodeobject.h Mon Sep 13 00:42:57 2010
@@ -78,7 +78,7 @@
#define Py_UNICODE_WIDE
#endif
-/* Set these flags if the platform has "wchar.h", "wctype.h" and the
+/* Set these flags if the platform has "wchar.h" and the
wchar_t type is a 16-bit unsigned type */
/* #define HAVE_WCHAR_H */
/* #define HAVE_USABLE_WCHAR_T */
@@ -309,39 +309,6 @@
/* --- Internal Unicode Operations ---------------------------------------- */
-/* If you want Python to use the compiler's wctype.h functions instead
- of the ones supplied with Python, define WANT_WCTYPE_FUNCTIONS or
- configure Python using --with-wctype-functions. This reduces the
- interpreter's code size. */
-
-#if defined(Py_UNICODE_WIDE) && defined(HAVE_USABLE_WCHAR_T) && defined(WANT_WCTYPE_FUNCTIONS)
-
-#include
-
-#define Py_UNICODE_ISSPACE(ch) iswspace(ch)
-
-#define Py_UNICODE_ISLOWER(ch) iswlower(ch)
-#define Py_UNICODE_ISUPPER(ch) iswupper(ch)
-#define Py_UNICODE_ISTITLE(ch) _PyUnicode_IsTitlecase(ch)
-#define Py_UNICODE_ISLINEBREAK(ch) _PyUnicode_IsLinebreak(ch)
-
-#define Py_UNICODE_TOLOWER(ch) towlower(ch)
-#define Py_UNICODE_TOUPPER(ch) towupper(ch)
-#define Py_UNICODE_TOTITLE(ch) _PyUnicode_ToTitlecase(ch)
-
-#define Py_UNICODE_ISDECIMAL(ch) _PyUnicode_IsDecimalDigit(ch)
-#define Py_UNICODE_ISDIGIT(ch) _PyUnicode_IsDigit(ch)
-#define Py_UNICODE_ISNUMERIC(ch) _PyUnicode_IsNumeric(ch)
-#define Py_UNICODE_ISPRINTABLE(ch) _PyUnicode_IsPrintable(ch)
-
-#define Py_UNICODE_TODECIMAL(ch) _PyUnicode_ToDecimalDigit(ch)
-#define Py_UNICODE_TODIGIT(ch) _PyUnicode_ToDigit(ch)
-#define Py_UNICODE_TONUMERIC(ch) _PyUnicode_ToNumeric(ch)
-
-#define Py_UNICODE_ISALPHA(ch) iswalpha(ch)
-
-#else
-
/* Since splitting on whitespace is an important use case, and
whitespace in most situations is solely ASCII whitespace, we
optimize for the common case by using a quick look-up table
@@ -371,8 +338,6 @@
#define Py_UNICODE_ISALPHA(ch) _PyUnicode_IsAlpha(ch)
-#endif
-
#define Py_UNICODE_ISALNUM(ch) \
(Py_UNICODE_ISALPHA(ch) || \
Py_UNICODE_ISDECIMAL(ch) || \
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 00:42:57 2010
@@ -10,6 +10,10 @@
Core and Builtins
-----------------
+- Issue #9210: Configure option --with-wctype-functions was removed. Using the
+ functions from the libc caused the methods .upper() and lower() to become
+ locale aware and created subtly wrong results.
+
- Issue #9738: PyUnicode_FromFormat() and PyErr_Format() raise an error on
a non-ASCII byte in the format string.
Modified: python/branches/py3k/Objects/unicodectype.c
==============================================================================
--- python/branches/py3k/Objects/unicodectype.c (original)
+++ python/branches/py3k/Objects/unicodectype.c Mon Sep 13 00:42:57 2010
@@ -163,8 +163,6 @@
return (ctype->flags & PRINTABLE_MASK) != 0;
}
-#ifndef WANT_WCTYPE_FUNCTIONS
-
/* Returns 1 for Unicode characters having the category 'Ll', 0
otherwise. */
@@ -223,34 +221,3 @@
return (ctype->flags & ALPHA_MASK) != 0;
}
-#else
-
-/* Export the interfaces using the wchar_t type for portability
- reasons: */
-
-int _PyUnicode_IsLowercase(Py_UCS4 ch)
-{
- return iswlower(ch);
-}
-
-int _PyUnicode_IsUppercase(Py_UCS4 ch)
-{
- return iswupper(ch);
-}
-
-Py_UCS4 _PyUnicode_ToLowercase(Py_UCS4 ch)
-{
- return towlower(ch);
-}
-
-Py_UCS4 _PyUnicode_ToUppercase(Py_UCS4 ch)
-{
- return towupper(ch);
-}
-
-int _PyUnicode_IsAlpha(Py_UCS4 ch)
-{
- return iswalpha(ch);
-}
-
-#endif
Modified: python/branches/py3k/Objects/unicodetype_db.h
==============================================================================
--- python/branches/py3k/Objects/unicodetype_db.h (original)
+++ python/branches/py3k/Objects/unicodetype_db.h Mon Sep 13 00:42:57 2010
@@ -3247,9 +3247,6 @@
*/
int _PyUnicode_IsWhitespace(register const Py_UCS4 ch)
{
-#ifdef WANT_WCTYPE_FUNCTIONS
- return iswspace(ch);
-#else
switch (ch) {
case 0x0009:
case 0x000A:
@@ -3284,7 +3281,6 @@
return 1;
}
return 0;
-#endif
}
/* Returns 1 for Unicode characters having the line break
Modified: python/branches/py3k/Tools/unicode/makeunicodedata.py
==============================================================================
--- python/branches/py3k/Tools/unicode/makeunicodedata.py (original)
+++ python/branches/py3k/Tools/unicode/makeunicodedata.py Mon Sep 13 00:42:57 2010
@@ -503,9 +503,6 @@
print(" */", file=fp)
print('int _PyUnicode_IsWhitespace(register const Py_UCS4 ch)', file=fp)
print('{', file=fp)
- print('#ifdef WANT_WCTYPE_FUNCTIONS', file=fp)
- print(' return iswspace(ch);', file=fp)
- print('#else', file=fp)
print(' switch (ch) {', file=fp)
for codepoint in sorted(spaces):
@@ -514,7 +511,6 @@
print(' }', file=fp)
print(' return 0;', file=fp)
- print('#endif', file=fp)
print('}', file=fp)
print(file=fp)
Modified: python/branches/py3k/configure
==============================================================================
--- python/branches/py3k/configure (original)
+++ python/branches/py3k/configure Mon Sep 13 00:42:57 2010
@@ -747,7 +747,6 @@
with_tsc
with_pymalloc
with_valgrind
-with_wctype_functions
with_fpectl
with_libm
with_libc
@@ -1418,7 +1417,6 @@
--with(out)-tsc enable/disable timestamp counter profile
--with(out)-pymalloc disable/enable specialized mallocs
--with-valgrind Enable Valgrind support
- --with-wctype-functions use wctype.h functions
--with-fpectl enable SIGFPE catching
--with-libm=STRING math library
--with-libc=STRING C library
@@ -9232,28 +9230,6 @@
OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT"
fi
-# Check for --with-wctype-functions
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-wctype-functions" >&5
-$as_echo_n "checking for --with-wctype-functions... " >&6; }
-
-# Check whether --with-wctype-functions was given.
-if test "${with_wctype_functions+set}" = set; then :
- withval=$with_wctype_functions;
-if test "$withval" != no
-then
-
-$as_echo "#define WANT_WCTYPE_FUNCTIONS 1" >>confdefs.h
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
# -I${DLINCLDIR} is added to the compile rule for importdl.o
Modified: python/branches/py3k/configure.in
==============================================================================
--- python/branches/py3k/configure.in (original)
+++ python/branches/py3k/configure.in Mon Sep 13 00:42:57 2010
@@ -2493,21 +2493,6 @@
OPT="-DDYNAMIC_ANNOTATIONS_ENABLED=1 $OPT"
fi
-# Check for --with-wctype-functions
-AC_MSG_CHECKING(for --with-wctype-functions)
-AC_ARG_WITH(wctype-functions,
- AS_HELP_STRING([--with-wctype-functions], [use wctype.h functions]),
-[
-if test "$withval" != no
-then
- AC_DEFINE(WANT_WCTYPE_FUNCTIONS, 1,
- [Define if you want wctype.h functions to be used instead of the
- one supplied by Python itself. (see Include/unicodectype.h).])
- AC_MSG_RESULT(yes)
-else AC_MSG_RESULT(no)
-fi],
-[AC_MSG_RESULT(no)])
-
# -I${DLINCLDIR} is added to the compile rule for importdl.o
AC_SUBST(DLINCLDIR)
DLINCLDIR=.
Modified: python/branches/py3k/pyconfig.h.in
==============================================================================
--- python/branches/py3k/pyconfig.h.in (original)
+++ python/branches/py3k/pyconfig.h.in Mon Sep 13 00:42:57 2010
@@ -1077,10 +1077,6 @@
/* Define if you want SIGFPE handled (see Include/pyfpe.h). */
#undef WANT_SIGFPE_HANDLER
-/* Define if you want wctype.h functions to be used instead of the one
- supplied by Python itself. (see Include/unicodectype.h). */
-#undef WANT_WCTYPE_FUNCTIONS
-
/* Define if WINDOW in curses.h offers a field _flags. */
#undef WINDOW_HAS_FLAGS
From python-checkins at python.org Mon Sep 13 00:55:41 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 00:55:41 +0200 (CEST)
Subject: [Python-checkins] r84753 -
python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
Message-ID: <20100912225541.13B0DEE981@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 00:55:40 2010
New Revision: 84753
Log:
Issue #9313: Skips test_remove_visual_c_ref on old MSVC.
Modified:
python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
==============================================================================
--- python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py (original)
+++ python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py Mon Sep 13 00:55:40 2010
@@ -109,6 +109,11 @@
self.assertTrue('Desktop' in keys)
def test_remove_visual_c_ref(self):
+ from distutils.msvccompiler import get_build_version
+ if get_build_version() < 8.0:
+ # this test is only for MSVC8.0 or above
+ return
+
from distutils.msvc9compiler import MSVCCompiler
tempdir = self.mkdtemp()
manifest = os.path.join(tempdir, 'manifest')
From python-checkins at python.org Mon Sep 13 03:25:38 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Mon, 13 Sep 2010 03:25:38 +0200 (CEST)
Subject: [Python-checkins] r84754 - python/branches/py3k/Doc/library/imp.rst
Message-ID: <20100913012538.7626CFB4F@mail.python.org>
Author: benjamin.peterson
Date: Mon Sep 13 03:25:38 2010
New Revision: 84754
Log:
remove duplicate statement
Modified:
python/branches/py3k/Doc/library/imp.rst
Modified: python/branches/py3k/Doc/library/imp.rst
==============================================================================
--- python/branches/py3k/Doc/library/imp.rst (original)
+++ python/branches/py3k/Doc/library/imp.rst Mon Sep 13 03:25:38 2010
@@ -113,8 +113,7 @@
.. function:: acquire_lock()
Acquire the interpreter's import lock for the current thread. This lock should
- be used by import hooks to ensure thread-safety when importing modules. On
- platforms without threads, this function does nothing.
+ be used by import hooks to ensure thread-safety when importing modules.
Once a thread has acquired the import lock, the same thread may acquire it
again without blocking; the thread must release it once for each time it has
From python-checkins at python.org Mon Sep 13 03:30:04 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Mon, 13 Sep 2010 03:30:04 +0200 (CEST)
Subject: [Python-checkins] r84755 - python/branches/py3k/Doc/library/imp.rst
Message-ID: <20100913013004.838C0F76F@mail.python.org>
Author: benjamin.peterson
Date: Mon Sep 13 03:30:04 2010
New Revision: 84755
Log:
remove less complete of duplicate docs
Modified:
python/branches/py3k/Doc/library/imp.rst
Modified: python/branches/py3k/Doc/library/imp.rst
==============================================================================
--- python/branches/py3k/Doc/library/imp.rst (original)
+++ python/branches/py3k/Doc/library/imp.rst Mon Sep 13 03:30:04 2010
@@ -190,19 +190,6 @@
continue to use the old class definition. The same is true for derived classes.
-.. function:: acquire_lock()
-
- Acquires the interpreter's import lock for the current thread. This lock should
- be used by import hooks to ensure thread-safety when importing modules. On
- platforms without threads, this function does nothing.
-
-
-.. function:: release_lock()
-
- Release the interpreter's import lock. On platforms without threads, this
- function does nothing.
-
-
The following functions and data provide conveniences for handling :pep:`3147`
byte-compiled file paths.
From python-checkins at python.org Mon Sep 13 03:31:57 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Mon, 13 Sep 2010 03:31:57 +0200 (CEST)
Subject: [Python-checkins] r84756 - python/branches/py3k/Doc/library/imp.rst
Message-ID: <20100913013157.A1EABFD78@mail.python.org>
Author: benjamin.peterson
Date: Mon Sep 13 03:31:57 2010
New Revision: 84756
Log:
add spaces
Modified:
python/branches/py3k/Doc/library/imp.rst
Modified: python/branches/py3k/Doc/library/imp.rst
==============================================================================
--- python/branches/py3k/Doc/library/imp.rst (original)
+++ python/branches/py3k/Doc/library/imp.rst Mon Sep 13 03:31:57 2010
@@ -209,6 +209,7 @@
*path* need not exist.
+
.. function:: source_from_cache(path)
Given the *path* to a :pep:`3147` file name, return the associated source code
@@ -217,6 +218,7 @@
``/foo/bar/baz.py``. *path* need not exist, however if it does not conform
to :pep:`3147` format, a ``ValueError`` is raised.
+
.. function:: get_tag()
Return the :pep:`3147` magic tag string matching this version of Python's
From python-checkins at python.org Mon Sep 13 03:48:02 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Mon, 13 Sep 2010 03:48:02 +0200 (CEST)
Subject: [Python-checkins] r84757 - in python/branches/release27-maint:
Doc/library/imp.rst
Message-ID: <20100913014802.8EBEAF538@mail.python.org>
Author: benjamin.peterson
Date: Mon Sep 13 03:48:02 2010
New Revision: 84757
Log:
Merged revisions 84754 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84754 | benjamin.peterson | 2010-09-12 20:25:38 -0500 (Sun, 12 Sep 2010) | 1 line
remove duplicate statement
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Doc/library/imp.rst
Modified: python/branches/release27-maint/Doc/library/imp.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/imp.rst (original)
+++ python/branches/release27-maint/Doc/library/imp.rst Mon Sep 13 03:48:02 2010
@@ -116,8 +116,7 @@
.. function:: acquire_lock()
Acquire the interpreter's import lock for the current thread. This lock should
- be used by import hooks to ensure thread-safety when importing modules. On
- platforms without threads, this function does nothing.
+ be used by import hooks to ensure thread-safety when importing modules.
Once a thread has acquired the import lock, the same thread may acquire it
again without blocking; the thread must release it once for each time it has
From python-checkins at python.org Mon Sep 13 03:52:40 2010
From: python-checkins at python.org (benjamin.peterson)
Date: Mon, 13 Sep 2010 03:52:40 +0200 (CEST)
Subject: [Python-checkins] r84758 - in python/branches/release31-maint:
Doc/library/imp.rst
Message-ID: <20100913015240.4C920F43F@mail.python.org>
Author: benjamin.peterson
Date: Mon Sep 13 03:52:40 2010
New Revision: 84758
Log:
Merged revisions 84754-84755 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84754 | benjamin.peterson | 2010-09-12 20:25:38 -0500 (Sun, 12 Sep 2010) | 1 line
remove duplicate statement
........
r84755 | benjamin.peterson | 2010-09-12 20:30:04 -0500 (Sun, 12 Sep 2010) | 1 line
remove less complete of duplicate docs
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/library/imp.rst
Modified: python/branches/release31-maint/Doc/library/imp.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/imp.rst (original)
+++ python/branches/release31-maint/Doc/library/imp.rst Mon Sep 13 03:52:40 2010
@@ -113,8 +113,7 @@
.. function:: acquire_lock()
Acquire the interpreter's import lock for the current thread. This lock should
- be used by import hooks to ensure thread-safety when importing modules. On
- platforms without threads, this function does nothing.
+ be used by import hooks to ensure thread-safety when importing modules.
Once a thread has acquired the import lock, the same thread may acquire it
again without blocking; the thread must release it once for each time it has
@@ -191,19 +190,6 @@
continue to use the old class definition. The same is true for derived classes.
-.. function:: acquire_lock()
-
- Acquires the interpreter's import lock for the current thread. This lock should
- be used by import hooks to ensure thread-safety when importing modules. On
- platforms without threads, this function does nothing.
-
-
-.. function:: release_lock()
-
- Release the interpreter's import lock. On platforms without threads, this
- function does nothing.
-
-
The following constants with integer values, defined in this module, are used to
indicate the search result of :func:`find_module`.
From python-checkins at python.org Mon Sep 13 04:28:18 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 04:28:18 +0200 (CEST)
Subject: [Python-checkins] r84759 - in python/branches/py3k/Lib/test:
string_tests.py test_unicode.py
Message-ID: <20100913022818.BE69EFBBD@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 04:28:18 2010
New Revision: 84759
Log:
Reenable test_ucs4 and remove some duplicated lines.
Modified:
python/branches/py3k/Lib/test/string_tests.py
python/branches/py3k/Lib/test/test_unicode.py
Modified: python/branches/py3k/Lib/test/string_tests.py
==============================================================================
--- python/branches/py3k/Lib/test/string_tests.py (original)
+++ python/branches/py3k/Lib/test/string_tests.py Mon Sep 13 04:28:18 2010
@@ -1131,7 +1131,7 @@
format = '%%.%if' % prec
value = 0.01
for x in range(60):
- value = value * 3.141592655 / 3.0 * 10.0
+ value = value * 3.14159265359 / 3.0 * 10.0
self.checkcall(format, "__mod__", value)
def test_inplace_rewrites(self):
Modified: python/branches/py3k/Lib/test/test_unicode.py
==============================================================================
--- python/branches/py3k/Lib/test/test_unicode.py (original)
+++ python/branches/py3k/Lib/test/test_unicode.py Mon Sep 13 04:28:18 2010
@@ -62,7 +62,7 @@
self.assertRaises(SyntaxError, eval, '\'\\Uffffffff\'')
self.assertRaises(SyntaxError, eval, '\'\\U%08x\'' % 0x110000)
# raw strings should not have unicode escapes
- self.assertNotEquals(r"\u0020", " ")
+ self.assertNotEqual(r"\u0020", " ")
def test_ascii(self):
if not sys.platform.startswith('java'):
@@ -286,13 +286,7 @@
def test_comparison(self):
# Comparisons:
self.assertEqual('abc', 'abc')
- self.assertEqual('abc', 'abc')
- self.assertEqual('abc', 'abc')
- self.assertTrue('abcd' > 'abc')
self.assertTrue('abcd' > 'abc')
- self.assertTrue('abcd' > 'abc')
- self.assertTrue('abc' < 'abcd')
- self.assertTrue('abc' < 'abcd')
self.assertTrue('abc' < 'abcd')
if 0:
@@ -652,8 +646,6 @@
self.assertRaises(IndexError, '{1}'.format, 'abc')
self.assertRaises(KeyError, '{x}'.format)
self.assertRaises(ValueError, "}{".format)
- self.assertRaises(ValueError, "{".format)
- self.assertRaises(ValueError, "}".format)
self.assertRaises(ValueError, "abc{0:{}".format)
self.assertRaises(ValueError, "{0".format)
self.assertRaises(IndexError, "{0.}".format)
@@ -1265,21 +1257,20 @@
y = x.encode("raw-unicode-escape").decode("raw-unicode-escape")
self.assertEqual(x, y)
- # FIXME
- #y = r'\U00100000'
- #x = y.encode("raw-unicode-escape").decode("raw-unicode-escape")
- #self.assertEqual(x, y)
- #y = r'\U00010000'
- #x = y.encode("raw-unicode-escape").decode("raw-unicode-escape")
- #self.assertEqual(x, y)
-
- #try:
- # '\U11111111'.decode("raw-unicode-escape")
- #except UnicodeDecodeError as e:
- # self.assertEqual(e.start, 0)
- # self.assertEqual(e.end, 10)
- #else:
- # self.fail("Should have raised UnicodeDecodeError")
+ y = br'\U00100000'
+ x = y.decode("raw-unicode-escape").encode("raw-unicode-escape")
+ self.assertEqual(x, y)
+ y = br'\U00010000'
+ x = y.decode("raw-unicode-escape").encode("raw-unicode-escape")
+ self.assertEqual(x, y)
+
+ try:
+ br'\U11111111'.decode("raw-unicode-escape")
+ except UnicodeDecodeError as e:
+ self.assertEqual(e.start, 0)
+ self.assertEqual(e.end, 10)
+ else:
+ self.fail("Should have raised UnicodeDecodeError")
def test_conversion(self):
# Make sure __unicode__() works properly
@@ -1382,8 +1373,8 @@
def __str__(self):
return '__str__ overridden'
s = S('xxx')
- self.assertEquals("%s" % s, '__str__ overridden')
- self.assertEquals("{}".format(s), '__str__ overridden')
+ self.assertEqual("%s" % s, '__str__ overridden')
+ self.assertEqual("{}".format(s), '__str__ overridden')
def test_from_format(self):
# Ensure that PyUnicode_FromFormat() raises an error for a non-ascii
From solipsis at pitrou.net Mon Sep 13 05:09:34 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Mon, 13 Sep 2010 05:09:34 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84754): sum=0
Message-ID:
py3k results for svn r84754 (hg cset ca273dad2359)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogBn7lPm', '-x']
From python-checkins at python.org Mon Sep 13 07:36:21 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 07:36:21 +0200 (CEST)
Subject: [Python-checkins] r84760 -
python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
Message-ID: <20100913053621.38CE1F525@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 07:36:21 2010
New Revision: 84760
Log:
Issue #9313: Use unittest.skipUnless to skip old MSVC.
Modified:
python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
==============================================================================
--- python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py (original)
+++ python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py Mon Sep 13 07:36:21 2010
@@ -60,7 +60,12 @@
"""
+if sys.platform=="win32":
+ from distutils.msvccompiler import get_build_version
+
@unittest.skipUnless(sys.platform=="win32", "These tests are only for win32")
+ at unittest.skipUnless(get_build_version()>=8.0, "These tests are only for"
+ " MSVC8.0 or above")
class msvc9compilerTestCase(support.TempdirManager,
unittest.TestCase):
@@ -68,10 +73,6 @@
# makes sure query_vcvarsall throws
# a DistutilsPlatformError if the compiler
# is not found
- from distutils.msvccompiler import get_build_version
- if get_build_version() < 8.0:
- # this test is only for MSVC8.0 or above
- return
from distutils.msvc9compiler import query_vcvarsall
def _find_vcvarsall(version):
return None
@@ -86,11 +87,6 @@
msvc9compiler.find_vcvarsall = old_find_vcvarsall
def test_reg_class(self):
- from distutils.msvccompiler import get_build_version
- if get_build_version() < 8.0:
- # this test is only for MSVC8.0 or above
- return
-
from distutils.msvc9compiler import Reg
self.assertRaises(KeyError, Reg.get_value, 'xxx', 'xxx')
@@ -109,11 +105,6 @@
self.assertTrue('Desktop' in keys)
def test_remove_visual_c_ref(self):
- from distutils.msvccompiler import get_build_version
- if get_build_version() < 8.0:
- # this test is only for MSVC8.0 or above
- return
-
from distutils.msvc9compiler import MSVCCompiler
tempdir = self.mkdtemp()
manifest = os.path.join(tempdir, 'manifest')
From python-checkins at python.org Mon Sep 13 07:48:30 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 07:48:30 +0200 (CEST)
Subject: [Python-checkins] r84761 - in python/branches/release31-maint:
Lib/distutils/tests/test_msvc9compiler.py
Message-ID: <20100913054830.AA5D3EE998@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 07:48:30 2010
New Revision: 84761
Log:
Merged revisions 84753,84760 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84753 | hirokazu.yamamoto | 2010-09-13 07:55:40 +0900 | 1 line
Issue #9313: Skips test_remove_visual_c_ref on old MSVC.
........
r84760 | hirokazu.yamamoto | 2010-09-13 14:36:21 +0900 | 1 line
Issue #9313: Use unittest.skipUnless to skip old MSVC.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py
Modified: python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py
==============================================================================
--- python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py (original)
+++ python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py Mon Sep 13 07:48:30 2010
@@ -60,7 +60,12 @@
"""
+if sys.platform=="win32":
+ from distutils.msvccompiler import get_build_version
+
@unittest.skipUnless(sys.platform=="win32", "These tests are only for win32")
+ at unittest.skipUnless(get_build_version()>=8.0, "These tests are only for"
+ " MSVC8.0 or above")
class msvc9compilerTestCase(support.TempdirManager,
unittest.TestCase):
@@ -68,10 +73,6 @@
# makes sure query_vcvarsall throws
# a DistutilsPlatformError if the compiler
# is not found
- from distutils.msvccompiler import get_build_version
- if get_build_version() < 8.0:
- # this test is only for MSVC8.0 or above
- return
from distutils.msvc9compiler import query_vcvarsall
def _find_vcvarsall(version):
return None
@@ -86,11 +87,6 @@
msvc9compiler.find_vcvarsall = old_find_vcvarsall
def test_reg_class(self):
- from distutils.msvccompiler import get_build_version
- if get_build_version() < 8.0:
- # this test is only for MSVC8.0 or above
- return
-
from distutils.msvc9compiler import Reg
self.assertRaises(KeyError, Reg.get_value, 'xxx', 'xxx')
From python-checkins at python.org Mon Sep 13 07:59:39 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 07:59:39 +0200 (CEST)
Subject: [Python-checkins] r84762 - in python/branches/py3k/PC/VS8.0:
_multiprocessing.vcproj _sqlite3.vcproj bdist_wininst.vcproj
pyd.vsprops pyd_d.vsprops pyproject.vsprops pythoncore.vcproj
sqlite3.vcproj sqlite3.vsprops
Message-ID: <20100913055939.3464CF78A@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 07:59:38 2010
New Revision: 84762
Log:
Updated PC/VS8.0 with PCBuild/vs9to8.py.
Added:
python/branches/py3k/PC/VS8.0/sqlite3.vsprops
Modified:
python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj
python/branches/py3k/PC/VS8.0/_sqlite3.vcproj
python/branches/py3k/PC/VS8.0/bdist_wininst.vcproj
python/branches/py3k/PC/VS8.0/pyd.vsprops
python/branches/py3k/PC/VS8.0/pyd_d.vsprops
python/branches/py3k/PC/VS8.0/pyproject.vsprops
python/branches/py3k/PC/VS8.0/pythoncore.vcproj
python/branches/py3k/PC/VS8.0/sqlite3.vcproj
Modified: python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj (original)
+++ python/branches/py3k/PC/VS8.0/_multiprocessing.vcproj Mon Sep 13 07:59:38 2010
@@ -3,7 +3,7 @@
ProjectType="Visual C++"
Version="8.00"
Name="_multiprocessing"
- ProjectGUID="{9e48b300-37d1-11dd-8c41-005056c00008}"
+ ProjectGUID="{9E48B300-37D1-11DD-8C41-005056C00008}"
RootNamespace="_multiprocessing"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
Modified: python/branches/py3k/PC/VS8.0/_sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/_sqlite3.vcproj (original)
+++ python/branches/py3k/PC/VS8.0/_sqlite3.vcproj Mon Sep 13 07:59:38 2010
@@ -42,7 +42,7 @@
/>
+
+
+
-
-
@@ -847,6 +843,10 @@
>
+
+
@@ -879,7 +879,7 @@
>
+
+
@@ -947,10 +951,6 @@
>
-
-
@@ -998,38 +998,6 @@
RelativePath="..\..\Modules\_csv.c"
>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1075,6 +1043,14 @@
>
+
+
+
+
@@ -1175,10 +1151,6 @@
>
-
-
@@ -1195,6 +1167,42 @@
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
@@ -1771,7 +1775,7 @@
>
+
+
Modified: python/branches/py3k/PC/VS8.0/sqlite3.vcproj
==============================================================================
--- python/branches/py3k/PC/VS8.0/sqlite3.vcproj (original)
+++ python/branches/py3k/PC/VS8.0/sqlite3.vcproj Mon Sep 13 07:59:38 2010
@@ -22,7 +22,7 @@
@@ -166,8 +164,7 @@
/>
@@ -229,8 +226,7 @@
/>
@@ -291,8 +287,7 @@
/>
@@ -354,8 +349,7 @@
/>
@@ -415,8 +409,7 @@
/>
@@ -478,8 +471,7 @@
/>
@@ -535,7 +527,7 @@
Name="Source Files"
>
Added: python/branches/py3k/PC/VS8.0/sqlite3.vsprops
==============================================================================
--- (empty file)
+++ python/branches/py3k/PC/VS8.0/sqlite3.vsprops Mon Sep 13 07:59:38 2010
@@ -0,0 +1,14 @@
+
+
+
+
From python-checkins at python.org Mon Sep 13 08:21:55 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 08:21:55 +0200 (CEST)
Subject: [Python-checkins] r84763 - in python/branches/py3k:
PC/VS8.0/pyd.vsprops PCbuild/pyd.vsprops
Message-ID: <20100913062155.241E3EE998@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 08:21:54 2010
New Revision: 84763
Log:
Cosmetic fix to project files.
Modified:
python/branches/py3k/PC/VS8.0/pyd.vsprops
python/branches/py3k/PCbuild/pyd.vsprops
Modified: python/branches/py3k/PC/VS8.0/pyd.vsprops
==============================================================================
--- python/branches/py3k/PC/VS8.0/pyd.vsprops (original)
+++ python/branches/py3k/PC/VS8.0/pyd.vsprops Mon Sep 13 08:21:54 2010
@@ -1,4 +1,4 @@
-
+
Author: hirokazu.yamamoto
Date: Mon Sep 13 08:36:09 2010
New Revision: 84764
Log:
Merged revisions 84753,84760 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84753 | hirokazu.yamamoto | 2010-09-13 07:55:40 +0900 | 1 line
Issue #9313: Skips test_remove_visual_c_ref on old MSVC.
........
r84760 | hirokazu.yamamoto | 2010-09-13 14:36:21 +0900 | 1 line
Issue #9313: Use unittest.skipUnless to skip old MSVC.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py
Modified: python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py
==============================================================================
--- python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py (original)
+++ python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py Mon Sep 13 08:36:09 2010
@@ -60,7 +60,12 @@
"""
+if sys.platform=="win32":
+ from distutils.msvccompiler import get_build_version
+
@unittest.skipUnless(sys.platform=="win32", "These tests are only for win32")
+ at unittest.skipUnless(get_build_version()>=8.0, "These tests are only for"
+ " MSVC8.0 or above")
class msvc9compilerTestCase(support.TempdirManager,
unittest.TestCase):
@@ -68,10 +73,6 @@
# makes sure query_vcvarsall throws
# a DistutilsPlatformError if the compiler
# is not found
- from distutils.msvccompiler import get_build_version
- if get_build_version() < 8.0:
- # this test is only for MSVC8.0 or above
- return
from distutils.msvc9compiler import query_vcvarsall
def _find_vcvarsall(version):
return None
@@ -86,11 +87,6 @@
msvc9compiler.find_vcvarsall = old_find_vcvarsall
def test_reg_class(self):
- from distutils.msvccompiler import get_build_version
- if get_build_version() < 8.0:
- # this test is only for MSVC8.0 or above
- return
-
from distutils.msvc9compiler import Reg
self.assertRaises(KeyError, Reg.get_value, 'xxx', 'xxx')
From python-checkins at python.org Mon Sep 13 09:18:30 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 09:18:30 +0200 (CEST)
Subject: [Python-checkins] r84765 -
python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
Message-ID: <20100913071830.B7275F629@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 09:18:30 2010
New Revision: 84765
Log:
The order of two decorators was wrong. Try to fix buildbot error in other way.
Modified:
python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
Modified: python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py
==============================================================================
--- python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py (original)
+++ python/branches/py3k/Lib/distutils/tests/test_msvc9compiler.py Mon Sep 13 09:18:30 2010
@@ -62,10 +62,14 @@
if sys.platform=="win32":
from distutils.msvccompiler import get_build_version
+ if get_build_version()>=8.0:
+ SKIP_MESSAGE = None
+ else:
+ SKIP_MESSAGE = "These tests are only for MSVC8.0 or above"
+else:
+ SKIP_MESSAGE = "These tests are only for win32"
- at unittest.skipUnless(sys.platform=="win32", "These tests are only for win32")
- at unittest.skipUnless(get_build_version()>=8.0, "These tests are only for"
- " MSVC8.0 or above")
+ at unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE)
class msvc9compilerTestCase(support.TempdirManager,
unittest.TestCase):
From python-checkins at python.org Mon Sep 13 09:25:54 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 09:25:54 +0200 (CEST)
Subject: [Python-checkins] r84765 - svn:log
Message-ID: <20100913072554.1024BF76F@mail.python.org>
Author: hirokazu.yamamoto
Revision: 84765
Property Name: svn:log
Action: modified
Property diff:
--- old property value
+++ new property value
@@ -1 +1,2 @@
-The order of two decorators was wrong. Try to fix buildbot error in other way.
\ No newline at end of file
+get_build_version() is needed even where sys.platform != "win32".
+Try to fix buildbot error in other way.
\ No newline at end of file
From python-checkins at python.org Mon Sep 13 09:46:37 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 09:46:37 +0200 (CEST)
Subject: [Python-checkins] r84766 - in python/branches/release27-maint:
Doc/reference/simple_stmts.rst Lib/string.py
Lib/test/string_tests.py Lib/test/test_bytes.py
Lib/test/test_unicode.py Misc/pymemcompat.h
Message-ID: <20100913074637.D9610F76F@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 09:46:37 2010
New Revision: 84766
Log:
Merged revisions 84470-84471,84566-84567,84759 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84470 | florent.xicluna | 2010-09-03 22:00:37 +0200 (ven., 03 sept. 2010) | 1 line
Strengthen BytesWarning tests.
........
r84471 | florent.xicluna | 2010-09-03 22:23:40 +0200 (ven., 03 sept. 2010) | 1 line
Typo
........
r84566 | florent.xicluna | 2010-09-06 22:27:15 +0200 (lun., 06 sept. 2010) | 1 line
typo
........
r84567 | florent.xicluna | 2010-09-06 22:27:55 +0200 (lun., 06 sept. 2010) | 1 line
typo
........
r84759 | florent.xicluna | 2010-09-13 04:28:18 +0200 (lun., 13 sept. 2010) | 1 line
Reenable test_ucs4 and remove some duplicated lines.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Doc/reference/simple_stmts.rst
python/branches/release27-maint/Lib/string.py
python/branches/release27-maint/Lib/test/string_tests.py
python/branches/release27-maint/Lib/test/test_bytes.py
python/branches/release27-maint/Lib/test/test_unicode.py
python/branches/release27-maint/Misc/pymemcompat.h
Modified: python/branches/release27-maint/Doc/reference/simple_stmts.rst
==============================================================================
--- python/branches/release27-maint/Doc/reference/simple_stmts.rst (original)
+++ python/branches/release27-maint/Doc/reference/simple_stmts.rst Mon Sep 13 09:46:37 2010
@@ -836,7 +836,7 @@
exists. Two dots means up one package level. Three dots is up two levels, etc.
So if you execute ``from . import mod`` from a module in the ``pkg`` package
then you will end up importing ``pkg.mod``. If you execute ``from ..subpkg2
-imprt mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``.
+import mod`` from within ``pkg.subpkg1`` you will import ``pkg.subpkg2.mod``.
The specification for relative imports is contained within :pep:`328`.
:func:`importlib.import_module` is provided to support applications that
Modified: python/branches/release27-maint/Lib/string.py
==============================================================================
--- python/branches/release27-maint/Lib/string.py (original)
+++ python/branches/release27-maint/Lib/string.py Mon Sep 13 09:46:37 2010
@@ -607,7 +607,7 @@
return str(value)
elif conversion is None:
return value
- raise ValueError("Unknown converion specifier {0!s}".format(conversion))
+ raise ValueError("Unknown conversion specifier {0!s}".format(conversion))
# returns an iterable that contains tuples of the form:
Modified: python/branches/release27-maint/Lib/test/string_tests.py
==============================================================================
--- python/branches/release27-maint/Lib/test/string_tests.py (original)
+++ python/branches/release27-maint/Lib/test/string_tests.py Mon Sep 13 09:46:37 2010
@@ -1119,7 +1119,7 @@
format = '%%.%if' % prec
value = 0.01
for x in xrange(60):
- value = value * 3.141592655 / 3.0 * 10.0
+ value = value * 3.14159265359 / 3.0 * 10.0
self.checkcall(format, "__mod__", value)
def test_inplace_rewrites(self):
Modified: python/branches/release27-maint/Lib/test/test_bytes.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_bytes.py (original)
+++ python/branches/release27-maint/Lib/test/test_bytes.py Mon Sep 13 09:46:37 2010
@@ -9,14 +9,28 @@
import re
import sys
import copy
+import functools
import pickle
import tempfile
import unittest
-import warnings
import test.test_support
import test.string_tests
import test.buffer_tests
+
+if sys.flags.bytes_warning:
+ def check_bytes_warnings(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kw):
+ with test.test_support.check_warnings(('', BytesWarning)):
+ return func(*args, **kw)
+ return wrapper
+else:
+ # no-op
+ def check_bytes_warnings(func):
+ return func
+
+
class Indexable:
def __init__(self, value=0):
self.value = value
@@ -26,12 +40,6 @@
class BaseBytesTest(unittest.TestCase):
- def setUp(self):
- self.warning_filters = warnings.filters[:]
-
- def tearDown(self):
- warnings.filters = self.warning_filters
-
def test_basics(self):
b = self.type2test()
self.assertEqual(type(b), self.type2test)
@@ -120,8 +128,8 @@
self.assertFalse(b3 < b2)
self.assertFalse(b3 <= b2)
+ @check_bytes_warnings
def test_compare_to_str(self):
- warnings.simplefilter('ignore', BytesWarning)
# Byte comparisons with unicode should always fail!
# Test this for all expected byte orders and Unicode character sizes
self.assertEqual(self.type2test(b"\0a\0b\0c") == u"abc", False)
@@ -795,14 +803,8 @@
# Test various combinations of bytes and bytearray
#
- def setUp(self):
- self.warning_filters = warnings.filters[:]
-
- def tearDown(self):
- warnings.filters = self.warning_filters
-
+ @check_bytes_warnings
def test_repr_str(self):
- warnings.simplefilter('ignore', BytesWarning)
for f in str, repr:
self.assertEqual(f(bytearray()), "bytearray(b'')")
self.assertEqual(f(bytearray([0])), "bytearray(b'\\x00')")
@@ -853,8 +855,8 @@
b = bytearray(buf)
self.assertEqual(b, bytearray(sample))
+ @check_bytes_warnings
def test_to_str(self):
- warnings.simplefilter('ignore', BytesWarning)
self.assertEqual(str(b''), "b''")
self.assertEqual(str(b'x'), "b'x'")
self.assertEqual(str(b'\x80'), "b'\\x80'")
Modified: python/branches/release27-maint/Lib/test/test_unicode.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_unicode.py (original)
+++ python/branches/release27-maint/Lib/test/test_unicode.py Mon Sep 13 09:46:37 2010
@@ -593,9 +593,9 @@
)
# UTF-8 specific decoding tests
- self.assertEqual(unicode('\xf0\xa3\x91\x96', 'utf-8'), u'\U00023456' )
- self.assertEqual(unicode('\xf0\x90\x80\x82', 'utf-8'), u'\U00010002' )
- self.assertEqual(unicode('\xe2\x82\xac', 'utf-8'), u'\u20ac' )
+ self.assertEqual(unicode('\xf0\xa3\x91\x96', 'utf-8'), u'\U00023456')
+ self.assertEqual(unicode('\xf0\x90\x80\x82', 'utf-8'), u'\U00010002')
+ self.assertEqual(unicode('\xe2\x82\xac', 'utf-8'), u'\u20ac')
# Other possible utf-8 test cases:
# * strict decoding testing for all of the
@@ -1360,8 +1360,8 @@
def __unicode__(self):
return u'__unicode__ overridden'
u = U(u'xxx')
- self.assertEquals("%s" % u, u'__unicode__ overridden')
- self.assertEquals("{}".format(u), u'__unicode__ overridden')
+ self.assertEqual("%s" % u, u'__unicode__ overridden')
+ self.assertEqual("{}".format(u), u'__unicode__ overridden')
def test_main():
Modified: python/branches/release27-maint/Misc/pymemcompat.h
==============================================================================
--- python/branches/release27-maint/Misc/pymemcompat.h (original)
+++ python/branches/release27-maint/Misc/pymemcompat.h Mon Sep 13 09:46:37 2010
@@ -72,7 +72,7 @@
It is possible to support both the 2.0 and 2.2 GC APIs, but it's
not pretty and this comment block is too narrow to contain a
- desciption of what's required... */
+ description of what's required... */
#if PY_VERSION_HEX < 0x020200B1
#define PyObject_GC_New PyObject_New
From python-checkins at python.org Mon Sep 13 09:48:22 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 09:48:22 +0200 (CEST)
Subject: [Python-checkins] r84767 -
python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py
Message-ID: <20100913074822.40037F76F@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 09:48:22 2010
New Revision: 84767
Log:
Merged revisions 84765 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84765 | hirokazu.yamamoto | 2010-09-13 16:18:30 +0900 | 2 lines
get_build_version() is needed even where sys.platform != "win32".
Try to fix buildbot error in other way.
........
Modified:
python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py
Modified: python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py
==============================================================================
--- python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py (original)
+++ python/branches/release31-maint/Lib/distutils/tests/test_msvc9compiler.py Mon Sep 13 09:48:22 2010
@@ -62,10 +62,14 @@
if sys.platform=="win32":
from distutils.msvccompiler import get_build_version
+ if get_build_version()>=8.0:
+ SKIP_MESSAGE = None
+ else:
+ SKIP_MESSAGE = "These tests are only for MSVC8.0 or above"
+else:
+ SKIP_MESSAGE = "These tests are only for win32"
- at unittest.skipUnless(sys.platform=="win32", "These tests are only for win32")
- at unittest.skipUnless(get_build_version()>=8.0, "These tests are only for"
- " MSVC8.0 or above")
+ at unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE)
class msvc9compilerTestCase(support.TempdirManager,
unittest.TestCase):
From python-checkins at python.org Mon Sep 13 09:50:44 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 09:50:44 +0200 (CEST)
Subject: [Python-checkins] r84768 - python/branches/release27-maint
Message-ID: <20100913075044.0D25EF76F@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 09:50:43 2010
New Revision: 84768
Log:
Blocked revisions 84081-84082,84363,84467-84469,84485 via svnmerge
........
r84081 | florent.xicluna | 2010-08-15 22:16:27 +0200 (dim., 15 ao?t 2010) | 1 line
Replace the deprecated ConfigParser.readfp() method, and fix the incomplete merge in r82293.
........
r84082 | florent.xicluna | 2010-08-15 22:21:26 +0200 (dim., 15 ao?t 2010) | 1 line
Replace readfp() with read_file() in configparser documentation.
........
r84363 | florent.xicluna | 2010-08-30 16:05:50 +0200 (lun., 30 ao?t 2010) | 1 line
remove pointless coding cookies
........
r84467 | florent.xicluna | 2010-09-03 21:52:03 +0200 (ven., 03 sept. 2010) | 1 line
Use a context manager for some file objects.
........
r84468 | florent.xicluna | 2010-09-03 21:54:02 +0200 (ven., 03 sept. 2010) | 1 line
Remove unused import, fix typo and rewrap docstrings.
........
r84469 | florent.xicluna | 2010-09-03 21:55:26 +0200 (ven., 03 sept. 2010) | 1 line
Remove redundant context manager.
........
r84485 | florent.xicluna | 2010-09-04 01:47:32 +0200 (sam., 04 sept. 2010) | 2 lines
Welcome to the UTF-8 world.
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Mon Sep 13 10:07:29 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 10:07:29 +0200 (CEST)
Subject: [Python-checkins] r84769 - python/branches/release31-maint
Message-ID: <20100913080729.2E0E8F525@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 10:07:29 2010
New Revision: 84769
Log:
Recorded merge of revisions 84765 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84765 | hirokazu.yamamoto | 2010-09-13 16:18:30 +0900 | 2 lines
get_build_version() is needed even where sys.platform != "win32".
Try to fix buildbot error in other way.
........
Modified:
python/branches/release31-maint/ (props changed)
From python-checkins at python.org Mon Sep 13 10:14:41 2010
From: python-checkins at python.org (hirokazu.yamamoto)
Date: Mon, 13 Sep 2010 10:14:41 +0200 (CEST)
Subject: [Python-checkins] r84770 - in python/branches/release27-maint:
Lib/distutils/tests/test_msvc9compiler.py
Message-ID: <20100913081441.9DCFEF343@mail.python.org>
Author: hirokazu.yamamoto
Date: Mon Sep 13 10:14:41 2010
New Revision: 84770
Log:
Merged revisions 84765 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84765 | hirokazu.yamamoto | 2010-09-13 16:18:30 +0900 | 2 lines
get_build_version() is needed even where sys.platform != "win32".
Try to fix buildbot error in other way.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py
Modified: python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py
==============================================================================
--- python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py (original)
+++ python/branches/release27-maint/Lib/distutils/tests/test_msvc9compiler.py Mon Sep 13 10:14:41 2010
@@ -62,10 +62,14 @@
if sys.platform=="win32":
from distutils.msvccompiler import get_build_version
+ if get_build_version()>=8.0:
+ SKIP_MESSAGE = None
+ else:
+ SKIP_MESSAGE = "These tests are only for MSVC8.0 or above"
+else:
+ SKIP_MESSAGE = "These tests are only for win32"
- at unittest.skipUnless(sys.platform=="win32", "These tests are only for win32")
- at unittest.skipUnless(get_build_version()>=8.0, "These tests are only for"
- " MSVC8.0 or above")
+ at unittest.skipUnless(SKIP_MESSAGE is None, SKIP_MESSAGE)
class msvc9compilerTestCase(support.TempdirManager,
unittest.TestCase):
From python-checkins at python.org Mon Sep 13 10:20:19 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 10:20:19 +0200 (CEST)
Subject: [Python-checkins] r84771 -
python/branches/release27-maint/Lib/test/test_io.py
Message-ID: <20100913082019.DDF9CF525@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 10:20:19 2010
New Revision: 84771
Log:
Silence warning about 1/0
Modified:
python/branches/release27-maint/Lib/test/test_io.py
Modified: python/branches/release27-maint/Lib/test/test_io.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_io.py (original)
+++ python/branches/release27-maint/Lib/test/test_io.py Mon Sep 13 10:20:19 2010
@@ -2484,7 +2484,7 @@
signal.signal(signal.SIGALRM, self.oldalrm)
def alarm_interrupt(self, sig, frame):
- 1/0
+ 1 // 0
@unittest.skipUnless(threading, 'Threading required for this test.')
def check_interrupted_write(self, item, bytes, **fdopen_kwargs):
From python-checkins at python.org Mon Sep 13 10:21:43 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 10:21:43 +0200 (CEST)
Subject: [Python-checkins] r84772 - in
python/branches/release27-maint/Lib/test: test_str.py
test_unicode.py
Message-ID: <20100913082143.63BB0F525@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 10:21:43 2010
New Revision: 84772
Log:
Check PendingDeprecationWarning after issue #7994.
Modified:
python/branches/release27-maint/Lib/test/test_str.py
python/branches/release27-maint/Lib/test/test_unicode.py
Modified: python/branches/release27-maint/Lib/test/test_str.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_str.py (original)
+++ python/branches/release27-maint/Lib/test/test_str.py Mon Sep 13 10:21:43 2010
@@ -276,7 +276,7 @@
# format specifiers for user defined type
self.assertEqual('{0:abc}'.format(C()), 'abc')
- # !r and !s coersions
+ # !r and !s coercions
self.assertEqual('{0!s}'.format('Hello'), 'Hello')
self.assertEqual('{0!s:}'.format('Hello'), 'Hello')
self.assertEqual('{0!s:15}'.format('Hello'), 'Hello ')
@@ -290,12 +290,15 @@
self.assertEqual('{0}'.format([]), '[]')
self.assertEqual('{0}'.format([1]), '[1]')
self.assertEqual('{0}'.format(E('data')), 'E(data)')
- self.assertEqual('{0:^10}'.format(E('data')), ' E(data) ')
- self.assertEqual('{0:^10s}'.format(E('data')), ' E(data) ')
self.assertEqual('{0:d}'.format(G('data')), 'G(data)')
- self.assertEqual('{0:>15s}'.format(G('data')), ' string is data')
self.assertEqual('{0!s}'.format(G('data')), 'string is data')
+ msg = 'object.__format__ with a non-empty format string is deprecated'
+ with test_support.check_warnings((msg, PendingDeprecationWarning)):
+ self.assertEqual('{0:^10}'.format(E('data')), ' E(data) ')
+ self.assertEqual('{0:^10s}'.format(E('data')), ' E(data) ')
+ self.assertEqual('{0:>15s}'.format(G('data')), ' string is data')
+
self.assertEqual("{0:date: %Y-%m-%d}".format(I(year=2007,
month=8,
day=27)),
Modified: python/branches/release27-maint/Lib/test/test_unicode.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_unicode.py (original)
+++ python/branches/release27-maint/Lib/test/test_unicode.py Mon Sep 13 10:21:43 2010
@@ -1209,7 +1209,7 @@
# format specifiers for user defined type
self.assertEqual(u'{0:abc}'.format(C()), u'abc')
- # !r and !s coersions
+ # !r and !s coercions
self.assertEqual(u'{0!s}'.format(u'Hello'), u'Hello')
self.assertEqual(u'{0!s:}'.format(u'Hello'), u'Hello')
self.assertEqual(u'{0!s:15}'.format(u'Hello'), u'Hello ')
@@ -1223,12 +1223,15 @@
self.assertEqual(u'{0}'.format([]), u'[]')
self.assertEqual(u'{0}'.format([1]), u'[1]')
self.assertEqual(u'{0}'.format(E(u'data')), u'E(data)')
- self.assertEqual(u'{0:^10}'.format(E(u'data')), u' E(data) ')
- self.assertEqual(u'{0:^10s}'.format(E(u'data')), u' E(data) ')
self.assertEqual(u'{0:d}'.format(G(u'data')), u'G(data)')
- self.assertEqual(u'{0:>15s}'.format(G(u'data')), u' string is data')
self.assertEqual(u'{0!s}'.format(G(u'data')), u'string is data')
+ msg = 'object.__format__ with a non-empty format string is deprecated'
+ with test_support.check_warnings((msg, PendingDeprecationWarning)):
+ self.assertEqual(u'{0:^10}'.format(E(u'data')), u' E(data) ')
+ self.assertEqual(u'{0:^10s}'.format(E(u'data')), u' E(data) ')
+ self.assertEqual(u'{0:>15s}'.format(G(u'data')), u' string is data')
+
self.assertEqual(u"{0:date: %Y-%m-%d}".format(I(year=2007,
month=8,
day=27)),
From python-checkins at python.org Mon Sep 13 10:53:00 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 10:53:00 +0200 (CEST)
Subject: [Python-checkins] r84773 - in python/branches/release27-maint:
Lib/test/string_tests.py Lib/test/test_unicode.py Misc/NEWS
Message-ID: <20100913085300.4120EF4CB@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 10:53:00 2010
New Revision: 84773
Log:
Strengthen test_unicode with explicit type checking for assertEqual tests.
Modified:
python/branches/release27-maint/Lib/test/string_tests.py
python/branches/release27-maint/Lib/test/test_unicode.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/test/string_tests.py
==============================================================================
--- python/branches/release27-maint/Lib/test/string_tests.py (original)
+++ python/branches/release27-maint/Lib/test/string_tests.py Mon Sep 13 10:53:00 2010
@@ -254,7 +254,7 @@
r2 = j in i
self.assertEqual(r1, r2)
if loc != -1:
- self.assertEqual(i[loc:loc+len(j)], j)
+ self.assertEqual(i[loc:loc+len(j)], self.fixtype(j))
# issue 7458
self.checkequal(-1, 'ab', 'rfind', 'xxx', sys.maxsize + 1, 0)
Modified: python/branches/release27-maint/Lib/test/test_unicode.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_unicode.py (original)
+++ python/branches/release27-maint/Lib/test/test_unicode.py Mon Sep 13 10:53:00 2010
@@ -34,6 +34,16 @@
):
type2test = unicode
+ def assertEqual(self, first, second, msg=None):
+ # strict assertEqual method: reject implicit bytes/unicode equality
+ super(UnicodeTest, self).assertEqual(first, second, msg)
+ if isinstance(first, unicode) or isinstance(second, unicode):
+ self.assertIsInstance(first, unicode)
+ self.assertIsInstance(second, unicode)
+ elif isinstance(first, str) or isinstance(second, str):
+ self.assertIsInstance(first, str)
+ self.assertIsInstance(second, str)
+
def checkequalnofix(self, result, object, methodname, *args):
method = getattr(object, methodname)
realresult = method(*args)
@@ -197,9 +207,9 @@
def test_comparison(self):
# Comparisons:
- self.assertEqual(u'abc', 'abc')
- self.assertEqual('abc', u'abc')
- self.assertEqual(u'abc', u'abc')
+ self.assertTrue(u'abc' == 'abc')
+ self.assertTrue('abc' == u'abc')
+ self.assertTrue(u'abc' == u'abc')
self.assertTrue(u'abcd' > 'abc')
self.assertTrue('abcd' > u'abc')
self.assertTrue(u'abcd' > u'abc')
@@ -398,8 +408,10 @@
for num in range(0x00,0x80):
char = chr(num)
- self.assertEqual(u"%c" % char, char)
- self.assertEqual(u"%c" % num, char)
+ self.assertEqual(u"%c" % char, unicode(char))
+ self.assertEqual(u"%c" % num, unicode(char))
+ self.assertTrue(char == u"%c" % char)
+ self.assertTrue(char == u"%c" % num)
# Issue 7649
for num in range(0x80,0x100):
uchar = unichr(num)
@@ -558,9 +570,11 @@
set_o = '!"#$%&*;<=>@[]^_`{|}'
for c in set_d:
self.assertEqual(c.encode('utf7'), c.encode('ascii'))
- self.assertEqual(c.encode('ascii').decode('utf7'), c)
+ self.assertEqual(c.encode('ascii').decode('utf7'), unicode(c))
+ self.assertTrue(c == c.encode('ascii').decode('utf7'))
for c in set_o:
- self.assertEqual(c.encode('ascii').decode('utf7'), c)
+ self.assertEqual(c.encode('ascii').decode('utf7'), unicode(c))
+ self.assertTrue(c == c.encode('ascii').decode('utf7'))
def test_codecs_utf8(self):
self.assertEqual(u''.encode('utf-8'), '')
@@ -1364,7 +1378,7 @@
return u'__unicode__ overridden'
u = U(u'xxx')
self.assertEqual("%s" % u, u'__unicode__ overridden')
- self.assertEqual("{}".format(u), u'__unicode__ overridden')
+ self.assertEqual("{}".format(u), '__unicode__ overridden')
def test_main():
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Mon Sep 13 10:53:00 2010
@@ -337,6 +337,8 @@
Tests
-----
+- Strengthen test_unicode with explicit type checking for assertEqual tests.
+
- Issue #8857: Provide a test case for socket.getaddrinfo.
- Issue #7564: Skip test_ioctl if another process is attached to /dev/tty.
From python-checkins at python.org Mon Sep 13 16:16:52 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Mon, 13 Sep 2010 16:16:52 +0200 (CEST)
Subject: [Python-checkins] r84774 - in python/branches/py3k: Include/ceval.h
Misc/NEWS Python/ceval.c Python/ceval_gil.h Python/pythonrun.c
Message-ID: <20100913141652.6B23BFAEF@mail.python.org>
Author: antoine.pitrou
Date: Mon Sep 13 16:16:46 2010
New Revision: 84774
Log:
Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
re-created on a subsequent call to Py_Initialize(). The problem (a crash)
wouldn't appear in 3.1 or 2.7 where the GIL's structure is more trivial.
Modified:
python/branches/py3k/Include/ceval.h
python/branches/py3k/Misc/NEWS
python/branches/py3k/Python/ceval.c
python/branches/py3k/Python/ceval_gil.h
python/branches/py3k/Python/pythonrun.c
Modified: python/branches/py3k/Include/ceval.h
==============================================================================
--- python/branches/py3k/Include/ceval.h (original)
+++ python/branches/py3k/Include/ceval.h Mon Sep 13 16:16:46 2010
@@ -160,6 +160,7 @@
PyAPI_FUNC(int) PyEval_ThreadsInitialized(void);
PyAPI_FUNC(void) PyEval_InitThreads(void);
+PyAPI_FUNC(void) _PyEval_FiniThreads(void);
PyAPI_FUNC(void) PyEval_AcquireLock(void);
PyAPI_FUNC(void) PyEval_ReleaseLock(void);
PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate);
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 16:16:46 2010
@@ -10,6 +10,10 @@
Core and Builtins
-----------------
+- Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
+ re-created on a subsequent call to Py_Initialize(). The problem (a crash)
+ wouldn't appear in 3.1 or 2.7 where the GIL's structure is more trivial.
+
- Issue #9210: Configure option --with-wctype-functions was removed. Using the
functions from the libc caused the methods .upper() and lower() to become
locale aware and created subtly wrong results.
Modified: python/branches/py3k/Python/ceval.c
==============================================================================
--- python/branches/py3k/Python/ceval.c (original)
+++ python/branches/py3k/Python/ceval.c Mon Sep 13 16:16:46 2010
@@ -313,6 +313,15 @@
}
void
+_PyEval_FiniThreads(void)
+{
+ if (!gil_created())
+ return;
+ destroy_gil();
+ assert(!gil_created());
+}
+
+void
PyEval_AcquireLock(void)
{
PyThreadState *tstate = PyThreadState_GET();
@@ -368,10 +377,6 @@
if (!gil_created())
return;
- /*XXX Can't use PyThread_free_lock here because it does too
- much error-checking. Doing this cleanly would require
- adding a new function to each thread_*.h. Instead, just
- create a new lock and waste a little bit of memory */
recreate_gil();
pending_lock = PyThread_allocate_lock();
take_gil(tstate);
Modified: python/branches/py3k/Python/ceval_gil.h
==============================================================================
--- python/branches/py3k/Python/ceval_gil.h (original)
+++ python/branches/py3k/Python/ceval_gil.h Mon Sep 13 16:16:46 2010
@@ -95,6 +95,9 @@
#define MUTEX_INIT(mut) \
if (pthread_mutex_init(&mut, NULL)) { \
Py_FatalError("pthread_mutex_init(" #mut ") failed"); };
+#define MUTEX_FINI(mut) \
+ if (pthread_mutex_destroy(&mut)) { \
+ Py_FatalError("pthread_mutex_destroy(" #mut ") failed"); };
#define MUTEX_LOCK(mut) \
if (pthread_mutex_lock(&mut)) { \
Py_FatalError("pthread_mutex_lock(" #mut ") failed"); };
@@ -106,6 +109,9 @@
#define COND_INIT(cond) \
if (pthread_cond_init(&cond, NULL)) { \
Py_FatalError("pthread_cond_init(" #cond ") failed"); };
+#define COND_FINI(cond) \
+ if (pthread_cond_destroy(&cond)) { \
+ Py_FatalError("pthread_cond_destroy(" #cond ") failed"); };
#define COND_SIGNAL(cond) \
if (pthread_cond_signal(&cond)) { \
Py_FatalError("pthread_cond_signal(" #cond ") failed"); };
@@ -305,9 +311,24 @@
_Py_atomic_store_explicit(&gil_locked, 0, _Py_memory_order_release);
}
+static void destroy_gil(void)
+{
+ MUTEX_FINI(gil_mutex);
+#ifdef FORCE_SWITCHING
+ MUTEX_FINI(switch_mutex);
+#endif
+ COND_FINI(gil_cond);
+#ifdef FORCE_SWITCHING
+ COND_FINI(switch_cond);
+#endif
+ _Py_atomic_store_explicit(&gil_locked, -1, _Py_memory_order_release);
+ _Py_ANNOTATE_RWLOCK_DESTROY(&gil_locked);
+}
+
static void recreate_gil(void)
{
_Py_ANNOTATE_RWLOCK_DESTROY(&gil_locked);
+ /* XXX should we destroy the old OS resources here? */
create_gil();
}
Modified: python/branches/py3k/Python/pythonrun.c
==============================================================================
--- python/branches/py3k/Python/pythonrun.c (original)
+++ python/branches/py3k/Python/pythonrun.c Mon Sep 13 16:16:46 2010
@@ -514,6 +514,10 @@
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
+#ifdef WITH_THREAD
+ _PyEval_FiniThreads();
+#endif
+
#ifdef Py_TRACE_REFS
/* Display addresses (& refcnts) of all objects still alive.
* An address can be used to find the repr of the object, printed
From python-checkins at python.org Mon Sep 13 16:18:44 2010
From: python-checkins at python.org (barry.warsaw)
Date: Mon, 13 Sep 2010 16:18:44 +0200 (CEST)
Subject: [Python-checkins] r84775 - peps/trunk/pep-3149.txt
Message-ID: <20100913141844.28C78FB1E@mail.python.org>
Author: barry.warsaw
Date: Mon Sep 13 16:18:43 2010
New Revision: 84775
Log:
Rephrase and emphasize inapplicability to Windows
Modified:
peps/trunk/pep-3149.txt
Modified: peps/trunk/pep-3149.txt
==============================================================================
--- peps/trunk/pep-3149.txt (original)
+++ peps/trunk/pep-3149.txt Mon Sep 13 16:18:43 2010
@@ -68,15 +68,15 @@
with Python 2.6 being the default.
In order to share as much as possible between the available Python
-versions, these distributions install third party (i.e. non-standard
-library) packages into `/usr/share/pyshared` and symlink to them from
-`/usr/lib/pythonX.Y/dist-packages`. The symlinks exist because in a
-pre-PEP 3147 world (i.e < Python 3.2), the `.pyc` files resulting from
-byte compilation by the various installed Pythons will name collide
-with each other. For Python versions >= 3.2, all pure-Python packages
-can be shared, because the `.pyc` files will no longer cause file
-system naming conflicts. Eliminating these symlinks makes for a
-simpler, more robust Python distribution.
+versions, these distributions install third party package modules
+(``.pyc`` and ``.so`` files) into `/usr/share/pyshared` and symlink to
+them from `/usr/lib/pythonX.Y/dist-packages`. The symlinks exist
+because in a pre-PEP 3147 world (i.e < Python 3.2), the `.pyc` files
+resulting from byte compilation by the various installed Pythons will
+name collide with each other. For Python versions >= 3.2, all
+pure-Python packages can be shared, because the `.pyc` files will no
+longer cause file system naming conflicts. Eliminating these symlinks
+makes for a simpler, more robust Python distribution.
A similar situation arises with shared library extensions. Because
extension modules are typically named `foo.so` for a `foo` extension
@@ -126,11 +126,6 @@
When the other two flags are also enabled, the file names would be
``foo.cpython-32dmu.so``.
-(This PEP only addresses build issues on POSIX systems that use the
-``configure`` script. While Windows or other platform support is not
-explicitly disallowed under this PEP, platform expertise is needed in
-order to evaluate, describe, and implement support on such platforms.)
-
The shared library file name tag is used unconditionally; it cannot be
changed. The tag and extension module suffix are available through
the ``sysconfig`` modules via the following variables::
@@ -144,11 +139,16 @@
platform extension for shared library files, and is the exact suffix
added to the extension module name.
-For an arbitrary package `foo`, you would see these files when the
+For an arbitrary package `foo`, you might see these files when the
distribution package was installed::
- /usr/share/pyshared/foo.cpython-32m.so
- /usr/share/pyshared/foo.cpython-33m.so
+ /usr/lib/python/foo.cpython-32m.so
+ /usr/lib/python/foo.cpython-33m.so
+
+(These paths are for example purposes only. Distributions are free to
+use whatever filesystem layout they choose, and nothing in this PEP
+changes the locations where from-source builds of Python are
+installed.)
Python's dynamic module loader will recognize and import shared
library extension modules with a tag that matches its build-time
@@ -173,6 +173,17 @@
major and minor version in the `.dll` file name.
+Windows
+=======
+
+This PEP only addresses build issues on POSIX systems that use the
+``configure`` script. While Windows or other platform support is not
+explicitly disallowed under this PEP, platform expertise is needed in
+order to evaluate, describe, and implement support on such platforms.
+It is not currently clear that the facilities in this PEP are even
+useful for Windows.
+
+
PEP 384
=======
From python-checkins at python.org Mon Sep 13 18:35:02 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 18:35:02 +0200 (CEST)
Subject: [Python-checkins] r84776 - in python/branches/py3k:
Lib/test/regrtest.py Misc/NEWS
Message-ID: <20100913163502.8CD8DFC2E@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 18:35:02 2010
New Revision: 84776
Log:
Make test.regrtest.__file__ absolute, this was not always the case when running profile or trace, for example. (issue #9323)
Modified:
python/branches/py3k/Lib/test/regrtest.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/test/regrtest.py
==============================================================================
--- python/branches/py3k/Lib/test/regrtest.py (original)
+++ python/branches/py3k/Lib/test/regrtest.py Mon Sep 13 18:35:02 2010
@@ -1458,7 +1458,13 @@
return self.expected
if __name__ == '__main__':
- # Simplification for findtestdir().
+ # findtestdir() gets the dirname out of __file__, so we have to make it
+ # absolute before changing the working directory.
+ # For example __file__ may be relative when running trace or profile.
+ # See issue #9323.
+ __file__ = os.path.abspath(__file__)
+
+ # sanity check
assert __file__ == os.path.abspath(sys.argv[0])
# When tests are run from the Python build directory, it is best practice
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 18:35:02 2010
@@ -142,6 +142,12 @@
as wide (UCS4) unicode builds for both the host interpreter (embedded
inside gdb) and the interpreter under test.
+Tests
+-----
+
+- Issue #9323: Make test.regrtest.__file__ absolute, this was not always the
+ case when running profile or trace, for example.
+
Build
-----
From python-checkins at python.org Mon Sep 13 18:45:02 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Mon, 13 Sep 2010 18:45:02 +0200 (CEST)
Subject: [Python-checkins] r84777 - in python/branches/release27-maint:
Lib/test/test_trace.py Lib/test/tracedmodules
Lib/test/tracedmodules/__init__.py
Lib/test/tracedmodules/testmod.py Lib/trace.py Misc/NEWS
Message-ID: <20100913164502.45C03EE99A@mail.python.org>
Author: alexander.belopolsky
Date: Mon Sep 13 18:45:02 2010
New Revision: 84777
Log:
Issue #9315: Fix for the trace module to record correct class name
when tracing methods. Unit tests. Patch by Eli Bendersky.
Added:
python/branches/release27-maint/Lib/test/test_trace.py
python/branches/release27-maint/Lib/test/tracedmodules/
python/branches/release27-maint/Lib/test/tracedmodules/__init__.py
python/branches/release27-maint/Lib/test/tracedmodules/testmod.py
Modified:
python/branches/release27-maint/Lib/trace.py
python/branches/release27-maint/Misc/NEWS
Added: python/branches/release27-maint/Lib/test/test_trace.py
==============================================================================
--- (empty file)
+++ python/branches/release27-maint/Lib/test/test_trace.py Mon Sep 13 18:45:02 2010
@@ -0,0 +1,320 @@
+import os
+import sys
+from test.test_support import (run_unittest, TESTFN, rmtree, unlink,
+ captured_stdout)
+import unittest
+
+import trace
+from trace import CoverageResults, Trace
+
+from test.tracedmodules import testmod
+
+
+#------------------------------- Utilities -----------------------------------#
+
+def fix_ext_py(filename):
+ """Given a .pyc/.pyo filename converts it to the appropriate .py"""
+ if filename.endswith(('.pyc', '.pyo')):
+ filename = filename[:-1]
+ return filename
+
+def my_file_and_modname():
+ """The .py file and module name of this file (__file__)"""
+ modname = os.path.splitext(os.path.basename(__file__))[0]
+ return fix_ext_py(__file__), modname
+
+def get_firstlineno(func):
+ return func.__code__.co_firstlineno
+
+#-------------------- Target functions for tracing ---------------------------#
+#
+# The relative line numbers of lines in these functions matter for verifying
+# tracing. Please modify the appropriate tests if you change one of the
+# functions. Absolute line numbers don't matter.
+#
+
+def traced_func_linear(x, y):
+ a = x
+ b = y
+ c = a + b
+ return c
+
+def traced_func_loop(x, y):
+ c = x
+ for i in range(5):
+ c += y
+ return c
+
+def traced_func_importing(x, y):
+ return x + y + testmod.func(1)
+
+def traced_func_simple_caller(x):
+ c = traced_func_linear(x, x)
+ return c + x
+
+def traced_func_importing_caller(x):
+ k = traced_func_simple_caller(x)
+ k += traced_func_importing(k, x)
+ return k
+
+def traced_func_generator(num):
+ c = 5 # executed once
+ for i in range(num):
+ yield i + c
+
+def traced_func_calling_generator():
+ k = 0
+ for i in traced_func_generator(10):
+ k += i
+
+def traced_doubler(num):
+ return num * 2
+
+def traced_caller_list_comprehension():
+ k = 10
+ mylist = [traced_doubler(i) for i in range(k)]
+ return mylist
+
+
+class TracedClass(object):
+ def __init__(self, x):
+ self.a = x
+
+ def inst_method_linear(self, y):
+ return self.a + y
+
+ def inst_method_calling(self, x):
+ c = self.inst_method_linear(x)
+ return c + traced_func_linear(x, c)
+
+ @classmethod
+ def class_method_linear(cls, y):
+ return y * 2
+
+ @staticmethod
+ def static_method_linear(y):
+ return y * 2
+
+
+#------------------------------ Test cases -----------------------------------#
+
+
+class TestLineCounts(unittest.TestCase):
+ """White-box testing of line-counting, via runfunc"""
+ def setUp(self):
+ self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ self.my_py_filename = fix_ext_py(__file__)
+
+ def test_traced_func_linear(self):
+ result = self.tracer.runfunc(traced_func_linear, 2, 5)
+ self.assertEqual(result, 7)
+
+ # all lines are executed once
+ expected = {}
+ firstlineno = get_firstlineno(traced_func_linear)
+ for i in range(1, 5):
+ expected[(self.my_py_filename, firstlineno + i)] = 1
+
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_traced_func_loop(self):
+ self.tracer.runfunc(traced_func_loop, 2, 3)
+
+ firstlineno = get_firstlineno(traced_func_loop)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (self.my_py_filename, firstlineno + 2): 6,
+ (self.my_py_filename, firstlineno + 3): 5,
+ (self.my_py_filename, firstlineno + 4): 1,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_traced_func_importing(self):
+ self.tracer.runfunc(traced_func_importing, 2, 5)
+
+ firstlineno = get_firstlineno(traced_func_importing)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (fix_ext_py(testmod.__file__), 2): 1,
+ (fix_ext_py(testmod.__file__), 3): 1,
+ }
+
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_trace_func_generator(self):
+ self.tracer.runfunc(traced_func_calling_generator)
+
+ firstlineno_calling = get_firstlineno(traced_func_calling_generator)
+ firstlineno_gen = get_firstlineno(traced_func_generator)
+ expected = {
+ (self.my_py_filename, firstlineno_calling + 1): 1,
+ (self.my_py_filename, firstlineno_calling + 2): 11,
+ (self.my_py_filename, firstlineno_calling + 3): 10,
+ (self.my_py_filename, firstlineno_gen + 1): 1,
+ (self.my_py_filename, firstlineno_gen + 2): 11,
+ (self.my_py_filename, firstlineno_gen + 3): 10,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_trace_list_comprehension(self):
+ self.tracer.runfunc(traced_caller_list_comprehension)
+
+ firstlineno_calling = get_firstlineno(traced_caller_list_comprehension)
+ firstlineno_called = get_firstlineno(traced_doubler)
+ expected = {
+ (self.my_py_filename, firstlineno_calling + 1): 1,
+ (self.my_py_filename, firstlineno_calling + 2): 11,
+ (self.my_py_filename, firstlineno_calling + 3): 1,
+ (self.my_py_filename, firstlineno_called + 1): 10,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+
+ def test_linear_methods(self):
+ # XXX todo: later add 'static_method_linear' and 'class_method_linear'
+ # here, once issue1764286 is resolved
+ #
+ for methname in ['inst_method_linear',]:
+ tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ traced_obj = TracedClass(25)
+ method = getattr(traced_obj, methname)
+ tracer.runfunc(method, 20)
+
+ firstlineno = get_firstlineno(method)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ }
+ self.assertEqual(tracer.results().counts, expected)
+
+
+class TestRunExecCounts(unittest.TestCase):
+ """A simple sanity test of line-counting, via runctx (exec)"""
+ def setUp(self):
+ self.my_py_filename = fix_ext_py(__file__)
+
+ def test_exec_counts(self):
+ self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ code = r'''traced_func_loop(2, 5)'''
+ code = compile(code, __file__, 'exec')
+ self.tracer.runctx(code, globals(), vars())
+
+ firstlineno = get_firstlineno(traced_func_loop)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (self.my_py_filename, firstlineno + 2): 6,
+ (self.my_py_filename, firstlineno + 3): 5,
+ (self.my_py_filename, firstlineno + 4): 1,
+ }
+
+ # When used through 'run', some other spurios counts are produced, like
+ # the settrace of threading, which we ignore, just making sure that the
+ # counts fo traced_func_loop were right.
+ #
+ for k in expected.keys():
+ self.assertEqual(self.tracer.results().counts[k], expected[k])
+
+
+class TestFuncs(unittest.TestCase):
+ """White-box testing of funcs tracing"""
+ def setUp(self):
+ self.tracer = Trace(count=0, trace=0, countfuncs=1)
+ self.filemod = my_file_and_modname()
+ self.maxDiff = None
+ def test_simple_caller(self):
+ self.tracer.runfunc(traced_func_simple_caller, 1)
+
+ expected = {
+ self.filemod + ('traced_func_simple_caller',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+ def test_loop_caller_importing(self):
+ self.tracer.runfunc(traced_func_importing_caller, 1)
+
+ expected = {
+ self.filemod + ('traced_func_simple_caller',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ self.filemod + ('traced_func_importing_caller',): 1,
+ self.filemod + ('traced_func_importing',): 1,
+ (fix_ext_py(testmod.__file__), 'testmod', 'func'): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+ def test_inst_method_calling(self):
+ obj = TracedClass(20)
+ self.tracer.runfunc(obj.inst_method_calling, 1)
+
+ expected = {
+ self.filemod + ('TracedClass.inst_method_calling',): 1,
+ self.filemod + ('TracedClass.inst_method_linear',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+
+class TestCallers(unittest.TestCase):
+ """White-box testing of callers tracing"""
+ def setUp(self):
+ self.tracer = Trace(count=0, trace=0, countcallers=1)
+ self.filemod = my_file_and_modname()
+
+ def test_loop_caller_importing(self):
+ self.tracer.runfunc(traced_func_importing_caller, 1)
+
+ expected = {
+ ((os.path.splitext(trace.__file__)[0] + '.py', 'trace', 'Trace.runfunc'),
+ (self.filemod + ('traced_func_importing_caller',))): 1,
+ ((self.filemod + ('traced_func_simple_caller',)),
+ (self.filemod + ('traced_func_linear',))): 1,
+ ((self.filemod + ('traced_func_importing_caller',)),
+ (self.filemod + ('traced_func_simple_caller',))): 1,
+ ((self.filemod + ('traced_func_importing_caller',)),
+ (self.filemod + ('traced_func_importing',))): 1,
+ ((self.filemod + ('traced_func_importing',)),
+ (fix_ext_py(testmod.__file__), 'testmod', 'func')): 1,
+ }
+ self.assertEqual(self.tracer.results().callers, expected)
+
+
+# Created separately for issue #3821
+class TestCoverage(unittest.TestCase):
+ def tearDown(self):
+ rmtree(TESTFN)
+ unlink(TESTFN)
+
+ def _coverage(self, tracer):
+ tracer.run('from test import test_pprint; test_pprint.test_main()')
+ r = tracer.results()
+ r.write_results(show_missing=True, summary=True, coverdir=TESTFN)
+
+ def test_coverage(self):
+ tracer = trace.Trace(trace=0, count=1)
+ with captured_stdout() as stdout:
+ self._coverage(tracer)
+ stdout = stdout.getvalue()
+ self.assertTrue("pprint.py" in stdout)
+ self.assertTrue("case.py" in stdout) # from unittest
+ files = os.listdir(TESTFN)
+ self.assertTrue("pprint.cover" in files)
+ self.assertTrue("unittest.case.cover" in files)
+
+ def test_coverage_ignore(self):
+ # Ignore all files, nothing should be traced nor printed
+ libpath = os.path.normpath(os.path.dirname(os.__file__))
+ # sys.prefix does not work when running from a checkout
+ tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix, libpath],
+ trace=0, count=1)
+ with captured_stdout() as stdout:
+ self._coverage(tracer)
+ if os.path.exists(TESTFN):
+ files = os.listdir(TESTFN)
+ self.assertEquals(files, [])
+
+
+def test_main():
+ run_unittest(__name__)
+
+
+if __name__ == '__main__':
+ test_main()
Added: python/branches/release27-maint/Lib/test/tracedmodules/__init__.py
==============================================================================
--- (empty file)
+++ python/branches/release27-maint/Lib/test/tracedmodules/__init__.py Mon Sep 13 18:45:02 2010
@@ -0,0 +1,4 @@
+"""This package contains modules that help testing the trace.py module. Note
+that the exact location of functions in these modules is important, as trace.py
+takes the real line numbers into account.
+"""
Added: python/branches/release27-maint/Lib/test/tracedmodules/testmod.py
==============================================================================
--- (empty file)
+++ python/branches/release27-maint/Lib/test/tracedmodules/testmod.py Mon Sep 13 18:45:02 2010
@@ -0,0 +1,3 @@
+def func(x):
+ b = x + 1
+ return b + 2
Modified: python/branches/release27-maint/Lib/trace.py
==============================================================================
--- python/branches/release27-maint/Lib/trace.py (original)
+++ python/branches/release27-maint/Lib/trace.py Mon Sep 13 18:45:02 2010
@@ -56,7 +56,7 @@
import time
import token
import tokenize
-import types
+import inspect
import gc
try:
@@ -398,7 +398,7 @@
# and check the constants for references to other code objects
for c in code.co_consts:
- if isinstance(c, types.CodeType):
+ if inspect.iscode(c):
# find another code object, so recurse into it
linenos.update(find_lines(c, strs))
return linenos
@@ -545,7 +545,7 @@
## use of gc.get_referrers() was suggested by Michael Hudson
# all functions which refer to this code object
funcs = [f for f in gc.get_referrers(code)
- if hasattr(f, "func_doc")]
+ if inspect.isfunction(f)]
# require len(func) == 1 to avoid ambiguity caused by calls to
# new.function(): "In the face of ambiguity, refuse the
# temptation to guess."
@@ -557,17 +557,13 @@
if hasattr(c, "__bases__")]
if len(classes) == 1:
# ditto for new.classobj()
- clsname = str(classes[0])
+ clsname = classes[0].__name__
# cache the result - assumption is that new.* is
# not called later to disturb this relationship
# _caller_cache could be flushed if functions in
# the new module get called.
self._caller_cache[code] = clsname
if clsname is not None:
- # final hack - module name shows up in str(cls), but we've already
- # computed module name, so remove it
- clsname = clsname.split(".")[1:]
- clsname = ".".join(clsname)
funcname = "%s.%s" % (clsname, funcname)
return filename, modulename, funcname
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Mon Sep 13 18:45:02 2010
@@ -255,6 +255,9 @@
- Issue #9164: Ensure sysconfig handles dupblice archs while building on OSX
+- Issue #9315: Fix for the trace module to record correct class name
+ for tracing methods.
+
Extension Modules
-----------------
@@ -337,6 +340,8 @@
Tests
-----
+- Issue #9315: Added tests for the trace module. Patch by Eli Bendersky.
+
- Strengthen test_unicode with explicit type checking for assertEqual tests.
- Issue #8857: Provide a test case for socket.getaddrinfo.
From python-checkins at python.org Mon Sep 13 19:29:12 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 19:29:12 +0200 (CEST)
Subject: [Python-checkins] r84778 - python/branches/release27-maint
Message-ID: <20100913172912.24BD6EE98D@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 19:29:11 2010
New Revision: 84778
Log:
Unblocked revisions 83524 via svnmerge
........
r83524 | georg.brandl | 2010-08-02 14:20:23 +0200 (lun., 02 ao?t 2010) | 1 line
#9428: fix running scripts from profile/cProfile with their own name and the right namespace. Same fix as for trace.py in #1690103.
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Mon Sep 13 19:36:36 2010
From: python-checkins at python.org (florent.xicluna)
Date: Mon, 13 Sep 2010 19:36:36 +0200 (CEST)
Subject: [Python-checkins] r84779 - in python/branches/release27-maint:
Lib/cProfile.py Lib/profile.py Lib/test/regrtest.py Misc/NEWS
Message-ID: <20100913173636.D9F8EF955@mail.python.org>
Author: florent.xicluna
Date: Mon Sep 13 19:36:36 2010
New Revision: 84779
Log:
Merged revisions 83524,84776 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r83524 | georg.brandl | 2010-08-02 14:20:23 +0200 (lun., 02 ao?t 2010) | 1 line
#9428: fix running scripts from profile/cProfile with their own name and the right namespace. Same fix as for trace.py in #1690103.
........
r84776 | florent.xicluna | 2010-09-13 18:35:02 +0200 (lun., 13 sept. 2010) | 1 line
Make test.regrtest.__file__ absolute, this was not always the case when running profile or trace, for example. (issue #9323)
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Lib/cProfile.py
python/branches/release27-maint/Lib/profile.py
python/branches/release27-maint/Lib/test/regrtest.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/cProfile.py
==============================================================================
--- python/branches/release27-maint/Lib/cProfile.py (original)
+++ python/branches/release27-maint/Lib/cProfile.py Mon Sep 13 19:36:36 2010
@@ -36,7 +36,7 @@
result = prof.print_stats(sort)
return result
-def runctx(statement, globals, locals, filename=None):
+def runctx(statement, globals, locals, filename=None, sort=-1):
"""Run statement under profiler, supplying your own globals and locals,
optionally saving results in filename.
@@ -53,7 +53,7 @@
if filename is not None:
prof.dump_stats(filename)
else:
- result = prof.print_stats()
+ result = prof.print_stats(sort)
return result
# Backwards compatibility.
@@ -169,7 +169,8 @@
parser.add_option('-o', '--outfile', dest="outfile",
help="Save stats to ", default=None)
parser.add_option('-s', '--sort', dest="sort",
- help="Sort order when printing to stdout, based on pstats.Stats class", default=-1)
+ help="Sort order when printing to stdout, based on pstats.Stats class",
+ default=-1)
if not sys.argv[1:]:
parser.print_usage()
@@ -178,9 +179,17 @@
(options, args) = parser.parse_args()
sys.argv[:] = args
- if (len(sys.argv) > 0):
- sys.path.insert(0, os.path.dirname(sys.argv[0]))
- run('execfile(%r)' % (sys.argv[0],), options.outfile, options.sort)
+ if len(args) > 0:
+ progname = args[0]
+ sys.path.insert(0, os.path.dirname(progname))
+ with open(progname, 'rb') as fp:
+ code = compile(fp.read(), progname, 'exec')
+ globs = {
+ '__file__': progname,
+ '__name__': '__main__',
+ '__package__': None,
+ }
+ runctx(code, globs, None, options.outfile, options.sort)
else:
parser.print_usage()
return parser
Modified: python/branches/release27-maint/Lib/profile.py
==============================================================================
--- python/branches/release27-maint/Lib/profile.py (original)
+++ python/branches/release27-maint/Lib/profile.py Mon Sep 13 19:36:36 2010
@@ -75,7 +75,7 @@
else:
return prof.print_stats(sort)
-def runctx(statement, globals, locals, filename=None):
+def runctx(statement, globals, locals, filename=None, sort=-1):
"""Run statement under profiler, supplying your own globals and locals,
optionally saving results in filename.
@@ -90,7 +90,7 @@
if filename is not None:
prof.dump_stats(filename)
else:
- return prof.print_stats()
+ return prof.print_stats(sort)
# Backwards compatibility.
def help():
@@ -589,18 +589,27 @@
parser.add_option('-o', '--outfile', dest="outfile",
help="Save stats to ", default=None)
parser.add_option('-s', '--sort', dest="sort",
- help="Sort order when printing to stdout, based on pstats.Stats class", default=-1)
+ help="Sort order when printing to stdout, based on pstats.Stats class",
+ default=-1)
if not sys.argv[1:]:
parser.print_usage()
sys.exit(2)
(options, args) = parser.parse_args()
+ sys.argv[:] = args
- if (len(args) > 0):
- sys.argv[:] = args
- sys.path.insert(0, os.path.dirname(sys.argv[0]))
- run('execfile(%r)' % (sys.argv[0],), options.outfile, options.sort)
+ if len(args) > 0:
+ progname = args[0]
+ sys.path.insert(0, os.path.dirname(progname))
+ with open(progname, 'rb') as fp:
+ code = compile(fp.read(), progname, 'exec')
+ globs = {
+ '__file__': progname,
+ '__name__': '__main__',
+ '__package__': None,
+ }
+ runctx(code, globs, None, options.outfile, options.sort)
else:
parser.print_usage()
return parser
Modified: python/branches/release27-maint/Lib/test/regrtest.py
==============================================================================
--- python/branches/release27-maint/Lib/test/regrtest.py (original)
+++ python/branches/release27-maint/Lib/test/regrtest.py Mon Sep 13 19:36:36 2010
@@ -1501,7 +1501,13 @@
return self.expected
if __name__ == '__main__':
- # Simplification for findtestdir().
+ # findtestdir() gets the dirname out of __file__, so we have to make it
+ # absolute before changing the working directory.
+ # For example __file__ may be relative when running trace or profile.
+ # See issue #9323.
+ __file__ = os.path.abspath(__file__)
+
+ # sanity check
assert __file__ == os.path.abspath(sys.argv[0])
# When tests are run from the Python build directory, it is best practice
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Mon Sep 13 19:36:36 2010
@@ -151,6 +151,9 @@
- Issue #9354: Provide getsockopt() in asyncore's file_wrapper.
+- Issue #9428: Fix running scripts with the profile/cProfile modules from
+ the command line.
+
- Issue #7781: Fix restricting stats by entry counts in the pstats
interactive browser.
@@ -340,8 +343,11 @@
Tests
-----
+- Issue #9323: Make test.regrtest.__file__ absolute, this was not always the
+ case when running profile or trace, for example.
+
- Issue #9315: Added tests for the trace module. Patch by Eli Bendersky.
-
+
- Strengthen test_unicode with explicit type checking for assertEqual tests.
- Issue #8857: Provide a test case for socket.getaddrinfo.
From python-checkins at python.org Mon Sep 13 20:14:34 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Mon, 13 Sep 2010 20:14:34 +0200 (CEST)
Subject: [Python-checkins] r84780 - in python/branches/py3k:
Lib/test/test_trace.py Lib/trace.py Misc/NEWS
Message-ID: <20100913181434.64524FC16@mail.python.org>
Author: alexander.belopolsky
Date: Mon Sep 13 20:14:34 2010
New Revision: 84780
Log:
Issue #9315: Fix for the trace module to record correct class name
when tracing methods. Unit tests. Patch by Eli Bendersky.
Modified:
python/branches/py3k/Lib/test/test_trace.py
python/branches/py3k/Lib/trace.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/test/test_trace.py
==============================================================================
--- python/branches/py3k/Lib/test/test_trace.py (original)
+++ python/branches/py3k/Lib/test/test_trace.py Mon Sep 13 20:14:34 2010
@@ -1,10 +1,286 @@
-# Testing the trace module
-
-from test.support import run_unittest, TESTFN, rmtree, unlink, captured_stdout
+import os
+import sys
+from test.support import (run_unittest, TESTFN, rmtree, unlink,
+ captured_stdout)
import unittest
+
import trace
-import os, sys
+from trace import CoverageResults, Trace
+
+from test.tracedmodules import testmod
+
+
+#------------------------------- Utilities -----------------------------------#
+
+def fix_ext_py(filename):
+ """Given a .pyc/.pyo filename converts it to the appropriate .py"""
+ if filename.endswith(('.pyc', '.pyo')):
+ filename = filename[:-1]
+ return filename
+
+def my_file_and_modname():
+ """The .py file and module name of this file (__file__)"""
+ modname = os.path.splitext(os.path.basename(__file__))[0]
+ return fix_ext_py(__file__), modname
+
+def get_firstlineno(func):
+ return func.__code__.co_firstlineno
+
+#-------------------- Target functions for tracing ---------------------------#
+#
+# The relative line numbers of lines in these functions matter for verifying
+# tracing. Please modify the appropriate tests if you change one of the
+# functions. Absolute line numbers don't matter.
+#
+
+def traced_func_linear(x, y):
+ a = x
+ b = y
+ c = a + b
+ return c
+
+def traced_func_loop(x, y):
+ c = x
+ for i in range(5):
+ c += y
+ return c
+
+def traced_func_importing(x, y):
+ return x + y + testmod.func(1)
+
+def traced_func_simple_caller(x):
+ c = traced_func_linear(x, x)
+ return c + x
+
+def traced_func_importing_caller(x):
+ k = traced_func_simple_caller(x)
+ k += traced_func_importing(k, x)
+ return k
+
+def traced_func_generator(num):
+ c = 5 # executed once
+ for i in range(num):
+ yield i + c
+
+def traced_func_calling_generator():
+ k = 0
+ for i in traced_func_generator(10):
+ k += i
+
+def traced_doubler(num):
+ return num * 2
+
+def traced_caller_list_comprehension():
+ k = 10
+ mylist = [traced_doubler(i) for i in range(k)]
+ return mylist
+
+
+class TracedClass(object):
+ def __init__(self, x):
+ self.a = x
+
+ def inst_method_linear(self, y):
+ return self.a + y
+
+ def inst_method_calling(self, x):
+ c = self.inst_method_linear(x)
+ return c + traced_func_linear(x, c)
+
+ @classmethod
+ def class_method_linear(cls, y):
+ return y * 2
+
+ @staticmethod
+ def static_method_linear(y):
+ return y * 2
+
+
+#------------------------------ Test cases -----------------------------------#
+
+
+class TestLineCounts(unittest.TestCase):
+ """White-box testing of line-counting, via runfunc"""
+ def setUp(self):
+ self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ self.my_py_filename = fix_ext_py(__file__)
+ self.maxDiff = None
+
+ def test_traced_func_linear(self):
+ result = self.tracer.runfunc(traced_func_linear, 2, 5)
+ self.assertEqual(result, 7)
+
+ # all lines are executed once
+ expected = {}
+ firstlineno = get_firstlineno(traced_func_linear)
+ for i in range(1, 5):
+ expected[(self.my_py_filename, firstlineno + i)] = 1
+
+ self.assertEqual(self.tracer.results().counts, expected)
+ def test_traced_func_loop(self):
+ self.tracer.runfunc(traced_func_loop, 2, 3)
+
+ firstlineno = get_firstlineno(traced_func_loop)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (self.my_py_filename, firstlineno + 2): 6,
+ (self.my_py_filename, firstlineno + 3): 5,
+ (self.my_py_filename, firstlineno + 4): 1,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_traced_func_importing(self):
+ self.tracer.runfunc(traced_func_importing, 2, 5)
+
+ firstlineno = get_firstlineno(traced_func_importing)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (fix_ext_py(testmod.__file__), 2): 1,
+ (fix_ext_py(testmod.__file__), 3): 1,
+ }
+
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_trace_func_generator(self):
+ self.tracer.runfunc(traced_func_calling_generator)
+
+ firstlineno_calling = get_firstlineno(traced_func_calling_generator)
+ firstlineno_gen = get_firstlineno(traced_func_generator)
+ expected = {
+ (self.my_py_filename, firstlineno_calling + 1): 1,
+ (self.my_py_filename, firstlineno_calling + 2): 11,
+ (self.my_py_filename, firstlineno_calling + 3): 10,
+ (self.my_py_filename, firstlineno_gen + 1): 1,
+ (self.my_py_filename, firstlineno_gen + 2): 11,
+ (self.my_py_filename, firstlineno_gen + 3): 10,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_trace_list_comprehension(self):
+ self.tracer.runfunc(traced_caller_list_comprehension)
+
+ firstlineno_calling = get_firstlineno(traced_caller_list_comprehension)
+ firstlineno_called = get_firstlineno(traced_doubler)
+ expected = {
+ (self.my_py_filename, firstlineno_calling + 1): 1,
+ # List compehentions work differently in 3.x, so the count
+ # below changed compared to 2.x.
+ (self.my_py_filename, firstlineno_calling + 2): 12,
+ (self.my_py_filename, firstlineno_calling + 3): 1,
+ (self.my_py_filename, firstlineno_called + 1): 10,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+
+ def test_linear_methods(self):
+ # XXX todo: later add 'static_method_linear' and 'class_method_linear'
+ # here, once issue1764286 is resolved
+ #
+ for methname in ['inst_method_linear',]:
+ tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ traced_obj = TracedClass(25)
+ method = getattr(traced_obj, methname)
+ tracer.runfunc(method, 20)
+
+ firstlineno = get_firstlineno(method)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ }
+ self.assertEqual(tracer.results().counts, expected)
+
+
+class TestRunExecCounts(unittest.TestCase):
+ """A simple sanity test of line-counting, via runctx (exec)"""
+ def setUp(self):
+ self.my_py_filename = fix_ext_py(__file__)
+
+ def test_exec_counts(self):
+ self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ code = r'''traced_func_loop(2, 5)'''
+ code = compile(code, __file__, 'exec')
+ self.tracer.runctx(code, globals(), vars())
+
+ firstlineno = get_firstlineno(traced_func_loop)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (self.my_py_filename, firstlineno + 2): 6,
+ (self.my_py_filename, firstlineno + 3): 5,
+ (self.my_py_filename, firstlineno + 4): 1,
+ }
+
+ # When used through 'run', some other spurios counts are produced, like
+ # the settrace of threading, which we ignore, just making sure that the
+ # counts fo traced_func_loop were right.
+ #
+ for k in expected.keys():
+ self.assertEqual(self.tracer.results().counts[k], expected[k])
+
+
+class TestFuncs(unittest.TestCase):
+ """White-box testing of funcs tracing"""
+ def setUp(self):
+ self.tracer = Trace(count=0, trace=0, countfuncs=1)
+ self.filemod = my_file_and_modname()
+
+ def test_simple_caller(self):
+ self.tracer.runfunc(traced_func_simple_caller, 1)
+
+ expected = {
+ self.filemod + ('traced_func_simple_caller',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+ def test_loop_caller_importing(self):
+ self.tracer.runfunc(traced_func_importing_caller, 1)
+
+ expected = {
+ self.filemod + ('traced_func_simple_caller',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ self.filemod + ('traced_func_importing_caller',): 1,
+ self.filemod + ('traced_func_importing',): 1,
+ (fix_ext_py(testmod.__file__), 'testmod', 'func'): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+ def test_inst_method_calling(self):
+ obj = TracedClass(20)
+ self.tracer.runfunc(obj.inst_method_calling, 1)
+
+ expected = {
+ self.filemod + ('TracedClass.inst_method_calling',): 1,
+ self.filemod + ('TracedClass.inst_method_linear',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+
+class TestCallers(unittest.TestCase):
+ """White-box testing of callers tracing"""
+ def setUp(self):
+ self.tracer = Trace(count=0, trace=0, countcallers=1)
+ self.filemod = my_file_and_modname()
+
+ def test_loop_caller_importing(self):
+ self.tracer.runfunc(traced_func_importing_caller, 1)
+
+ expected = {
+ ((os.path.splitext(trace.__file__)[0] + '.py', 'trace', 'Trace.runfunc'),
+ (self.filemod + ('traced_func_importing_caller',))): 1,
+ ((self.filemod + ('traced_func_simple_caller',)),
+ (self.filemod + ('traced_func_linear',))): 1,
+ ((self.filemod + ('traced_func_importing_caller',)),
+ (self.filemod + ('traced_func_simple_caller',))): 1,
+ ((self.filemod + ('traced_func_importing_caller',)),
+ (self.filemod + ('traced_func_importing',))): 1,
+ ((self.filemod + ('traced_func_importing',)),
+ (fix_ext_py(testmod.__file__), 'testmod', 'func')): 1,
+ }
+ self.assertEqual(self.tracer.results().callers, expected)
+
+
+# Created separately for issue #3821
class TestCoverage(unittest.TestCase):
def tearDown(self):
rmtree(TESTFN)
@@ -34,7 +310,6 @@
trace=0, count=1)
with captured_stdout() as stdout:
self._coverage(tracer)
- self.assertEquals(stdout.getvalue(), "")
if os.path.exists(TESTFN):
files = os.listdir(TESTFN)
self.assertEquals(files, [])
@@ -43,5 +318,6 @@
def test_main():
run_unittest(__name__)
-if __name__ == "__main__":
+
+if __name__ == '__main__':
test_main()
Modified: python/branches/py3k/Lib/trace.py
==============================================================================
--- python/branches/py3k/Lib/trace.py (original)
+++ python/branches/py3k/Lib/trace.py Mon Sep 13 20:14:34 2010
@@ -57,7 +57,7 @@
import time
import token
import tokenize
-import types
+import inspect
import gc
import pickle
@@ -395,7 +395,7 @@
# and check the constants for references to other code objects
for c in code.co_consts:
- if isinstance(c, types.CodeType):
+ if inspect.iscode(c):
# find another code object, so recurse into it
linenos.update(find_lines(c, strs))
return linenos
@@ -544,7 +544,7 @@
## use of gc.get_referrers() was suggested by Michael Hudson
# all functions which refer to this code object
funcs = [f for f in gc.get_referrers(code)
- if hasattr(f, "__doc__")]
+ if inspect.isfunction(f)]
# require len(func) == 1 to avoid ambiguity caused by calls to
# new.function(): "In the face of ambiguity, refuse the
# temptation to guess."
@@ -556,17 +556,13 @@
if hasattr(c, "__bases__")]
if len(classes) == 1:
# ditto for new.classobj()
- clsname = str(classes[0])
+ clsname = classes[0].__name__
# cache the result - assumption is that new.* is
# not called later to disturb this relationship
# _caller_cache could be flushed if functions in
# the new module get called.
self._caller_cache[code] = clsname
if clsname is not None:
- # final hack - module name shows up in str(cls), but we've already
- # computed module name, so remove it
- clsname = clsname.split(".")[1:]
- clsname = ".".join(clsname)
funcname = "%s.%s" % (clsname, funcname)
return filename, modulename, funcname
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 20:14:34 2010
@@ -145,6 +145,8 @@
Tests
-----
+- Issue #9315: Added tests for the trace module. Patch by Eli Bendersky.
+
- Issue #9323: Make test.regrtest.__file__ absolute, this was not always the
case when running profile or trace, for example.
@@ -2070,6 +2072,9 @@
- Issue #8235: _socket: Add the constant ``SO_SETFIB``. SO_SETFIB is a socket
option available on FreeBSD 7.1 and newer.
+- Issue #9315: Fix for the trace module to record correct class name
+ for tracing methods.
+
Extension Modules
-----------------
From python-checkins at python.org Mon Sep 13 20:15:33 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Mon, 13 Sep 2010 20:15:33 +0200 (CEST)
Subject: [Python-checkins] r84781 -
python/branches/py3k/Lib/test/test_trace.py
Message-ID: <20100913181533.5748AEE991@mail.python.org>
Author: alexander.belopolsky
Date: Mon Sep 13 20:15:33 2010
New Revision: 84781
Log:
Removed debugging setting
Modified:
python/branches/py3k/Lib/test/test_trace.py
Modified: python/branches/py3k/Lib/test/test_trace.py
==============================================================================
--- python/branches/py3k/Lib/test/test_trace.py (original)
+++ python/branches/py3k/Lib/test/test_trace.py Mon Sep 13 20:15:33 2010
@@ -104,7 +104,6 @@
def setUp(self):
self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
self.my_py_filename = fix_ext_py(__file__)
- self.maxDiff = None
def test_traced_func_linear(self):
result = self.tracer.runfunc(traced_func_linear, 2, 5)
From python-checkins at python.org Mon Sep 13 20:16:55 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Mon, 13 Sep 2010 20:16:55 +0200 (CEST)
Subject: [Python-checkins] r84782 -
python/branches/release27-maint/Lib/test/test_trace.py
Message-ID: <20100913181655.81C70EE9AE@mail.python.org>
Author: alexander.belopolsky
Date: Mon Sep 13 20:16:55 2010
New Revision: 84782
Log:
Removed debugging setting
Modified:
python/branches/release27-maint/Lib/test/test_trace.py
Modified: python/branches/release27-maint/Lib/test/test_trace.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_trace.py (original)
+++ python/branches/release27-maint/Lib/test/test_trace.py Mon Sep 13 20:16:55 2010
@@ -219,7 +219,7 @@
def setUp(self):
self.tracer = Trace(count=0, trace=0, countfuncs=1)
self.filemod = my_file_and_modname()
- self.maxDiff = None
+
def test_simple_caller(self):
self.tracer.runfunc(traced_func_simple_caller, 1)
From python-checkins at python.org Mon Sep 13 20:38:54 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Mon, 13 Sep 2010 20:38:54 +0200 (CEST)
Subject: [Python-checkins] r84783 - in python/branches/release31-maint:
Lib/test/test_trace.py Lib/test/tracedmodules
Lib/test/tracedmodules/__init__.py
Lib/test/tracedmodules/testmod.py Lib/trace.py Misc/NEWS
Message-ID: <20100913183854.B967AEE9B4@mail.python.org>
Author: alexander.belopolsky
Date: Mon Sep 13 20:38:54 2010
New Revision: 84783
Log:
Merged revisions 84780-84781 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
with some manual fixes
........
r84780 | alexander.belopolsky | 2010-09-13 14:14:34 -0400 (Mon, 13 Sep 2010) | 3 lines
Issue #9315: Fix for the trace module to record correct class name
when tracing methods. Unit tests. Patch by Eli Bendersky.
........
r84781 | alexander.belopolsky | 2010-09-13 14:15:33 -0400 (Mon, 13 Sep 2010) | 1 line
Removed debugging setting
........
Added:
python/branches/release31-maint/Lib/test/test_trace.py
python/branches/release31-maint/Lib/test/tracedmodules/
python/branches/release31-maint/Lib/test/tracedmodules/__init__.py
python/branches/release31-maint/Lib/test/tracedmodules/testmod.py
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/trace.py
python/branches/release31-maint/Misc/NEWS
Added: python/branches/release31-maint/Lib/test/test_trace.py
==============================================================================
--- (empty file)
+++ python/branches/release31-maint/Lib/test/test_trace.py Mon Sep 13 20:38:54 2010
@@ -0,0 +1,322 @@
+import os
+import sys
+from test.support import (run_unittest, TESTFN, rmtree, unlink,
+ captured_stdout)
+import unittest
+
+import trace
+from trace import CoverageResults, Trace
+
+from test.tracedmodules import testmod
+
+
+#------------------------------- Utilities -----------------------------------#
+
+def fix_ext_py(filename):
+ """Given a .pyc/.pyo filename converts it to the appropriate .py"""
+ if filename.endswith(('.pyc', '.pyo')):
+ filename = filename[:-1]
+ return filename
+
+def my_file_and_modname():
+ """The .py file and module name of this file (__file__)"""
+ modname = os.path.splitext(os.path.basename(__file__))[0]
+ return fix_ext_py(__file__), modname
+
+def get_firstlineno(func):
+ return func.__code__.co_firstlineno
+
+#-------------------- Target functions for tracing ---------------------------#
+#
+# The relative line numbers of lines in these functions matter for verifying
+# tracing. Please modify the appropriate tests if you change one of the
+# functions. Absolute line numbers don't matter.
+#
+
+def traced_func_linear(x, y):
+ a = x
+ b = y
+ c = a + b
+ return c
+
+def traced_func_loop(x, y):
+ c = x
+ for i in range(5):
+ c += y
+ return c
+
+def traced_func_importing(x, y):
+ return x + y + testmod.func(1)
+
+def traced_func_simple_caller(x):
+ c = traced_func_linear(x, x)
+ return c + x
+
+def traced_func_importing_caller(x):
+ k = traced_func_simple_caller(x)
+ k += traced_func_importing(k, x)
+ return k
+
+def traced_func_generator(num):
+ c = 5 # executed once
+ for i in range(num):
+ yield i + c
+
+def traced_func_calling_generator():
+ k = 0
+ for i in traced_func_generator(10):
+ k += i
+
+def traced_doubler(num):
+ return num * 2
+
+def traced_caller_list_comprehension():
+ k = 10
+ mylist = [traced_doubler(i) for i in range(k)]
+ return mylist
+
+
+class TracedClass(object):
+ def __init__(self, x):
+ self.a = x
+
+ def inst_method_linear(self, y):
+ return self.a + y
+
+ def inst_method_calling(self, x):
+ c = self.inst_method_linear(x)
+ return c + traced_func_linear(x, c)
+
+ @classmethod
+ def class_method_linear(cls, y):
+ return y * 2
+
+ @staticmethod
+ def static_method_linear(y):
+ return y * 2
+
+
+#------------------------------ Test cases -----------------------------------#
+
+
+class TestLineCounts(unittest.TestCase):
+ """White-box testing of line-counting, via runfunc"""
+ def setUp(self):
+ self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ self.my_py_filename = fix_ext_py(__file__)
+
+ def test_traced_func_linear(self):
+ result = self.tracer.runfunc(traced_func_linear, 2, 5)
+ self.assertEqual(result, 7)
+
+ # all lines are executed once
+ expected = {}
+ firstlineno = get_firstlineno(traced_func_linear)
+ for i in range(1, 5):
+ expected[(self.my_py_filename, firstlineno + i)] = 1
+
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_traced_func_loop(self):
+ self.tracer.runfunc(traced_func_loop, 2, 3)
+
+ firstlineno = get_firstlineno(traced_func_loop)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (self.my_py_filename, firstlineno + 2): 6,
+ (self.my_py_filename, firstlineno + 3): 5,
+ (self.my_py_filename, firstlineno + 4): 1,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_traced_func_importing(self):
+ self.tracer.runfunc(traced_func_importing, 2, 5)
+
+ firstlineno = get_firstlineno(traced_func_importing)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (fix_ext_py(testmod.__file__), 2): 1,
+ (fix_ext_py(testmod.__file__), 3): 1,
+ }
+
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_trace_func_generator(self):
+ self.tracer.runfunc(traced_func_calling_generator)
+
+ firstlineno_calling = get_firstlineno(traced_func_calling_generator)
+ firstlineno_gen = get_firstlineno(traced_func_generator)
+ expected = {
+ (self.my_py_filename, firstlineno_calling + 1): 1,
+ (self.my_py_filename, firstlineno_calling + 2): 11,
+ (self.my_py_filename, firstlineno_calling + 3): 10,
+ (self.my_py_filename, firstlineno_gen + 1): 1,
+ (self.my_py_filename, firstlineno_gen + 2): 11,
+ (self.my_py_filename, firstlineno_gen + 3): 10,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+ def test_trace_list_comprehension(self):
+ self.tracer.runfunc(traced_caller_list_comprehension)
+
+ firstlineno_calling = get_firstlineno(traced_caller_list_comprehension)
+ firstlineno_called = get_firstlineno(traced_doubler)
+ expected = {
+ (self.my_py_filename, firstlineno_calling + 1): 1,
+ # List compehentions work differently in 3.x, so the count
+ # below changed compared to 2.x.
+ (self.my_py_filename, firstlineno_calling + 2): 12,
+ (self.my_py_filename, firstlineno_calling + 3): 1,
+ (self.my_py_filename, firstlineno_called + 1): 10,
+ }
+ self.assertEqual(self.tracer.results().counts, expected)
+
+
+ def test_linear_methods(self):
+ # XXX todo: later add 'static_method_linear' and 'class_method_linear'
+ # here, once issue1764286 is resolved
+ #
+ for methname in ['inst_method_linear',]:
+ tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ traced_obj = TracedClass(25)
+ method = getattr(traced_obj, methname)
+ tracer.runfunc(method, 20)
+
+ firstlineno = get_firstlineno(method)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ }
+ self.assertEqual(tracer.results().counts, expected)
+
+
+class TestRunExecCounts(unittest.TestCase):
+ """A simple sanity test of line-counting, via runctx (exec)"""
+ def setUp(self):
+ self.my_py_filename = fix_ext_py(__file__)
+
+ def test_exec_counts(self):
+ self.tracer = Trace(count=1, trace=0, countfuncs=0, countcallers=0)
+ code = r'''traced_func_loop(2, 5)'''
+ code = compile(code, __file__, 'exec')
+ self.tracer.runctx(code, globals(), vars())
+
+ firstlineno = get_firstlineno(traced_func_loop)
+ expected = {
+ (self.my_py_filename, firstlineno + 1): 1,
+ (self.my_py_filename, firstlineno + 2): 6,
+ (self.my_py_filename, firstlineno + 3): 5,
+ (self.my_py_filename, firstlineno + 4): 1,
+ }
+
+ # When used through 'run', some other spurios counts are produced, like
+ # the settrace of threading, which we ignore, just making sure that the
+ # counts fo traced_func_loop were right.
+ #
+ for k in expected.keys():
+ self.assertEqual(self.tracer.results().counts[k], expected[k])
+
+
+class TestFuncs(unittest.TestCase):
+ """White-box testing of funcs tracing"""
+ def setUp(self):
+ self.tracer = Trace(count=0, trace=0, countfuncs=1)
+ self.filemod = my_file_and_modname()
+
+ def test_simple_caller(self):
+ self.tracer.runfunc(traced_func_simple_caller, 1)
+
+ expected = {
+ self.filemod + ('traced_func_simple_caller',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+ def test_loop_caller_importing(self):
+ self.tracer.runfunc(traced_func_importing_caller, 1)
+
+ expected = {
+ self.filemod + ('traced_func_simple_caller',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ self.filemod + ('traced_func_importing_caller',): 1,
+ self.filemod + ('traced_func_importing',): 1,
+ (fix_ext_py(testmod.__file__), 'testmod', 'func'): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+ def test_inst_method_calling(self):
+ obj = TracedClass(20)
+ self.tracer.runfunc(obj.inst_method_calling, 1)
+
+ expected = {
+ self.filemod + ('TracedClass.inst_method_calling',): 1,
+ self.filemod + ('TracedClass.inst_method_linear',): 1,
+ self.filemod + ('traced_func_linear',): 1,
+ }
+ self.assertEqual(self.tracer.results().calledfuncs, expected)
+
+
+class TestCallers(unittest.TestCase):
+ """White-box testing of callers tracing"""
+ def setUp(self):
+ self.tracer = Trace(count=0, trace=0, countcallers=1)
+ self.filemod = my_file_and_modname()
+
+ def test_loop_caller_importing(self):
+ self.tracer.runfunc(traced_func_importing_caller, 1)
+
+ expected = {
+ ((os.path.splitext(trace.__file__)[0] + '.py', 'trace', 'Trace.runfunc'),
+ (self.filemod + ('traced_func_importing_caller',))): 1,
+ ((self.filemod + ('traced_func_simple_caller',)),
+ (self.filemod + ('traced_func_linear',))): 1,
+ ((self.filemod + ('traced_func_importing_caller',)),
+ (self.filemod + ('traced_func_simple_caller',))): 1,
+ ((self.filemod + ('traced_func_importing_caller',)),
+ (self.filemod + ('traced_func_importing',))): 1,
+ ((self.filemod + ('traced_func_importing',)),
+ (fix_ext_py(testmod.__file__), 'testmod', 'func')): 1,
+ }
+ self.assertEqual(self.tracer.results().callers, expected)
+
+
+# Created separately for issue #3821
+class TestCoverage(unittest.TestCase):
+ def tearDown(self):
+ rmtree(TESTFN)
+ unlink(TESTFN)
+
+ def _coverage(self, tracer):
+ tracer.run('from test import test_pprint; test_pprint.test_main()')
+ r = tracer.results()
+ r.write_results(show_missing=True, summary=True, coverdir=TESTFN)
+
+ def test_coverage(self):
+ tracer = trace.Trace(trace=0, count=1)
+ with captured_stdout() as stdout:
+ self._coverage(tracer)
+ stdout = stdout.getvalue()
+ self.assertTrue("pprint.py" in stdout)
+ self.assertTrue("unittest.py" in stdout)
+ files = os.listdir(TESTFN)
+ self.assertTrue("pprint.cover" in files)
+ self.assertTrue("unittest.cover" in files)
+
+ def test_coverage_ignore(self):
+ # Ignore all files, nothing should be traced nor printed
+ libpath = os.path.normpath(os.path.dirname(os.__file__))
+ # sys.prefix does not work when running from a checkout
+ tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix, libpath],
+ trace=0, count=1)
+ with captured_stdout() as stdout:
+ self._coverage(tracer)
+ if os.path.exists(TESTFN):
+ files = os.listdir(TESTFN)
+ self.assertEquals(files, [])
+
+
+def test_main():
+ run_unittest(__name__)
+
+
+if __name__ == '__main__':
+ test_main()
Added: python/branches/release31-maint/Lib/test/tracedmodules/__init__.py
==============================================================================
--- (empty file)
+++ python/branches/release31-maint/Lib/test/tracedmodules/__init__.py Mon Sep 13 20:38:54 2010
@@ -0,0 +1,9 @@
+"""This package contains modules that help testing the trace.py module. Note
+that the exact location of functions in these modules is important, as trace.py
+takes the real line numbers into account.
+"""
+"""This directory contains modules that help testing the trace.py module. Note
+that the exact location of functions in these modules is important, as trace.py
+takes the real line numbers into account.
+
+"""
Added: python/branches/release31-maint/Lib/test/tracedmodules/testmod.py
==============================================================================
--- (empty file)
+++ python/branches/release31-maint/Lib/test/tracedmodules/testmod.py Mon Sep 13 20:38:54 2010
@@ -0,0 +1,3 @@
+def func(x):
+ b = x + 1
+ return b + 2
Modified: python/branches/release31-maint/Lib/trace.py
==============================================================================
--- python/branches/release31-maint/Lib/trace.py (original)
+++ python/branches/release31-maint/Lib/trace.py Mon Sep 13 20:38:54 2010
@@ -57,7 +57,7 @@
import time
import token
import tokenize
-import types
+import inspect
import gc
import pickle
@@ -395,7 +395,7 @@
# and check the constants for references to other code objects
for c in code.co_consts:
- if isinstance(c, types.CodeType):
+ if inspect.iscode(c):
# find another code object, so recurse into it
linenos.update(find_lines(c, strs))
return linenos
@@ -544,7 +544,7 @@
## use of gc.get_referrers() was suggested by Michael Hudson
# all functions which refer to this code object
funcs = [f for f in gc.get_referrers(code)
- if hasattr(f, "__doc__")]
+ if inspect.isfunction(f)]
# require len(func) == 1 to avoid ambiguity caused by calls to
# new.function(): "In the face of ambiguity, refuse the
# temptation to guess."
@@ -556,17 +556,13 @@
if hasattr(c, "__bases__")]
if len(classes) == 1:
# ditto for new.classobj()
- clsname = str(classes[0])
+ clsname = classes[0].__name__
# cache the result - assumption is that new.* is
# not called later to disturb this relationship
# _caller_cache could be flushed if functions in
# the new module get called.
self._caller_cache[code] = clsname
if clsname is not None:
- # final hack - module name shows up in str(cls), but we've already
- # computed module name, so remove it
- clsname = clsname.split(".")[1:]
- clsname = ".".join(clsname)
funcname = "%s.%s" % (clsname, funcname)
return filename, modulename, funcname
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Mon Sep 13 20:38:54 2010
@@ -584,6 +584,8 @@
Tests
-----
+- Issue #9315: Added tests for the trace module. Patch by Eli Bendersky.
+
- Issue #7564: Skip test_ioctl if another process is attached to /dev/tty.
- Issue #8857: Provide a test case for socket.getaddrinfo.
@@ -1019,6 +1021,9 @@
- Issue #1068268: The subprocess module now handles EINTR in internal
os.waitpid and os.read system calls where appropriate.
+- Issue #9315: Fix for the trace module to record correct class name
+ for tracing methods.
+
Extension Modules
-----------------
From python-checkins at python.org Mon Sep 13 21:41:37 2010
From: python-checkins at python.org (victor.stinner)
Date: Mon, 13 Sep 2010 21:41:37 +0200 (CEST)
Subject: [Python-checkins] r84784 - in python/branches/py3k: Lib/macpath.py
Misc/NEWS
Message-ID: <20100913194137.0B7EDEE988@mail.python.org>
Author: victor.stinner
Date: Mon Sep 13 21:41:36 2010
New Revision: 84784
Log:
Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
(macpath module).
Modified:
python/branches/py3k/Lib/macpath.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/macpath.py
==============================================================================
--- python/branches/py3k/Lib/macpath.py (original)
+++ python/branches/py3k/Lib/macpath.py Mon Sep 13 21:41:36 2010
@@ -202,4 +202,4 @@
pass
return path
-supports_unicode_filenames = False
+supports_unicode_filenames = True
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 21:41:36 2010
@@ -40,6 +40,9 @@
Library
-------
+- Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
+ (macpath module).
+
- Issue #9837: The read() method of ZipExtFile objects (as returned by
ZipFile.open()) could return more bytes than requested.
From python-checkins at python.org Mon Sep 13 22:02:39 2010
From: python-checkins at python.org (vinay.sajip)
Date: Mon, 13 Sep 2010 22:02:39 +0200 (CEST)
Subject: [Python-checkins] r84785 -
python/branches/py3k/Doc/library/logging.rst
Message-ID: <20100913200239.CA4F3EE997@mail.python.org>
Author: vinay.sajip
Date: Mon Sep 13 22:02:39 2010
New Revision: 84785
Log:
Expanded QueueHandler documentation.
Modified:
python/branches/py3k/Doc/library/logging.rst
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Mon Sep 13 22:02:39 2010
@@ -2605,7 +2605,9 @@
.. class:: QueueHandler(queue)
Returns a new instance of the :class:`QueueHandler` class. The instance is
- initialized with the queue to send messages to.
+ initialized with the queue to send messages to. The queue can be any queue-
+ like object; it's passed as-is to the :meth:`enqueue` method, which needs
+ to know how to send messages to it.
.. method:: emit(record)
@@ -2623,6 +2625,37 @@
The :class:`QueueHandler` class was not present in previous versions.
+.. _zeromq-handlers:
+
+You can use a :class:`QueueHandler` subclass to send messages to other kinds
+of queues, for example a ZeroMQ "publish" socket. In the example below,the
+socket is created separately and passed to the handler (as its 'queue')::
+
+ import zmq # using pyzmq, the Python binding for ZeroMQ
+ import json # for serializing records portably
+
+ ctx = zmq.Context()
+ sock = zmq.Socket(ctx, zmq.PUB) # or zmq.PUSH, or other suitable value
+ sock.bind('tcp://*:5556') # or wherever
+
+ class ZeroMQSocketHandler(QueueHandler):
+ def enqueue(self, record):
+ data = json.dumps(record.__dict__)
+ self.queue.send(data)
+
+Of course there are other ways of organizing this, for example passing in the
+data needed by the handler to create the socket::
+
+ class ZeroMQSocketHandler(QueueHandler):
+ def __init__(self, uri, socktype=zmq.PUB, ctx=None):
+ self.ctx = ctx or zmq.Context()
+ socket = zmq.Socket(self.ctx, socktype)
+ super(ZeroMQSocketHandler, self).__init__(socket)
+
+ def enqueue(self, record):
+ data = json.dumps(record.__dict__)
+ self.queue.send(data)
+
.. _formatter-objects:
From python-checkins at python.org Mon Sep 13 22:28:57 2010
From: python-checkins at python.org (vinay.sajip)
Date: Mon, 13 Sep 2010 22:28:57 +0200 (CEST)
Subject: [Python-checkins] r84786 -
python/branches/py3k/Lib/logging/__init__.py
Message-ID: <20100913202857.B3DCFEE9D9@mail.python.org>
Author: vinay.sajip
Date: Mon Sep 13 22:28:57 2010
New Revision: 84786
Log:
Removed unused, commented-out code.
Modified:
python/branches/py3k/Lib/logging/__init__.py
Modified: python/branches/py3k/Lib/logging/__init__.py
==============================================================================
--- python/branches/py3k/Lib/logging/__init__.py (original)
+++ python/branches/py3k/Lib/logging/__init__.py Mon Sep 13 22:28:57 2010
@@ -1498,15 +1498,6 @@
else:
return root
-#def getRootLogger():
-# """
-# Return the root logger.
-#
-# Note that getLogger('') now does the same thing, so this function is
-# deprecated and may disappear in the future.
-# """
-# return root
-
def critical(msg, *args, **kwargs):
"""
Log a message with severity 'CRITICAL' on the root logger.
From python-checkins at python.org Mon Sep 13 22:31:35 2010
From: python-checkins at python.org (victor.stinner)
Date: Mon, 13 Sep 2010 22:31:35 +0200 (CEST)
Subject: [Python-checkins] r84787 - in python/branches/release27-maint:
Doc/library/os.path.rst Lib/macpath.py Misc/NEWS
Message-ID: <20100913203135.0EA28EE9C4@mail.python.org>
Author: victor.stinner
Date: Mon Sep 13 22:31:34 2010
New Revision: 84787
Log:
Merged revisions 84701,84784 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84701 | victor.stinner | 2010-09-11 02:22:12 +0200 (sam., 11 sept. 2010) | 5 lines
Issue #767645: fix os.path.supports_unicode_filenames definition
os.listdir(str) always returns unicode and it can return non-ascii filenames
even if supports_unicode_filenames is False.
........
r84784 | victor.stinner | 2010-09-13 21:41:36 +0200 (lun., 13 sept. 2010) | 2 lines
Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
(macpath module).
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Doc/library/os.path.rst
python/branches/release27-maint/Lib/macpath.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Doc/library/os.path.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/os.path.rst (original)
+++ python/branches/release27-maint/Doc/library/os.path.rst Mon Sep 13 22:31:34 2010
@@ -337,8 +337,7 @@
.. data:: supports_unicode_filenames
True if arbitrary Unicode strings can be used as file names (within limitations
- imposed by the file system), and if :func:`os.listdir` returns Unicode strings
- for a Unicode argument.
+ imposed by the file system).
.. versionadded:: 2.3
Modified: python/branches/release27-maint/Lib/macpath.py
==============================================================================
--- python/branches/release27-maint/Lib/macpath.py (original)
+++ python/branches/release27-maint/Lib/macpath.py Mon Sep 13 22:31:34 2010
@@ -212,4 +212,4 @@
pass
return path
-supports_unicode_filenames = False
+supports_unicode_filenames = True
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Mon Sep 13 22:31:34 2010
@@ -43,6 +43,9 @@
Library
-------
+- Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
+ (macpath module).
+
- Issue #9837: The read() method of ZipExtFile objects (as returned by
ZipFile.open()) could return more bytes than requested.
From python-checkins at python.org Mon Sep 13 22:37:50 2010
From: python-checkins at python.org (vinay.sajip)
Date: Mon, 13 Sep 2010 22:37:50 +0200 (CEST)
Subject: [Python-checkins] r84788 -
python/branches/py3k/Doc/library/logging.rst
Message-ID: <20100913203750.BA50AEE99C@mail.python.org>
Author: vinay.sajip
Date: Mon Sep 13 22:37:50 2010
New Revision: 84788
Log:
Enhanced HTTPHandler documentation.
Modified:
python/branches/py3k/Doc/library/logging.rst
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Mon Sep 13 22:37:50 2010
@@ -2578,12 +2578,16 @@
``POST`` semantics.
-.. class:: HTTPHandler(host, url, method='GET')
+.. class:: HTTPHandler(host, url, method='GET', secure=False, credentials=None)
- Returns a new instance of the :class:`HTTPHandler` class. The instance is
- initialized with a host address, url and HTTP method. The *host* can be of the
- form ``host:port``, should you need to use a specific port number. If no
- *method* is specified, ``GET`` is used.
+ Returns a new instance of the :class:`HTTPHandler` class. The *host* can be
+ of the form ``host:port``, should you need to use a specific port number.
+ If no *method* is specified, ``GET`` is used. If *secure* is True, an HTTPS
+ connection will be used. If *credentials* is specified, it should be a
+ 2-tuple consisting of userid and password, which will be placed in an HTTP
+ 'Authorization' header using Basic authentication. If you specify
+ credentials, you should also specify secure=True so that your userid and
+ password are not passed in cleartext across the wire.
.. method:: emit(record)
From python-checkins at python.org Mon Sep 13 22:40:30 2010
From: python-checkins at python.org (vinay.sajip)
Date: Mon, 13 Sep 2010 22:40:30 +0200 (CEST)
Subject: [Python-checkins] r84789 - in python/branches/py3k:
Lib/logging/handlers.py Misc/NEWS
Message-ID: <20100913204030.69B50EE988@mail.python.org>
Author: vinay.sajip
Date: Mon Sep 13 22:40:30 2010
New Revision: 84789
Log:
logging: enhanced HTTPHandler
Modified:
python/branches/py3k/Lib/logging/handlers.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/logging/handlers.py
==============================================================================
--- python/branches/py3k/Lib/logging/handlers.py (original)
+++ python/branches/py3k/Lib/logging/handlers.py Mon Sep 13 22:40:30 2010
@@ -977,7 +977,7 @@
A class which sends records to a Web server, using either GET or
POST semantics.
"""
- def __init__(self, host, url, method="GET"):
+ def __init__(self, host, url, method="GET", secure=False, credentials=None):
"""
Initialize the instance with the host, the request URL, and the method
("GET" or "POST")
@@ -989,12 +989,14 @@
self.host = host
self.url = url
self.method = method
+ self.secure = secure
+ self.credentials = credentials
def mapLogRecord(self, record):
"""
Default implementation of mapping the log record into a dict
that is sent as the CGI data. Overwrite in your class.
- Contributed by Franz Glasner.
+ Contributed by Franz Glasner.
"""
return record.__dict__
@@ -1007,7 +1009,10 @@
try:
import http.client, urllib.parse
host = self.host
- h = http.client.HTTP(host)
+ if self.secure:
+ h = http.client.HTTPSConnection(host)
+ else:
+ h = http.client.HTTPConnection(host)
url = self.url
data = urllib.parse.urlencode(self.mapLogRecord(record))
if self.method == "GET":
@@ -1027,8 +1032,13 @@
h.putheader("Content-type",
"application/x-www-form-urlencoded")
h.putheader("Content-length", str(len(data)))
+ if self.credentials:
+ import base64
+ s = ('u%s:%s' % self.credentials).encode('utf-8')
+ s = 'Basic ' + base64.b64encode(s).strip()
+ h.putheader('Authorization', s)
h.endheaders(data if self.method == "POST" else None)
- h.getreply() #can't do anything with the result
+ h.getresponse() #can't do anything with the result
except (KeyboardInterrupt, SystemExit):
raise
except:
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 22:40:30 2010
@@ -40,6 +40,8 @@
Library
-------
+- logging: Enhanced HTTPHandler with secure and credentials initializers.
+
- Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
(macpath module).
From python-checkins at python.org Mon Sep 13 22:48:43 2010
From: python-checkins at python.org (eric.smith)
Date: Mon, 13 Sep 2010 22:48:43 +0200 (CEST)
Subject: [Python-checkins] r84790 - in python/branches/py3k:
Lib/test/test_builtin.py Lib/test/test_unicode.py Misc/NEWS
Objects/typeobject.c
Message-ID: <20100913204843.B36C1F0F1@mail.python.org>
Author: eric.smith
Date: Mon Sep 13 22:48:43 2010
New Revision: 84790
Log:
Issue 7994: Make object.__format__() raise a PendingDeprecationWarning
if the format string is not empty. Manually merge r79596 and r84772
from 2.x.
Also, apparently test_format() from test_builtin never made it into
3.x. I've added it as well. It tests the basic format()
infrastructure.
Modified:
python/branches/py3k/Lib/test/test_builtin.py
python/branches/py3k/Lib/test/test_unicode.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/typeobject.c
Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py (original)
+++ python/branches/py3k/Lib/test/test_builtin.py Mon Sep 13 22:48:43 2010
@@ -1279,6 +1279,116 @@
return i
self.assertRaises(ValueError, list, zip(BadSeq(), BadSeq()))
+ def test_format(self):
+ # Test the basic machinery of the format() builtin. Don't test
+ # the specifics of the various formatters
+ self.assertEqual(format(3, ''), '3')
+
+ # Returns some classes to use for various tests. There's
+ # an old-style version, and a new-style version
+ def classes_new():
+ class A(object):
+ def __init__(self, x):
+ self.x = x
+ def __format__(self, format_spec):
+ return str(self.x) + format_spec
+ class DerivedFromA(A):
+ pass
+
+ class Simple(object): pass
+ class DerivedFromSimple(Simple):
+ def __init__(self, x):
+ self.x = x
+ def __format__(self, format_spec):
+ return str(self.x) + format_spec
+ class DerivedFromSimple2(DerivedFromSimple): pass
+ return A, DerivedFromA, DerivedFromSimple, DerivedFromSimple2
+
+ def class_test(A, DerivedFromA, DerivedFromSimple, DerivedFromSimple2):
+ self.assertEqual(format(A(3), 'spec'), '3spec')
+ self.assertEqual(format(DerivedFromA(4), 'spec'), '4spec')
+ self.assertEqual(format(DerivedFromSimple(5), 'abc'), '5abc')
+ self.assertEqual(format(DerivedFromSimple2(10), 'abcdef'),
+ '10abcdef')
+
+ class_test(*classes_new())
+
+ def empty_format_spec(value):
+ # test that:
+ # format(x, '') == str(x)
+ # format(x) == str(x)
+ self.assertEqual(format(value, ""), str(value))
+ self.assertEqual(format(value), str(value))
+
+ # for builtin types, format(x, "") == str(x)
+ empty_format_spec(17**13)
+ empty_format_spec(1.0)
+ empty_format_spec(3.1415e104)
+ empty_format_spec(-3.1415e104)
+ empty_format_spec(3.1415e-104)
+ empty_format_spec(-3.1415e-104)
+ empty_format_spec(object)
+ empty_format_spec(None)
+
+ # TypeError because self.__format__ returns the wrong type
+ class BadFormatResult:
+ def __format__(self, format_spec):
+ return 1.0
+ self.assertRaises(TypeError, format, BadFormatResult(), "")
+
+ # TypeError because format_spec is not unicode or str
+ self.assertRaises(TypeError, format, object(), 4)
+ self.assertRaises(TypeError, format, object(), object())
+
+ # tests for object.__format__ really belong elsewhere, but
+ # there's no good place to put them
+ x = object().__format__('')
+ self.assertTrue(x.startswith('15s}'.format(G('data')), ' string is data')
self.assertEqual('{0!s}'.format(G('data')), 'string is data')
+ msg = 'object.__format__ with a non-empty format string is deprecated'
+ with support.check_warnings((msg, PendingDeprecationWarning)):
+ self.assertEqual('{0:^10}'.format(E('data')), ' E(data) ')
+ self.assertEqual('{0:^10s}'.format(E('data')), ' E(data) ')
+ self.assertEqual('{0:>15s}'.format(G('data')), ' string is data')
+
self.assertEqual("{0:date: %Y-%m-%d}".format(I(year=2007,
month=8,
day=27)),
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 22:48:43 2010
@@ -10,6 +10,14 @@
Core and Builtins
-----------------
+- Issue #7994: Issue a PendingDeprecationWarning if object.__format__
+ is called with a non-empty format string. This is an effort to
+ future-proof user code. If a derived class does not currently
+ implement __format__ but later adds its own __format__, it would
+ most likely break user code that had supplied a format string. This
+ will be changed to a DeprecationWaring in Python 3.3 and it will be
+ an error in Python 3.4.
+
- Issue #9828: Destroy the GIL in Py_Finalize(), so that it gets properly
re-created on a subsequent call to Py_Initialize(). The problem (a crash)
wouldn't appear in 3.1 or 2.7 where the GIL's structure is more trivial.
Modified: python/branches/py3k/Objects/typeobject.c
==============================================================================
--- python/branches/py3k/Objects/typeobject.c (original)
+++ python/branches/py3k/Objects/typeobject.c Mon Sep 13 22:48:43 2010
@@ -3315,9 +3315,26 @@
return NULL;
self_as_str = PyObject_Str(self);
- if (self_as_str != NULL)
- result = PyObject_Format(self_as_str, format_spec);
+ if (self_as_str != NULL) {
+ /* Issue 7994: If we're converting to a string, we
+ should reject format specifications */
+ if (PyUnicode_GET_SIZE(format_spec) > 0) {
+ if (PyErr_WarnEx(PyExc_PendingDeprecationWarning,
+ "object.__format__ with a non-empty format "
+ "string is deprecated", 1) < 0) {
+ goto done;
+ }
+ /* Eventually this will become an error:
+ PyErr_Format(PyExc_TypeError,
+ "non-empty format string passed to object.__format__");
+ goto done;
+ */
+ }
+ result = PyObject_Format(self_as_str, format_spec);
+ }
+
+done:
Py_XDECREF(self_as_str);
return result;
From python-checkins at python.org Mon Sep 13 23:16:30 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Mon, 13 Sep 2010 23:16:30 +0200 (CEST)
Subject: [Python-checkins] r84791 - in python/branches/py3k:
Doc/library/stdtypes.rst Lib/test/test_builtin.py Misc/NEWS
Objects/rangeobject.c
Message-ID: <20100913211630.20F48EE9D9@mail.python.org>
Author: daniel.stutzbach
Date: Mon Sep 13 23:16:29 2010
New Revision: 84791
Log:
Issue #9213: Add index and count methods to range objects, needed to
meet the API of the collections.Sequence ABC.
Modified:
python/branches/py3k/Doc/library/stdtypes.rst
python/branches/py3k/Lib/test/test_builtin.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Objects/rangeobject.c
Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst (original)
+++ python/branches/py3k/Doc/library/stdtypes.rst Mon Sep 13 23:16:29 2010
@@ -1554,9 +1554,23 @@
object will always take the same amount of memory, no matter the size of the
range it represents. There are no consistent performance advantages.
-Range objects have very little behavior: they only support indexing, iteration,
-and the :func:`len` function.
+Range objects have relatively little behavior: they support indexing,
+iteration, the :func:`len` function, and the following methods.
+.. method:: range.count(x)
+
+ Return the number of *i*'s for which ``s[i] == x``. Normally the
+ result will be 0 or 1, but it could be greater if *x* defines an
+ unusual equality function.
+
+ .. versionadded:: 3.2
+
+.. method:: range.index(x)
+
+ Return the smallest *i* such that ``s[i] == x``. Raises
+ :exc:`ValueError` when *x* is not in the range.
+
+ .. versionadded:: 3.2
.. _typesseq-mutable:
Modified: python/branches/py3k/Lib/test/test_builtin.py
==============================================================================
--- python/branches/py3k/Lib/test/test_builtin.py (original)
+++ python/branches/py3k/Lib/test/test_builtin.py Mon Sep 13 23:16:29 2010
@@ -1028,6 +1028,60 @@
self.assertRaises(TypeError, range, 0.0, 0.0, 1)
self.assertRaises(TypeError, range, 0.0, 0.0, 1.0)
+ self.assertEqual(range(3).count(-1), 0)
+ self.assertEqual(range(3).count(0), 1)
+ self.assertEqual(range(3).count(1), 1)
+ self.assertEqual(range(3).count(2), 1)
+ self.assertEqual(range(3).count(3), 0)
+
+ self.assertEqual(range(10**20).count(1), 1)
+ self.assertEqual(range(10**20).count(10**20), 0)
+ self.assertEqual(range(3).index(1), 1)
+ self.assertEqual(range(1, 2**100, 2).count(2**87), 0)
+ self.assertEqual(range(1, 2**100, 2).count(2**87+1), 1)
+
+ self.assertEqual(range(1, 10, 3).index(4), 1)
+ self.assertEqual(range(1, -10, -3).index(-5), 2)
+
+ self.assertEqual(range(10**20).index(1), 1)
+ self.assertEqual(range(10**20).index(10**20 - 1), 10**20 - 1)
+
+ self.assertRaises(ValueError, range(1, 2**100, 2).index, 2**87)
+ self.assertEqual(range(1, 2**100, 2).index(2**87+1), 2**86)
+
+ class AlwaysEqual(object):
+ def __eq__(self, other):
+ return True
+ always_equal = AlwaysEqual()
+ self.assertEqual(range(10).count(always_equal), 10)
+ self.assertEqual(range(10).index(always_equal), 0)
+
+ def test_range_index(self):
+ u = range(2)
+ self.assertEqual(u.index(0), 0)
+ self.assertEqual(u.index(1), 1)
+ self.assertRaises(ValueError, u.index, 2)
+
+ u = range(-2, 3)
+ self.assertEqual(u.count(0), 1)
+ self.assertEqual(u.index(0), 2)
+ self.assertRaises(TypeError, u.index)
+
+ class BadExc(Exception):
+ pass
+
+ class BadCmp:
+ def __eq__(self, other):
+ if other == 2:
+ raise BadExc()
+ return False
+
+ a = range(4)
+ self.assertRaises(BadExc, a.index, BadCmp())
+
+ a = range(-2, 3)
+ self.assertEqual(a.index(0), 2)
+
def test_input(self):
self.write_testfile()
fp = open(TESTFN, 'r')
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 23:16:29 2010
@@ -10,6 +10,10 @@
Core and Builtins
-----------------
+- Issue #9212: The range type_items now provides index() and count()
+ methods, to conform to the Sequence ABC. Patch by Daniel Urban and
+ Daniel Stutzbach.
+
- Issue #7994: Issue a PendingDeprecationWarning if object.__format__
is called with a non-empty format string. This is an effort to
future-proof user code. If a derived class does not currently
Modified: python/branches/py3k/Objects/rangeobject.c
==============================================================================
--- python/branches/py3k/Objects/rangeobject.c (original)
+++ python/branches/py3k/Objects/rangeobject.c Mon Sep 13 23:16:29 2010
@@ -273,60 +273,135 @@
r->start, r->stop, r->step);
}
+/* Assumes (PyLong_CheckExact(ob) || PyBool_Check(ob)) */
+static int
+range_contains_long(rangeobject *r, PyObject *ob)
+{
+ int cmp1, cmp2, cmp3;
+ PyObject *tmp1 = NULL;
+ PyObject *tmp2 = NULL;
+ PyObject *zero = NULL;
+ int result = -1;
+
+ zero = PyLong_FromLong(0);
+ if (zero == NULL) /* MemoryError in int(0) */
+ goto end;
+
+ /* Check if the value can possibly be in the range. */
+
+ cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
+ if (cmp1 == -1)
+ goto end;
+ if (cmp1 == 1) { /* positive steps: start <= ob < stop */
+ cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
+ cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
+ }
+ else { /* negative steps: stop < ob <= start */
+ cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
+ cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
+ }
+
+ if (cmp2 == -1 || cmp3 == -1) /* TypeError */
+ goto end;
+ if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
+ result = 0;
+ goto end;
+ }
+
+ /* Check that the stride does not invalidate ob's membership. */
+ tmp1 = PyNumber_Subtract(ob, r->start);
+ if (tmp1 == NULL)
+ goto end;
+ tmp2 = PyNumber_Remainder(tmp1, r->step);
+ if (tmp2 == NULL)
+ goto end;
+ /* result = (int(ob) - start % step) == 0 */
+ result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
+ end:
+ Py_XDECREF(tmp1);
+ Py_XDECREF(tmp2);
+ Py_XDECREF(zero);
+ return result;
+}
+
static int
range_contains(rangeobject *r, PyObject *ob) {
- if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
- int cmp1, cmp2, cmp3;
- PyObject *tmp1 = NULL;
- PyObject *tmp2 = NULL;
- PyObject *zero = NULL;
- int result = -1;
-
- zero = PyLong_FromLong(0);
- if (zero == NULL) /* MemoryError in int(0) */
- goto end;
-
- /* Check if the value can possibly be in the range. */
-
- cmp1 = PyObject_RichCompareBool(r->step, zero, Py_GT);
- if (cmp1 == -1)
- goto end;
- if (cmp1 == 1) { /* positive steps: start <= ob < stop */
- cmp2 = PyObject_RichCompareBool(r->start, ob, Py_LE);
- cmp3 = PyObject_RichCompareBool(ob, r->stop, Py_LT);
- }
- else { /* negative steps: stop < ob <= start */
- cmp2 = PyObject_RichCompareBool(ob, r->start, Py_LE);
- cmp3 = PyObject_RichCompareBool(r->stop, ob, Py_LT);
- }
-
- if (cmp2 == -1 || cmp3 == -1) /* TypeError */
- goto end;
- if (cmp2 == 0 || cmp3 == 0) { /* ob outside of range */
- result = 0;
- goto end;
- }
-
- /* Check that the stride does not invalidate ob's membership. */
- tmp1 = PyNumber_Subtract(ob, r->start);
- if (tmp1 == NULL)
- goto end;
- tmp2 = PyNumber_Remainder(tmp1, r->step);
- if (tmp2 == NULL)
- goto end;
- /* result = (int(ob) - start % step) == 0 */
- result = PyObject_RichCompareBool(tmp2, zero, Py_EQ);
- end:
- Py_XDECREF(tmp1);
- Py_XDECREF(tmp2);
- Py_XDECREF(zero);
- return result;
- }
- /* Fall back to iterative search. */
+ if (PyLong_CheckExact(ob) || PyBool_Check(ob))
+ return range_contains_long(r, ob);
+
return (int)_PySequence_IterSearch((PyObject*)r, ob,
PY_ITERSEARCH_CONTAINS);
}
+static PyObject *
+range_count(rangeobject *r, PyObject *ob)
+{
+ if (PyLong_CheckExact(ob) || PyBool_Check(ob)) {
+ if (range_contains_long(r, ob))
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+ } else {
+ Py_ssize_t count;
+ count = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_COUNT);
+ if (count == -1)
+ return NULL;
+ return PyLong_FromSsize_t(count);
+ }
+}
+
+static PyObject *
+range_index(rangeobject *r, PyObject *ob)
+{
+ PyObject *idx, *tmp;
+ int contains;
+ PyObject *format_tuple, *err_string;
+ static PyObject *err_format = NULL;
+
+ if (!PyLong_CheckExact(ob) && !PyBool_Check(ob)) {
+ Py_ssize_t index;
+ index = _PySequence_IterSearch((PyObject*)r, ob, PY_ITERSEARCH_INDEX);
+ if (index == -1)
+ return NULL;
+ return PyLong_FromSsize_t(index);
+ }
+
+ contains = range_contains_long(r, ob);
+ if (contains == -1)
+ return NULL;
+
+ if (!contains)
+ goto value_error;
+
+ tmp = PyNumber_Subtract(ob, r->start);
+ if (tmp == NULL)
+ return NULL;
+
+ /* idx = (ob - r.start) // r.step */
+ idx = PyNumber_FloorDivide(tmp, r->step);
+ Py_DECREF(tmp);
+ return idx;
+
+value_error:
+
+ /* object is not in the range */
+ if (err_format == NULL) {
+ err_format = PyUnicode_FromString("%r is not in range");
+ if (err_format == NULL)
+ return NULL;
+ }
+ format_tuple = PyTuple_Pack(1, ob);
+ if (format_tuple == NULL)
+ return NULL;
+ err_string = PyUnicode_Format(err_format, format_tuple);
+ Py_DECREF(format_tuple);
+ if (err_string == NULL)
+ return NULL;
+ PyErr_SetObject(PyExc_ValueError, err_string);
+ Py_DECREF(err_string);
+ return NULL;
+}
+
static PySequenceMethods range_as_sequence = {
(lenfunc)range_length, /* sq_length */
0, /* sq_concat */
@@ -344,10 +419,18 @@
PyDoc_STRVAR(reverse_doc,
"Returns a reverse iterator.");
+PyDoc_STRVAR(count_doc,
+"rangeobject.count(value) -> integer -- return number of occurrences of value");
+
+PyDoc_STRVAR(index_doc,
+"rangeobject.index(value, [start, [stop]]) -> integer -- return index of value.\n"
+"Raises ValueError if the value is not present.");
+
static PyMethodDef range_methods[] = {
- {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS,
- reverse_doc},
- {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
+ {"__reversed__", (PyCFunction)range_reverse, METH_NOARGS, reverse_doc},
+ {"__reduce__", (PyCFunction)range_reduce, METH_VARARGS},
+ {"count", (PyCFunction)range_count, METH_O, count_doc},
+ {"index", (PyCFunction)range_index, METH_O, index_doc},
{NULL, NULL} /* sentinel */
};
From python-checkins at python.org Mon Sep 13 23:36:00 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Mon, 13 Sep 2010 23:36:00 +0200 (CEST)
Subject: [Python-checkins] r84792 - in python/branches/py3k:
Doc/library/reprlib.rst Lib/collections.py Lib/reprlib.py
Lib/test/test_reprlib.py Misc/NEWS
Message-ID: <20100913213600.4FC73DD9A@mail.python.org>
Author: raymond.hettinger
Date: Mon Sep 13 23:36:00 2010
New Revision: 84792
Log:
Issue 9840: Add reprlib.recursive_repr(), a decorator for handling recursive calls to __repr__ methods.
Modified:
python/branches/py3k/Doc/library/reprlib.rst
python/branches/py3k/Lib/collections.py
python/branches/py3k/Lib/reprlib.py
python/branches/py3k/Lib/test/test_reprlib.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/reprlib.rst
==============================================================================
--- python/branches/py3k/Doc/library/reprlib.rst (original)
+++ python/branches/py3k/Doc/library/reprlib.rst Mon Sep 13 23:36:00 2010
@@ -34,6 +34,29 @@
similar to that returned by the built-in function of the same name, but with
limits on most sizes.
+In addition to size-limiting tools, the module also provides a decorator for
+detecting recursive calls to :meth:`__repr__` and substituting a placeholder
+string instead.
+
+.. decorator:: recursive_repr(fillvalue="...")
+
+ Decorator for :meth:`__repr__` methods to detect recursive calls within the
+ same thread. If a recursive call is made, the *fillvalue* is returned,
+ otherwise, the usual :meth:`__repr__` call is made. For example:
+
+ >>> class MyList(list):
+ ... @recursive_repr()
+ ... def __repr__(self):
+ ... return '<' + '|'.join(map(repr, self)) + '>'
+ ...
+ >>> m = MyList('abc')
+ >>> m.append(m)
+ >>> m.append('x')
+ >>> print(m)
+ <'a'|'b'|'c'|...|'x'>
+
+ .. versionadded:: 3.2
+
.. _repr-objects:
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Mon Sep 13 23:36:00 2010
@@ -13,6 +13,7 @@
import heapq as _heapq
from weakref import proxy as _proxy
from itertools import repeat as _repeat, chain as _chain, starmap as _starmap
+from reprlib import recursive_repr as _recursive_repr
################################################################################
### OrderedDict
@@ -43,7 +44,6 @@
'''
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
- self.__in_repr = False # detects recursive repr
try:
self.__root
except AttributeError:
@@ -97,10 +97,10 @@
def __reduce__(self):
'Return state information for pickling'
items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__root, self.__in_repr
- del self.__map, self.__root, self.__in_repr
+ tmp = self.__map, self.__root
+ del self.__map, self.__root
inst_dict = vars(self).copy()
- self.__map, self.__root, self.__in_repr = tmp
+ self.__map, self.__root = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
@@ -167,18 +167,12 @@
items = MutableMapping.items
__ne__ = MutableMapping.__ne__
+ @_recursive_repr()
def __repr__(self):
'od.__repr__() <==> repr(od)'
if not self:
return '%s()' % (self.__class__.__name__,)
- if self.__in_repr:
- return '...'
- self.__in_repr = True
- try:
- result = '%s(%r)' % (self.__class__.__name__, list(self.items()))
- finally:
- self.__in_repr = False
- return result
+ return '%s(%r)' % (self.__class__.__name__, list(self.items()))
def copy(self):
'od.copy() -> a shallow copy of od'
Modified: python/branches/py3k/Lib/reprlib.py
==============================================================================
--- python/branches/py3k/Lib/reprlib.py (original)
+++ python/branches/py3k/Lib/reprlib.py Mon Sep 13 23:36:00 2010
@@ -1,9 +1,38 @@
"""Redo the builtin repr() (representation) but with limits on most sizes."""
-__all__ = ["Repr","repr"]
+__all__ = ["Repr", "repr", "recursive_repr"]
import builtins
from itertools import islice
+try:
+ from _thread import get_ident
+except AttributeError:
+ from _dummy_thread import get_ident
+
+def recursive_repr(fillvalue='...'):
+ 'Decorator to make a repr function return fillvalue for a recursive call'
+
+ def decorating_function(user_function):
+ repr_running = set()
+
+ def wrapper(self):
+ key = id(self), get_ident()
+ if key in repr_running:
+ return fillvalue
+ repr_running.add(key)
+ try:
+ result = user_function(self)
+ finally:
+ repr_running.discard(key)
+ return result
+
+ # Can't use functools.wraps() here because of bootstrap issues
+ wrapper.__module__ = getattr(user_function, '__module__')
+ wrapper.__doc__ = getattr(user_function, '__doc__')
+ wrapper.__name__ = getattr(user_function, '__name__')
+ return wrapper
+
+ return decorating_function
class Repr:
Modified: python/branches/py3k/Lib/test/test_reprlib.py
==============================================================================
--- python/branches/py3k/Lib/test/test_reprlib.py (original)
+++ python/branches/py3k/Lib/test/test_reprlib.py Mon Sep 13 23:36:00 2010
@@ -11,6 +11,7 @@
from test.support import run_unittest
from reprlib import repr as r # Don't shadow builtin repr
from reprlib import Repr
+from reprlib import recursive_repr
def nestedTuple(nesting):
@@ -301,10 +302,38 @@
def __repr__(self):
raise Exception("This should be caught by Repr.repr_instance")
+class MyContainer:
+ 'Helper class for TestRecursiveRepr'
+ def __init__(self, values):
+ self.values = list(values)
+ def append(self, value):
+ self.values.append(value)
+ @recursive_repr()
+ def __repr__(self):
+ return '<' + ', '.join(map(str, self.values)) + '>'
+
+class MyContainer2(MyContainer):
+ @recursive_repr('+++')
+ def __repr__(self):
+ return '<' + ', '.join(map(str, self.values)) + '>'
+
+class TestRecursiveRepr(unittest.TestCase):
+ def test_recursive_repr(self):
+ m = MyContainer(list('abcde'))
+ m.append(m)
+ m.append('x')
+ m.append(m)
+ self.assertEqual(repr(m), '')
+ m = MyContainer2(list('abcde'))
+ m.append(m)
+ m.append('x')
+ m.append(m)
+ self.assertEqual(repr(m), ' ')
def test_main():
run_unittest(ReprTests)
run_unittest(LongReprTest)
+ run_unittest(TestRecursiveRepr)
if __name__ == "__main__":
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Mon Sep 13 23:36:00 2010
@@ -52,6 +52,9 @@
Library
-------
+- Issue 9840: Added a decorator to reprlib for wrapping __repr__ methods
+ to make them handle recursive calls within the same thread.
+
- logging: Enhanced HTTPHandler with secure and credentials initializers.
- Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
From ncoghlan at gmail.com Mon Sep 13 23:50:34 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Tue, 14 Sep 2010 07:50:34 +1000
Subject: [Python-checkins] r84792 - in python/branches/py3k:
Doc/library/reprlib.rst Lib/collections.py Lib/reprlib.py
Lib/test/test_reprlib.py Misc/NEWS
In-Reply-To: <20100913213600.4FC73DD9A@mail.python.org>
References: <20100913213600.4FC73DD9A@mail.python.org>
Message-ID:
On Tue, Sep 14, 2010 at 7:36 AM, raymond.hettinger
wrote:
> + ? ? ? ?# Can't use functools.wraps() here because of bootstrap issues
> + ? ? ? ?wrapper.__module__ = getattr(user_function, '__module__')
> + ? ? ? ?wrapper.__doc__ = getattr(user_function, '__doc__')
> + ? ? ? ?wrapper.__name__ = getattr(user_function, '__name__')
> + ? ? ? ?return wrapper
Perhaps add __wrapped__ as well?
(I assume that, similar to _collections before it was made a builtin,
the bootstrap issue is that _functools is an extension module rather
than builtin, but reprlib is needed when building the extension
modules?)
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From python-checkins at python.org Tue Sep 14 00:14:37 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 14 Sep 2010 00:14:37 +0200 (CEST)
Subject: [Python-checkins] r84793 - in python/branches/release27-maint:
Lib/collections.py Lib/test/test_collections.py Misc/NEWS
Message-ID: <20100913221437.13C67FBB1@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 14 00:14:36 2010
New Revision: 84793
Log:
Issue 9826: OrderedDict.__repr__ did not play well with self-referencing dicts.
Modified:
python/branches/release27-maint/Lib/collections.py
python/branches/release27-maint/Lib/test/test_collections.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/collections.py
==============================================================================
--- python/branches/release27-maint/Lib/collections.py (original)
+++ python/branches/release27-maint/Lib/collections.py Tue Sep 14 00:14:36 2010
@@ -12,6 +12,32 @@
import heapq as _heapq
from itertools import repeat as _repeat, chain as _chain, starmap as _starmap, \
ifilter as _ifilter, imap as _imap
+try:
+ from thread import get_ident
+except AttributeError:
+ from dummy_thread import get_ident
+
+def _recursive_repr(user_function):
+ 'Decorator to make a repr function return "..." for a recursive call'
+ repr_running = set()
+
+ def wrapper(self):
+ key = id(self), get_ident()
+ if key in repr_running:
+ return '...'
+ repr_running.add(key)
+ try:
+ result = user_function(self)
+ finally:
+ repr_running.discard(key)
+ return result
+
+ # Can't use functools.wraps() here because of bootstrap issues
+ wrapper.__module__ = getattr(user_function, '__module__')
+ wrapper.__doc__ = getattr(user_function, '__doc__')
+ wrapper.__name__ = getattr(user_function, '__name__')
+ return wrapper
+
################################################################################
### OrderedDict
@@ -142,6 +168,7 @@
value = self.pop(key)
return key, value
+ @_recursive_repr
def __repr__(self):
'od.__repr__() <==> repr(od)'
if not self:
Modified: python/branches/release27-maint/Lib/test/test_collections.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_collections.py (original)
+++ python/branches/release27-maint/Lib/test/test_collections.py Tue Sep 14 00:14:36 2010
@@ -926,6 +926,13 @@
self.assertEqual(eval(repr(od)), od)
self.assertEqual(repr(OrderedDict()), "OrderedDict()")
+ def test_repr_recursive(self):
+ # See issue #9826
+ od = OrderedDict.fromkeys('abc')
+ od['x'] = od
+ self.assertEqual(repr(od),
+ "OrderedDict([('a', None), ('b', None), ('c', None), ('x', ...)])")
+
def test_setdefault(self):
pairs = [('c', 1), ('b', 2), ('a', 3), ('d', 4), ('e', 5), ('f', 6)]
shuffle(pairs)
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Tue Sep 14 00:14:36 2010
@@ -43,6 +43,9 @@
Library
-------
+- Issue #9826: OrderedDict.__repr__ can now handle self-referential
+ values: d['x'] = d.
+
- Issue #767645: Set os.path.supports_unicode_filenames to True on Mac OS X
(macpath module).
From python-checkins at python.org Tue Sep 14 03:11:36 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Tue, 14 Sep 2010 03:11:36 +0200 (CEST)
Subject: [Python-checkins] r84794 - in
python/branches/py3k/Lib/test/tracedmodules: __init__.py testmod.py
Message-ID: <20100914011136.19A38FCD4@mail.python.org>
Author: alexander.belopolsky
Date: Tue Sep 14 03:11:35 2010
New Revision: 84794
Log:
Added files missed in r84780. Thanks, Florent.
Added:
python/branches/py3k/Lib/test/tracedmodules/
python/branches/py3k/Lib/test/tracedmodules/__init__.py
python/branches/py3k/Lib/test/tracedmodules/testmod.py
Added: python/branches/py3k/Lib/test/tracedmodules/__init__.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/tracedmodules/__init__.py Tue Sep 14 03:11:35 2010
@@ -0,0 +1,9 @@
+"""This package contains modules that help testing the trace.py module. Note
+that the exact location of functions in these modules is important, as trace.py
+takes the real line numbers into account.
+"""
+"""This directory contains modules that help testing the trace.py module. Note
+that the exact location of functions in these modules is important, as trace.py
+takes the real line numbers into account.
+
+"""
Added: python/branches/py3k/Lib/test/tracedmodules/testmod.py
==============================================================================
--- (empty file)
+++ python/branches/py3k/Lib/test/tracedmodules/testmod.py Tue Sep 14 03:11:35 2010
@@ -0,0 +1,3 @@
+def func(x):
+ b = x + 1
+ return b + 2
From solipsis at pitrou.net Tue Sep 14 05:09:05 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Tue, 14 Sep 2010 05:09:05 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84794): sum=0
Message-ID:
py3k results for svn r84794 (hg cset f8003795a4dd)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflognzZHBI', '-x']
From python-checkins at python.org Tue Sep 14 08:59:24 2010
From: python-checkins at python.org (vinay.sajip)
Date: Tue, 14 Sep 2010 08:59:24 +0200 (CEST)
Subject: [Python-checkins] r84795 -
python/branches/py3k/Doc/library/logging.rst
Message-ID: <20100914065924.DED4FFE0A@mail.python.org>
Author: vinay.sajip
Date: Tue Sep 14 08:59:24 2010
New Revision: 84795
Log:
Tidied example script.
Modified:
python/branches/py3k/Doc/library/logging.rst
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Tue Sep 14 08:59:24 2010
@@ -2660,6 +2660,8 @@
data = json.dumps(record.__dict__)
self.queue.send(data)
+ def close(self):
+ self.queue.close()
.. _formatter-objects:
From python-checkins at python.org Tue Sep 14 11:34:09 2010
From: python-checkins at python.org (vinay.sajip)
Date: Tue, 14 Sep 2010 11:34:09 +0200 (CEST)
Subject: [Python-checkins] r84796 -
python/branches/py3k/Lib/test/test_logging.py
Message-ID: <20100914093409.65AF0EE992@mail.python.org>
Author: vinay.sajip
Date: Tue Sep 14 11:34:09 2010
New Revision: 84796
Log:
Added test for QueueHandler.
Modified:
python/branches/py3k/Lib/test/test_logging.py
Modified: python/branches/py3k/Lib/test/test_logging.py
==============================================================================
--- python/branches/py3k/Lib/test/test_logging.py (original)
+++ python/branches/py3k/Lib/test/test_logging.py Tue Sep 14 11:34:09 2010
@@ -31,6 +31,7 @@
import gc
import json
import os
+import queue
import re
import select
import socket
@@ -1760,6 +1761,35 @@
self.assertTrue(c2 is c3)
+class QueueHandlerTest(BaseTest):
+ # Do not bother with a logger name group.
+ expected_log_pat = r"^[\w.]+ -> ([\w]+): ([\d]+)$"
+
+ def setUp(self):
+ BaseTest.setUp(self)
+ self.queue = queue.Queue(-1)
+ self.que_hdlr = logging.handlers.QueueHandler(self.queue)
+ self.que_logger = logging.getLogger('que')
+ self.que_logger.propagate = False
+ self.que_logger.setLevel(logging.WARNING)
+ self.que_logger.addHandler(self.que_hdlr)
+
+ def tearDown(self):
+ self.que_hdlr.close()
+ BaseTest.tearDown(self)
+
+ def test_queue_handler(self):
+ self.que_logger.debug(self.next_message())
+ self.assertRaises(queue.Empty, self.queue.get_nowait)
+ self.que_logger.info(self.next_message())
+ self.assertRaises(queue.Empty, self.queue.get_nowait)
+ msg = self.next_message()
+ self.que_logger.warning(msg)
+ data = self.queue.get_nowait()
+ self.assertTrue(isinstance(data, logging.LogRecord))
+ self.assertEqual(data.name, self.que_logger.name)
+ self.assertEqual((data.msg, data.args), (msg, None))
+
# Set the locale to the platform-dependent default. I have no idea
# why the test does this, but in any case we save the current locale
# first and restore it at the end.
@@ -1769,7 +1799,7 @@
CustomLevelsAndFiltersTest, MemoryHandlerTest,
ConfigFileTest, SocketHandlerTest, MemoryTest,
EncodingTest, WarningsTest, ConfigDictTest, ManagerTest,
- ChildLoggerTest)
+ ChildLoggerTest, QueueHandlerTest)
if __name__ == "__main__":
test_main()
From python-checkins at python.org Tue Sep 14 11:42:39 2010
From: python-checkins at python.org (vinay.sajip)
Date: Tue, 14 Sep 2010 11:42:39 +0200 (CEST)
Subject: [Python-checkins] r84797 -
python/branches/py3k/Doc/library/logging.rst
Message-ID: <20100914094239.85FE3EE99A@mail.python.org>
Author: vinay.sajip
Date: Tue Sep 14 11:42:39 2010
New Revision: 84797
Log:
Tidied example script.
Modified:
python/branches/py3k/Doc/library/logging.rst
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst (original)
+++ python/branches/py3k/Doc/library/logging.rst Tue Sep 14 11:42:39 2010
@@ -2647,6 +2647,9 @@
data = json.dumps(record.__dict__)
self.queue.send(data)
+ handler = ZeroMQSocketHandler(sock)
+
+
Of course there are other ways of organizing this, for example passing in the
data needed by the handler to create the socket::
@@ -2654,7 +2657,7 @@
def __init__(self, uri, socktype=zmq.PUB, ctx=None):
self.ctx = ctx or zmq.Context()
socket = zmq.Socket(self.ctx, socktype)
- super(ZeroMQSocketHandler, self).__init__(socket)
+ QueueHandler.__init__(self, socket)
def enqueue(self, record):
data = json.dumps(record.__dict__)
From python-checkins at python.org Tue Sep 14 11:48:39 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 11:48:39 +0200 (CEST)
Subject: [Python-checkins] r84798 - in python/branches/py3k:
Lib/test/test_gc.py Modules/gcmodule.c
Message-ID: <20100914094839.B2A69FD20@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 11:48:39 2010
New Revision: 84798
Log:
Do not print additional shutdown message when gc.DEBUG_SAVEALL is set
Modified:
python/branches/py3k/Lib/test/test_gc.py
python/branches/py3k/Modules/gcmodule.c
Modified: python/branches/py3k/Lib/test/test_gc.py
==============================================================================
--- python/branches/py3k/Lib/test/test_gc.py (original)
+++ python/branches/py3k/Lib/test/test_gc.py Tue Sep 14 11:48:39 2010
@@ -482,8 +482,7 @@
x.x = x
x.y = X('second')
del x
- if %d:
- gc.set_debug(gc.DEBUG_UNCOLLECTABLE)
+ gc.set_debug(%s)
"""
def run_command(code):
p = subprocess.Popen([sys.executable, "-c", code],
@@ -494,13 +493,19 @@
self.assertEqual(stdout.strip(), b"")
return strip_python_stderr(stderr)
- stderr = run_command(code % 0)
+ stderr = run_command(code % "0")
self.assertIn(b"gc: 2 uncollectable objects at shutdown", stderr)
self.assertNotIn(b"[, ]", stderr)
# With DEBUG_UNCOLLECTABLE, the garbage list gets printed
- stderr = run_command(code % 1)
+ stderr = run_command(code % "gc.DEBUG_UNCOLLECTABLE")
self.assertIn(b"gc: 2 uncollectable objects at shutdown", stderr)
self.assertIn(b"[, ]", stderr)
+ # With DEBUG_SAVEALL, no additional message should get printed
+ # (because gc.garbage also contains normally reclaimable cyclic
+ # references, and its elements get printed at runtime anyway).
+ stderr = run_command(code % "gc.DEBUG_SAVEALL")
+ self.assertNotIn(b"uncollectable objects at shutdown", stderr)
+
class GCTogglingTests(unittest.TestCase):
def setUp(self):
Modified: python/branches/py3k/Modules/gcmodule.c
==============================================================================
--- python/branches/py3k/Modules/gcmodule.c (original)
+++ python/branches/py3k/Modules/gcmodule.c Tue Sep 14 11:48:39 2010
@@ -1366,7 +1366,8 @@
void
_PyGC_Fini(void)
{
- if (garbage != NULL && PyList_GET_SIZE(garbage) > 0) {
+ if (!(debug & DEBUG_SAVEALL)
+ && garbage != NULL && PyList_GET_SIZE(garbage) > 0) {
PySys_WriteStderr(
"gc: "
"%" PY_FORMAT_SIZE_T "d uncollectable objects at shutdown:\n",
From python-checkins at python.org Tue Sep 14 12:08:08 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 12:08:08 +0200 (CEST)
Subject: [Python-checkins] r84799 -
python/branches/py3k/Modules/posixmodule.c
Message-ID: <20100914100808.C2B22FAAC@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 12:08:08 2010
New Revision: 84799
Log:
Remove C++-style comments
Modified:
python/branches/py3k/Modules/posixmodule.c
Modified: python/branches/py3k/Modules/posixmodule.c
==============================================================================
--- python/branches/py3k/Modules/posixmodule.c (original)
+++ python/branches/py3k/Modules/posixmodule.c Tue Sep 14 12:08:08 2010
@@ -2330,7 +2330,7 @@
WIN32_FIND_DATAW wFileData;
Py_UNICODE *wnamebuf, *po_wchars;
- if (po == NULL) { // Default arg: "."
+ if (po == NULL) { /* Default arg: "." */
po_wchars = L".";
len = 1;
} else {
@@ -2577,7 +2577,7 @@
oname = NULL;
if (!PyArg_ParseTuple(args, "|O&:listdir", PyUnicode_FSConverter, &oname))
return NULL;
- if (oname == NULL) { // Default arg: "."
+ if (oname == NULL) { /* Default arg: "." */
oname = PyBytes_FromString(".");
}
name = PyBytes_AsString(oname);
From python-checkins at python.org Tue Sep 14 14:54:08 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 14:54:08 +0200 (CEST)
Subject: [Python-checkins] r84800 -
python/branches/release27-maint/Lib/test/test_ssl.py
Message-ID: <20100914125408.8378BFCD4@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 14:54:08 2010
New Revision: 84800
Log:
Some tests didn't get executed (because of the merge in r83728)
Modified:
python/branches/release27-maint/Lib/test/test_ssl.py
Modified: python/branches/release27-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release27-maint/Lib/test/test_ssl.py Tue Sep 14 14:54:08 2010
@@ -1285,7 +1285,7 @@
not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT)):
raise test_support.TestFailed("Can't read certificate files!")
- tests = [BasicTests]
+ tests = [BasicTests, BasicSocketTests]
if test_support.is_resource_enabled('network'):
tests.append(NetworkedTests)
From python-checkins at python.org Tue Sep 14 15:03:39 2010
From: python-checkins at python.org (eric.smith)
Date: Tue, 14 Sep 2010 15:03:39 +0200 (CEST)
Subject: [Python-checkins] r84801 - python/branches/release31-maint
Message-ID: <20100914130339.CBC41D8D8@mail.python.org>
Author: eric.smith
Date: Tue Sep 14 15:03:39 2010
New Revision: 84801
Log:
Blocked revisions 84790 via svnmerge
........
r84790 | eric.smith | 2010-09-13 16:48:43 -0400 (Mon, 13 Sep 2010) | 8 lines
Issue 7994: Make object.__format__() raise a PendingDeprecationWarning
if the format string is not empty. Manually merge r79596 and r84772
from 2.x.
Also, apparently test_format() from test_builtin never made it into
3.x. I've added it as well. It tests the basic format()
infrastructure.
........
Modified:
python/branches/release31-maint/ (props changed)
From python-checkins at python.org Tue Sep 14 15:03:57 2010
From: python-checkins at python.org (eric.smith)
Date: Tue, 14 Sep 2010 15:03:57 +0200 (CEST)
Subject: [Python-checkins] r84802 - python/branches/release27-maint
Message-ID: <20100914130357.4305FD8D8@mail.python.org>
Author: eric.smith
Date: Tue Sep 14 15:03:57 2010
New Revision: 84802
Log:
Blocked revisions 84790 via svnmerge
........
r84790 | eric.smith | 2010-09-13 16:48:43 -0400 (Mon, 13 Sep 2010) | 8 lines
Issue 7994: Make object.__format__() raise a PendingDeprecationWarning
if the format string is not empty. Manually merge r79596 and r84772
from 2.x.
Also, apparently test_format() from test_builtin never made it into
3.x. I've added it as well. It tests the basic format()
infrastructure.
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Tue Sep 14 16:12:20 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Tue, 14 Sep 2010 16:12:20 +0200 (CEST)
Subject: [Python-checkins] r84803 - python/branches/py3k/Makefile.pre.in
Message-ID: <20100914141220.223BBF4F4@mail.python.org>
Author: alexander.belopolsky
Date: Tue Sep 14 16:12:19 2010
New Revision: 84803
Log:
Issue 9315: Added test/tracedmodules to LIBSUBDIRS
Modified:
python/branches/py3k/Makefile.pre.in
Modified: python/branches/py3k/Makefile.pre.in
==============================================================================
--- python/branches/py3k/Makefile.pre.in (original)
+++ python/branches/py3k/Makefile.pre.in Tue Sep 14 16:12:19 2010
@@ -870,6 +870,7 @@
LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \
tkinter/test/test_ttk site-packages test \
test/decimaltestdata test/xmltestdata \
+ test/tracedmodules \
encodings \
email email/mime email/test email/test/data \
html json json/tests http dbm xmlrpc \
From python-checkins at python.org Tue Sep 14 16:21:18 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Tue, 14 Sep 2010 16:21:18 +0200 (CEST)
Subject: [Python-checkins] r84804 - in python/branches/release31-maint:
Makefile.pre.in
Message-ID: <20100914142118.A43F1EE9AA@mail.python.org>
Author: alexander.belopolsky
Date: Tue Sep 14 16:21:12 2010
New Revision: 84804
Log:
Merged revisions 84803 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84803 | alexander.belopolsky | 2010-09-14 10:12:19 -0400 (Tue, 14 Sep 2010) | 1 line
Issue 9315: Added test/tracedmodules to LIBSUBDIRS
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Makefile.pre.in
Modified: python/branches/release31-maint/Makefile.pre.in
==============================================================================
--- python/branches/release31-maint/Makefile.pre.in (original)
+++ python/branches/release31-maint/Makefile.pre.in Tue Sep 14 16:21:12 2010
@@ -837,6 +837,7 @@
LIBSUBDIRS= tkinter tkinter/test tkinter/test/test_tkinter \
tkinter/test/test_ttk site-packages test test/data \
test/decimaltestdata \
+ test/tracedmodules \
encodings \
email email/mime email/test email/test/data \
html json json/tests http dbm xmlrpc \
From python-checkins at python.org Tue Sep 14 16:24:58 2010
From: python-checkins at python.org (alexander.belopolsky)
Date: Tue, 14 Sep 2010 16:24:58 +0200 (CEST)
Subject: [Python-checkins] r84805 - in python/branches/release27-maint:
Makefile.pre.in
Message-ID: <20100914142458.4C3A3EE99A@mail.python.org>
Author: alexander.belopolsky
Date: Tue Sep 14 16:24:58 2010
New Revision: 84805
Log:
Merged revisions 84803 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84803 | alexander.belopolsky | 2010-09-14 10:12:19 -0400 (Tue, 14 Sep 2010) | 1 line
Issue 9315: Added test/tracedmodules to LIBSUBDIRS
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Makefile.pre.in
Modified: python/branches/release27-maint/Makefile.pre.in
==============================================================================
--- python/branches/release27-maint/Makefile.pre.in (original)
+++ python/branches/release27-maint/Makefile.pre.in Tue Sep 14 16:24:58 2010
@@ -850,6 +850,7 @@
LIBSUBDIRS= lib-tk lib-tk/test lib-tk/test/test_tkinter \
lib-tk/test/test_ttk site-packages test test/data \
test/decimaltestdata test/xmltestdata \
+ test/tracedmodules \
encodings compiler hotshot \
email email/mime email/test email/test/data \
json json/tests \
From python-checkins at python.org Tue Sep 14 16:37:18 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 16:37:18 +0200 (CEST)
Subject: [Python-checkins] r84806 - in python/branches/release27-maint:
Lib/ssl.py Lib/test/test_ssl.py Misc/NEWS
Message-ID: <20100914143718.783B5FB1A@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 16:37:18 2010
New Revision: 84806
Log:
Issue #9729: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods. Also,
fix various SSLSocket methods to raise socket.error rather than an
unhelpful TypeError when called on an unconnected socket. Original patch
by Andrew Bennetts.
NOTE: obviously, these methods are untested and unused in the real world...
Modified:
python/branches/release27-maint/Lib/ssl.py
python/branches/release27-maint/Lib/test/test_ssl.py
python/branches/release27-maint/Misc/NEWS
Modified: python/branches/release27-maint/Lib/ssl.py
==============================================================================
--- python/branches/release27-maint/Lib/ssl.py (original)
+++ python/branches/release27-maint/Lib/ssl.py Tue Sep 14 16:37:18 2010
@@ -184,14 +184,16 @@
else:
return v
else:
- return socket.send(self, data, flags)
+ return self._sock.send(data, flags)
- def sendto(self, data, addr, flags=0):
+ def sendto(self, data, flags_or_addr, addr=None):
if self._sslobj:
raise ValueError("sendto not allowed on instances of %s" %
self.__class__)
+ elif addr is None:
+ return self._sock.sendto(data, flags_or_addr)
else:
- return socket.sendto(self, data, addr, flags)
+ return self._sock.sendto(data, flags_or_addr, addr)
def sendall(self, data, flags=0):
if self._sslobj:
@@ -216,7 +218,7 @@
self.__class__)
return self.read(buflen)
else:
- return socket.recv(self, buflen, flags)
+ return self._sock.recv(buflen, flags)
def recv_into(self, buffer, nbytes=None, flags=0):
if buffer and (nbytes is None):
@@ -233,21 +235,21 @@
buffer[:v] = tmp_buffer
return v
else:
- return socket.recv_into(self, buffer, nbytes, flags)
+ return self._sock.recv_into(buffer, nbytes, flags)
- def recvfrom(self, addr, buflen=1024, flags=0):
+ def recvfrom(self, buflen=1024, flags=0):
if self._sslobj:
raise ValueError("recvfrom not allowed on instances of %s" %
self.__class__)
else:
- return socket.recvfrom(self, addr, buflen, flags)
+ return self._sock.recvfrom(buflen, flags)
def recvfrom_into(self, buffer, nbytes=None, flags=0):
if self._sslobj:
raise ValueError("recvfrom_into not allowed on instances of %s" %
self.__class__)
else:
- return socket.recvfrom_into(self, buffer, nbytes, flags)
+ return self._sock.recvfrom_into(buffer, nbytes, flags)
def pending(self):
if self._sslobj:
Modified: python/branches/release27-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release27-maint/Lib/test/test_ssl.py Tue Sep 14 16:37:18 2010
@@ -179,6 +179,19 @@
del ss
self.assertEqual(wr(), None)
+ def test_wrapped_unconnected(self):
+ # The _delegate_methods in socket.py are correctly delegated to by an
+ # unconnected SSLSocket, so they will raise a socket.error rather than
+ # something unexpected like TypeError.
+ s = socket.socket(socket.AF_INET)
+ ss = ssl.wrap_socket(s)
+ self.assertRaises(socket.error, ss.recv, 1)
+ self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
+ self.assertRaises(socket.error, ss.recvfrom, 1)
+ self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
+ self.assertRaises(socket.error, ss.send, b'x')
+ self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
+
class NetworkedTests(unittest.TestCase):
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Tue Sep 14 16:37:18 2010
@@ -43,6 +43,12 @@
Library
-------
+- Issue #9729: Fix the signature of SSLSocket.recvfrom() and
+ SSLSocket.sendto() to match the corresponding socket methods. Also,
+ fix various SSLSocket methods to raise socket.error rather than an
+ unhelpful TypeError when called on an unconnected socket. Original patch
+ by Andrew Bennetts.
+
- Issue #9826: OrderedDict.__repr__ can now handle self-referential
values: d['x'] = d.
From python-checkins at python.org Tue Sep 14 16:43:44 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 16:43:44 +0200 (CEST)
Subject: [Python-checkins] r84807 - in python/branches/py3k: Lib/ssl.py
Lib/test/test_ssl.py Misc/NEWS
Message-ID: <20100914144344.D175DEE9CA@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 16:43:44 2010
New Revision: 84807
Log:
Issue #9853: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods.
Modified:
python/branches/py3k/Lib/ssl.py
python/branches/py3k/Lib/test/test_ssl.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Lib/ssl.py
==============================================================================
--- python/branches/py3k/Lib/ssl.py (original)
+++ python/branches/py3k/Lib/ssl.py Tue Sep 14 16:43:44 2010
@@ -258,13 +258,15 @@
else:
return socket.send(self, data, flags)
- def sendto(self, data, addr, flags=0):
+ def sendto(self, data, flags_or_addr, addr=None):
self._checkClosed()
if self._sslobj:
raise ValueError("sendto not allowed on instances of %s" %
self.__class__)
+ elif addr is None:
+ return socket.sendto(self, data, flags_or_addr)
else:
- return socket.sendto(self, data, addr, flags)
+ return socket.sendto(self, data, flags_or_addr, addr)
def sendall(self, data, flags=0):
self._checkClosed()
@@ -308,13 +310,13 @@
else:
return socket.recv_into(self, buffer, nbytes, flags)
- def recvfrom(self, addr, buflen=1024, flags=0):
+ def recvfrom(self, buflen=1024, flags=0):
self._checkClosed()
if self._sslobj:
raise ValueError("recvfrom not allowed on instances of %s" %
self.__class__)
else:
- return socket.recvfrom(self, addr, buflen, flags)
+ return socket.recvfrom(self, buflen, flags)
def recvfrom_into(self, buffer, nbytes=None, flags=0):
self._checkClosed()
Modified: python/branches/py3k/Lib/test/test_ssl.py
==============================================================================
--- python/branches/py3k/Lib/test/test_ssl.py (original)
+++ python/branches/py3k/Lib/test/test_ssl.py Tue Sep 14 16:43:44 2010
@@ -163,6 +163,18 @@
del ss
self.assertEqual(wr(), None)
+ def test_wrapped_unconnected(self):
+ # Methods on an unconnected SSLSocket propagate the original
+ # socket.error raise by the underlying socket object.
+ s = socket.socket(socket.AF_INET)
+ ss = ssl.wrap_socket(s)
+ self.assertRaises(socket.error, ss.recv, 1)
+ self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
+ self.assertRaises(socket.error, ss.recvfrom, 1)
+ self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
+ self.assertRaises(socket.error, ss.send, b'x')
+ self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
+
def test_timeout(self):
# Issue #8524: when creating an SSL socket, the timeout of the
# original socket should be retained.
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 14 16:43:44 2010
@@ -52,6 +52,9 @@
Library
-------
+- Issue #9853: Fix the signature of SSLSocket.recvfrom() and
+ SSLSocket.sendto() to match the corresponding socket methods.
+
- Issue 9840: Added a decorator to reprlib for wrapping __repr__ methods
to make them handle recursive calls within the same thread.
From python-checkins at python.org Tue Sep 14 16:44:56 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 16:44:56 +0200 (CEST)
Subject: [Python-checkins] r84808 - python/branches/release27-maint
Message-ID: <20100914144456.97439EE9A7@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 16:44:56 2010
New Revision: 84808
Log:
Blocked revisions 84807 via svnmerge
........
r84807 | antoine.pitrou | 2010-09-14 16:43:44 +0200 (mar., 14 sept. 2010) | 4 lines
Issue #9853: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods.
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Tue Sep 14 16:47:09 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 16:47:09 +0200 (CEST)
Subject: [Python-checkins] r84809 - in python/branches/release31-maint:
Lib/ssl.py Lib/test/test_ssl.py Misc/NEWS
Message-ID: <20100914144709.16DBDEE989@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 16:47:08 2010
New Revision: 84809
Log:
Merged revisions 84807 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84807 | antoine.pitrou | 2010-09-14 16:43:44 +0200 (mar., 14 sept. 2010) | 4 lines
Issue #9853: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Lib/ssl.py
python/branches/release31-maint/Lib/test/test_ssl.py
python/branches/release31-maint/Misc/NEWS
Modified: python/branches/release31-maint/Lib/ssl.py
==============================================================================
--- python/branches/release31-maint/Lib/ssl.py (original)
+++ python/branches/release31-maint/Lib/ssl.py Tue Sep 14 16:47:08 2010
@@ -221,13 +221,15 @@
else:
return socket.send(self, data, flags)
- def sendto(self, data, addr, flags=0):
+ def sendto(self, data, flags_or_addr, addr=None):
self._checkClosed()
if self._sslobj:
raise ValueError("sendto not allowed on instances of %s" %
self.__class__)
+ elif addr is None:
+ return socket.sendto(self, data, flags_or_addr)
else:
- return socket.sendto(self, data, addr, flags)
+ return socket.sendto(self, data, flags_or_addr, addr)
def sendall(self, data, flags=0):
self._checkClosed()
@@ -267,13 +269,13 @@
else:
return socket.recv_into(self, buffer, nbytes, flags)
- def recvfrom(self, addr, buflen=1024, flags=0):
+ def recvfrom(self, buflen=1024, flags=0):
self._checkClosed()
if self._sslobj:
raise ValueError("recvfrom not allowed on instances of %s" %
self.__class__)
else:
- return socket.recvfrom(self, addr, buflen, flags)
+ return socket.recvfrom(self, buflen, flags)
def recvfrom_into(self, buffer, nbytes=None, flags=0):
self._checkClosed()
Modified: python/branches/release31-maint/Lib/test/test_ssl.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_ssl.py (original)
+++ python/branches/release31-maint/Lib/test/test_ssl.py Tue Sep 14 16:47:08 2010
@@ -92,6 +92,18 @@
del ss
self.assertEqual(wr(), None)
+ def test_wrapped_unconnected(self):
+ # Methods on an unconnected SSLSocket propagate the original
+ # socket.error raise by the underlying socket object.
+ s = socket.socket(socket.AF_INET)
+ ss = ssl.wrap_socket(s)
+ self.assertRaises(socket.error, ss.recv, 1)
+ self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
+ self.assertRaises(socket.error, ss.recvfrom, 1)
+ self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
+ self.assertRaises(socket.error, ss.send, b'x')
+ self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
+
def test_timeout(self):
# Issue #8524: when creating an SSL socket, the timeout of the
# original socket should be retained.
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Tue Sep 14 16:47:08 2010
@@ -117,6 +117,9 @@
Library
-------
+- Issue #9853: Fix the signature of SSLSocket.recvfrom() and
+ SSLSocket.sendto() to match the corresponding socket methods.
+
- Issue #9792: In case of connection failure, socket.create_connection()
would swallow the exception and raise a new one, making it impossible
to fetch the original errno, or to filter timeout errors. Now the
From python-checkins at python.org Tue Sep 14 18:02:01 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Tue, 14 Sep 2010 18:02:01 +0200 (CEST)
Subject: [Python-checkins] r84810 - in python/branches/py3k:
Doc/extending/windows.rst Include/pyport.h
Message-ID: <20100914160201.9CB72EE987@mail.python.org>
Author: daniel.stutzbach
Date: Tue Sep 14 18:02:01 2010
New Revision: 84810
Log:
Remove pointers to a FAQ entry that no longer exists. Incorporate some text from the old FAQ into the docs
Modified:
python/branches/py3k/Doc/extending/windows.rst
python/branches/py3k/Include/pyport.h
Modified: python/branches/py3k/Doc/extending/windows.rst
==============================================================================
--- python/branches/py3k/Doc/extending/windows.rst (original)
+++ python/branches/py3k/Doc/extending/windows.rst Tue Sep 14 18:02:01 2010
@@ -171,7 +171,9 @@
PyVarObject_HEAD_INIT(&PyType_Type, 0)
-Change it to::
+Static type object initializers in extension modules may cause
+compiles to fail with an error message like "initializer not a
+constant". This shows up when building DLL under MSVC. Change it to::
PyVarObject_HEAD_INIT(NULL, 0)
@@ -179,8 +181,6 @@
MyObject_Type.ob_type = &PyType_Type;
-Refer to section 3 of the `Python FAQ `_ for
-details on why you must do this.
.. _dynamic-linking:
Modified: python/branches/py3k/Include/pyport.h
==============================================================================
--- python/branches/py3k/Include/pyport.h (original)
+++ python/branches/py3k/Include/pyport.h Tue Sep 14 18:02:01 2010
@@ -695,23 +695,24 @@
# ifdef Py_BUILD_CORE
# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
- /* module init functions inside the core need no external linkage */
- /* except for Cygwin to handle embedding */
+ /* module init functions inside the core need no external linkage */
+ /* except for Cygwin to handle embedding */
# if defined(__CYGWIN__)
# define PyMODINIT_FUNC __declspec(dllexport) PyObject*
# else /* __CYGWIN__ */
# define PyMODINIT_FUNC PyObject*
# endif /* __CYGWIN__ */
# else /* Py_BUILD_CORE */
- /* Building an extension module, or an embedded situation */
- /* public Python functions and data are imported */
- /* Under Cygwin, auto-import functions to prevent compilation */
- /* failures similar to http://python.org/doc/FAQ.html#3.24 */
+ /* Building an extension module, or an embedded situation */
+ /* public Python functions and data are imported */
+ /* Under Cygwin, auto-import functions to prevent compilation */
+ /* failures similar to those described at the bottom of 4.1: */
+ /* http://docs.python.org/extending/windows.html#a-cookbook-approach */
# if !defined(__CYGWIN__)
# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE
# endif /* !__CYGWIN__ */
# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
- /* module init functions outside the core must be exported */
+ /* module init functions outside the core must be exported */
# if defined(__cplusplus)
# define PyMODINIT_FUNC extern "C" __declspec(dllexport) PyObject*
# else /* __cplusplus */
From python-checkins at python.org Tue Sep 14 18:07:54 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Tue, 14 Sep 2010 18:07:54 +0200 (CEST)
Subject: [Python-checkins] r84811 - in python/branches/release31-maint:
Doc/extending/windows.rst Include/pyport.h
Message-ID: <20100914160754.C6799FE0A@mail.python.org>
Author: daniel.stutzbach
Date: Tue Sep 14 18:07:54 2010
New Revision: 84811
Log:
Merged revisions 84810 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84810 | daniel.stutzbach | 2010-09-14 11:02:01 -0500 (Tue, 14 Sep 2010) | 1 line
Remove pointers to a FAQ entry that no longer exists. Incorporate some text from the old FAQ into the docs
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/extending/windows.rst
python/branches/release31-maint/Include/pyport.h
Modified: python/branches/release31-maint/Doc/extending/windows.rst
==============================================================================
--- python/branches/release31-maint/Doc/extending/windows.rst (original)
+++ python/branches/release31-maint/Doc/extending/windows.rst Tue Sep 14 18:07:54 2010
@@ -171,7 +171,9 @@
PyVarObject_HEAD_INIT(&PyType_Type, 0)
-Change it to::
+Static type object initializers in extension modules may cause
+compiles to fail with an error message like "initializer not a
+constant". This shows up when building DLL under MSVC. Change it to::
PyVarObject_HEAD_INIT(NULL, 0)
@@ -179,8 +181,6 @@
MyObject_Type.ob_type = &PyType_Type;
-Refer to section 3 of the `Python FAQ `_ for
-details on why you must do this.
.. _dynamic-linking:
Modified: python/branches/release31-maint/Include/pyport.h
==============================================================================
--- python/branches/release31-maint/Include/pyport.h (original)
+++ python/branches/release31-maint/Include/pyport.h Tue Sep 14 18:07:54 2010
@@ -663,23 +663,24 @@
# ifdef Py_BUILD_CORE
# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
- /* module init functions inside the core need no external linkage */
- /* except for Cygwin to handle embedding */
+ /* module init functions inside the core need no external linkage */
+ /* except for Cygwin to handle embedding */
# if defined(__CYGWIN__)
# define PyMODINIT_FUNC __declspec(dllexport) PyObject*
# else /* __CYGWIN__ */
# define PyMODINIT_FUNC PyObject*
# endif /* __CYGWIN__ */
# else /* Py_BUILD_CORE */
- /* Building an extension module, or an embedded situation */
- /* public Python functions and data are imported */
- /* Under Cygwin, auto-import functions to prevent compilation */
- /* failures similar to http://python.org/doc/FAQ.html#3.24 */
+ /* Building an extension module, or an embedded situation */
+ /* public Python functions and data are imported */
+ /* Under Cygwin, auto-import functions to prevent compilation */
+ /* failures similar to those described at the bottom of 4.1: */
+ /* http://docs.python.org/extending/windows.html#a-cookbook-approach */
# if !defined(__CYGWIN__)
# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE
# endif /* !__CYGWIN__ */
# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
- /* module init functions outside the core must be exported */
+ /* module init functions outside the core must be exported */
# if defined(__cplusplus)
# define PyMODINIT_FUNC extern "C" __declspec(dllexport) PyObject*
# else /* __cplusplus */
From python-checkins at python.org Tue Sep 14 18:10:22 2010
From: python-checkins at python.org (daniel.stutzbach)
Date: Tue, 14 Sep 2010 18:10:22 +0200 (CEST)
Subject: [Python-checkins] r84812 - in python/branches/release27-maint:
Doc/extending/windows.rst Include/pyport.h
Message-ID: <20100914161022.95467FE0A@mail.python.org>
Author: daniel.stutzbach
Date: Tue Sep 14 18:10:22 2010
New Revision: 84812
Log:
Merged revisions 84810 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84810 | daniel.stutzbach | 2010-09-14 11:02:01 -0500 (Tue, 14 Sep 2010) | 1 line
Remove pointers to a FAQ entry that no longer exists. Incorporate some text from the old FAQ into the docs
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Doc/extending/windows.rst
python/branches/release27-maint/Include/pyport.h
Modified: python/branches/release27-maint/Doc/extending/windows.rst
==============================================================================
--- python/branches/release27-maint/Doc/extending/windows.rst (original)
+++ python/branches/release27-maint/Doc/extending/windows.rst Tue Sep 14 18:10:22 2010
@@ -175,7 +175,9 @@
PyObject_HEAD_INIT(&PyType_Type)
-Change it to::
+Static type object initializers in extension modules may cause
+compiles to fail with an error message like "initializer not a
+constant". This shows up when building DLL under MSVC. Change it to::
PyObject_HEAD_INIT(NULL)
@@ -183,8 +185,6 @@
MyObject_Type.ob_type = &PyType_Type;
-Refer to section 3 of the `Python FAQ `_ for
-details on why you must do this.
.. _dynamic-linking:
Modified: python/branches/release27-maint/Include/pyport.h
==============================================================================
--- python/branches/release27-maint/Include/pyport.h (original)
+++ python/branches/release27-maint/Include/pyport.h Tue Sep 14 18:10:22 2010
@@ -724,23 +724,24 @@
# ifdef Py_BUILD_CORE
# define PyAPI_FUNC(RTYPE) __declspec(dllexport) RTYPE
# define PyAPI_DATA(RTYPE) extern __declspec(dllexport) RTYPE
- /* module init functions inside the core need no external linkage */
- /* except for Cygwin to handle embedding (FIXME: BeOS too?) */
+ /* module init functions inside the core need no external linkage */
+ /* except for Cygwin to handle embedding (FIXME: BeOS too?) */
# if defined(__CYGWIN__)
# define PyMODINIT_FUNC __declspec(dllexport) void
# else /* __CYGWIN__ */
# define PyMODINIT_FUNC void
# endif /* __CYGWIN__ */
# else /* Py_BUILD_CORE */
- /* Building an extension module, or an embedded situation */
- /* public Python functions and data are imported */
- /* Under Cygwin, auto-import functions to prevent compilation */
- /* failures similar to http://python.org/doc/FAQ.html#3.24 */
+ /* Building an extension module, or an embedded situation */
+ /* public Python functions and data are imported */
+ /* Under Cygwin, auto-import functions to prevent compilation */
+ /* failures similar to those described at the bottom of 4.1: */
+ /* http://docs.python.org/extending/windows.html#a-cookbook-approach */
# if !defined(__CYGWIN__)
# define PyAPI_FUNC(RTYPE) __declspec(dllimport) RTYPE
# endif /* !__CYGWIN__ */
# define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
- /* module init functions outside the core must be exported */
+ /* module init functions outside the core must be exported */
# if defined(__cplusplus)
# define PyMODINIT_FUNC extern "C" __declspec(dllexport) void
# else /* __cplusplus */
From python-checkins at python.org Tue Sep 14 20:00:03 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 20:00:03 +0200 (CEST)
Subject: [Python-checkins] r84813 - in python/branches/py3k:
Doc/library/socket.rst Lib/socket.py Lib/test/test_socket.py
Misc/NEWS
Message-ID: <20100914180003.40634FCD4@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 20:00:02 2010
New Revision: 84813
Log:
Issue #1552: socket.socketpair() now returns regular socket.socket
objects supporting the whole socket API (rather than the "raw"
_socket.socket objects).
Modified:
python/branches/py3k/Doc/library/socket.rst
python/branches/py3k/Lib/socket.py
python/branches/py3k/Lib/test/test_socket.py
python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/socket.rst
==============================================================================
--- python/branches/py3k/Doc/library/socket.rst (original)
+++ python/branches/py3k/Doc/library/socket.rst Tue Sep 14 20:00:02 2010
@@ -364,6 +364,10 @@
if defined on the platform; otherwise, the default is :const:`AF_INET`.
Availability: Unix.
+ .. versionchanged:: 3.2
+ The returned socket objects now support the whole socket API, rather
+ than a subset.
+
.. function:: fromfd(fd, family, type[, proto])
Modified: python/branches/py3k/Lib/socket.py
==============================================================================
--- python/branches/py3k/Lib/socket.py (original)
+++ python/branches/py3k/Lib/socket.py Tue Sep 14 20:00:02 2010
@@ -199,6 +199,27 @@
return socket(family, type, proto, nfd)
+if hasattr(_socket, "socketpair"):
+
+ def socketpair(family=None, type=SOCK_STREAM, proto=0):
+ """socketpair([family[, type[, proto]]]) -> (socket object, socket object)
+
+ Create a pair of socket objects from the sockets returned by the platform
+ socketpair() function.
+ The arguments are the same as for socket() except the default family is
+ AF_UNIX if defined on the platform; otherwise, the default is AF_INET.
+ """
+ if family is None:
+ try:
+ family = AF_UNIX
+ except NameError:
+ family = AF_INET
+ a, b = _socket.socketpair(family, type, proto)
+ a = socket(family, type, proto, a.detach())
+ b = socket(family, type, proto, b.detach())
+ return a, b
+
+
class SocketIO(io.RawIOBase):
"""Raw I/O implementation for stream sockets.
Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py (original)
+++ python/branches/py3k/Lib/test/test_socket.py Tue Sep 14 20:00:02 2010
@@ -714,6 +714,7 @@
# Testing fromfd()
fd = self.cli_conn.fileno()
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
+ self.assertIsInstance(sock, socket.socket)
msg = sock.recv(1024)
self.assertEqual(msg, MSG)
@@ -814,6 +815,23 @@
def __init__(self, methodName='runTest'):
SocketPairTest.__init__(self, methodName=methodName)
+ def _testDefaults(self):
+ pass
+
+ def testDefaults(self):
+ self.assertIsInstance(self.cli, socket.socket)
+ self.assertIsInstance(self.serv, socket.socket)
+ if hasattr(socket, 'AF_UNIX'):
+ self.assertEqual(self.cli.family, socket.AF_UNIX)
+ self.assertEqual(self.serv.family, socket.AF_UNIX)
+ else:
+ self.assertEqual(self.cli.family, socket.AF_INET)
+ self.assertEqual(self.serv.family, socket.AF_INET)
+ self.assertEqual(self.cli.type, socket.SOCK_STREAM)
+ self.assertEqual(self.serv.type, socket.SOCK_STREAM)
+ self.assertEqual(self.cli.proto, 0)
+ self.assertEqual(self.serv.proto, 0)
+
def testRecv(self):
msg = self.serv.recv(1024)
self.assertEqual(msg, MSG)
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 14 20:00:02 2010
@@ -52,6 +52,10 @@
Library
-------
+- Issue #1552: socket.socketpair() now returns regular socket.socket
+ objects supporting the whole socket API (rather than the "raw"
+ _socket.socket objects).
+
- Issue #9853: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods.
From python-checkins at python.org Tue Sep 14 20:37:24 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 20:37:24 +0200 (CEST)
Subject: [Python-checkins] r84814 - in python/branches/py3k:
Doc/library/io.rst Lib/_pyio.py Lib/test/test_io.py Misc/NEWS
Modules/_io/iobase.c
Message-ID: <20100914183724.5F99FEE9B4@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 20:37:24 2010
New Revision: 84814
Log:
Issue #9854: The default read() implementation in io.RawIOBase now
handles non-blocking readinto() returning None correctly.
Modified:
python/branches/py3k/Doc/library/io.rst
python/branches/py3k/Lib/_pyio.py
python/branches/py3k/Lib/test/test_io.py
python/branches/py3k/Misc/NEWS
python/branches/py3k/Modules/_io/iobase.c
Modified: python/branches/py3k/Doc/library/io.rst
==============================================================================
--- python/branches/py3k/Doc/library/io.rst (original)
+++ python/branches/py3k/Doc/library/io.rst Tue Sep 14 20:37:24 2010
@@ -361,8 +361,9 @@
.. method:: readinto(b)
- Read up to len(b) bytes into bytearray *b* and return the number of bytes
- read.
+ Read up to len(b) bytes into bytearray *b* and return the number ofbytes
+ read. If the object is in non-blocking mode and no bytes are available,
+ ``None`` is returned.
.. method:: write(b)
Modified: python/branches/py3k/Lib/_pyio.py
==============================================================================
--- python/branches/py3k/Lib/_pyio.py (original)
+++ python/branches/py3k/Lib/_pyio.py Tue Sep 14 20:37:24 2010
@@ -544,6 +544,8 @@
return self.readall()
b = bytearray(n.__index__())
n = self.readinto(b)
+ if n is None:
+ return None
del b[n:]
return bytes(b)
@@ -561,7 +563,7 @@
"""Read up to len(b) bytes into b.
Returns number of bytes read (0 for EOF), or None if the object
- is set not to block as has no data to read.
+ is set not to block and has no data to read.
"""
self._unsupported("readinto")
Modified: python/branches/py3k/Lib/test/test_io.py
==============================================================================
--- python/branches/py3k/Lib/test/test_io.py (original)
+++ python/branches/py3k/Lib/test/test_io.py Tue Sep 14 20:37:24 2010
@@ -48,7 +48,9 @@
return f._CHUNK_SIZE
-class MockRawIO:
+class MockRawIOWithoutRead:
+ """A RawIO implementation without read(), so as to exercise the default
+ RawIO.read() which calls readinto()."""
def __init__(self, read_stack=()):
self._read_stack = list(read_stack)
@@ -56,14 +58,6 @@
self._reads = 0
self._extraneous_reads = 0
- def read(self, n=None):
- self._reads += 1
- try:
- return self._read_stack.pop(0)
- except:
- self._extraneous_reads += 1
- return b""
-
def write(self, b):
self._write_stack.append(bytes(b))
return len(b)
@@ -110,6 +104,23 @@
def truncate(self, pos=None):
return pos
+class CMockRawIOWithoutRead(MockRawIOWithoutRead, io.RawIOBase):
+ pass
+
+class PyMockRawIOWithoutRead(MockRawIOWithoutRead, pyio.RawIOBase):
+ pass
+
+
+class MockRawIO(MockRawIOWithoutRead):
+
+ def read(self, n=None):
+ self._reads += 1
+ try:
+ return self._read_stack.pop(0)
+ except:
+ self._extraneous_reads += 1
+ return b""
+
class CMockRawIO(MockRawIO, io.RawIOBase):
pass
@@ -582,6 +593,19 @@
f.close()
self.assertRaises(ValueError, f.flush)
+ def test_RawIOBase_read(self):
+ # Exercise the default RawIOBase.read() implementation (which calls
+ # readinto() internally).
+ rawio = self.MockRawIOWithoutRead((b"abc", b"d", None, b"efg", None))
+ self.assertEqual(rawio.read(2), b"ab")
+ self.assertEqual(rawio.read(2), b"c")
+ self.assertEqual(rawio.read(2), b"d")
+ self.assertEqual(rawio.read(2), None)
+ self.assertEqual(rawio.read(2), b"ef")
+ self.assertEqual(rawio.read(2), b"g")
+ self.assertEqual(rawio.read(2), None)
+ self.assertEqual(rawio.read(2), b"")
+
class CIOTest(IOTest):
pass
@@ -2590,7 +2614,7 @@
# Put the namespaces of the IO module we are testing and some useful mock
# classes in the __dict__ of each test.
mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO,
- MockNonBlockWriterIO, MockUnseekableIO)
+ MockNonBlockWriterIO, MockUnseekableIO, MockRawIOWithoutRead)
all_members = io.__all__ + ["IncrementalNewlineDecoder"]
c_io_ns = {name : getattr(io, name) for name in all_members}
py_io_ns = {name : getattr(pyio, name) for name in all_members}
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 14 20:37:24 2010
@@ -52,6 +52,9 @@
Library
-------
+- Issue #9854: The default read() implementation in io.RawIOBase now
+ handles non-blocking readinto() returning None correctly.
+
- Issue #1552: socket.socketpair() now returns regular socket.socket
objects supporting the whole socket API (rather than the "raw"
_socket.socket objects).
Modified: python/branches/py3k/Modules/_io/iobase.c
==============================================================================
--- python/branches/py3k/Modules/_io/iobase.c (original)
+++ python/branches/py3k/Modules/_io/iobase.c Tue Sep 14 20:37:24 2010
@@ -777,9 +777,9 @@
return NULL;
res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
- if (res == NULL) {
+ if (res == NULL || res == Py_None) {
Py_DECREF(b);
- return NULL;
+ return res;
}
n = PyNumber_AsSsize_t(res, PyExc_ValueError);
From python-checkins at python.org Tue Sep 14 20:39:20 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 20:39:20 +0200 (CEST)
Subject: [Python-checkins] r84815 - python/branches/release31-maint
Message-ID: <20100914183920.5B0A5EE9C2@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 20:39:20 2010
New Revision: 84815
Log:
Blocked revisions 84813 via svnmerge
........
r84813 | antoine.pitrou | 2010-09-14 20:00:02 +0200 (mar., 14 sept. 2010) | 5 lines
Issue #1552: socket.socketpair() now returns regular socket.socket
objects supporting the whole socket API (rather than the "raw"
_socket.socket objects).
........
Modified:
python/branches/release31-maint/ (props changed)
From python-checkins at python.org Tue Sep 14 20:48:19 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 20:48:19 +0200 (CEST)
Subject: [Python-checkins] r84816 - in python/branches/release27-maint:
Doc/library/io.rst Lib/_pyio.py Lib/test/test_io.py Misc/NEWS
Modules/_io/iobase.c
Message-ID: <20100914184819.99DF7EE987@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 20:48:19 2010
New Revision: 84816
Log:
Merged revisions 84814 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84814 | antoine.pitrou | 2010-09-14 20:37:24 +0200 (mar., 14 sept. 2010) | 4 lines
Issue #9854: The default read() implementation in io.RawIOBase now
handles non-blocking readinto() returning None correctly.
........
Modified:
python/branches/release27-maint/ (props changed)
python/branches/release27-maint/Doc/library/io.rst
python/branches/release27-maint/Lib/_pyio.py
python/branches/release27-maint/Lib/test/test_io.py
python/branches/release27-maint/Misc/NEWS
python/branches/release27-maint/Modules/_io/iobase.c
Modified: python/branches/release27-maint/Doc/library/io.rst
==============================================================================
--- python/branches/release27-maint/Doc/library/io.rst (original)
+++ python/branches/release27-maint/Doc/library/io.rst Tue Sep 14 20:48:19 2010
@@ -371,8 +371,9 @@
.. method:: readinto(b)
- Read up to len(b) bytes into bytearray *b* and return the number of bytes
- read.
+ Read up to len(b) bytes into bytearray *b* and return the number ofbytes
+ read. If the object is in non-blocking mode and no bytes are available,
+ ``None`` is returned.
.. method:: write(b)
Modified: python/branches/release27-maint/Lib/_pyio.py
==============================================================================
--- python/branches/release27-maint/Lib/_pyio.py (original)
+++ python/branches/release27-maint/Lib/_pyio.py Tue Sep 14 20:48:19 2010
@@ -546,6 +546,8 @@
return self.readall()
b = bytearray(n.__index__())
n = self.readinto(b)
+ if n is None:
+ return None
del b[n:]
return bytes(b)
@@ -563,7 +565,7 @@
"""Read up to len(b) bytes into b.
Returns number of bytes read (0 for EOF), or None if the object
- is set not to block as has no data to read.
+ is set not to block and has no data to read.
"""
self._unsupported("readinto")
Modified: python/branches/release27-maint/Lib/test/test_io.py
==============================================================================
--- python/branches/release27-maint/Lib/test/test_io.py (original)
+++ python/branches/release27-maint/Lib/test/test_io.py Tue Sep 14 20:48:19 2010
@@ -53,7 +53,9 @@
return f._CHUNK_SIZE
-class MockRawIO:
+class MockRawIOWithoutRead:
+ """A RawIO implementation without read(), so as to exercise the default
+ RawIO.read() which calls readinto()."""
def __init__(self, read_stack=()):
self._read_stack = list(read_stack)
@@ -61,14 +63,6 @@
self._reads = 0
self._extraneous_reads = 0
- def read(self, n=None):
- self._reads += 1
- try:
- return self._read_stack.pop(0)
- except:
- self._extraneous_reads += 1
- return b""
-
def write(self, b):
self._write_stack.append(bytes(b))
return len(b)
@@ -115,6 +109,23 @@
def truncate(self, pos=None):
return pos
+class CMockRawIOWithoutRead(MockRawIOWithoutRead, io.RawIOBase):
+ pass
+
+class PyMockRawIOWithoutRead(MockRawIOWithoutRead, pyio.RawIOBase):
+ pass
+
+
+class MockRawIO(MockRawIOWithoutRead):
+
+ def read(self, n=None):
+ self._reads += 1
+ try:
+ return self._read_stack.pop(0)
+ except:
+ self._extraneous_reads += 1
+ return b""
+
class CMockRawIO(MockRawIO, io.RawIOBase):
pass
@@ -560,6 +571,19 @@
f.close()
self.assertRaises(ValueError, f.flush)
+ def test_RawIOBase_read(self):
+ # Exercise the default RawIOBase.read() implementation (which calls
+ # readinto() internally).
+ rawio = self.MockRawIOWithoutRead((b"abc", b"d", None, b"efg", None))
+ self.assertEqual(rawio.read(2), b"ab")
+ self.assertEqual(rawio.read(2), b"c")
+ self.assertEqual(rawio.read(2), b"d")
+ self.assertEqual(rawio.read(2), None)
+ self.assertEqual(rawio.read(2), b"ef")
+ self.assertEqual(rawio.read(2), b"g")
+ self.assertEqual(rawio.read(2), None)
+ self.assertEqual(rawio.read(2), b"")
+
class CIOTest(IOTest):
pass
@@ -2558,7 +2582,7 @@
# Put the namespaces of the IO module we are testing and some useful mock
# classes in the __dict__ of each test.
mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO,
- MockNonBlockWriterIO)
+ MockNonBlockWriterIO, MockRawIOWithoutRead)
all_members = io.__all__ + ["IncrementalNewlineDecoder"]
c_io_ns = dict((name, getattr(io, name)) for name in all_members)
py_io_ns = dict((name, getattr(pyio, name)) for name in all_members)
Modified: python/branches/release27-maint/Misc/NEWS
==============================================================================
--- python/branches/release27-maint/Misc/NEWS (original)
+++ python/branches/release27-maint/Misc/NEWS Tue Sep 14 20:48:19 2010
@@ -43,6 +43,9 @@
Library
-------
+- Issue #9854: The default read() implementation in io.RawIOBase now
+ handles non-blocking readinto() returning None correctly.
+
- Issue #9729: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods. Also,
fix various SSLSocket methods to raise socket.error rather than an
Modified: python/branches/release27-maint/Modules/_io/iobase.c
==============================================================================
--- python/branches/release27-maint/Modules/_io/iobase.c (original)
+++ python/branches/release27-maint/Modules/_io/iobase.c Tue Sep 14 20:48:19 2010
@@ -776,9 +776,9 @@
return NULL;
res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
- if (res == NULL) {
+ if (res == NULL || res == Py_None) {
Py_DECREF(b);
- return NULL;
+ return res;
}
n = PyNumber_AsSsize_t(res, PyExc_ValueError);
From python-checkins at python.org Tue Sep 14 20:53:08 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 20:53:08 +0200 (CEST)
Subject: [Python-checkins] r84817 - in python/branches/release31-maint:
Doc/library/io.rst Lib/_pyio.py Lib/test/test_io.py Misc/NEWS
Modules/_io/iobase.c
Message-ID: <20100914185308.24358EE987@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 20:53:07 2010
New Revision: 84817
Log:
Merged revisions 84814 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84814 | antoine.pitrou | 2010-09-14 20:37:24 +0200 (mar., 14 sept. 2010) | 4 lines
Issue #9854: The default read() implementation in io.RawIOBase now
handles non-blocking readinto() returning None correctly.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/library/io.rst
python/branches/release31-maint/Lib/_pyio.py
python/branches/release31-maint/Lib/test/test_io.py
python/branches/release31-maint/Misc/NEWS
python/branches/release31-maint/Modules/_io/iobase.c
Modified: python/branches/release31-maint/Doc/library/io.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/io.rst (original)
+++ python/branches/release31-maint/Doc/library/io.rst Tue Sep 14 20:53:07 2010
@@ -361,8 +361,9 @@
.. method:: readinto(b)
- Read up to len(b) bytes into bytearray *b* and return the number of bytes
- read.
+ Read up to len(b) bytes into bytearray *b* and return the number ofbytes
+ read. If the object is in non-blocking mode and no bytes are available,
+ ``None`` is returned.
.. method:: write(b)
Modified: python/branches/release31-maint/Lib/_pyio.py
==============================================================================
--- python/branches/release31-maint/Lib/_pyio.py (original)
+++ python/branches/release31-maint/Lib/_pyio.py Tue Sep 14 20:53:07 2010
@@ -542,6 +542,8 @@
return self.readall()
b = bytearray(n.__index__())
n = self.readinto(b)
+ if n is None:
+ return None
del b[n:]
return bytes(b)
@@ -559,7 +561,7 @@
"""Read up to len(b) bytes into b.
Returns number of bytes read (0 for EOF), or None if the object
- is set not to block as has no data to read.
+ is set not to block and has no data to read.
"""
self._unsupported("readinto")
Modified: python/branches/release31-maint/Lib/test/test_io.py
==============================================================================
--- python/branches/release31-maint/Lib/test/test_io.py (original)
+++ python/branches/release31-maint/Lib/test/test_io.py Tue Sep 14 20:53:07 2010
@@ -47,7 +47,9 @@
return f._CHUNK_SIZE
-class MockRawIO:
+class MockRawIOWithoutRead:
+ """A RawIO implementation without read(), so as to exercise the default
+ RawIO.read() which calls readinto()."""
def __init__(self, read_stack=()):
self._read_stack = list(read_stack)
@@ -55,14 +57,6 @@
self._reads = 0
self._extraneous_reads = 0
- def read(self, n=None):
- self._reads += 1
- try:
- return self._read_stack.pop(0)
- except:
- self._extraneous_reads += 1
- return b""
-
def write(self, b):
self._write_stack.append(bytes(b))
return len(b)
@@ -109,6 +103,23 @@
def truncate(self, pos=None):
return pos
+class CMockRawIOWithoutRead(MockRawIOWithoutRead, io.RawIOBase):
+ pass
+
+class PyMockRawIOWithoutRead(MockRawIOWithoutRead, pyio.RawIOBase):
+ pass
+
+
+class MockRawIO(MockRawIOWithoutRead):
+
+ def read(self, n=None):
+ self._reads += 1
+ try:
+ return self._read_stack.pop(0)
+ except:
+ self._extraneous_reads += 1
+ return b""
+
class CMockRawIO(MockRawIO, io.RawIOBase):
pass
@@ -554,6 +565,19 @@
f.close()
self.assertRaises(ValueError, f.flush)
+ def test_RawIOBase_read(self):
+ # Exercise the default RawIOBase.read() implementation (which calls
+ # readinto() internally).
+ rawio = self.MockRawIOWithoutRead((b"abc", b"d", None, b"efg", None))
+ self.assertEqual(rawio.read(2), b"ab")
+ self.assertEqual(rawio.read(2), b"c")
+ self.assertEqual(rawio.read(2), b"d")
+ self.assertEqual(rawio.read(2), None)
+ self.assertEqual(rawio.read(2), b"ef")
+ self.assertEqual(rawio.read(2), b"g")
+ self.assertEqual(rawio.read(2), None)
+ self.assertEqual(rawio.read(2), b"")
+
class CIOTest(IOTest):
pass
@@ -2557,7 +2581,7 @@
# Put the namespaces of the IO module we are testing and some useful mock
# classes in the __dict__ of each test.
mocks = (MockRawIO, MisbehavedRawIO, MockFileIO, CloseFailureIO,
- MockNonBlockWriterIO)
+ MockNonBlockWriterIO, MockRawIOWithoutRead)
all_members = io.__all__ + ["IncrementalNewlineDecoder"]
c_io_ns = {name : getattr(io, name) for name in all_members}
py_io_ns = {name : getattr(pyio, name) for name in all_members}
Modified: python/branches/release31-maint/Misc/NEWS
==============================================================================
--- python/branches/release31-maint/Misc/NEWS (original)
+++ python/branches/release31-maint/Misc/NEWS Tue Sep 14 20:53:07 2010
@@ -117,6 +117,9 @@
Library
-------
+- Issue #9854: The default read() implementation in io.RawIOBase now
+ handles non-blocking readinto() returning None correctly.
+
- Issue #9853: Fix the signature of SSLSocket.recvfrom() and
SSLSocket.sendto() to match the corresponding socket methods.
Modified: python/branches/release31-maint/Modules/_io/iobase.c
==============================================================================
--- python/branches/release31-maint/Modules/_io/iobase.c (original)
+++ python/branches/release31-maint/Modules/_io/iobase.c Tue Sep 14 20:53:07 2010
@@ -776,9 +776,9 @@
return NULL;
res = PyObject_CallMethodObjArgs(self, _PyIO_str_readinto, b, NULL);
- if (res == NULL) {
+ if (res == NULL || res == Py_None) {
Py_DECREF(b);
- return NULL;
+ return res;
}
n = PyNumber_AsSsize_t(res, PyExc_ValueError);
From nnorwitz at gmail.com Tue Sep 14 13:11:25 2010
From: nnorwitz at gmail.com (Neal Norwitz)
Date: Tue, 14 Sep 2010 07:11:25 -0400
Subject: [Python-checkins] Python Regression Test Failures refleak (1)
Message-ID: <20100914111125.GA32453@kbk-i386-bb.dyndns.org>
More important issues:
----------------------
test_bz2 leaked [-69, 0, 0] references, sum=-69
Less important issues:
----------------------
From python-checkins at python.org Tue Sep 14 21:40:15 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Tue, 14 Sep 2010 21:40:15 +0200 (CEST)
Subject: [Python-checkins] r84818 - python/branches/py3k/Lib/collections.py
Message-ID: <20100914194015.5AE4EEE9B6@mail.python.org>
Author: raymond.hettinger
Date: Tue Sep 14 21:40:15 2010
New Revision: 84818
Log:
Improve iteration speed by only proxying back links.
The forward links are hard references.
The sentinel element is also a weakref proxy
(to break a forward cylce wrapping around the sentinel).
Modified:
python/branches/py3k/Lib/collections.py
Modified: python/branches/py3k/Lib/collections.py
==============================================================================
--- python/branches/py3k/Lib/collections.py (original)
+++ python/branches/py3k/Lib/collections.py Tue Sep 14 21:40:15 2010
@@ -32,6 +32,7 @@
# The internal self.__map dictionary maps keys to links in a doubly linked list.
# The circular doubly linked list starts and ends with a sentinel element.
# The sentinel element never gets deleted (this simplifies the algorithm).
+ # The sentinel is stored in self.__hardroot with a weakref proxy in self.__root.
# The prev/next links are weakref proxies (to prevent circular references).
# Individual links are kept alive by the hard reference in self.__map.
# Those hard references disappear when a key is deleted from an OrderedDict.
@@ -47,7 +48,8 @@
try:
self.__root
except AttributeError:
- self.__root = root = _Link() # sentinel node for the doubly linked list
+ self.__hardroot = _Link()
+ self.__root = root = _proxy(self.__hardroot)
root.prev = root.next = root
self.__map = {}
self.update(*args, **kwds)
@@ -62,8 +64,9 @@
root = self.__root
last = root.prev
link.prev, link.next, link.key = last, root, key
- last.next = root.prev = proxy(link)
- dict.__setitem__(self, key, value)
+ last.next = link
+ root.prev = proxy(link)
+ dict_setitem(self, key, value)
def __delitem__(self, key, dict_delitem=dict.__delitem__):
'od.__delitem__(y) <==> del od[y]'
@@ -97,10 +100,10 @@
def __reduce__(self):
'Return state information for pickling'
items = [[k, self[k]] for k in self]
- tmp = self.__map, self.__root
- del self.__map, self.__root
+ tmp = self.__map, self.__root, self.__hardroot
+ del self.__map, self.__root, self.__hardroot
inst_dict = vars(self).copy()
- self.__map, self.__root = tmp
+ self.__map, self.__root, self.__hardroot = tmp
if inst_dict:
return (self.__class__, (items,), inst_dict)
return self.__class__, (items,)
From python-checkins at python.org Tue Sep 14 21:41:23 2010
From: python-checkins at python.org (brett.cannon)
Date: Tue, 14 Sep 2010 21:41:23 +0200 (CEST)
Subject: [Python-checkins] r84819 - in python/branches/py3k: Misc/NEWS
setup.py
Message-ID: <20100914194123.5A95AFAAC@mail.python.org>
Author: brett.cannon
Date: Tue Sep 14 21:41:23 2010
New Revision: 84819
Log:
setup.py was trying to build _weakref which is redundant as it's a built-in
module.
Closes issue #9848. Thanks to Arfrever Frehtes Taifersar Arahesis for the bug
report.
Modified:
python/branches/py3k/Misc/NEWS
python/branches/py3k/setup.py
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS (original)
+++ python/branches/py3k/Misc/NEWS Tue Sep 14 21:41:23 2010
@@ -183,6 +183,9 @@
Build
-----
+- Issue #9848: Stopping trying to build _weakref in setup.py as it is a
+ built-in module.
+
- Issue #9806: python-config now has an ``--extension-suffix`` option that
outputs the suffix for dynamic libraries including the ABI version name
defined by PEP 3149.
Modified: python/branches/py3k/setup.py
==============================================================================
--- python/branches/py3k/setup.py (original)
+++ python/branches/py3k/setup.py Tue Sep 14 21:41:23 2010
@@ -456,9 +456,6 @@
# on pretty much any POSIXish platform.
#
- # Some modules that are normally always on:
- exts.append( Extension('_weakref', ['_weakref.c']) )
-
# array objects
exts.append( Extension('array', ['arraymodule.c']) )
# complex math library functions
From python-checkins at python.org Tue Sep 14 23:24:25 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Tue, 14 Sep 2010 23:24:25 +0200 (CEST)
Subject: [Python-checkins] r84820 -
python/branches/py3k/Lib/test/test_socket.py
Message-ID: <20100914212425.D1709EE9EC@mail.python.org>
Author: antoine.pitrou
Date: Tue Sep 14 23:24:25 2010
New Revision: 84820
Log:
Make testDefaults in test.test_socket.BasicSocketPairTest more reliable.
Modified:
python/branches/py3k/Lib/test/test_socket.py
Modified: python/branches/py3k/Lib/test/test_socket.py
==============================================================================
--- python/branches/py3k/Lib/test/test_socket.py (original)
+++ python/branches/py3k/Lib/test/test_socket.py Tue Sep 14 23:24:25 2010
@@ -815,22 +815,20 @@
def __init__(self, methodName='runTest'):
SocketPairTest.__init__(self, methodName=methodName)
+ def _check_defaults(self, sock):
+ self.assertIsInstance(sock, socket.socket)
+ if hasattr(socket, 'AF_UNIX'):
+ self.assertEqual(sock.family, socket.AF_UNIX)
+ else:
+ self.assertEqual(sock.family, socket.AF_INET)
+ self.assertEqual(sock.type, socket.SOCK_STREAM)
+ self.assertEqual(sock.proto, 0)
+
def _testDefaults(self):
- pass
+ self._check_defaults(self.cli)
def testDefaults(self):
- self.assertIsInstance(self.cli, socket.socket)
- self.assertIsInstance(self.serv, socket.socket)
- if hasattr(socket, 'AF_UNIX'):
- self.assertEqual(self.cli.family, socket.AF_UNIX)
- self.assertEqual(self.serv.family, socket.AF_UNIX)
- else:
- self.assertEqual(self.cli.family, socket.AF_INET)
- self.assertEqual(self.serv.family, socket.AF_INET)
- self.assertEqual(self.cli.type, socket.SOCK_STREAM)
- self.assertEqual(self.serv.type, socket.SOCK_STREAM)
- self.assertEqual(self.cli.proto, 0)
- self.assertEqual(self.serv.proto, 0)
+ self._check_defaults(self.serv)
def testRecv(self):
msg = self.serv.recv(1024)
From python-checkins at python.org Wed Sep 15 00:55:13 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 15 Sep 2010 00:55:13 +0200 (CEST)
Subject: [Python-checkins] r84821 - python/branches/py3k/Lib/functools.py
Message-ID: <20100914225513.F38C1EE982@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 15 00:55:13 2010
New Revision: 84821
Log:
Future proof total_ordering against changes in methods defined on object.
Modified:
python/branches/py3k/Lib/functools.py
Modified: python/branches/py3k/Lib/functools.py
==============================================================================
--- python/branches/py3k/Lib/functools.py (original)
+++ python/branches/py3k/Lib/functools.py Wed Sep 15 00:55:13 2010
@@ -82,7 +82,7 @@
('__lt__', lambda self, other: not self >= other)]
}
# Find comparisons not inherited from object.
- roots = [op for op in convert if getattr(cls, op) is not getattr(object, op)]
+ roots = [op for op in convert if getattr(cls, op, None) is not getattr(object, op, None)]
if not roots:
raise ValueError('must define at least one ordering operation: < > <= >=')
root = max(roots) # prefer __lt__ to __le__ to __gt__ to __ge__
From python-checkins at python.org Wed Sep 15 01:13:42 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 15 Sep 2010 01:13:42 +0200 (CEST)
Subject: [Python-checkins] r84822 -
python/branches/py3k/Doc/library/functions.rst
Message-ID: <20100914231342.4B430EE98D@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 15 01:13:42 2010
New Revision: 84822
Log:
Issue 9802: Document min()/max() sort stability
Modified:
python/branches/py3k/Doc/library/functions.rst
Modified: python/branches/py3k/Doc/library/functions.rst
==============================================================================
--- python/branches/py3k/Doc/library/functions.rst (original)
+++ python/branches/py3k/Doc/library/functions.rst Wed Sep 15 01:13:42 2010
@@ -634,6 +634,10 @@
The optional keyword-only *key* argument specifies a one-argument ordering
function like that used for :meth:`list.sort`.
+ If multiple items are maximal, the function returns the first one encountered.
+ This is consistent with other sort-stability preserving tools such as
+ ``sorted(iterable, key=keyfunc, reverse=True)[0]` and
+ ``heapq.nlargest(1, iterable, key=keyfunc)``.
.. function:: memoryview(obj)
:noindex:
@@ -651,6 +655,10 @@
The optional keyword-only *key* argument specifies a one-argument ordering
function like that used for :meth:`list.sort`.
+ If multiple items are minimal, the function returns the first one encountered.
+ This is consistent with other sort-stability preserving tools such as
+ ``sorted(iterable, key=keyfunc)[0]` and
+ ``heapq.nsmallest(1, iterable, key=keyfunc)``.
.. function:: next(iterator[, default])
From python-checkins at python.org Wed Sep 15 02:09:26 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 15 Sep 2010 02:09:26 +0200 (CEST)
Subject: [Python-checkins] r84823 -
python/branches/py3k/Doc/reference/expressions.rst
Message-ID: <20100915000926.8AFF3EE9B1@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 15 02:09:26 2010
New Revision: 84823
Log:
Clarify where support for negative indices fall in the language hierarchy.
Modified:
python/branches/py3k/Doc/reference/expressions.rst
Modified: python/branches/py3k/Doc/reference/expressions.rst
==============================================================================
--- python/branches/py3k/Doc/reference/expressions.rst (original)
+++ python/branches/py3k/Doc/reference/expressions.rst Wed Sep 15 02:09:26 2010
@@ -518,11 +518,18 @@
value in the mapping that corresponds to that key. (The expression list is a
tuple except if it has exactly one item.)
-If the primary is a sequence, the expression (list) must evaluate to an integer.
-If this value is negative, the length of the sequence is added to it (so that,
-e.g., ``x[-1]`` selects the last item of ``x``.) The resulting value must be a
-nonnegative integer less than the number of items in the sequence, and the
-subscription selects the item whose index is that value (counting from zero).
+If the primary is a sequence, the expression (list) must evaluate to an integer
+or a slice (as discussed in the following section).
+
+The formal syntax makes no special provision for negative indices in
+sequences; however, built-in sequences all provide a :meth:`__getitem__`
+method that interprets negative indices by adding the length of the sequence
+to the index (so that ``x[-1]`` selects the last item of ``x``). The
+resulting value must be a nonnegative integer less than the number of items in
+the sequence, and the subscription selects the item whose index is that value
+(counting from zero). Since the support for negative indices and slicing
+occurs in the object's :meth:`__getitem__` method, subclasses overriding
+this method will need to explicitly add that support.
.. index::
single: character
From python-checkins at python.org Wed Sep 15 02:12:05 2010
From: python-checkins at python.org (raymond.hettinger)
Date: Wed, 15 Sep 2010 02:12:05 +0200 (CEST)
Subject: [Python-checkins] r84824 -
python/branches/release31-maint/Doc/reference/expressions.rst
Message-ID: <20100915001205.5510AF89C@mail.python.org>
Author: raymond.hettinger
Date: Wed Sep 15 02:12:05 2010
New Revision: 84824
Log:
Clarify where support for negative indices fall in the language hierarchy.
Modified:
python/branches/release31-maint/Doc/reference/expressions.rst
Modified: python/branches/release31-maint/Doc/reference/expressions.rst
==============================================================================
--- python/branches/release31-maint/Doc/reference/expressions.rst (original)
+++ python/branches/release31-maint/Doc/reference/expressions.rst Wed Sep 15 02:12:05 2010
@@ -518,11 +518,18 @@
value in the mapping that corresponds to that key. (The expression list is a
tuple except if it has exactly one item.)
-If the primary is a sequence, the expression (list) must evaluate to an integer.
-If this value is negative, the length of the sequence is added to it (so that,
-e.g., ``x[-1]`` selects the last item of ``x``.) The resulting value must be a
-nonnegative integer less than the number of items in the sequence, and the
-subscription selects the item whose index is that value (counting from zero).
+If the primary is a sequence, the expression (list) must evaluate to an integer
+or a slice (as discussed in the following section).
+
+The formal syntax makes no special provision for negative indices in
+sequences; however, built-in sequences all provide a :meth:`__getitem__`
+method that interprets negative indices by adding the length of the sequence
+to the index (so that ``x[-1]`` selects the last item of ``x``). The
+resulting value must be a nonnegative integer less than the number of items in
+the sequence, and the subscription selects the item whose index is that value
+(counting from zero). Since the support for negative indices and slicing
+occurs in the object's :meth:`__getitem__` method, subclasses overriding
+this method will need to explicitly add that support.
.. index::
single: character
From solipsis at pitrou.net Wed Sep 15 05:09:27 2010
From: solipsis at pitrou.net (solipsis at pitrou.net)
Date: Wed, 15 Sep 2010 05:09:27 +0200
Subject: [Python-checkins] Daily py3k reference leaks (r84823): sum=0
Message-ID:
py3k results for svn r84823 (hg cset 175a1d16210b)
--------------------------------------------------
Command line was: ['./python', '-m', 'test.regrtest', '-uall', '-R', '3:3:/home/antoine/py3k/refleaks/reflogL6YDRg', '-x']
From python-checkins at python.org Wed Sep 15 10:39:25 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 10:39:25 +0200 (CEST)
Subject: [Python-checkins] r84825 - python/branches/py3k/Lib/socket.py
Message-ID: <20100915083925.3B3E7EE989@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 10:39:25 2010
New Revision: 84825
Log:
Add a comment explaining why SocketIO is needed
Modified:
python/branches/py3k/Lib/socket.py
Modified: python/branches/py3k/Lib/socket.py
==============================================================================
--- python/branches/py3k/Lib/socket.py (original)
+++ python/branches/py3k/Lib/socket.py Wed Sep 15 10:39:25 2010
@@ -228,6 +228,13 @@
the raw I/O interface on top of a socket object.
"""
+ # One might wonder why not let FileIO do the job instead. There are two
+ # main reasons why FileIO is not adapted:
+ # - it wouldn't work under Windows (where you can't used read() and
+ # write() on a socket handle)
+ # - it wouldn't work with socket timeouts (FileIO would ignore the
+ # timeout and consider the socket non-blocking)
+
# XXX More docs
def __init__(self, sock, mode):
From python-checkins at python.org Wed Sep 15 11:32:45 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 11:32:45 +0200 (CEST)
Subject: [Python-checkins] r84826 - in python/branches/py3k:
Doc/library/socket.rst Lib/socket.py
Message-ID: <20100915093245.76BECEE98A@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 11:32:45 2010
New Revision: 84826
Log:
Improve docs for socket.makefile() and SocketIO
Modified:
python/branches/py3k/Doc/library/socket.rst
python/branches/py3k/Lib/socket.py
Modified: python/branches/py3k/Doc/library/socket.rst
==============================================================================
--- python/branches/py3k/Doc/library/socket.rst (original)
+++ python/branches/py3k/Doc/library/socket.rst Wed Sep 15 11:32:45 2010
@@ -622,10 +622,9 @@
arguments are interpreted the same way as by the built-in :func:`open`
function.
- The returned file object references a :cfunc:`dup`\ ped version of the
- socket file descriptor, so the file object and socket object may be
- closed or garbage-collected independently. The socket must be in
- blocking mode (it can not have a timeout).
+ Closing the file object won't close the socket unless there are no
+ remaining references to the socket. The socket must be in blocking mode
+ (it can not have a timeout).
.. method:: socket.recv(bufsize[, flags])
Modified: python/branches/py3k/Lib/socket.py
==============================================================================
--- python/branches/py3k/Lib/socket.py (original)
+++ python/branches/py3k/Lib/socket.py Wed Sep 15 11:32:45 2010
@@ -54,6 +54,8 @@
errno = None
EBADF = getattr(errno, 'EBADF', 9)
EINTR = getattr(errno, 'EINTR', 4)
+EAGAIN = getattr(errno, 'EAGAIN', 11)
+EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11)
__all__ = ["getfqdn", "create_connection"]
__all__.extend(os._get_exports_list(_socket))
@@ -249,6 +251,13 @@
self._writing = "w" in mode
def readinto(self, b):
+ """Read up to len(b) bytes into the writable buffer *b* and return
+ the number of bytes read. If the socket is non-blocking and no bytes
+ are available, None is returned.
+
+ If *b* is non-empty, a 0 return value indicates that the connection
+ was shutdown at the other end.
+ """
self._checkClosed()
self._checkReadable()
while True:
@@ -260,17 +269,28 @@
raise
def write(self, b):
+ """Write the given bytes or bytearray object *b* to the socket
+ and return the number of bytes written. This can be less than
+ len(b) if not all data could be written. If the socket is
+ non-blocking and no bytes could be written None is returned.
+ """
self._checkClosed()
self._checkWritable()
return self._sock.send(b)
def readable(self):
+ """True if the SocketIO is open for reading.
+ """
return self._reading and not self.closed
def writable(self):
+ """True if the SocketIO is open for writing.
+ """
return self._writing and not self.closed
def fileno(self):
+ """Return the file descriptor of the underlying socket.
+ """
self._checkClosed()
return self._sock.fileno()
@@ -283,6 +303,9 @@
return self._mode
def close(self):
+ """Close the SocketIO object. This doesn't close the underlying
+ socket, except if all references to it have disappeared.
+ """
if self.closed:
return
io.RawIOBase.close(self)
From python-checkins at python.org Wed Sep 15 11:58:26 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 11:58:26 +0200 (CEST)
Subject: [Python-checkins] r84827 - in python/branches/py3k/Doc:
glossary.rst library/socket.rst reference/datamodel.rst
Message-ID: <20100915095827.00B3AEE989@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 11:58:26 2010
New Revision: 84827
Log:
Add a glossary entry for file objects.
Modified:
python/branches/py3k/Doc/glossary.rst
python/branches/py3k/Doc/library/socket.rst
python/branches/py3k/Doc/reference/datamodel.rst
Modified: python/branches/py3k/Doc/glossary.rst
==============================================================================
--- python/branches/py3k/Doc/glossary.rst (original)
+++ python/branches/py3k/Doc/glossary.rst Wed Sep 15 11:58:26 2010
@@ -184,6 +184,23 @@
A module written in C or C++, using Python's C API to interact with the core and
with user code.
+ file object
+ An object exposing a file-oriented API (with methods such as
+ :meth:`read()` or :meth:`write()`) to an underlying resource.
+ Depending on the way it was created, a file object can mediate access
+ to a real on-disk file or to another other type of storage or
+ communication device (for example standard input/output, in-memory
+ buffers, sockets, pipes, etc.). File objects are also called
+ :dfn:`file-like objects` or :dfn:`streams`.
+
+ There are actually three categories of file objects: raw binary
+ files, buffered binary files and text files. Their interfaces are
+ defined in the :mod:`io` module. The canonical way to create a
+ file object is by using the :func:`open` function.
+
+ file-like object
+ A synonym for :term:`file object`.
+
finder
An object that tries to find the :term:`loader` for a module. It must
implement a method named :meth:`find_module`. See :pep:`302` for
Modified: python/branches/py3k/Doc/library/socket.rst
==============================================================================
--- python/branches/py3k/Doc/library/socket.rst (original)
+++ python/branches/py3k/Doc/library/socket.rst Wed Sep 15 11:58:26 2010
@@ -617,7 +617,7 @@
.. index:: single: I/O control; buffering
- Return a :dfn:`file object` associated with the socket. The exact
+ Return a :term:`file object` associated with the socket. The exact
returned type depends on the arguments given to :meth:`makefile`. These
arguments are interpreted the same way as by the built-in :func:`open`
function.
Modified: python/branches/py3k/Doc/reference/datamodel.rst
==============================================================================
--- python/branches/py3k/Doc/reference/datamodel.rst (original)
+++ python/branches/py3k/Doc/reference/datamodel.rst Wed Sep 15 11:58:26 2010
@@ -781,9 +781,9 @@
single: stdout (in module sys)
single: stderr (in module sys)
- A file object represents an open file. Various shortcuts are available
- to create file objects: the :func:`open` built-in function, and also
- :func:`os.popen`, :func:`os.fdopen`, and the :meth:`makefile` method
+ A :term:`file object` represents an open file. Various shortcuts are
+ available to create file objects: the :func:`open` built-in function, and
+ also :func:`os.popen`, :func:`os.fdopen`, and the :meth:`makefile` method
of socket objects (and perhaps by other functions or methods provided
by extension modules).
From python-checkins at python.org Wed Sep 15 12:08:31 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 12:08:31 +0200 (CEST)
Subject: [Python-checkins] r84828 - python/branches/py3k/Doc/faq/library.rst
Message-ID: <20100915100831.AE327EE98A@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 12:08:31 2010
New Revision: 84828
Log:
Update file-related information in the FAQ.
Modified:
python/branches/py3k/Doc/faq/library.rst
Modified: python/branches/py3k/Doc/faq/library.rst
==============================================================================
--- python/branches/py3k/Doc/faq/library.rst (original)
+++ python/branches/py3k/Doc/faq/library.rst Wed Sep 15 12:08:31 2010
@@ -458,7 +458,7 @@
To rename a file, use ``os.rename(old_path, new_path)``.
-To truncate a file, open it using ``f = open(filename, "r+")``, and use
+To truncate a file, open it using ``f = open(filename, "rb+")``, and use
``f.truncate(offset)``; offset defaults to the current seek position. There's
also ```os.ftruncate(fd, offset)`` for files opened with :func:`os.open`, where
``fd`` is the file descriptor (a small integer).
@@ -487,9 +487,9 @@
import struct
- f = open(filename, "rb") # Open in binary mode for portability
- s = f.read(8)
- x, y, z = struct.unpack(">hhl", s)
+ with open(filename, "rb") as f:
+ s = f.read(8)
+ x, y, z = struct.unpack(">hhl", s)
The '>' in the format string forces big-endian data; the letter 'h' reads one
"short integer" (2 bytes), and 'l' reads one "long integer" (4 bytes) from the
@@ -498,6 +498,13 @@
For data that is more regular (e.g. a homogeneous list of ints or thefloats),
you can also use the :mod:`array` module.
+ .. note::
+ To read and write binary data, it is mandatory to open the file in
+ binary mode (here, passing ``"rb"`` to :func:`open`). If you use
+ ``"r"`` instead (the default), the file will be open in text mode
+ and ``f.read()`` will return :class:`str` objects rather than
+ :class:`bytes` objects.
+
I can't seem to use os.read() on a pipe created with os.popen(); why?
---------------------------------------------------------------------
@@ -603,28 +610,29 @@
Why doesn't closing sys.stdout (stdin, stderr) really close it?
---------------------------------------------------------------
-Python file objects are a high-level layer of abstraction on top of C streams,
-which in turn are a medium-level layer of abstraction on top of (among other
-things) low-level C file descriptors.
-
-For most file objects you create in Python via the built-in ``open``
-constructor, ``f.close()`` marks the Python file object as being closed from
-Python's point of view, and also arranges to close the underlying C stream.
-This also happens automatically in ``f``'s destructor, when ``f`` becomes
-garbage.
+Python :term:`file objects ` are a high-level layer of
+abstraction on low-level C file descriptors.
+
+For most file objects you create in Python via the built-in :func:`open`
+function, ``f.close()`` marks the Python file object as being closed from
+Python's point of view, and also arranges to close the underlying C file
+descriptor. This also happens automatically in ``f``'s destructor, when
+``f`` becomes garbage.
But stdin, stdout and stderr are treated specially by Python, because of the
special status also given to them by C. Running ``sys.stdout.close()`` marks
the Python-level file object as being closed, but does *not* close the
-associated C stream.
+associated C file descriptor.
+
+To close the underlying C file descriptor for one of these three, you should
+first be sure that's what you really want to do (e.g., you may confuse
+extension modules trying to do I/O). If it is, use :func:`os.close`::
+
+ os.close(stdin.fileno())
+ os.close(stdout.fileno())
+ os.close(stderr.fileno())
-To close the underlying C stream for one of these three, you should first be
-sure that's what you really want to do (e.g., you may confuse extension modules
-trying to do I/O). If it is, use os.close::
-
- os.close(0) # close C's stdin stream
- os.close(1) # close C's stdout stream
- os.close(2) # close C's stderr stream
+Or you can use the numeric constants 0, 1 and 2, respectively.
Network/Internet Programming
From python-checkins at python.org Wed Sep 15 13:11:28 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 13:11:28 +0200 (CEST)
Subject: [Python-checkins] r84829 - in python/branches/py3k/Doc:
faq/design.rst library/aifc.rst library/array.rst
library/asyncore.rst library/base64.rst library/bz2.rst
library/configparser.rst library/csv.rst
library/email.generator.rst library/email.parser.rst
library/exceptions.rst library/filesys.rst
library/formatter.rst library/ftplib.rst library/gettext.rst
library/gzip.rst library/http.client.rst library/imp.rst
library/mmap.rst library/nntplib.rst library/os.rst
library/pickle.rst library/quopri.rst library/select.rst
library/stdtypes.rst library/subprocess.rst library/sys.rst
library/tarfile.rst library/tempfile.rst library/termios.rst
library/weakref.rst library/xml.etree.elementtree.rst
tutorial/inputoutput.rst
Message-ID: <20100915111128.CF78EEE989@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 13:11:28 2010
New Revision: 84829
Log:
Add cross-references to the glossary entry for file objects.
Modified:
python/branches/py3k/Doc/faq/design.rst
python/branches/py3k/Doc/library/aifc.rst
python/branches/py3k/Doc/library/array.rst
python/branches/py3k/Doc/library/asyncore.rst
python/branches/py3k/Doc/library/base64.rst
python/branches/py3k/Doc/library/bz2.rst
python/branches/py3k/Doc/library/configparser.rst
python/branches/py3k/Doc/library/csv.rst
python/branches/py3k/Doc/library/email.generator.rst
python/branches/py3k/Doc/library/email.parser.rst
python/branches/py3k/Doc/library/exceptions.rst
python/branches/py3k/Doc/library/filesys.rst
python/branches/py3k/Doc/library/formatter.rst
python/branches/py3k/Doc/library/ftplib.rst
python/branches/py3k/Doc/library/gettext.rst
python/branches/py3k/Doc/library/gzip.rst
python/branches/py3k/Doc/library/http.client.rst
python/branches/py3k/Doc/library/imp.rst
python/branches/py3k/Doc/library/mmap.rst
python/branches/py3k/Doc/library/nntplib.rst
python/branches/py3k/Doc/library/os.rst
python/branches/py3k/Doc/library/pickle.rst
python/branches/py3k/Doc/library/quopri.rst
python/branches/py3k/Doc/library/select.rst
python/branches/py3k/Doc/library/stdtypes.rst
python/branches/py3k/Doc/library/subprocess.rst
python/branches/py3k/Doc/library/sys.rst
python/branches/py3k/Doc/library/tarfile.rst
python/branches/py3k/Doc/library/tempfile.rst
python/branches/py3k/Doc/library/termios.rst
python/branches/py3k/Doc/library/weakref.rst
python/branches/py3k/Doc/library/xml.etree.elementtree.rst
python/branches/py3k/Doc/tutorial/inputoutput.rst
Modified: python/branches/py3k/Doc/faq/design.rst
==============================================================================
--- python/branches/py3k/Doc/faq/design.rst (original)
+++ python/branches/py3k/Doc/faq/design.rst Wed Sep 15 13:11:28 2010
@@ -210,8 +210,8 @@
is hidden at the bottom of the loop.
The best approach is to use iterators, making it possible to loop through
-objects using the ``for`` statement. For example, in the current version of
-Python file objects support the iterator protocol, so you can now write simply::
+objects using the ``for`` statement. For example, :term:`file objects
+` support the iterator protocol, so you can write simply::
for line in f:
... # do something with line...
Modified: python/branches/py3k/Doc/library/aifc.rst
==============================================================================
--- python/branches/py3k/Doc/library/aifc.rst (original)
+++ python/branches/py3k/Doc/library/aifc.rst Wed Sep 15 13:11:28 2010
@@ -40,10 +40,10 @@
.. function:: open(file, mode=None)
Open an AIFF or AIFF-C file and return an object instance with methods that are
- described below. The argument *file* is either a string naming a file or a file
- object. *mode* must be ``'r'`` or ``'rb'`` when the file must be opened for
- reading, or ``'w'`` or ``'wb'`` when the file must be opened for writing. If
- omitted, ``file.mode`` is used if it exists, otherwise ``'rb'`` is used. When
+ described below. The argument *file* is either a string naming a file or a
+ :term:`file object`. *mode* must be ``'r'`` or ``'rb'`` when the file must be
+ opened for reading, or ``'w'`` or ``'wb'`` when the file must be opened for writing.
+ If omitted, ``file.mode`` is used if it exists, otherwise ``'rb'`` is used. When
used for writing, the file object should be seekable, unless you know ahead of
time how many samples you are going to write in total and use
:meth:`writeframesraw` and :meth:`setnframes`.
Modified: python/branches/py3k/Doc/library/array.rst
==============================================================================
--- python/branches/py3k/Doc/library/array.rst (original)
+++ python/branches/py3k/Doc/library/array.rst Wed Sep 15 13:11:28 2010
@@ -147,11 +147,11 @@
.. method:: array.fromfile(f, n)
- Read *n* items (as machine values) from the file object *f* and append them to
- the end of the array. If less than *n* items are available, :exc:`EOFError` is
- raised, but the items that were available are still inserted into the array.
- *f* must be a real built-in file object; something else with a :meth:`read`
- method won't do.
+ Read *n* items (as machine values) from the :term:`file object` *f* and append
+ them to the end of the array. If less than *n* items are available,
+ :exc:`EOFError` is raised, but the items that were available are still
+ inserted into the array. *f* must be a real built-in file object; something
+ else with a :meth:`read` method won't do.
.. method:: array.fromlist(list)
@@ -214,7 +214,7 @@
.. method:: array.tofile(f)
- Write all items (as machine values) to the file object *f*.
+ Write all items (as machine values) to the :term:`file object` *f*.
.. method:: array.tolist()
Modified: python/branches/py3k/Doc/library/asyncore.rst
==============================================================================
--- python/branches/py3k/Doc/library/asyncore.rst (original)
+++ python/branches/py3k/Doc/library/asyncore.rst Wed Sep 15 13:11:28 2010
@@ -225,9 +225,9 @@
.. class:: file_dispatcher()
- A file_dispatcher takes a file descriptor or file object along with an
- optional map argument and wraps it for use with the :cfunc:`poll` or
- :cfunc:`loop` functions. If provided a file object or anything with a
+ A file_dispatcher takes a file descriptor or :term:`file object` along
+ with an optional map argument and wraps it for use with the :cfunc:`poll`
+ or :cfunc:`loop` functions. If provided a file object or anything with a
:cfunc:`fileno` method, that method will be called and passed to the
:class:`file_wrapper` constructor. Availability: UNIX.
Modified: python/branches/py3k/Doc/library/base64.rst
==============================================================================
--- python/branches/py3k/Doc/library/base64.rst (original)
+++ python/branches/py3k/Doc/library/base64.rst Wed Sep 15 13:11:28 2010
@@ -122,9 +122,9 @@
.. function:: decode(input, output)
Decode the contents of the binary *input* file and write the resulting binary
- data to the *output* file. *input* and *output* must either be file objects
- or objects that mimic the file object interface working with bytes
- objects. *input* will be read until ``input.read()`` returns an empty string.
+ data to the *output* file. *input* and *output* must be :term:`file objects
+ `. *input* will be read until ``input.read()`` returns an empty
+ bytes object.
.. function:: decodebytes(s)
@@ -138,11 +138,10 @@
.. function:: encode(input, output)
Encode the contents of the binary *input* file and write the resulting base64
- encoded data to the *output* file. *input* and *output* must either be file
- objects or objects that mimic the file object interface working with bytes
- objects. *input* will be read until ``input.read()`` returns an empty string.
- :func:`encode` returns the encoded data plus a trailing newline character
- (``b'\n'``).
+ encoded data to the *output* file. *input* and *output* must be :term:`file
+ objects `. *input* will be read until ``input.read()`` returns
+ an empty bytes object. :func:`encode` returns the encoded data plus a trailing
+ newline character (``b'\n'``).
.. function:: encodebytes(s)
Modified: python/branches/py3k/Doc/library/bz2.rst
==============================================================================
--- python/branches/py3k/Doc/library/bz2.rst (original)
+++ python/branches/py3k/Doc/library/bz2.rst Wed Sep 15 13:11:28 2010
@@ -25,8 +25,8 @@
* :class:`BZ2File` class implements universal newline support;
-* :class:`BZ2File` class offers an optimized line iteration using the readahead
- algorithm borrowed from file objects;
+* :class:`BZ2File` class offers an optimized line iteration using a readahead
+ algorithm;
* Sequential (de)compression supported by :class:`BZ2Compressor` and
:class:`BZ2Decompressor` classes;
Modified: python/branches/py3k/Doc/library/configparser.rst
==============================================================================
--- python/branches/py3k/Doc/library/configparser.rst (original)
+++ python/branches/py3k/Doc/library/configparser.rst Wed Sep 15 13:11:28 2010
@@ -422,7 +422,7 @@
.. method:: RawConfigParser.write(fileobject, space_around_delimiters=True)
- Write a representation of the configuration to the specified file object,
+ Write a representation of the configuration to the specified :term:`file object`,
which must be opened in text mode (accepting strings). This representation
can be parsed by a future :meth:`read` call. If ``space_around_delimiters``
is ``True`` (the default), delimiters between keys and values are surrounded
Modified: python/branches/py3k/Doc/library/csv.rst
==============================================================================
--- python/branches/py3k/Doc/library/csv.rst (original)
+++ python/branches/py3k/Doc/library/csv.rst Wed Sep 15 13:11:28 2010
@@ -50,9 +50,9 @@
Return a reader object which will iterate over lines in the given *csvfile*.
*csvfile* can be any object which supports the :term:`iterator` protocol and returns a
- string each time its :meth:`!next` method is called --- file objects and list
- objects are both suitable. If *csvfile* is a file object, it should be opened
- with ``newline=''``. [#]_ An optional
+ string each time its :meth:`!next` method is called --- :term:`file objects
+ ` and list objects are both suitable. If *csvfile* is a file object,
+ it should be opened with ``newline=''``. [#]_ An optional
*dialect* parameter can be given which is used to define a set of parameters
specific to a particular CSV dialect. It may be an instance of a subclass of
the :class:`Dialect` class or one of the strings returned by the
Modified: python/branches/py3k/Doc/library/email.generator.rst
==============================================================================
--- python/branches/py3k/Doc/library/email.generator.rst (original)
+++ python/branches/py3k/Doc/library/email.generator.rst Wed Sep 15 13:11:28 2010
@@ -28,9 +28,9 @@
.. class:: Generator(outfp, mangle_from_=True, maxheaderlen=78)
- The constructor for the :class:`Generator` class takes a file-like object called
- *outfp* for an argument. *outfp* must support the :meth:`write` method and be
- usable as the output file for the :func:`print` function.
+ The constructor for the :class:`Generator` class takes a :term:`file-like object`
+ called *outfp* for an argument. *outfp* must support the :meth:`write` method
+ and be usable as the output file for the :func:`print` function.
Optional *mangle_from_* is a flag that, when ``True``, puts a ``>`` character in
front of any line in the body that starts exactly as ``From``, i.e. ``From``
Modified: python/branches/py3k/Doc/library/email.parser.rst
==============================================================================
--- python/branches/py3k/Doc/library/email.parser.rst (original)
+++ python/branches/py3k/Doc/library/email.parser.rst Wed Sep 15 13:11:28 2010
@@ -154,9 +154,9 @@
.. function:: message_from_file(fp[, _class][, strict])
- Return a message object structure tree from an open file object. This is
- exactly equivalent to ``Parser().parse(fp)``. Optional *_class* and *strict*
- are interpreted as with the :class:`Parser` class constructor.
+ Return a message object structure tree from an open :term:`file object`.
+ This is exactly equivalent to ``Parser().parse(fp)``. Optional *_class*
+ and *strict* are interpreted as with the :class:`Parser` class constructor.
Here's an example of how you might use this at an interactive Python prompt::
Modified: python/branches/py3k/Doc/library/exceptions.rst
==============================================================================
--- python/branches/py3k/Doc/library/exceptions.rst (original)
+++ python/branches/py3k/Doc/library/exceptions.rst Wed Sep 15 13:11:28 2010
@@ -134,8 +134,8 @@
.. exception:: IOError
Raised when an I/O operation (such as the built-in :func:`print` or
- :func:`open` functions or a method of a file object) fails for an I/O-related
- reason, e.g., "file not found" or "disk full".
+ :func:`open` functions or a method of a :term:`file object`) fails for an
+ I/O-related reason, e.g., "file not found" or "disk full".
This class is derived from :exc:`EnvironmentError`. See the discussion above
for more information on exception instance attributes.
Modified: python/branches/py3k/Doc/library/filesys.rst
==============================================================================
--- python/branches/py3k/Doc/library/filesys.rst (original)
+++ python/branches/py3k/Doc/library/filesys.rst Wed Sep 15 13:11:28 2010
@@ -27,8 +27,8 @@
.. seealso::
Module :mod:`os`
- Operating system interfaces, including functions to work with files at a lower
- level than the built-in file object.
+ Operating system interfaces, including functions to work with files at a
+ lower level than Python :term:`file objects `.
Module :mod:`io`
Python's built-in I/O library, including both abstract classes and
Modified: python/branches/py3k/Doc/library/formatter.rst
==============================================================================
--- python/branches/py3k/Doc/library/formatter.rst (original)
+++ python/branches/py3k/Doc/library/formatter.rst Wed Sep 15 13:11:28 2010
@@ -339,8 +339,8 @@
.. class:: DumbWriter(file=None, maxcol=72)
- Simple writer class which writes output on the file object passed in as *file*
- or, if *file* is omitted, on standard output. The output is simply word-wrapped
- to the number of columns specified by *maxcol*. This class is suitable for
- reflowing a sequence of paragraphs.
+ Simple writer class which writes output on the :term:`file object` passed
+ in as *file* or, if *file* is omitted, on standard output. The output is
+ simply word-wrapped to the number of columns specified by *maxcol*. This
+ class is suitable for reflowing a sequence of paragraphs.
Modified: python/branches/py3k/Doc/library/ftplib.rst
==============================================================================
--- python/branches/py3k/Doc/library/ftplib.rst (original)
+++ python/branches/py3k/Doc/library/ftplib.rst Wed Sep 15 13:11:28 2010
@@ -245,12 +245,12 @@
.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None, rest=None)
Store a file in binary transfer mode. *cmd* should be an appropriate
- ``STOR`` command: ``"STOR filename"``. *file* is an open file object which is
- read until EOF using its :meth:`read` method in blocks of size *blocksize* to
- provide the data to be stored. The *blocksize* argument defaults to 8192.
- *callback* is an optional single parameter callable that is called
- on each block of data after it is sent. *rest* means the same thing as in
- the :meth:`transfercmd` method.
+ ``STOR`` command: ``"STOR filename"``. *file* is an open :term:`file object`
+ which is read until EOF using its :meth:`read` method in blocks of size
+ *blocksize* to provide the data to be stored. The *blocksize* argument
+ defaults to 8192. *callback* is an optional single parameter callable that
+ is called on each block of data after it is sent. *rest* means the same thing
+ as in the :meth:`transfercmd` method.
.. versionchanged:: 3.2
*rest* parameter added.
@@ -260,8 +260,8 @@
Store a file in ASCII transfer mode. *cmd* should be an appropriate
``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the
- open file object *file* using its :meth:`readline` method to provide the data to
- be stored. *callback* is an optional single parameter callable
+ open :term:`file object` *file* using its :meth:`readline` method to provide
+ the data to be stored. *callback* is an optional single parameter callable
that is called on each line after it is sent.
Modified: python/branches/py3k/Doc/library/gettext.rst
==============================================================================
--- python/branches/py3k/Doc/library/gettext.rst (original)
+++ python/branches/py3k/Doc/library/gettext.rst Wed Sep 15 13:11:28 2010
@@ -173,8 +173,8 @@
associated :file:`.mo` file paths. Instances with identical :file:`.mo` file
names are cached. The actual class instantiated is either *class_* if
provided, otherwise :class:`GNUTranslations`. The class's constructor must
- take a single file object argument. If provided, *codeset* will change the
- charset used to encode translated strings in the :meth:`lgettext` and
+ take a single :term:`file object` argument. If provided, *codeset* will change
+ the charset used to encode translated strings in the :meth:`lgettext` and
:meth:`lngettext` methods.
If multiple files are found, later files are used as fallbacks for earlier ones.
@@ -219,7 +219,7 @@
.. class:: NullTranslations(fp=None)
- Takes an optional file object *fp*, which is ignored by the base class.
+ Takes an optional :term:`file object` *fp*, which is ignored by the base class.
Initializes "protected" instance variables *_info* and *_charset* which are set
by derived classes, as well as *_fallback*, which is set through
:meth:`add_fallback`. It then calls ``self._parse(fp)`` if *fp* is not
Modified: python/branches/py3k/Doc/library/gzip.rst
==============================================================================
--- python/branches/py3k/Doc/library/gzip.rst (original)
+++ python/branches/py3k/Doc/library/gzip.rst Wed Sep 15 13:11:28 2010
@@ -9,10 +9,9 @@
The data compression is provided by the :mod:`zlib` module.
-The :mod:`gzip` module provides the :class:`GzipFile` class which is modeled
-after Python's File Object. The :class:`GzipFile` class reads and writes
-:program:`gzip`\ -format files, automatically compressing or decompressing the
-data so that it looks like an ordinary file object.
+The :mod:`gzip` module provides the :class:`GzipFile` class. The :class:`GzipFile`
+class reads and writes :program:`gzip`\ -format files, automatically compressing
+or decompressing the data so that it looks like an ordinary :term:`file object`.
Note that additional file formats which can be decompressed by the
:program:`gzip` and :program:`gunzip` programs, such as those produced by
@@ -27,7 +26,7 @@
.. class:: GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None)
Constructor for the :class:`GzipFile` class, which simulates most of the methods
- of a file object, with the exception of the :meth:`readinto` and
+ of a :term:`file object`, with the exception of the :meth:`readinto` and
:meth:`truncate` methods. At least one of *fileobj* and *filename* must be
given a non-trivial value.
Modified: python/branches/py3k/Doc/library/http.client.rst
==============================================================================
--- python/branches/py3k/Doc/library/http.client.rst (original)
+++ python/branches/py3k/Doc/library/http.client.rst Wed Sep 15 13:11:28 2010
@@ -367,7 +367,7 @@
object. The Content-Length header is set to the length of the
string.
- The *body* may also be an open file object, in which case the
+ The *body* may also be an open :term:`file object`, in which case the
contents of the file is sent; this file object should support
``fileno()`` and ``read()`` methods. The header Content-Length is
automatically set to the length of the file as reported by
Modified: python/branches/py3k/Doc/library/imp.rst
==============================================================================
--- python/branches/py3k/Doc/library/imp.rst (original)
+++ python/branches/py3k/Doc/library/imp.rst Wed Sep 15 13:11:28 2010
@@ -48,8 +48,8 @@
If search is successful, the return value is a 3-element tuple ``(file,
pathname, description)``:
- *file* is an open file object positioned at the beginning, *pathname* is the
- pathname of the file found, and *description* is a 3-element tuple as
+ *file* is an open :term:`file object` positioned at the beginning, *pathname*
+ is the pathname of the file found, and *description* is a 3-element tuple as
contained in the list returned by :func:`get_suffixes` describing the kind of
module found.
Modified: python/branches/py3k/Doc/library/mmap.rst
==============================================================================
--- python/branches/py3k/Doc/library/mmap.rst (original)
+++ python/branches/py3k/Doc/library/mmap.rst Wed Sep 15 13:11:28 2010
@@ -5,14 +5,13 @@
:synopsis: Interface to memory-mapped files for Unix and Windows.
-Memory-mapped file objects behave like both :class:`bytes` and like file
-objects. Unlike normal :class:`bytes` objects, however, these are mutable.
-You can use mmap objects in most places where :class:`bytes` are expected; for
-example, you can use the :mod:`re` module to search through a memory-mapped file.
-Since they're mutable, you can change a single byte by doing ``obj[index] = 97``,
-or change a subsequence by assigning to a slice: ``obj[i1:i2] = b'...'``.
-You can also read and write data starting at the current file position, and
-:meth:`seek` through the file to different positions.
+Memory-mapped file objects behave like both :class:`bytearray` and like
+:term:`file objects `. You can use mmap objects in most places
+where :class:`bytearray` are expected; for example, you can use the :mod:`re`
+module to search through a memory-mapped file. You can also change a single
+byte by doing ``obj[index] = 97``, or change a subsequence by assigning to a
+slice: ``obj[i1:i2] = b'...'``. You can also read and write data starting at
+the current file position, and :meth:`seek` through the file to different positions.
A memory-mapped file is created by the :class:`mmap` constructor, which is
different on Unix and on Windows. In either case you must provide a file
Modified: python/branches/py3k/Doc/library/nntplib.rst
==============================================================================
--- python/branches/py3k/Doc/library/nntplib.rst (original)
+++ python/branches/py3k/Doc/library/nntplib.rst Wed Sep 15 13:11:28 2010
@@ -143,9 +143,9 @@
*groups* is a list of group names that are new since the given date and time. If
the *file* parameter is supplied, then the output of the ``NEWGROUPS`` command
is stored in a file. If *file* is a string, then the method will open a file
- object with that name, write to it then close it. If *file* is a file object,
- then it will start calling :meth:`write` on it to store the lines of the command
- output. If *file* is supplied, then the returned *list* is an empty list.
+ object with that name, write to it then close it. If *file* is a :term:`file
+ object`, then it will start calling :meth:`write` on it to store the lines of
+ the command output. If *file* is supplied, then the returned *list* is an empty list.
.. method:: NNTP.newnews(group, date, time, [file])
@@ -155,9 +155,9 @@
``(response, articles)`` where *articles* is a list of message ids. If the
*file* parameter is supplied, then the output of the ``NEWNEWS`` command is
stored in a file. If *file* is a string, then the method will open a file
- object with that name, write to it then close it. If *file* is a file object,
- then it will start calling :meth:`write` on it to store the lines of the command
- output. If *file* is supplied, then the returned *list* is an empty list.
+ object with that name, write to it then close it. If *file* is a :term:`file
+ object`, then it will start calling :meth:`write` on it to store the lines of the
+ command output. If *file* is supplied, then the returned *list* is an empty list.
.. method:: NNTP.list([file])
@@ -169,9 +169,9 @@
not, and ``'m'`` if the newsgroup is moderated. (Note the ordering: *last*,
*first*.) If the *file* parameter is supplied, then the output of the ``LIST``
command is stored in a file. If *file* is a string, then the method will open
- a file object with that name, write to it then close it. If *file* is a file
- object, then it will start calling :meth:`write` on it to store the lines of the
- command output. If *file* is supplied, then the returned *list* is an empty
+ a file with that name, write to it then close it. If *file* is a :term:`file
+ object`, then it will start calling :meth:`write` on it to store the lines of
+ the command output. If *file* is supplied, then the returned *list* is an empty
list.
@@ -207,8 +207,8 @@
Send a ``HELP`` command. Return a pair ``(response, list)`` where *list* is a
list of help strings. If the *file* parameter is supplied, then the output of
the ``HELP`` command is stored in a file. If *file* is a string, then the
- method will open a file object with that name, write to it then close it. If
- *file* is a file object, then it will start calling :meth:`write` on it to store
+ method will open a file with that name, write to it then close it. If *file*
+ is a :term:`file object`, then it will start calling :meth:`write` on it to store
the lines of the command output. If *file* is supplied, then the returned *list*
is an empty list.
@@ -243,8 +243,8 @@
Send a ``BODY`` command, where *id* has the same meaning as for :meth:`stat`.
If the *file* parameter is supplied, then the body is stored in a file. If
- *file* is a string, then the method will open a file object with that name,
- write to it then close it. If *file* is a file object, then it will start
+ *file* is a string, then the method will open a file with that name, write
+ to it then close it. If *file* is a :term:`file object`, then it will start
calling :meth:`write` on it to store the lines of the body. Return as for
:meth:`head`. If *file* is supplied, then the returned *list* is an empty list.
@@ -270,9 +270,9 @@
text)``, where *id* is an article number (as a string) and *text* is the text of
the requested header for that article. If the *file* parameter is supplied, then
the output of the ``XHDR`` command is stored in a file. If *file* is a string,
- then the method will open a file object with that name, write to it then close
- it. If *file* is a file object, then it will start calling :meth:`write` on it
- to store the lines of the command output. If *file* is supplied, then the
+ then the method will open a file with that name, write to it then close it.
+ If *file* is a :term:`file object`, then it will start calling :meth:`write` on
+ it to store the lines of the command output. If *file* is supplied, then the
returned *list* is an empty list.
@@ -303,8 +303,8 @@
Process an ``XGTITLE`` command, returning a pair ``(response, list)``, where
*list* is a list of tuples containing ``(name, title)``. If the *file* parameter
is supplied, then the output of the ``XGTITLE`` command is stored in a file.
- If *file* is a string, then the method will open a file object with that name,
- write to it then close it. If *file* is a file object, then it will start
+ If *file* is a string, then the method will open a file with that name, write
+ to it then close it. If *file* is a :term:`file object`, then it will start
calling :meth:`write` on it to store the lines of the command output. If *file*
is supplied, then the returned *list* is an empty list. This is an optional NNTP
extension, and may not be supported by all servers.
@@ -320,8 +320,8 @@
tuple is of the form ``(article number, subject, poster, date, id, references,
size, lines)``. If the *file* parameter is supplied, then the output of the
``XOVER`` command is stored in a file. If *file* is a string, then the method
- will open a file object with that name, write to it then close it. If *file*
- is a file object, then it will start calling :meth:`write` on it to store the
+ will open a file with that name, write to it then close it. If *file* is a
+ :term:`file object`, then it will start calling :meth:`write` on it to store the
lines of the command output. If *file* is supplied, then the returned *list* is
an empty list. This is an optional NNTP extension, and may not be supported by
all servers.
Modified: python/branches/py3k/Doc/library/os.rst
==============================================================================
--- python/branches/py3k/Doc/library/os.rst (original)
+++ python/branches/py3k/Doc/library/os.rst Wed Sep 15 13:11:28 2010
@@ -526,7 +526,7 @@
File Object Creation
--------------------
-These functions create new file objects. (See also :func:`open`.)
+These functions create new :term:`file objects `. (See also :func:`open`.)
.. function:: fdopen(fd[, mode[, bufsize]])
@@ -562,7 +562,7 @@
by file descriptors.
The :meth:`~file.fileno` method can be used to obtain the file descriptor
-associated with a file object when required. Note that using the file
+associated with a :term:`file object` when required. Note that using the file
descriptor directly will bypass the file object methods, ignoring aspects such
as internal buffering of data.
@@ -679,9 +679,9 @@
Force write of file with filedescriptor *fd* to disk. On Unix, this calls the
native :cfunc:`fsync` function; on Windows, the MS :cfunc:`_commit` function.
- If you're starting with a Python file object *f*, first do ``f.flush()``, and
- then do ``os.fsync(f.fileno())``, to ensure that all internal buffers associated
- with *f* are written to disk.
+ If you're starting with a buffered Python :term:`file object` *f*, first do
+ ``f.flush()``, and then do ``os.fsync(f.fileno())``, to ensure that all internal
+ buffers associated with *f* are written to disk.
Availability: Unix, and Windows.
@@ -738,9 +738,9 @@
.. note::
This function is intended for low-level I/O. For normal usage, use the
- built-in function :func:`open`, which returns a "file object" with
+ built-in function :func:`open`, which returns a :term:`file object` with
:meth:`~file.read` and :meth:`~file.write` methods (and many more). To
- wrap a file descriptor in a "file object", use :func:`fdopen`.
+ wrap a file descriptor in a file object, use :func:`fdopen`.
.. function:: openpty()
Modified: python/branches/py3k/Doc/library/pickle.rst
==============================================================================
--- python/branches/py3k/Doc/library/pickle.rst (original)
+++ python/branches/py3k/Doc/library/pickle.rst Wed Sep 15 13:11:28 2010
@@ -143,8 +143,8 @@
.. function:: dump(obj, file, protocol=None, \*, fix_imports=True)
- Write a pickled representation of *obj* to the open file object *file*. This
- is equivalent to ``Pickler(file, protocol).dump(obj)``.
+ Write a pickled representation of *obj* to the open :term:`file object` *file*.
+ This is equivalent to ``Pickler(file, protocol).dump(obj)``.
The optional *protocol* argument tells the pickler to use the given protocol;
supported protocols are 0, 1, 2, 3. The default protocol is 3; a
@@ -155,8 +155,9 @@
Python needed to read the pickle produced.
The *file* argument must have a write() method that accepts a single bytes
- argument. It can thus be a file object opened for binary writing, a
- io.BytesIO instance, or any other custom object that meets this interface.
+ argument. It can thus be an on-disk file opened for binary writing, a
+ :class:`io.BytesIO` instance, or any other custom object that meets this
+ interface.
If *fix_imports* is True and *protocol* is less than 3, pickle will try to
map the new Python 3.x names to the old module names used in Python 2.x,
@@ -181,8 +182,8 @@
.. function:: load(file, \*, fix_imports=True, encoding="ASCII", errors="strict")
- Read a pickled object representation from the open file object *file* and
- return the reconstituted object hierarchy specified therein. This is
+ Read a pickled object representation from the open :term:`file object` *file*
+ and return the reconstituted object hierarchy specified therein. This is
equivalent to ``Unpickler(file).load()``.
The protocol version of the pickle is detected automatically, so no protocol
@@ -191,9 +192,9 @@
The argument *file* must have two methods, a read() method that takes an
integer argument, and a readline() method that requires no arguments. Both
- methods should return bytes. Thus *file* can be a binary file object opened
- for reading, a BytesIO object, or any other custom object that meets this
- interface.
+ methods should return bytes. Thus *file* can be an on-disk file opened
+ for binary reading, a :class:`io.BytesIO` object, or any other custom object
+ that meets this interface.
Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
which are used to control compatiblity support for pickle stream generated
@@ -260,8 +261,8 @@
Python needed to read the pickle produced.
The *file* argument must have a write() method that accepts a single bytes
- argument. It can thus be a file object opened for binary writing, a
- io.BytesIO instance, or any other custom object that meets this interface.
+ argument. It can thus be an on-disk file opened for binary writing, a
+ :class:`io.BytesIO` instance, or any other custom object that meets this interface.
If *fix_imports* is True and *protocol* is less than 3, pickle will try to
map the new Python 3.x names to the old module names used in Python 2.x,
@@ -304,9 +305,9 @@
The argument *file* must have two methods, a read() method that takes an
integer argument, and a readline() method that requires no arguments. Both
- methods should return bytes. Thus *file* can be a binary file object opened
- for reading, a BytesIO object, or any other custom object that meets this
- interface.
+ methods should return bytes. Thus *file* can be an on-disk file object opened
+ for binary reading, a :class:`io.BytesIO` object, or any other custom object
+ that meets this interface.
Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
which are used to control compatiblity support for pickle stream generated
Modified: python/branches/py3k/Doc/library/quopri.rst
==============================================================================
--- python/branches/py3k/Doc/library/quopri.rst (original)
+++ python/branches/py3k/Doc/library/quopri.rst Wed Sep 15 13:11:28 2010
@@ -21,25 +21,24 @@
.. function:: decode(input, output, header=False)
Decode the contents of the *input* file and write the resulting decoded binary
- data to the *output* file. *input* and *output* must either be file objects or
- objects that mimic the file object interface. *input* will be read until
- ``input.readline()`` returns an empty string. If the optional argument *header*
- is present and true, underscore will be decoded as space. This is used to decode
- "Q"-encoded headers as described in :rfc:`1522`: "MIME (Multipurpose Internet
- Mail Extensions) Part Two: Message Header Extensions for Non-ASCII Text".
+ data to the *output* file. *input* and *output* must be :term:`file objects
+ `. *input* will be read until ``input.readline()`` returns an
+ empty string. If the optional argument *header* is present and true, underscore
+ will be decoded as space. This is used to decode "Q"-encoded headers as
+ described in :rfc:`1522`: "MIME (Multipurpose Internet Mail Extensions)
+ Part Two: Message Header Extensions for Non-ASCII Text".
.. function:: encode(input, output, quotetabs, header=False)
Encode the contents of the *input* file and write the resulting quoted-printable
- data to the *output* file. *input* and *output* must either be file objects or
- objects that mimic the file object interface. *input* will be read until
- ``input.readline()`` returns an empty string. *quotetabs* is a flag which
- controls whether to encode embedded spaces and tabs; when true it encodes such
- embedded whitespace, and when false it leaves them unencoded. Note that spaces
- and tabs appearing at the end of lines are always encoded, as per
- :rfc:`1521`. *header* is a flag which controls if spaces are encoded as
- underscores as per :rfc:`1522`.
+ data to the *output* file. *input* and *output* must be :term:`file objects
+ `. *input* will be read until ``input.readline()`` returns an
+ empty string. *quotetabs* is a flag which controls whether to encode embedded
+ spaces and tabs; when true it encodes such embedded whitespace, and when
+ false it leaves them unencoded. Note that spaces and tabs appearing at the
+ end of lines are always encoded, as per :rfc:`1521`. *header* is a flag
+ which controls if spaces are encoded as underscores as per :rfc:`1522`.
.. function:: decodestring(s, header=False)
Modified: python/branches/py3k/Doc/library/select.rst
==============================================================================
--- python/branches/py3k/Doc/library/select.rst (original)
+++ python/branches/py3k/Doc/library/select.rst Wed Sep 15 13:11:28 2010
@@ -78,11 +78,12 @@
single: socket() (in module socket)
single: popen() (in module os)
- Among the acceptable object types in the sequences are Python file objects (e.g.
- ``sys.stdin``, or objects returned by :func:`open` or :func:`os.popen`), socket
- objects returned by :func:`socket.socket`. You may also define a :dfn:`wrapper`
- class yourself, as long as it has an appropriate :meth:`fileno` method (that
- really returns a file descriptor, not just a random integer).
+ Among the acceptable object types in the sequences are Python :term:`file
+ objects ` (e.g. ``sys.stdin``, or objects returned by
+ :func:`open` or :func:`os.popen`), socket objects returned by
+ :func:`socket.socket`. You may also define a :dfn:`wrapper` class yourself,
+ as long as it has an appropriate :meth:`fileno` method (that really returns
+ a file descriptor, not just a random integer).
.. note::
Modified: python/branches/py3k/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/py3k/Doc/library/stdtypes.rst (original)
+++ python/branches/py3k/Doc/library/stdtypes.rst Wed Sep 15 13:11:28 2010
@@ -2441,9 +2441,9 @@
the identifier in the :keyword:`as` clause of :keyword:`with` statements using
this context manager.
- An example of a context manager that returns itself is a file object. File
- objects return themselves from __enter__() to allow :func:`open` to be used as
- the context expression in a :keyword:`with` statement.
+ An example of a context manager that returns itself is a :term:`file object`.
+ File objects return themselves from __enter__() to allow :func:`open` to be
+ used as the context expression in a :keyword:`with` statement.
An example of a context manager that returns a related object is the one
returned by :func:`decimal.localcontext`. These managers set the active
Modified: python/branches/py3k/Doc/library/subprocess.rst
==============================================================================
--- python/branches/py3k/Doc/library/subprocess.rst (original)
+++ python/branches/py3k/Doc/library/subprocess.rst Wed Sep 15 13:11:28 2010
@@ -108,9 +108,9 @@
*stdin*, *stdout* and *stderr* specify the executed programs' standard input,
standard output and standard error file handles, respectively. Valid values
are :data:`PIPE`, an existing file descriptor (a positive integer), an
- existing file object, and ``None``. :data:`PIPE` indicates that a new pipe
- to the child should be created. With ``None``, no redirection will occur;
- the child's file handles will be inherited from the parent. Additionally,
+ existing :term:`file object`, and ``None``. :data:`PIPE` indicates that a
+ new pipe to the child should be created. With ``None``, no redirection will
+ occur; the child's file handles will be inherited from the parent. Additionally,
*stderr* can be :data:`STDOUT`, which indicates that the stderr data from the
applications should be captured into the same file handle as for stdout.
@@ -409,20 +409,20 @@
.. attribute:: Popen.stdin
- If the *stdin* argument was :data:`PIPE`, this attribute is a file object
- that provides input to the child process. Otherwise, it is ``None``.
+ If the *stdin* argument was :data:`PIPE`, this attribute is a :term:`file
+ object` that provides input to the child process. Otherwise, it is ``None``.
.. attribute:: Popen.stdout
- If the *stdout* argument was :data:`PIPE`, this attribute is a file object
- that provides output from the child process. Otherwise, it is ``None``.
+ If the *stdout* argument was :data:`PIPE`, this attribute is a :term:`file
+ object` that provides output from the child process. Otherwise, it is ``None``.
.. attribute:: Popen.stderr
- If the *stderr* argument was :data:`PIPE`, this attribute is a file object
- that provides error output from the child process. Otherwise, it is
+ If the *stderr* argument was :data:`PIPE`, this attribute is a :term:`file
+ object` that provides error output from the child process. Otherwise, it is
``None``.
Modified: python/branches/py3k/Doc/library/sys.rst
==============================================================================
--- python/branches/py3k/Doc/library/sys.rst (original)
+++ python/branches/py3k/Doc/library/sys.rst Wed Sep 15 13:11:28 2010
@@ -853,10 +853,10 @@
stdout
stderr
- File objects corresponding to the interpreter's standard input, output and error
- streams. ``stdin`` is used for all interpreter input except for scripts but
- including calls to :func:`input`. ``stdout`` is used for
- the output of :func:`print` and :term:`expression` statements and for the
+ :term:`File objects ` corresponding to the interpreter's standard
+ input, output and error streams. ``stdin`` is used for all interpreter input
+ except for scripts but including calls to :func:`input`. ``stdout`` is used
+ for the output of :func:`print` and :term:`expression` statements and for the
prompts of :func:`input`. The interpreter's own prompts
and (almost all of) its error messages go to ``stderr``. ``stdout`` and
``stderr`` needn't be built-in file objects: any object is acceptable as long
Modified: python/branches/py3k/Doc/library/tarfile.rst
==============================================================================
--- python/branches/py3k/Doc/library/tarfile.rst (original)
+++ python/branches/py3k/Doc/library/tarfile.rst Wed Sep 15 13:11:28 2010
@@ -66,8 +66,8 @@
*mode* ``'r'`` to avoid this. If a compression method is not supported,
:exc:`CompressionError` is raised.
- If *fileobj* is specified, it is used as an alternative to a file object opened
- for *name*. It is supposed to be at position 0.
+ If *fileobj* is specified, it is used as an alternative to a :term:`file object`
+ opened in binary mode for *name*. It is supposed to be at position 0.
For special purposes, there is a second format for *mode*:
``'filemode|[compression]'``. :func:`tarfile.open` will return a :class:`TarFile`
@@ -75,7 +75,7 @@
be done on the file. If given, *fileobj* may be any object that has a
:meth:`read` or :meth:`write` method (depending on the *mode*). *bufsize*
specifies the blocksize and defaults to ``20 * 512`` bytes. Use this variant
- in combination with e.g. ``sys.stdin``, a socket file object or a tape
+ in combination with e.g. ``sys.stdin``, a socket :term:`file object` or a tape
device. However, such a :class:`TarFile` object is limited in that it does
not allow to be accessed randomly, see :ref:`tar-examples`. The currently
possible modes:
@@ -355,9 +355,9 @@
.. method:: TarFile.extractfile(member)
Extract a member from the archive as a file object. *member* may be a filename
- or a :class:`TarInfo` object. If *member* is a regular file, a file-like object
- is returned. If *member* is a link, a file-like object is constructed from the
- link's target. If *member* is none of the above, :const:`None` is returned.
+ or a :class:`TarInfo` object. If *member* is a regular file, a :term:`file-like
+ object` is returned. If *member* is a link, a file-like object is constructed from
+ the link's target. If *member* is none of the above, :const:`None` is returned.
.. note::
@@ -402,9 +402,9 @@
.. method:: TarFile.gettarinfo(name=None, arcname=None, fileobj=None)
- Create a :class:`TarInfo` object for either the file *name* or the file object
- *fileobj* (using :func:`os.fstat` on its file descriptor). You can modify some
- of the :class:`TarInfo`'s attributes before you add it using :meth:`addfile`.
+ Create a :class:`TarInfo` object for either the file *name* or the :term:`file
+ object` *fileobj* (using :func:`os.fstat` on its file descriptor). You can modify
+ some of the :class:`TarInfo`'s attributes before you add it using :meth:`addfile`.
If given, *arcname* specifies an alternative name for the file in the archive.
Modified: python/branches/py3k/Doc/library/tempfile.rst
==============================================================================
--- python/branches/py3k/Doc/library/tempfile.rst (original)
+++ python/branches/py3k/Doc/library/tempfile.rst Wed Sep 15 13:11:28 2010
@@ -29,7 +29,7 @@
.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None)
- Return a file-like object that can be used as a temporary storage area.
+ Return a :term:`file-like object` that can be used as a temporary storage area.
The file is created using :func:`mkstemp`. It will be destroyed as soon
as it is closed (including an implicit close when the object is garbage
collected). Under Unix, the directory entry for the file is removed
Modified: python/branches/py3k/Doc/library/termios.rst
==============================================================================
--- python/branches/py3k/Doc/library/termios.rst (original)
+++ python/branches/py3k/Doc/library/termios.rst Wed Sep 15 13:11:28 2010
@@ -17,7 +17,7 @@
All functions in this module take a file descriptor *fd* as their first
argument. This can be an integer file descriptor, such as returned by
-``sys.stdin.fileno()``, or a file object, such as ``sys.stdin`` itself.
+``sys.stdin.fileno()``, or a :term:`file object`, such as ``sys.stdin`` itself.
This module also defines all the constants needed to work with the functions
provided here; these have the same name as their counterparts in C. Please
Modified: python/branches/py3k/Doc/library/weakref.rst
==============================================================================
--- python/branches/py3k/Doc/library/weakref.rst (original)
+++ python/branches/py3k/Doc/library/weakref.rst Wed Sep 15 13:11:28 2010
@@ -58,8 +58,9 @@
Not all objects can be weakly referenced; those objects which can include class
instances, functions written in Python (but not in C), instance methods, sets,
-frozensets, file objects, :term:`generator`\s, type objects, sockets, arrays,
-deques, regular expression pattern objects, and code objects.
+frozensets, some :term:`file objects `, :term:`generator`\s, type
+objects, sockets, arrays, deques, regular expression pattern objects, and code
+objects.
.. versionchanged:: 3.2
Added support for thread.lock, threading.Lock, and code objects.
Modified: python/branches/py3k/Doc/library/xml.etree.elementtree.rst
==============================================================================
--- python/branches/py3k/Doc/library/xml.etree.elementtree.rst (original)
+++ python/branches/py3k/Doc/library/xml.etree.elementtree.rst Wed Sep 15 13:11:28 2010
@@ -92,8 +92,8 @@
.. function:: iterparse(source, events=None, parser=None)
Parses an XML section into an element tree incrementally, and reports what's
- going on to the user. *source* is a filename or file object containing XML
- data. *events* is a list of events to report back. If omitted, only "end"
+ going on to the user. *source* is a filename or :term:`file object` containing
+ XML data. *events* is a list of events to report back. If omitted, only "end"
events are reported. *parser* is an optional parser instance. If not
given, the standard :class:`XMLParser` parser is used. Returns an
:term:`iterator` providing ``(event, elem)`` pairs.
@@ -455,15 +455,15 @@
.. method:: parse(source, parser=None)
Loads an external XML section into this element tree. *source* is a file
- name or file object. *parser* is an optional parser instance. If not
- given, the standard XMLParser parser is used. Returns the section
+ name or :term:`file object`. *parser* is an optional parser instance.
+ If not given, the standard XMLParser parser is used. Returns the section
root element.
.. method:: write(file, encoding="us-ascii", xml_declaration=None, method="xml")
Writes the element tree to a file, as XML. *file* is a file name, or a
- file object opened for writing. *encoding* [1]_ is the output encoding
+ :term:`file object` opened for writing. *encoding* [1]_ is the output encoding
(default is US-ASCII). Use ``encoding="unicode"`` to write a Unicode string.
*xml_declaration* controls if an XML declaration
should be added to the file. Use False for never, True for always, None
Modified: python/branches/py3k/Doc/tutorial/inputoutput.rst
==============================================================================
--- python/branches/py3k/Doc/tutorial/inputoutput.rst (original)
+++ python/branches/py3k/Doc/tutorial/inputoutput.rst Wed Sep 15 13:11:28 2010
@@ -232,8 +232,8 @@
builtin: open
object: file
-:func:`open` returns a file object, and is most commonly used with two
-arguments: ``open(filename, mode)``.
+:func:`open` returns a :term:`file object`, and is most commonly used with
+two arguments: ``open(filename, mode)``.
::
From python-checkins at python.org Wed Sep 15 13:12:57 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 13:12:57 +0200 (CEST)
Subject: [Python-checkins] r84830 - python/branches/py3k/Lib/socket.py
Message-ID: <20100915111257.E4DF6FBB1@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 13:12:57 2010
New Revision: 84830
Log:
Reverted unwanted change in r84826
Modified:
python/branches/py3k/Lib/socket.py
Modified: python/branches/py3k/Lib/socket.py
==============================================================================
--- python/branches/py3k/Lib/socket.py (original)
+++ python/branches/py3k/Lib/socket.py Wed Sep 15 13:12:57 2010
@@ -54,8 +54,6 @@
errno = None
EBADF = getattr(errno, 'EBADF', 9)
EINTR = getattr(errno, 'EINTR', 4)
-EAGAIN = getattr(errno, 'EAGAIN', 11)
-EWOULDBLOCK = getattr(errno, 'EWOULDBLOCK', 11)
__all__ = ["getfqdn", "create_connection"]
__all__.extend(os._get_exports_list(_socket))
From python-checkins at python.org Wed Sep 15 13:14:58 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 13:14:58 +0200 (CEST)
Subject: [Python-checkins] r84831 - python/branches/release27-maint
Message-ID: <20100915111458.E10E5EE989@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 13:14:58 2010
New Revision: 84831
Log:
Blocked revisions 84825-84826,84830 via svnmerge
........
r84825 | antoine.pitrou | 2010-09-15 10:39:25 +0200 (mer., 15 sept. 2010) | 3 lines
Add a comment explaining why SocketIO is needed
........
r84826 | antoine.pitrou | 2010-09-15 11:32:45 +0200 (mer., 15 sept. 2010) | 3 lines
Improve docs for socket.makefile() and SocketIO
........
r84830 | antoine.pitrou | 2010-09-15 13:12:57 +0200 (mer., 15 sept. 2010) | 3 lines
Reverted unwanted change in r84826
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Wed Sep 15 13:16:39 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 13:16:39 +0200 (CEST)
Subject: [Python-checkins] r84832 - in python/branches/release31-maint:
Doc/library/socket.rst Lib/socket.py
Message-ID: <20100915111639.C50BDEE989@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 13:16:39 2010
New Revision: 84832
Log:
Merged revisions 84825-84826,84830 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84825 | antoine.pitrou | 2010-09-15 10:39:25 +0200 (mer., 15 sept. 2010) | 3 lines
Add a comment explaining why SocketIO is needed
........
r84826 | antoine.pitrou | 2010-09-15 11:32:45 +0200 (mer., 15 sept. 2010) | 3 lines
Improve docs for socket.makefile() and SocketIO
........
r84830 | antoine.pitrou | 2010-09-15 13:12:57 +0200 (mer., 15 sept. 2010) | 3 lines
Reverted unwanted change in r84826
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/library/socket.rst
python/branches/release31-maint/Lib/socket.py
Modified: python/branches/release31-maint/Doc/library/socket.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/socket.rst (original)
+++ python/branches/release31-maint/Doc/library/socket.rst Wed Sep 15 13:16:39 2010
@@ -597,10 +597,9 @@
arguments are interpreted the same way as by the built-in :func:`open`
function.
- The returned file object references a :cfunc:`dup`\ ped version of the
- socket file descriptor, so the file object and socket object may be
- closed or garbage-collected independently. The socket must be in
- blocking mode (it can not have a timeout).
+ Closing the file object won't close the socket unless there are no
+ remaining references to the socket. The socket must be in blocking mode
+ (it can not have a timeout).
.. method:: socket.recv(bufsize[, flags])
Modified: python/branches/release31-maint/Lib/socket.py
==============================================================================
--- python/branches/release31-maint/Lib/socket.py (original)
+++ python/branches/release31-maint/Lib/socket.py Wed Sep 15 13:16:39 2010
@@ -195,6 +195,13 @@
the raw I/O interface on top of a socket object.
"""
+ # One might wonder why not let FileIO do the job instead. There are two
+ # main reasons why FileIO is not adapted:
+ # - it wouldn't work under Windows (where you can't used read() and
+ # write() on a socket handle)
+ # - it wouldn't work with socket timeouts (FileIO would ignore the
+ # timeout and consider the socket non-blocking)
+
# XXX More docs
def __init__(self, sock, mode):
@@ -209,22 +216,40 @@
self._writing = "w" in mode
def readinto(self, b):
+ """Read up to len(b) bytes into the writable buffer *b* and return
+ the number of bytes read. If the socket is non-blocking and no bytes
+ are available, None is returned.
+
+ If *b* is non-empty, a 0 return value indicates that the connection
+ was shutdown at the other end.
+ """
self._checkClosed()
self._checkReadable()
return self._sock.recv_into(b)
def write(self, b):
+ """Write the given bytes or bytearray object *b* to the socket
+ and return the number of bytes written. This can be less than
+ len(b) if not all data could be written. If the socket is
+ non-blocking and no bytes could be written None is returned.
+ """
self._checkClosed()
self._checkWritable()
return self._sock.send(b)
def readable(self):
+ """True if the SocketIO is open for reading.
+ """
return self._reading and not self.closed
def writable(self):
+ """True if the SocketIO is open for writing.
+ """
return self._writing and not self.closed
def fileno(self):
+ """Return the file descriptor of the underlying socket.
+ """
self._checkClosed()
return self._sock.fileno()
@@ -237,6 +262,9 @@
return self._mode
def close(self):
+ """Close the SocketIO object. This doesn't close the underlying
+ socket, except if all references to it have disappeared.
+ """
if self.closed:
return
io.RawIOBase.close(self)
From python-checkins at python.org Wed Sep 15 13:25:12 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 13:25:12 +0200 (CEST)
Subject: [Python-checkins] r84833 - in python/branches/release31-maint:
Doc/faq/design.rst Doc/faq/library.rst Doc/glossary.rst
Doc/library/aifc.rst Doc/library/array.rst
Doc/library/asyncore.rst Doc/library/base64.rst
Doc/library/bz2.rst Doc/library/configparser.rst
Doc/library/csv.rst Doc/library/email.generator.rst
Doc/library/email.parser.rst Doc/library/exceptions.rst
Doc/library/filesys.rst Doc/library/formatter.rst
Doc/library/ftplib.rst Doc/library/gettext.rst
Doc/library/gzip.rst Doc/library/http.client.rst
Doc/library/imp.rst Doc/library/mmap.rst
Doc/library/nntplib.rst Doc/library/os.rst
Doc/library/pickle.rst Doc/library/quopri.rst
Doc/library/select.rst Doc/library/socket.rst
Doc/library/stdtypes.rst Doc/library/subprocess.rst
Doc/library/sys.rst Doc/library/tarfile.rst
Doc/library/tempfile.rst Doc/library/termios.rst
Doc/library/weakref.rst Doc/library/xml.etree.elementtree.rst
Doc/reference/datamodel.rst Doc/tutorial/inputoutput.rst
Message-ID: <20100915112512.538A4EE98C@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 13:25:11 2010
New Revision: 84833
Log:
Merged revisions 84827-84829 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84827 | antoine.pitrou | 2010-09-15 11:58:26 +0200 (mer., 15 sept. 2010) | 3 lines
Add a glossary entry for file objects.
........
r84828 | antoine.pitrou | 2010-09-15 12:08:31 +0200 (mer., 15 sept. 2010) | 3 lines
Update file-related information in the FAQ.
........
r84829 | antoine.pitrou | 2010-09-15 13:11:28 +0200 (mer., 15 sept. 2010) | 3 lines
Add cross-references to the glossary entry for file objects.
........
Modified:
python/branches/release31-maint/ (props changed)
python/branches/release31-maint/Doc/faq/design.rst
python/branches/release31-maint/Doc/faq/library.rst
python/branches/release31-maint/Doc/glossary.rst
python/branches/release31-maint/Doc/library/aifc.rst
python/branches/release31-maint/Doc/library/array.rst
python/branches/release31-maint/Doc/library/asyncore.rst
python/branches/release31-maint/Doc/library/base64.rst
python/branches/release31-maint/Doc/library/bz2.rst
python/branches/release31-maint/Doc/library/configparser.rst
python/branches/release31-maint/Doc/library/csv.rst
python/branches/release31-maint/Doc/library/email.generator.rst
python/branches/release31-maint/Doc/library/email.parser.rst
python/branches/release31-maint/Doc/library/exceptions.rst
python/branches/release31-maint/Doc/library/filesys.rst
python/branches/release31-maint/Doc/library/formatter.rst
python/branches/release31-maint/Doc/library/ftplib.rst
python/branches/release31-maint/Doc/library/gettext.rst
python/branches/release31-maint/Doc/library/gzip.rst
python/branches/release31-maint/Doc/library/http.client.rst
python/branches/release31-maint/Doc/library/imp.rst
python/branches/release31-maint/Doc/library/mmap.rst
python/branches/release31-maint/Doc/library/nntplib.rst
python/branches/release31-maint/Doc/library/os.rst
python/branches/release31-maint/Doc/library/pickle.rst
python/branches/release31-maint/Doc/library/quopri.rst
python/branches/release31-maint/Doc/library/select.rst
python/branches/release31-maint/Doc/library/socket.rst
python/branches/release31-maint/Doc/library/stdtypes.rst
python/branches/release31-maint/Doc/library/subprocess.rst
python/branches/release31-maint/Doc/library/sys.rst
python/branches/release31-maint/Doc/library/tarfile.rst
python/branches/release31-maint/Doc/library/tempfile.rst
python/branches/release31-maint/Doc/library/termios.rst
python/branches/release31-maint/Doc/library/weakref.rst
python/branches/release31-maint/Doc/library/xml.etree.elementtree.rst
python/branches/release31-maint/Doc/reference/datamodel.rst
python/branches/release31-maint/Doc/tutorial/inputoutput.rst
Modified: python/branches/release31-maint/Doc/faq/design.rst
==============================================================================
--- python/branches/release31-maint/Doc/faq/design.rst (original)
+++ python/branches/release31-maint/Doc/faq/design.rst Wed Sep 15 13:25:11 2010
@@ -209,8 +209,8 @@
is hidden at the bottom of the loop.
The best approach is to use iterators, making it possible to loop through
-objects using the ``for`` statement. For example, in the current version of
-Python file objects support the iterator protocol, so you can now write simply::
+objects using the ``for`` statement. For example, :term:`file objects
+` support the iterator protocol, so you can write simply::
for line in f:
... # do something with line...
Modified: python/branches/release31-maint/Doc/faq/library.rst
==============================================================================
--- python/branches/release31-maint/Doc/faq/library.rst (original)
+++ python/branches/release31-maint/Doc/faq/library.rst Wed Sep 15 13:25:11 2010
@@ -454,7 +454,7 @@
To rename a file, use ``os.rename(old_path, new_path)``.
-To truncate a file, open it using ``f = open(filename, "r+")``, and use
+To truncate a file, open it using ``f = open(filename, "rb+")``, and use
``f.truncate(offset)``; offset defaults to the current seek position. There's
also ```os.ftruncate(fd, offset)`` for files opened with :func:`os.open`, where
``fd`` is the file descriptor (a small integer).
@@ -483,9 +483,9 @@
import struct
- f = open(filename, "rb") # Open in binary mode for portability
- s = f.read(8)
- x, y, z = struct.unpack(">hhl", s)
+ with open(filename, "rb") as f:
+ s = f.read(8)
+ x, y, z = struct.unpack(">hhl", s)
The '>' in the format string forces big-endian data; the letter 'h' reads one
"short integer" (2 bytes), and 'l' reads one "long integer" (4 bytes) from the
@@ -494,6 +494,13 @@
For data that is more regular (e.g. a homogeneous list of ints or thefloats),
you can also use the :mod:`array` module.
+ .. note::
+ To read and write binary data, it is mandatory to open the file in
+ binary mode (here, passing ``"rb"`` to :func:`open`). If you use
+ ``"r"`` instead (the default), the file will be open in text mode
+ and ``f.read()`` will return :class:`str` objects rather than
+ :class:`bytes` objects.
+
I can't seem to use os.read() on a pipe created with os.popen(); why?
---------------------------------------------------------------------
@@ -597,27 +604,29 @@
Why doesn't closing sys.stdout (stdin, stderr) really close it?
---------------------------------------------------------------
-Python file objects are a high-level layer of abstraction on top of C streams,
-which in turn are a medium-level layer of abstraction on top of (among other
-things) low-level C file descriptors.
-
-For most file objects you create in Python via the builtin ``file`` constructor,
-``f.close()`` marks the Python file object as being closed from Python's point
-of view, and also arranges to close the underlying C stream. This also happens
-automatically in f's destructor, when f becomes garbage.
+Python :term:`file objects ` are a high-level layer of
+abstraction on low-level C file descriptors.
+
+For most file objects you create in Python via the built-in :func:`open`
+function, ``f.close()`` marks the Python file object as being closed from
+Python's point of view, and also arranges to close the underlying C file
+descriptor. This also happens automatically in ``f``'s destructor, when
+``f`` becomes garbage.
But stdin, stdout and stderr are treated specially by Python, because of the
special status also given to them by C. Running ``sys.stdout.close()`` marks
the Python-level file object as being closed, but does *not* close the
-associated C stream.
+associated C file descriptor.
+
+To close the underlying C file descriptor for one of these three, you should
+first be sure that's what you really want to do (e.g., you may confuse
+extension modules trying to do I/O). If it is, use :func:`os.close`::
+
+ os.close(stdin.fileno())
+ os.close(stdout.fileno())
+ os.close(stderr.fileno())
-To close the underlying C stream for one of these three, you should first be
-sure that's what you really want to do (e.g., you may confuse extension modules
-trying to do I/O). If it is, use os.close::
-
- os.close(0) # close C's stdin stream
- os.close(1) # close C's stdout stream
- os.close(2) # close C's stderr stream
+Or you can use the numeric constants 0, 1 and 2, respectively.
Network/Internet Programming
Modified: python/branches/release31-maint/Doc/glossary.rst
==============================================================================
--- python/branches/release31-maint/Doc/glossary.rst (original)
+++ python/branches/release31-maint/Doc/glossary.rst Wed Sep 15 13:25:11 2010
@@ -178,6 +178,23 @@
A module written in C or C++, using Python's C API to interact with the core and
with user code.
+ file object
+ An object exposing a file-oriented API (with methods such as
+ :meth:`read()` or :meth:`write()`) to an underlying resource.
+ Depending on the way it was created, a file object can mediate access
+ to a real on-disk file or to another other type of storage or
+ communication device (for example standard input/output, in-memory
+ buffers, sockets, pipes, etc.). File objects are also called
+ :dfn:`file-like objects` or :dfn:`streams`.
+
+ There are actually three categories of file objects: raw binary
+ files, buffered binary files and text files. Their interfaces are
+ defined in the :mod:`io` module. The canonical way to create a
+ file object is by using the :func:`open` function.
+
+ file-like object
+ A synonym for :term:`file object`.
+
finder
An object that tries to find the :term:`loader` for a module. It must
implement a method named :meth:`find_module`. See :pep:`302` for
Modified: python/branches/release31-maint/Doc/library/aifc.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/aifc.rst (original)
+++ python/branches/release31-maint/Doc/library/aifc.rst Wed Sep 15 13:25:11 2010
@@ -40,10 +40,10 @@
.. function:: open(file, mode=None)
Open an AIFF or AIFF-C file and return an object instance with methods that are
- described below. The argument *file* is either a string naming a file or a file
- object. *mode* must be ``'r'`` or ``'rb'`` when the file must be opened for
- reading, or ``'w'`` or ``'wb'`` when the file must be opened for writing. If
- omitted, ``file.mode`` is used if it exists, otherwise ``'rb'`` is used. When
+ described below. The argument *file* is either a string naming a file or a
+ :term:`file object`. *mode* must be ``'r'`` or ``'rb'`` when the file must be
+ opened for reading, or ``'w'`` or ``'wb'`` when the file must be opened for writing.
+ If omitted, ``file.mode`` is used if it exists, otherwise ``'rb'`` is used. When
used for writing, the file object should be seekable, unless you know ahead of
time how many samples you are going to write in total and use
:meth:`writeframesraw` and :meth:`setnframes`.
Modified: python/branches/release31-maint/Doc/library/array.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/array.rst (original)
+++ python/branches/release31-maint/Doc/library/array.rst Wed Sep 15 13:25:11 2010
@@ -138,11 +138,11 @@
.. method:: array.fromfile(f, n)
- Read *n* items (as machine values) from the file object *f* and append them to
- the end of the array. If less than *n* items are available, :exc:`EOFError` is
- raised, but the items that were available are still inserted into the array.
- *f* must be a real built-in file object; something else with a :meth:`read`
- method won't do.
+ Read *n* items (as machine values) from the :term:`file object` *f* and append
+ them to the end of the array. If less than *n* items are available,
+ :exc:`EOFError` is raised, but the items that were available are still
+ inserted into the array. *f* must be a real built-in file object; something
+ else with a :meth:`read` method won't do.
.. method:: array.fromlist(list)
@@ -196,7 +196,7 @@
.. method:: array.tofile(f)
- Write all items (as machine values) to the file object *f*.
+ Write all items (as machine values) to the :term:`file object` *f*.
.. method:: array.tolist()
Modified: python/branches/release31-maint/Doc/library/asyncore.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/asyncore.rst (original)
+++ python/branches/release31-maint/Doc/library/asyncore.rst Wed Sep 15 13:25:11 2010
@@ -224,9 +224,9 @@
.. class:: file_dispatcher()
- A file_dispatcher takes a file descriptor or file object along with an
- optional map argument and wraps it for use with the :cfunc:`poll` or
- :cfunc:`loop` functions. If provided a file object or anything with a
+ A file_dispatcher takes a file descriptor or :term:`file object` along
+ with an optional map argument and wraps it for use with the :cfunc:`poll`
+ or :cfunc:`loop` functions. If provided a file object or anything with a
:cfunc:`fileno` method, that method will be called and passed to the
:class:`file_wrapper` constructor. Availability: UNIX.
Modified: python/branches/release31-maint/Doc/library/base64.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/base64.rst (original)
+++ python/branches/release31-maint/Doc/library/base64.rst Wed Sep 15 13:25:11 2010
@@ -122,9 +122,9 @@
.. function:: decode(input, output)
Decode the contents of the binary *input* file and write the resulting binary
- data to the *output* file. *input* and *output* must either be file objects
- or objects that mimic the file object interface working with bytes
- objects. *input* will be read until ``input.read()`` returns an empty string.
+ data to the *output* file. *input* and *output* must be :term:`file objects
+ `. *input* will be read until ``input.read()`` returns an empty
+ bytes object.
.. function:: decodebytes(s)
@@ -138,11 +138,10 @@
.. function:: encode(input, output)
Encode the contents of the binary *input* file and write the resulting base64
- encoded data to the *output* file. *input* and *output* must either be file
- objects or objects that mimic the file object interface working with bytes
- objects. *input* will be read until ``input.read()`` returns an empty string.
- :func:`encode` returns the encoded data plus a trailing newline character
- (``b'\n'``).
+ encoded data to the *output* file. *input* and *output* must be :term:`file
+ objects `. *input* will be read until ``input.read()`` returns
+ an empty bytes object. :func:`encode` returns the encoded data plus a trailing
+ newline character (``b'\n'``).
.. function:: encodebytes(s)
Modified: python/branches/release31-maint/Doc/library/bz2.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/bz2.rst (original)
+++ python/branches/release31-maint/Doc/library/bz2.rst Wed Sep 15 13:25:11 2010
@@ -25,8 +25,8 @@
* :class:`BZ2File` class implements universal newline support;
-* :class:`BZ2File` class offers an optimized line iteration using the readahead
- algorithm borrowed from file objects;
+* :class:`BZ2File` class offers an optimized line iteration using a readahead
+ algorithm;
* Sequential (de)compression supported by :class:`BZ2Compressor` and
:class:`BZ2Decompressor` classes;
Modified: python/branches/release31-maint/Doc/library/configparser.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/configparser.rst (original)
+++ python/branches/release31-maint/Doc/library/configparser.rst Wed Sep 15 13:25:11 2010
@@ -298,7 +298,7 @@
.. method:: RawConfigParser.write(fileobject)
- Write a representation of the configuration to the specified file object,
+ Write a representation of the configuration to the specified :term:`file object`,
which must be opened in text mode (accepting strings). This representation
can be parsed by a future :meth:`read` call.
Modified: python/branches/release31-maint/Doc/library/csv.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/csv.rst (original)
+++ python/branches/release31-maint/Doc/library/csv.rst Wed Sep 15 13:25:11 2010
@@ -50,9 +50,9 @@
Return a reader object which will iterate over lines in the given *csvfile*.
*csvfile* can be any object which supports the :term:`iterator` protocol and returns a
- string each time its :meth:`!next` method is called --- file objects and list
- objects are both suitable. If *csvfile* is a file object, it should be opened
- with ``newline=''``. [#]_ An optional
+ string each time its :meth:`!next` method is called --- :term:`file objects
+ ` and list objects are both suitable. If *csvfile* is a file object,
+ it should be opened with ``newline=''``. [#]_ An optional
*dialect* parameter can be given which is used to define a set of parameters
specific to a particular CSV dialect. It may be an instance of a subclass of
the :class:`Dialect` class or one of the strings returned by the
Modified: python/branches/release31-maint/Doc/library/email.generator.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/email.generator.rst (original)
+++ python/branches/release31-maint/Doc/library/email.generator.rst Wed Sep 15 13:25:11 2010
@@ -28,9 +28,9 @@
.. class:: Generator(outfp, mangle_from_=True, maxheaderlen=78)
- The constructor for the :class:`Generator` class takes a file-like object called
- *outfp* for an argument. *outfp* must support the :meth:`write` method and be
- usable as the output file for the :func:`print` function.
+ The constructor for the :class:`Generator` class takes a :term:`file-like object`
+ called *outfp* for an argument. *outfp* must support the :meth:`write` method
+ and be usable as the output file for the :func:`print` function.
Optional *mangle_from_* is a flag that, when ``True``, puts a ``>`` character in
front of any line in the body that starts exactly as ``From``, i.e. ``From``
Modified: python/branches/release31-maint/Doc/library/email.parser.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/email.parser.rst (original)
+++ python/branches/release31-maint/Doc/library/email.parser.rst Wed Sep 15 13:25:11 2010
@@ -154,9 +154,9 @@
.. function:: message_from_file(fp[, _class][, strict])
- Return a message object structure tree from an open file object. This is
- exactly equivalent to ``Parser().parse(fp)``. Optional *_class* and *strict*
- are interpreted as with the :class:`Parser` class constructor.
+ Return a message object structure tree from an open :term:`file object`.
+ This is exactly equivalent to ``Parser().parse(fp)``. Optional *_class*
+ and *strict* are interpreted as with the :class:`Parser` class constructor.
Here's an example of how you might use this at an interactive Python prompt::
Modified: python/branches/release31-maint/Doc/library/exceptions.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/exceptions.rst (original)
+++ python/branches/release31-maint/Doc/library/exceptions.rst Wed Sep 15 13:25:11 2010
@@ -142,8 +142,8 @@
.. exception:: IOError
Raised when an I/O operation (such as the built-in :func:`print` or
- :func:`open` functions or a method of a file object) fails for an I/O-related
- reason, e.g., "file not found" or "disk full".
+ :func:`open` functions or a method of a :term:`file object`) fails for an
+ I/O-related reason, e.g., "file not found" or "disk full".
This class is derived from :exc:`EnvironmentError`. See the discussion above
for more information on exception instance attributes.
Modified: python/branches/release31-maint/Doc/library/filesys.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/filesys.rst (original)
+++ python/branches/release31-maint/Doc/library/filesys.rst Wed Sep 15 13:25:11 2010
@@ -27,8 +27,8 @@
.. seealso::
Module :mod:`os`
- Operating system interfaces, including functions to work with files at a lower
- level than the built-in file object.
+ Operating system interfaces, including functions to work with files at a
+ lower level than Python :term:`file objects `.
Module :mod:`io`
Python's built-in I/O library, including both abstract classes and
Modified: python/branches/release31-maint/Doc/library/formatter.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/formatter.rst (original)
+++ python/branches/release31-maint/Doc/library/formatter.rst Wed Sep 15 13:25:11 2010
@@ -339,8 +339,8 @@
.. class:: DumbWriter(file=None, maxcol=72)
- Simple writer class which writes output on the file object passed in as *file*
- or, if *file* is omitted, on standard output. The output is simply word-wrapped
- to the number of columns specified by *maxcol*. This class is suitable for
- reflowing a sequence of paragraphs.
+ Simple writer class which writes output on the :term:`file object` passed
+ in as *file* or, if *file* is omitted, on standard output. The output is
+ simply word-wrapped to the number of columns specified by *maxcol*. This
+ class is suitable for reflowing a sequence of paragraphs.
Modified: python/branches/release31-maint/Doc/library/ftplib.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/ftplib.rst (original)
+++ python/branches/release31-maint/Doc/library/ftplib.rst Wed Sep 15 13:25:11 2010
@@ -194,19 +194,19 @@
.. method:: FTP.storbinary(cmd, file, blocksize=8192, callback=None)
Store a file in binary transfer mode. *cmd* should be an appropriate
- ``STOR`` command: ``"STOR filename"``. *file* is an open file object which is
- read until EOF using its :meth:`read` method in blocks of size *blocksize* to
- provide the data to be stored. The *blocksize* argument defaults to 8192.
- *callback* is an optional single parameter callable that is called
- on each block of data after it is sent.
+ ``STOR`` command: ``"STOR filename"``. *file* is an open :term:`file object`
+ which is read until EOF using its :meth:`read` method in blocks of size
+ *blocksize* to provide the data to be stored. The *blocksize* argument
+ defaults to 8192. *callback* is an optional single parameter callable that
+ is called on each block of data after it is sent.
.. method:: FTP.storlines(cmd, file, callback=None)
Store a file in ASCII transfer mode. *cmd* should be an appropriate
``STOR`` command (see :meth:`storbinary`). Lines are read until EOF from the
- open file object *file* using its :meth:`readline` method to provide the data to
- be stored. *callback* is an optional single parameter callable
+ open :term:`file object` *file* using its :meth:`readline` method to provide
+ the data to be stored. *callback* is an optional single parameter callable
that is called on each line after it is sent.
Modified: python/branches/release31-maint/Doc/library/gettext.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/gettext.rst (original)
+++ python/branches/release31-maint/Doc/library/gettext.rst Wed Sep 15 13:25:11 2010
@@ -173,8 +173,8 @@
associated :file:`.mo` file paths. Instances with identical :file:`.mo` file
names are cached. The actual class instantiated is either *class_* if
provided, otherwise :class:`GNUTranslations`. The class's constructor must
- take a single file object argument. If provided, *codeset* will change the
- charset used to encode translated strings in the :meth:`lgettext` and
+ take a single :term:`file object` argument. If provided, *codeset* will change
+ the charset used to encode translated strings in the :meth:`lgettext` and
:meth:`lngettext` methods.
If multiple files are found, later files are used as fallbacks for earlier ones.
@@ -219,7 +219,7 @@
.. class:: NullTranslations(fp=None)
- Takes an optional file object *fp*, which is ignored by the base class.
+ Takes an optional :term:`file object` *fp*, which is ignored by the base class.
Initializes "protected" instance variables *_info* and *_charset* which are set
by derived classes, as well as *_fallback*, which is set through
:meth:`add_fallback`. It then calls ``self._parse(fp)`` if *fp* is not
Modified: python/branches/release31-maint/Doc/library/gzip.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/gzip.rst (original)
+++ python/branches/release31-maint/Doc/library/gzip.rst Wed Sep 15 13:25:11 2010
@@ -9,10 +9,9 @@
The data compression is provided by the :mod:`zlib` module.
-The :mod:`gzip` module provides the :class:`GzipFile` class which is modeled
-after Python's File Object. The :class:`GzipFile` class reads and writes
-:program:`gzip`\ -format files, automatically compressing or decompressing the
-data so that it looks like an ordinary file object.
+The :mod:`gzip` module provides the :class:`GzipFile` class. The :class:`GzipFile`
+class reads and writes :program:`gzip`\ -format files, automatically compressing
+or decompressing the data so that it looks like an ordinary :term:`file object`.
Note that additional file formats which can be decompressed by the
:program:`gzip` and :program:`gunzip` programs, such as those produced by
@@ -27,7 +26,7 @@
.. class:: GzipFile(filename=None, mode=None, compresslevel=9, fileobj=None, mtime=None)
Constructor for the :class:`GzipFile` class, which simulates most of the methods
- of a file object, with the exception of the :meth:`readinto` and
+ of a :term:`file object`, with the exception of the :meth:`readinto` and
:meth:`truncate` methods. At least one of *fileobj* and *filename* must be
given a non-trivial value.
Modified: python/branches/release31-maint/Doc/library/http.client.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/http.client.rst (original)
+++ python/branches/release31-maint/Doc/library/http.client.rst Wed Sep 15 13:25:11 2010
@@ -359,7 +359,7 @@
object. The Content-Length header is set to the length of the
string.
- The *body* may also be an open file object, in which case the
+ The *body* may also be an open :term:`file object`, in which case the
contents of the file is sent; this file object should support
``fileno()`` and ``read()`` methods. The header Content-Length is
automatically set to the length of the file as reported by
Modified: python/branches/release31-maint/Doc/library/imp.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/imp.rst (original)
+++ python/branches/release31-maint/Doc/library/imp.rst Wed Sep 15 13:25:11 2010
@@ -48,8 +48,8 @@
If search is successful, the return value is a 3-element tuple ``(file,
pathname, description)``:
- *file* is an open file object positioned at the beginning, *pathname* is the
- pathname of the file found, and *description* is a 3-element tuple as
+ *file* is an open :term:`file object` positioned at the beginning, *pathname*
+ is the pathname of the file found, and *description* is a 3-element tuple as
contained in the list returned by :func:`get_suffixes` describing the kind of
module found.
Modified: python/branches/release31-maint/Doc/library/mmap.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/mmap.rst (original)
+++ python/branches/release31-maint/Doc/library/mmap.rst Wed Sep 15 13:25:11 2010
@@ -5,14 +5,13 @@
:synopsis: Interface to memory-mapped files for Unix and Windows.
-Memory-mapped file objects behave like both :class:`bytes` and like file
-objects. Unlike normal :class:`bytes` objects, however, these are mutable.
-You can use mmap objects in most places where :class:`bytes` are expected; for
-example, you can use the :mod:`re` module to search through a memory-mapped file.
-Since they're mutable, you can change a single byte by doing ``obj[index] = 97``,
-or change a subsequence by assigning to a slice: ``obj[i1:i2] = b'...'``.
-You can also read and write data starting at the current file position, and
-:meth:`seek` through the file to different positions.
+Memory-mapped file objects behave like both :class:`bytearray` and like
+:term:`file objects `. You can use mmap objects in most places
+where :class:`bytearray` are expected; for example, you can use the :mod:`re`
+module to search through a memory-mapped file. You can also change a single
+byte by doing ``obj[index] = 97``, or change a subsequence by assigning to a
+slice: ``obj[i1:i2] = b'...'``. You can also read and write data starting at
+the current file position, and :meth:`seek` through the file to different positions.
A memory-mapped file is created by the :class:`mmap` constructor, which is
different on Unix and on Windows. In either case you must provide a file
Modified: python/branches/release31-maint/Doc/library/nntplib.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/nntplib.rst (original)
+++ python/branches/release31-maint/Doc/library/nntplib.rst Wed Sep 15 13:25:11 2010
@@ -143,9 +143,9 @@
*groups* is a list of group names that are new since the given date and time. If
the *file* parameter is supplied, then the output of the ``NEWGROUPS`` command
is stored in a file. If *file* is a string, then the method will open a file
- object with that name, write to it then close it. If *file* is a file object,
- then it will start calling :meth:`write` on it to store the lines of the command
- output. If *file* is supplied, then the returned *list* is an empty list.
+ object with that name, write to it then close it. If *file* is a :term:`file
+ object`, then it will start calling :meth:`write` on it to store the lines of
+ the command output. If *file* is supplied, then the returned *list* is an empty list.
.. method:: NNTP.newnews(group, date, time, [file])
@@ -155,9 +155,9 @@
``(response, articles)`` where *articles* is a list of message ids. If the
*file* parameter is supplied, then the output of the ``NEWNEWS`` command is
stored in a file. If *file* is a string, then the method will open a file
- object with that name, write to it then close it. If *file* is a file object,
- then it will start calling :meth:`write` on it to store the lines of the command
- output. If *file* is supplied, then the returned *list* is an empty list.
+ object with that name, write to it then close it. If *file* is a :term:`file
+ object`, then it will start calling :meth:`write` on it to store the lines of the
+ command output. If *file* is supplied, then the returned *list* is an empty list.
.. method:: NNTP.list([file])
@@ -169,9 +169,9 @@
not, and ``'m'`` if the newsgroup is moderated. (Note the ordering: *last*,
*first*.) If the *file* parameter is supplied, then the output of the ``LIST``
command is stored in a file. If *file* is a string, then the method will open
- a file object with that name, write to it then close it. If *file* is a file
- object, then it will start calling :meth:`write` on it to store the lines of the
- command output. If *file* is supplied, then the returned *list* is an empty
+ a file with that name, write to it then close it. If *file* is a :term:`file
+ object`, then it will start calling :meth:`write` on it to store the lines of
+ the command output. If *file* is supplied, then the returned *list* is an empty
list.
@@ -207,8 +207,8 @@
Send a ``HELP`` command. Return a pair ``(response, list)`` where *list* is a
list of help strings. If the *file* parameter is supplied, then the output of
the ``HELP`` command is stored in a file. If *file* is a string, then the
- method will open a file object with that name, write to it then close it. If
- *file* is a file object, then it will start calling :meth:`write` on it to store
+ method will open a file with that name, write to it then close it. If *file*
+ is a :term:`file object`, then it will start calling :meth:`write` on it to store
the lines of the command output. If *file* is supplied, then the returned *list*
is an empty list.
@@ -243,8 +243,8 @@
Send a ``BODY`` command, where *id* has the same meaning as for :meth:`stat`.
If the *file* parameter is supplied, then the body is stored in a file. If
- *file* is a string, then the method will open a file object with that name,
- write to it then close it. If *file* is a file object, then it will start
+ *file* is a string, then the method will open a file with that name, write
+ to it then close it. If *file* is a :term:`file object`, then it will start
calling :meth:`write` on it to store the lines of the body. Return as for
:meth:`head`. If *file* is supplied, then the returned *list* is an empty list.
@@ -270,9 +270,9 @@
text)``, where *id* is an article number (as a string) and *text* is the text of
the requested header for that article. If the *file* parameter is supplied, then
the output of the ``XHDR`` command is stored in a file. If *file* is a string,
- then the method will open a file object with that name, write to it then close
- it. If *file* is a file object, then it will start calling :meth:`write` on it
- to store the lines of the command output. If *file* is supplied, then the
+ then the method will open a file with that name, write to it then close it.
+ If *file* is a :term:`file object`, then it will start calling :meth:`write` on
+ it to store the lines of the command output. If *file* is supplied, then the
returned *list* is an empty list.
@@ -303,8 +303,8 @@
Process an ``XGTITLE`` command, returning a pair ``(response, list)``, where
*list* is a list of tuples containing ``(name, title)``. If the *file* parameter
is supplied, then the output of the ``XGTITLE`` command is stored in a file.
- If *file* is a string, then the method will open a file object with that name,
- write to it then close it. If *file* is a file object, then it will start
+ If *file* is a string, then the method will open a file with that name, write
+ to it then close it. If *file* is a :term:`file object`, then it will start
calling :meth:`write` on it to store the lines of the command output. If *file*
is supplied, then the returned *list* is an empty list. This is an optional NNTP
extension, and may not be supported by all servers.
@@ -320,8 +320,8 @@
tuple is of the form ``(article number, subject, poster, date, id, references,
size, lines)``. If the *file* parameter is supplied, then the output of the
``XOVER`` command is stored in a file. If *file* is a string, then the method
- will open a file object with that name, write to it then close it. If *file*
- is a file object, then it will start calling :meth:`write` on it to store the
+ will open a file with that name, write to it then close it. If *file* is a
+ :term:`file object`, then it will start calling :meth:`write` on it to store the
lines of the command output. If *file* is supplied, then the returned *list* is
an empty list. This is an optional NNTP extension, and may not be supported by
all servers.
Modified: python/branches/release31-maint/Doc/library/os.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/os.rst (original)
+++ python/branches/release31-maint/Doc/library/os.rst Wed Sep 15 13:25:11 2010
@@ -401,7 +401,7 @@
File Object Creation
--------------------
-These functions create new file objects. (See also :func:`open`.)
+These functions create new :term:`file objects `. (See also :func:`open`.)
.. function:: fdopen(fd[, mode[, bufsize]])
@@ -436,6 +436,10 @@
is slightly deceptive; on Unix platforms, sockets and pipes are also referenced
by file descriptors.
+The :meth:`~file.fileno` method can be used to obtain the file descriptor
+associated with a :term:`file object` when required. Note that using the file
+descriptor directly will bypass the file object methods, ignoring aspects such
+as internal buffering of data.
.. function:: close(fd)
@@ -550,9 +554,9 @@
Force write of file with filedescriptor *fd* to disk. On Unix, this calls the
native :cfunc:`fsync` function; on Windows, the MS :cfunc:`_commit` function.
- If you're starting with a Python file object *f*, first do ``f.flush()``, and
- then do ``os.fsync(f.fileno())``, to ensure that all internal buffers associated
- with *f* are written to disk.
+ If you're starting with a buffered Python :term:`file object` *f*, first do
+ ``f.flush()``, and then do ``os.fsync(f.fileno())``, to ensure that all internal
+ buffers associated with *f* are written to disk.
Availability: Unix, and Windows.
@@ -609,9 +613,9 @@
.. note::
This function is intended for low-level I/O. For normal usage, use the
- built-in function :func:`open`, which returns a "file object" with
+ built-in function :func:`open`, which returns a :term:`file object` with
:meth:`~file.read` and :meth:`~file.wprite` methods (and many more). To
- wrap a file descriptor in a "file object", use :func:`fdopen`.
+ wrap a file descriptor in a file object, use :func:`fdopen`.
.. function:: openpty()
Modified: python/branches/release31-maint/Doc/library/pickle.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/pickle.rst (original)
+++ python/branches/release31-maint/Doc/library/pickle.rst Wed Sep 15 13:25:11 2010
@@ -143,8 +143,8 @@
.. function:: dump(obj, file[, protocol, \*, fix_imports=True])
- Write a pickled representation of *obj* to the open file object *file*. This
- is equivalent to ``Pickler(file, protocol).dump(obj)``.
+ Write a pickled representation of *obj* to the open :term:`file object` *file*.
+ This is equivalent to ``Pickler(file, protocol).dump(obj)``.
The optional *protocol* argument tells the pickler to use the given protocol;
supported protocols are 0, 1, 2, 3. The default protocol is 3; a
@@ -155,8 +155,9 @@
Python needed to read the pickle produced.
The *file* argument must have a write() method that accepts a single bytes
- argument. It can thus be a file object opened for binary writing, a
- io.BytesIO instance, or any other custom object that meets this interface.
+ argument. It can thus be an on-disk file opened for binary writing, a
+ :class:`io.BytesIO` instance, or any other custom object that meets this
+ interface.
If *fix_imports* is True and *protocol* is less than 3, pickle will try to
map the new Python 3.x names to the old module names used in Python 2.x,
@@ -181,8 +182,8 @@
.. function:: load(file, [\*, fix_imports=True, encoding="ASCII", errors="strict"])
- Read a pickled object representation from the open file object *file* and
- return the reconstituted object hierarchy specified therein. This is
+ Read a pickled object representation from the open :term:`file object` *file*
+ and return the reconstituted object hierarchy specified therein. This is
equivalent to ``Unpickler(file).load()``.
The protocol version of the pickle is detected automatically, so no protocol
@@ -191,9 +192,9 @@
The argument *file* must have two methods, a read() method that takes an
integer argument, and a readline() method that requires no arguments. Both
- methods should return bytes. Thus *file* can be a binary file object opened
- for reading, a BytesIO object, or any other custom object that meets this
- interface.
+ methods should return bytes. Thus *file* can be an on-disk file opened
+ for binary reading, a :class:`io.BytesIO` object, or any other custom object
+ that meets this interface.
Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
which are used to control compatiblity support for pickle stream generated
@@ -260,8 +261,8 @@
Python needed to read the pickle produced.
The *file* argument must have a write() method that accepts a single bytes
- argument. It can thus be a file object opened for binary writing, a
- io.BytesIO instance, or any other custom object that meets this interface.
+ argument. It can thus be an on-disk file opened for binary writing, a
+ :class:`io.BytesIO` instance, or any other custom object that meets this interface.
If *fix_imports* is True and *protocol* is less than 3, pickle will try to
map the new Python 3.x names to the old module names used in Python 2.x,
@@ -304,9 +305,9 @@
The argument *file* must have two methods, a read() method that takes an
integer argument, and a readline() method that requires no arguments. Both
- methods should return bytes. Thus *file* can be a binary file object opened
- for reading, a BytesIO object, or any other custom object that meets this
- interface.
+ methods should return bytes. Thus *file* can be an on-disk file object opened
+ for binary reading, a :class:`io.BytesIO` object, or any other custom object
+ that meets this interface.
Optional keyword arguments are *fix_imports*, *encoding* and *errors*,
which are used to control compatiblity support for pickle stream generated
Modified: python/branches/release31-maint/Doc/library/quopri.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/quopri.rst (original)
+++ python/branches/release31-maint/Doc/library/quopri.rst Wed Sep 15 13:25:11 2010
@@ -22,23 +22,23 @@
.. function:: decode(input, output[,header])
Decode the contents of the *input* file and write the resulting decoded binary
- data to the *output* file. *input* and *output* must either be file objects or
- objects that mimic the file object interface. *input* will be read until
- ``input.readline()`` returns an empty string. If the optional argument *header*
- is present and true, underscore will be decoded as space. This is used to decode
- "Q"-encoded headers as described in :rfc:`1522`: "MIME (Multipurpose Internet
- Mail Extensions) Part Two: Message Header Extensions for Non-ASCII Text".
+ data to the *output* file. *input* and *output* must be :term:`file objects
+ `. *input* will be read until ``input.readline()`` returns an
+ empty string. If the optional argument *header* is present and true, underscore
+ will be decoded as space. This is used to decode "Q"-encoded headers as
+ described in :rfc:`1522`: "MIME (Multipurpose Internet Mail Extensions)
+ Part Two: Message Header Extensions for Non-ASCII Text".
.. function:: encode(input, output, quotetabs)
Encode the contents of the *input* file and write the resulting quoted-printable
- data to the *output* file. *input* and *output* must either be file objects or
- objects that mimic the file object interface. *input* will be read until
- ``input.readline()`` returns an empty string. *quotetabs* is a flag which
- controls whether to encode embedded spaces and tabs; when true it encodes such
- embedded whitespace, and when false it leaves them unencoded. Note that spaces
- and tabs appearing at the end of lines are always encoded, as per :rfc:`1521`.
+ data to the *output* file. *input* and *output* must be :term:`file objects
+ `. *input* will be read until ``input.readline()`` returns an
+ empty string. *quotetabs* is a flag which controls whether to encode embedded
+ spaces and tabs; when true it encodes such embedded whitespace, and when
+ false it leaves them unencoded. Note that spaces and tabs appearing at the
+ end of lines are always encoded, as per :rfc:`1521`.
.. function:: decodestring(s[,header])
Modified: python/branches/release31-maint/Doc/library/select.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/select.rst (original)
+++ python/branches/release31-maint/Doc/library/select.rst Wed Sep 15 13:25:11 2010
@@ -79,11 +79,12 @@
single: socket() (in module socket)
single: popen() (in module os)
- Among the acceptable object types in the sequences are Python file objects (e.g.
- ``sys.stdin``, or objects returned by :func:`open` or :func:`os.popen`), socket
- objects returned by :func:`socket.socket`. You may also define a :dfn:`wrapper`
- class yourself, as long as it has an appropriate :meth:`fileno` method (that
- really returns a file descriptor, not just a random integer).
+ Among the acceptable object types in the sequences are Python :term:`file
+ objects ` (e.g. ``sys.stdin``, or objects returned by
+ :func:`open` or :func:`os.popen`), socket objects returned by
+ :func:`socket.socket`. You may also define a :dfn:`wrapper` class yourself,
+ as long as it has an appropriate :meth:`fileno` method (that really returns
+ a file descriptor, not just a random integer).
.. note::
Modified: python/branches/release31-maint/Doc/library/socket.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/socket.rst (original)
+++ python/branches/release31-maint/Doc/library/socket.rst Wed Sep 15 13:25:11 2010
@@ -592,7 +592,7 @@
.. index:: single: I/O control; buffering
- Return a :dfn:`file object` associated with the socket. The exact
+ Return a :term:`file object` associated with the socket. The exact
returned type depends on the arguments given to :meth:`makefile`. These
arguments are interpreted the same way as by the built-in :func:`open`
function.
Modified: python/branches/release31-maint/Doc/library/stdtypes.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/stdtypes.rst (original)
+++ python/branches/release31-maint/Doc/library/stdtypes.rst Wed Sep 15 13:25:11 2010
@@ -2210,9 +2210,9 @@
the identifier in the :keyword:`as` clause of :keyword:`with` statements using
this context manager.
- An example of a context manager that returns itself is a file object. File
- objects return themselves from __enter__() to allow :func:`open` to be used as
- the context expression in a :keyword:`with` statement.
+ An example of a context manager that returns itself is a :term:`file object`.
+ File objects return themselves from __enter__() to allow :func:`open` to be
+ used as the context expression in a :keyword:`with` statement.
An example of a context manager that returns a related object is the one
returned by :func:`decimal.localcontext`. These managers set the active
Modified: python/branches/release31-maint/Doc/library/subprocess.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/subprocess.rst (original)
+++ python/branches/release31-maint/Doc/library/subprocess.rst Wed Sep 15 13:25:11 2010
@@ -107,9 +107,9 @@
*stdin*, *stdout* and *stderr* specify the executed programs' standard input,
standard output and standard error file handles, respectively. Valid values
are :data:`PIPE`, an existing file descriptor (a positive integer), an
- existing file object, and ``None``. :data:`PIPE` indicates that a new pipe
- to the child should be created. With ``None``, no redirection will occur;
- the child's file handles will be inherited from the parent. Additionally,
+ existing :term:`file object`, and ``None``. :data:`PIPE` indicates that a
+ new pipe to the child should be created. With ``None``, no redirection will
+ occur; the child's file handles will be inherited from the parent. Additionally,
*stderr* can be :data:`STDOUT`, which indicates that the stderr data from the
applications should be captured into the same file handle as for stdout.
@@ -377,20 +377,20 @@
.. attribute:: Popen.stdin
- If the *stdin* argument was :data:`PIPE`, this attribute is a file object
- that provides input to the child process. Otherwise, it is ``None``.
+ If the *stdin* argument was :data:`PIPE`, this attribute is a :term:`file
+ object` that provides input to the child process. Otherwise, it is ``None``.
.. attribute:: Popen.stdout
- If the *stdout* argument was :data:`PIPE`, this attribute is a file object
- that provides output from the child process. Otherwise, it is ``None``.
+ If the *stdout* argument was :data:`PIPE`, this attribute is a :term:`file
+ object` that provides output from the child process. Otherwise, it is ``None``.
.. attribute:: Popen.stderr
- If the *stderr* argument was :data:`PIPE`, this attribute is a file object
- that provides error output from the child process. Otherwise, it is
+ If the *stderr* argument was :data:`PIPE`, this attribute is a :term:`file
+ object` that provides error output from the child process. Otherwise, it is
``None``.
Modified: python/branches/release31-maint/Doc/library/sys.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/sys.rst (original)
+++ python/branches/release31-maint/Doc/library/sys.rst Wed Sep 15 13:25:11 2010
@@ -792,10 +792,10 @@
stdout
stderr
- File objects corresponding to the interpreter's standard input, output and error
- streams. ``stdin`` is used for all interpreter input except for scripts but
- including calls to :func:`input`. ``stdout`` is used for
- the output of :func:`print` and :term:`expression` statements and for the
+ :term:`File objects ` corresponding to the interpreter's standard
+ input, output and error streams. ``stdin`` is used for all interpreter input
+ except for scripts but including calls to :func:`input`. ``stdout`` is used
+ for the output of :func:`print` and :term:`expression` statements and for the
prompts of :func:`input`. The interpreter's own prompts
and (almost all of) its error messages go to ``stderr``. ``stdout`` and
``stderr`` needn't be built-in file objects: any object is acceptable as long
Modified: python/branches/release31-maint/Doc/library/tarfile.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/tarfile.rst (original)
+++ python/branches/release31-maint/Doc/library/tarfile.rst Wed Sep 15 13:25:11 2010
@@ -66,8 +66,8 @@
*mode* ``'r'`` to avoid this. If a compression method is not supported,
:exc:`CompressionError` is raised.
- If *fileobj* is specified, it is used as an alternative to a file object opened
- for *name*. It is supposed to be at position 0.
+ If *fileobj* is specified, it is used as an alternative to a :term:`file object`
+ opened in binary mode for *name*. It is supposed to be at position 0.
For special purposes, there is a second format for *mode*:
``'filemode|[compression]'``. :func:`tarfile.open` will return a :class:`TarFile`
@@ -75,7 +75,7 @@
be done on the file. If given, *fileobj* may be any object that has a
:meth:`read` or :meth:`write` method (depending on the *mode*). *bufsize*
specifies the blocksize and defaults to ``20 * 512`` bytes. Use this variant
- in combination with e.g. ``sys.stdin``, a socket file object or a tape
+ in combination with e.g. ``sys.stdin``, a socket :term:`file object` or a tape
device. However, such a :class:`TarFile` object is limited in that it does
not allow to be accessed randomly, see :ref:`tar-examples`. The currently
possible modes:
@@ -344,9 +344,9 @@
.. method:: TarFile.extractfile(member)
Extract a member from the archive as a file object. *member* may be a filename
- or a :class:`TarInfo` object. If *member* is a regular file, a file-like object
- is returned. If *member* is a link, a file-like object is constructed from the
- link's target. If *member* is none of the above, :const:`None` is returned.
+ or a :class:`TarInfo` object. If *member* is a regular file, a :term:`file-like
+ object` is returned. If *member* is a link, a file-like object is constructed from
+ the link's target. If *member* is none of the above, :const:`None` is returned.
.. note::
@@ -380,9 +380,9 @@
.. method:: TarFile.gettarinfo(name=None, arcname=None, fileobj=None)
- Create a :class:`TarInfo` object for either the file *name* or the file object
- *fileobj* (using :func:`os.fstat` on its file descriptor). You can modify some
- of the :class:`TarInfo`'s attributes before you add it using :meth:`addfile`.
+ Create a :class:`TarInfo` object for either the file *name* or the :term:`file
+ object` *fileobj* (using :func:`os.fstat` on its file descriptor). You can modify
+ some of the :class:`TarInfo`'s attributes before you add it using :meth:`addfile`.
If given, *arcname* specifies an alternative name for the file in the archive.
Modified: python/branches/release31-maint/Doc/library/tempfile.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/tempfile.rst (original)
+++ python/branches/release31-maint/Doc/library/tempfile.rst Wed Sep 15 13:25:11 2010
@@ -29,7 +29,7 @@
.. function:: TemporaryFile(mode='w+b', buffering=None, encoding=None, newline=None, suffix='', prefix='tmp', dir=None)
- Return a file-like object that can be used as a temporary storage area.
+ Return a :term:`file-like object` that can be used as a temporary storage area.
The file is created using :func:`mkstemp`. It will be destroyed as soon
as it is closed (including an implicit close when the object is garbage
collected). Under Unix, the directory entry for the file is removed
Modified: python/branches/release31-maint/Doc/library/termios.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/termios.rst (original)
+++ python/branches/release31-maint/Doc/library/termios.rst Wed Sep 15 13:25:11 2010
@@ -17,7 +17,7 @@
All functions in this module take a file descriptor *fd* as their first
argument. This can be an integer file descriptor, such as returned by
-``sys.stdin.fileno()``, or a file object, such as ``sys.stdin`` itself.
+``sys.stdin.fileno()``, or a :term:`file object`, such as ``sys.stdin`` itself.
This module also defines all the constants needed to work with the functions
provided here; these have the same name as their counterparts in C. Please
Modified: python/branches/release31-maint/Doc/library/weakref.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/weakref.rst (original)
+++ python/branches/release31-maint/Doc/library/weakref.rst Wed Sep 15 13:25:11 2010
@@ -58,8 +58,9 @@
Not all objects can be weakly referenced; those objects which can include class
instances, functions written in Python (but not in C), instance methods, sets,
-frozensets, file objects, :term:`generator`\s, type objects, sockets, arrays,
-deques, and regular expression pattern objects.
+frozensets, some :term:`file objects `, :term:`generator`\s, type
+objects, sockets, arrays, deques and regular expression pattern objects.
+
Several built-in types such as :class:`list` and :class:`dict` do not directly
support weak references but can add support through subclassing::
Modified: python/branches/release31-maint/Doc/library/xml.etree.elementtree.rst
==============================================================================
--- python/branches/release31-maint/Doc/library/xml.etree.elementtree.rst (original)
+++ python/branches/release31-maint/Doc/library/xml.etree.elementtree.rst Wed Sep 15 13:25:11 2010
@@ -89,9 +89,10 @@
.. function:: iterparse(source, events=None)
Parses an XML section into an element tree incrementally, and reports what's
- going on to the user. *source* is a filename or file object containing XML data.
- *events* is a list of events to report back. If omitted, only "end" events are
- reported. Returns an :term:`iterator` providing ``(event, elem)`` pairs.
+ going on to the user. *source* is a filename or :term:`file object` containing
+ XML data. *events* is a list of events to report back. If omitted, only "end"
+ events are reported. Returns an :term:`iterator` providing ``(event, elem)``
+ pairs.
.. note::
@@ -359,16 +360,16 @@
.. method:: parse(source, parser=None)
- Loads an external XML section into this element tree. *source* is a file
- name or file object. *parser* is an optional parser instance. If not
- given, the standard XMLTreeBuilder parser is used. Returns the section
+ Loads an external XML section into this element tree. *source* is a file
+ name or :term:`file object`. *parser* is an optional parser instance.
+ If not given, the standard XMLTreeBuilder parser is used. Returns the section
root element.
.. method:: write(file, encoding=None)
- Writes the element tree to a file, as XML. *file* is a file name, or a
- file object opened for writing. *encoding* [1]_ is the output encoding
+ Writes the element tree to a file, as XML. *file* is a file name, or a
+ :term:`file object` opened for writing. *encoding* [1]_ is the output encoding
(default is US-ASCII).
This is the XML file that is going to be manipulated::
Modified: python/branches/release31-maint/Doc/reference/datamodel.rst
==============================================================================
--- python/branches/release31-maint/Doc/reference/datamodel.rst (original)
+++ python/branches/release31-maint/Doc/reference/datamodel.rst Wed Sep 15 13:25:11 2010
@@ -781,9 +781,9 @@
single: stdout (in module sys)
single: stderr (in module sys)
- A file object represents an open file. Various shortcuts are available
- to create file objects: the :func:`open` built-in function, and also
- :func:`os.popen`, :func:`os.fdopen`, and the :meth:`makefile` method
+ A :term:`file object` represents an open file. Various shortcuts are
+ available to create file objects: the :func:`open` built-in function, and
+ also :func:`os.popen`, :func:`os.fdopen`, and the :meth:`makefile` method
of socket objects (and perhaps by other functions or methods provided
by extension modules).
Modified: python/branches/release31-maint/Doc/tutorial/inputoutput.rst
==============================================================================
--- python/branches/release31-maint/Doc/tutorial/inputoutput.rst (original)
+++ python/branches/release31-maint/Doc/tutorial/inputoutput.rst Wed Sep 15 13:25:11 2010
@@ -232,8 +232,8 @@
builtin: open
object: file
-:func:`open` returns a file object, and is most commonly used with two
-arguments: ``open(filename, mode)``.
+:func:`open` returns a :term:`file object`, and is most commonly used with
+two arguments: ``open(filename, mode)``.
::
From python-checkins at python.org Wed Sep 15 13:25:22 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 13:25:22 +0200 (CEST)
Subject: [Python-checkins] r84834 - python/branches/release27-maint
Message-ID: <20100915112522.28D2FEE9D0@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 13:25:22 2010
New Revision: 84834
Log:
Blocked revisions 84827-84829 via svnmerge
........
r84827 | antoine.pitrou | 2010-09-15 11:58:26 +0200 (mer., 15 sept. 2010) | 3 lines
Add a glossary entry for file objects.
........
r84828 | antoine.pitrou | 2010-09-15 12:08:31 +0200 (mer., 15 sept. 2010) | 3 lines
Update file-related information in the FAQ.
........
r84829 | antoine.pitrou | 2010-09-15 13:11:28 +0200 (mer., 15 sept. 2010) | 3 lines
Add cross-references to the glossary entry for file objects.
........
Modified:
python/branches/release27-maint/ (props changed)
From python-checkins at python.org Wed Sep 15 15:01:19 2010
From: python-checkins at python.org (matthias.klose)
Date: Wed, 15 Sep 2010 15:01:19 +0200 (CEST)
Subject: [Python-checkins] r84835 -
python/branches/release27-maint/Lib/ctypes/util.py
Message-ID: <20100915130119.51AAFEE9C7@mail.python.org>
Author: matthias.klose
Date: Wed Sep 15 15:01:19 2010
New Revision: 84835
Log:
Try harder on issue #7356: ctypes.util: Make parsing of ldconfig output
independent of the locale. Set LC_ALL=C too.
Modified:
python/branches/release27-maint/Lib/ctypes/util.py
Modified: python/branches/release27-maint/Lib/ctypes/util.py
==============================================================================
--- python/branches/release27-maint/Lib/ctypes/util.py (original)
+++ python/branches/release27-maint/Lib/ctypes/util.py Wed Sep 15 15:01:19 2010
@@ -185,7 +185,7 @@
def _findLib_ldconfig(name):
# XXX assuming GLIBC's ldconfig (with option -p)
expr = r'/[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name)
- f = os.popen('LANG=C /sbin/ldconfig -p 2>/dev/null')
+ f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null')
try:
data = f.read()
finally:
From python-checkins at python.org Wed Sep 15 15:06:09 2010
From: python-checkins at python.org (matthias.klose)
Date: Wed, 15 Sep 2010 15:06:09 +0200 (CEST)
Subject: [Python-checkins] r84836 - python/branches/py3k/Lib/ctypes/util.py
Message-ID: <20100915130609.406AAEE9F1@mail.python.org>
Author: matthias.klose
Date: Wed Sep 15 15:06:09 2010
New Revision: 84836
Log:
Try harder on issue #7356: ctypes.util: Make parsing of ldconfig output
independent of the locale. Set LC_ALL=C too.
Modified:
python/branches/py3k/Lib/ctypes/util.py
Modified: python/branches/py3k/Lib/ctypes/util.py
==============================================================================
--- python/branches/py3k/Lib/ctypes/util.py (original)
+++ python/branches/py3k/Lib/ctypes/util.py Wed Sep 15 15:06:09 2010
@@ -205,7 +205,7 @@
# XXX assuming GLIBC's ldconfig (with option -p)
expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \
% (abi_type, re.escape(name))
- with contextlib.closing(os.popen('LANG=C /sbin/ldconfig -p 2>/dev/null')) as f:
+ with contextlib.closing(os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null')) as f:
data = f.read()
res = re.search(expr, data)
if not res:
From python-checkins at python.org Wed Sep 15 15:08:12 2010
From: python-checkins at python.org (matthias.klose)
Date: Wed, 15 Sep 2010 15:08:12 +0200 (CEST)
Subject: [Python-checkins] r84837 -
python/branches/release31-maint/Lib/ctypes/util.py
Message-ID: <20100915130812.E60B0EE9C7@mail.python.org>
Author: matthias.klose
Date: Wed Sep 15 15:08:12 2010
New Revision: 84837
Log:
Merged revisions 84836 via svnmerge from
svn+ssh://pythondev at svn.python.org/python/branches/py3k
........
r84836 | matthias.klose | 2010-09-15 15:06:09 +0200 (Mi, 15 Sep 2010) | 3 lines
Try harder on issue #7356: ctypes.util: Make parsing of ldconfig output
independent of the locale. Set LC_ALL=C too.
........
Modified:
python/branches/release31-maint/Lib/ctypes/util.py
Modified: python/branches/release31-maint/Lib/ctypes/util.py
==============================================================================
--- python/branches/release31-maint/Lib/ctypes/util.py (original)
+++ python/branches/release31-maint/Lib/ctypes/util.py Wed Sep 15 15:08:12 2010
@@ -219,7 +219,7 @@
# XXX assuming GLIBC's ldconfig (with option -p)
expr = r'(\S+)\s+\((%s(?:, OS ABI:[^\)]*)?)\)[^/]*(/[^\(\)\s]*lib%s\.[^\(\)\s]*)' \
% (abi_type, re.escape(name))
- f = os.popen('LANG=C /sbin/ldconfig -p 2>/dev/null')
+ f = os.popen('LC_ALL=C LANG=C /sbin/ldconfig -p 2>/dev/null')
try:
data = f.read()
finally:
From ncoghlan at gmail.com Wed Sep 15 15:28:20 2010
From: ncoghlan at gmail.com (Nick Coghlan)
Date: Wed, 15 Sep 2010 23:28:20 +1000
Subject: [Python-checkins] r84823 -
python/branches/py3k/Doc/reference/expressions.rst
In-Reply-To: <20100915000926.8AFF3EE9B1@mail.python.org>
References: <20100915000926.8AFF3EE9B1@mail.python.org>
Message-ID:
On Wed, Sep 15, 2010 at 10:09 AM, raymond.hettinger
wrote:
> +The formal syntax makes no special provision for negative indices in
> +sequences; however, built-in sequences all provide a :meth:`__getitem__`
> +method that interprets negative indices by adding the length of the sequence
> +to the index (so that ``x[-1]`` selects the last item of ``x``). ?The
> +resulting value must be a nonnegative integer less than the number of items in
> +the sequence, and the subscription selects the item whose index is that value
> +(counting from zero). Since the support for negative indices and slicing
> +occurs in the object's :meth:`__getitem__` method, subclasses overriding
> +this method will need to explicitly add that support.
Perhaps mention the slice.indices(len) helper for performing the
standard conversion from negative indices to positive ones when
dealing with negative indices *in* slices?
Cheers,
Nick.
--
Nick Coghlan?? |?? ncoghlan at gmail.com?? |?? Brisbane, Australia
From python-checkins at python.org Wed Sep 15 17:09:40 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 17:09:40 +0200 (CEST)
Subject: [Python-checkins] r84838 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100915150940.98B77EE9EA@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 17:09:40 2010
New Revision: 84838
Log:
Add entries to whatsnew
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Wed Sep 15 17:09:40 2010
@@ -211,6 +211,12 @@
(Proposed and implemented by Mark Dickinson; :issue:`9337`.)
+* :class:`memoryview` objects now have a :meth:`release()` method and support
+ the context manager protocol. This allows timely release of any resources
+ that were acquired when requesting a buffer from the original object.
+
+ (Added by Antoine Pitrou; :issue:`9757`.)
+
* The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
pointing to the original callable function. This allows wrapped functions to
be introspected. It also copies :attr:`__annotations__` if defined. And now
@@ -397,6 +403,14 @@
5-tuple), and :data:`ssl.OPENSSL_VERSION_NUMBER` (an integer). (Added by
Antoine Pitrou; :issue:`8321`.)
+* Instances of :class:`unittest.TestCase` have two new methods
+ :meth:`~unittest.TestCase.assertWarns` and :meth:`~unittest.TestCase.assertWarnsRegexp`
+ to check that a given warning type was triggered by the code under test::
+
+ with self.assertWarns(DeprecationWarning):
+ legacy_function('XYZ')
+
+
* The previously deprecated :func:`string.maketrans` function has been removed
in favor of the static methods, :meth:`bytes.maketrans` and
:meth:`bytearray.maketrans`. This change solves the confusion around which
@@ -464,7 +478,7 @@
(Contributed by Antoine Pitrou; :issue:`7451`.)
-- Python's peephole optimizer now recognizes patterns such ``x in {1, 2, 3}`` as
+* Python's peephole optimizer now recognizes patterns such ``x in {1, 2, 3}`` as
being a test for membership in a set of constants. The optimizer recasts the
:class:`set` as a :class:`frozenset` and stores the pre-built constant.
@@ -486,6 +500,14 @@
(Patch by Florent Xicluna in :issue:`7622` and :issue:`7462`.)
+* Serializing and unserializing data using the :mod:`pickle` module is now
+ up to 4x faster, thanks to various optimizations initially contributed
+ to the Unladen Swalled project.
+
+ (Ported to Python 3 by Alexandre Vassalotti and Antoine Pitrou in
+ :issue:`9410`)
+
+
Filenames and Unicode
=====================
@@ -498,6 +520,8 @@
The :mod:`os` module has two new functions: :func:`~os.fsencode` and
:func:`~os.fsdecode`.
+.. XXX mention Victor's improvements for support of undecodable filenames.
+
.. IDLE
====
From python-checkins at python.org Wed Sep 15 17:13:17 2010
From: python-checkins at python.org (antoine.pitrou)
Date: Wed, 15 Sep 2010 17:13:17 +0200 (CEST)
Subject: [Python-checkins] r84839 - python/branches/py3k/Doc/whatsnew/3.2.rst
Message-ID: <20100915151317.9700CEE996@mail.python.org>
Author: antoine.pitrou
Date: Wed Sep 15 17:13:17 2010
New Revision: 84839
Log:
Move library changes to the right section
Modified:
python/branches/py3k/Doc/whatsnew/3.2.rst
Modified: python/branches/py3k/Doc/whatsnew/3.2.rst
==============================================================================
--- python/branches/py3k/Doc/whatsnew/3.2.rst (original)
+++ python/branches/py3k/Doc/whatsnew/3.2.rst Wed Sep 15 17:13:17 2010
@@ -217,20 +217,6 @@
(Added by Antoine Pitrou; :issue:`9757`.)
-* The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
- pointing to the original callable function. This allows wrapped functions to
- be introspected. It also copies :attr:`__annotations__` if defined. And now
- it also gracefully skips over missing attributes such as :attr:`__doc__` which
- might not be defined for the wrapped callable.
-
- (By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
- :issue:`8814`.)
-
-* The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
- :func:`~abc.abstractstaticmethod`.
-
- (Patch submitted by Daniel Urban; :issue:`5867`.)
-
* A warning message will now get printed at interpreter shutdown if the
:data:`gc.garbage` list isn't empty. This is meant to make the programmer
aware that their code contains object finalization issues.
@@ -304,6 +290,20 @@
(Contributed by Raymond Hettinger.)
+* The :func:`functools.wraps` decorator now adds a :attr:`__wrapped__` attribute
+ pointing to the original callable function. This allows wrapped functions to
+ be introspected. It also copies :attr:`__annotations__` if defined. And now
+ it also gracefully skips over missing attributes such as :attr:`__doc__` which
+ might not be defined for the wrapped callable.
+
+ (By Nick Coghlan and Terrence Cole; :issue:`9567`, :issue:`3445`, and
+ :issue:`8814`.)
+
+* The :mod:`abc` module now supports :func:`~abc.abstractclassmethod` and
+ :func:`~abc.abstractstaticmethod`.
+
+ (Patch submitted by Daniel Urban; :issue:`5867`.)
+
* The previously deprecated :func:`contextlib.nested` function has been removed
in favor of a plain :keyword:`with` statement which can accept multiple
context managers. The latter technique is faster (because it is built-in),
From python-checkins at python.org Wed Sep 15 23:43:47 2010
From: python-checkins at python.org (giampaolo.rodola)
Date: Wed, 15 Sep 2010 23:43:47 +0200 (CEST)
Subject: [Python-checkins] r84840 - python/branches/py3k/Lib/asyncore.py
Message-ID: <20100915214347.79B11FB1A@mail.python.org>
Author: giampaolo.rodola
Date: Wed Sep 15 23:43:47 2010
New Revision: 84840
Log:
Store all errors signaling a disconnection into a global frozenset to save some computation time on recv() and send().
Modified:
python/branches/py3k/Lib/asyncore.py
Modified: python/branches/py3k/Lib/asyncore.py
==============================================================================
--- python/branches/py3k/Lib/asyncore.py (original)
+++ python/branches/py3k/Lib/asyncore.py Wed Sep 15 23:43:47 2010
@@ -56,6 +56,8 @@
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \
ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, errorcode
+DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED))
+
try:
socket_map
except NameError:
@@ -364,7 +366,7 @@
except socket.error as why:
if why.args[0] == EWOULDBLOCK:
return 0
- elif why.args[0] in (ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED):
+ elif why.args[0] in DISCONNECTED:
self.handle_close()
return 0
else:
@@ -382,7 +384,7 @@
return data
except socket.error as why:
# winsock sometimes throws ENOTCONN
- if why.args[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED]:
+ if why.args[0] in DISCONNECTED:
self.handle_close()
return b''
else:
From python-checkins at python.org Wed Sep 15 23:59:05 2010
From: python-checkins at python.org (giampaolo.rodola)
Date: Wed, 15 Sep 2010 23:59:05 +0200 (CEST)
Subject: [Python-checkins] r84841 - python/branches/py3k/Lib/asyncore.py
Message-ID: <20100915215905.01CD1EE9B9@mail.python.org>
Author: giampaolo.rodola
Date: Wed Sep 15 23:59:04 2010
New Revision: 84841
Log:
rename DISCONNECTED global constant in _DISCONNECTED
Modified:
python/branches/py3k/Lib/asyncore.py
Modified: python/branches/py3k/Lib/asyncore.py
==============================================================================
--- python/branches/py3k/Lib/asyncore.py (original)
+++ python/branches/py3k/Lib/asyncore.py Wed Sep 15 23:59:04 2010
@@ -56,7 +56,7 @@
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \
ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, errorcode
-DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED))
+_DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED))
try:
socket_map
@@ -366,7 +366,7 @@
except socket.error as why:
if why.args[0] == EWOULDBLOCK:
return 0
- elif why.args[0] in DISCONNECTED:
+ elif why.args[0] in _DISCONNECTED:
self.handle_close()
return 0
else:
@@ -384,7 +384,7 @@
return data
except socket.error as why:
# winsock sometimes throws ENOTCONN
- if why.args[0] in DISCONNECTED:
+ if why.args[0] in _DISCONNECTED:
self.handle_close()
return b''
else:
From python-checkins at python.org Thu Sep 16 00:40:38 2010
From: python-checkins at python.org (georg.brandl)
Date: Thu, 16 Sep 2010 00:40:38 +0200 (CEST)
Subject: [Python-checkins] r84842 - peps/trunk/pep-0444.txt
Message-ID: <20100915224038.95AECC5D5@mail.python.org>
Author: georg.brandl
Date: Thu Sep 16 00:40:38 2010
New Revision: 84842
Log:
Add PEP 444, Python Web3 Interface.
Added:
peps/trunk/pep-0444.txt (contents, props changed)
Added: peps/trunk/pep-0444.txt
==============================================================================
--- (empty file)
+++ peps/trunk/pep-0444.txt Thu Sep 16 00:40:38 2010
@@ -0,0 +1,1570 @@
+PEP: 444
+Title: Python Web3 Interface
+Version: $Revision$
+Last-Modified: $Date$
+Author: Chris McDonough ,
+ Armin Ronacher
+Discussions-To: Python Web-SIG
+Status: Draft
+Type: Informational
+Content-Type: text/x-rst
+Created: 19-Jul-2010
+
+
+Abstract
+========
+
+This document specifies a proposed second-generation standard
+interface between web servers and Python web applications or
+frameworks.
+
+
+Rationale and Goals
+===================
+
+This protocol and specification is influenced heavily by the Web
+Services Gateway Interface (WSGI) 1.0 standard described in PEP 333
+[1]_ . The high-level rationale for having any standard that allows
+Python-based web servers and applications to interoperate is outlined
+in PEP 333. This document essentially uses PEP 333 as a template, and
+changes its wording in various places for the purpose of forming a
+different standard.
+
+Python currently boasts a wide variety of web application frameworks
+which use the WSGI 1.0 protocol. However, due to changes in the
+language, the WSGI 1.0 protocol is not compatible with Python 3. This
+specification describes a standardized WSGI-like protocol that lets
+Python 2.6, 2.7 and 3.1+ applications communicate with web servers.
+Web3 is clearly a WSGI derivative; it only uses a different name than
+"WSGI" in order to indicate that it is not in any way backwards
+compatible.
+
+Applications and servers which are written to this specification are
+meant to work properly under Python 2.6.X, Python 2.7.X and Python
+3.1+. Neither an application nor a server that implements the Web3
+specification can be easily written which will work under Python 2
+versions earlier than 2.6 nor Python 3 versions earlier than 3.1.
+
+.. note::
+
+ Whatever Python 3 version fixed http://bugs.python.org/issue4006 so
+ ``os.environ['foo']`` returns surrogates (ala PEP 383) when the
+ value of 'foo' cannot be decoded using the current locale instead
+ of failing with a KeyError is the *true* minimum Python 3 version.
+ In particular, however, Python 3.0 is not supported.
+
+.. note::
+
+ Python 2.6 is the first Python version that supported an alias for
+ ``bytes`` and the ``b"foo"`` literal syntax. This is why it is the
+ minimum version supported by Web3.
+
+Explicability and documentability are the main technical drivers for
+the decisions made within the standard.
+
+
+Differences from WSGI
+=====================
+
+- All protocol-specific environment names are prefixed with ``web3.``
+ rather than ``wsgi.``, eg. ``web3.input`` rather than
+ ``wsgi.input``.
+
+- All values present as environment dictionary *values* are explicitly
+ *bytes* instances instead of native strings. (Environment *keys*
+ however are native strings, always ``str`` regardless of
+ platform).
+
+- All values returned by an application must be bytes instances,
+ including status code, header names and values, and the body.
+
+- Wherever WSGI 1.0 referred to an ``app_iter``, this specification
+ refers to a ``body``.
+
+- No ``start_response()`` callback (and therefore no ``write()``
+ callable nor ``exc_info`` data).
+
+- The ``readline()`` function of ``web3.input`` must support a size
+ hint parameter.
+
+- The ``read()`` function of ``web3.input`` must be length delimited.
+ A call without a size argument must not read more than the content
+ length header specifies. In case a content length header is absent
+ the stream must not return anything on read. It must never request
+ more data than specified from the client.
+
+- No requirement for middleware to yield an empty string if it needs
+ more information from an application to produce output (e.g. no
+ "Middleware Handling of Block Boundaries").
+
+- Filelike objects passed to a "file_wrapper" must have an
+ ``__iter__`` which returns bytes (never text).
+
+- ``wsgi.file_wrapper`` is not supported.
+
+- ``QUERY_STRING``, ``SCRIPT_NAME``, ``PATH_INFO`` values required to
+ be placed in environ by server (each as the empty bytes instance if
+ no associated value is received in the HTTP request).
+
+- ``web3.path_info`` and ``web3.script_name`` should be put into the
+ Web3 environment, if possible, by the origin Web3 server. When
+ available, each is the original, plain 7-bit ASCII, URL-encoded
+ variant of its CGI equivalent derived directly from the request URI
+ (with %2F segment markers and other meta-characters intact). If the
+ server cannot provide one (or both) of these values, it must omit
+ the value(s) it cannot provide from the environment.
+
+- This requirement was removed: "middleware components **must not**
+ block iteration waiting for multiple values from an application
+ iterable. If the middleware needs to accumulate more data from the
+ application before it can produce any output, it **must** yield an
+ empty string."
+
+- ``SERVER_PORT`` must be a bytes instance (not an integer).
+
+- The server must not inject an additional ``Content-Length`` header
+ by guessing the length from the response iterable. This must be set
+ by the application itself in all situations.
+
+- If the origin server advertises that it has the ``web3.async``
+ capability, a Web3 application callable used by the server is
+ permitted to return a callable that accepts no arguments. When it
+ does so, this callable is to be called periodically by the origin
+ server until it returns a non-``None`` response, which must be a
+ normal Web3 response tuple.
+
+ .. XXX (chrism) Needs a section of its own for explanation.
+
+
+Specification Overview
+======================
+
+The Web3 interface has two sides: the "server" or "gateway" side, and
+the "application" or "framework" side. The server side invokes a
+callable object that is provided by the application side. The
+specifics of how that object is provided are up to the server or
+gateway. It is assumed that some servers or gateways will require an
+application's deployer to write a short script to create an instance
+of the server or gateway, and supply it with the application object.
+Other servers and gateways may use configuration files or other
+mechanisms to specify where an application object should be imported
+from, or otherwise obtained.
+
+In addition to "pure" servers/gateways and applications/frameworks, it
+is also possible to create "middleware" components that implement both
+sides of this specification. Such components act as an application to
+their containing server, and as a server to a contained application,
+and can be used to provide extended APIs, content transformation,
+navigation, and other useful functions.
+
+Throughout this specification, we will use the term "application
+callable" to mean "a function, a method, or an instance with a
+``__call__`` method". It is up to the server, gateway, or application
+implementing the application callable to choose the appropriate
+implementation technique for their needs. Conversely, a server,
+gateway, or application that is invoking a callable **must not** have
+any dependency on what kind of callable was provided to it.
+Application callables are only to be called, not introspected upon.
+
+
+The Application/Framework Side
+------------------------------
+
+The application object is simply a callable object that accepts one
+argument. The term "object" should not be misconstrued as requiring
+an actual object instance: a function, method, or instance with a
+``__call__`` method are all acceptable for use as an application
+object. Application objects must be able to be invoked more than
+once, as virtually all servers/gateways (other than CGI) will make
+such repeated requests. It this cannot be guaranteed by the
+implementation of the actual application, it has to be wrapped in a
+function that creates a new instance on each call.
+
+.. note::
+
+ Although we refer to it as an "application" object, this should not
+ be construed to mean that application developers will use Web3 as a
+ web programming API. It is assumed that application developers
+ will continue to use existing, high-level framework services to
+ develop their applications. Web3 is a tool for framework and
+ server developers, and is not intended to directly support
+ application developers.)
+
+An example of an application which is a function (``simple_app``)::
+
+ def simple_app(environ):
+ """Simplest possible application object"""
+ status = b'200 OK'
+ headers = [(b'Content-type', b'text/plain')]
+ body = [b'Hello world!\n']
+ return body, status, headers
+
+An example of an application which is an instance (``simple_app``)::
+
+ class AppClass(object):
+
+ """Produce the same output, but using an instance. An
+ instance of this class must be instantiated before it is
+ passed to the server. """
+
+ def __call__(self, environ):
+ status = b'200 OK'
+ headers = [(b'Content-type', b'text/plain')]
+ body = [b'Hello world!\n']
+ return body, status, headers
+
+ simple_app = AppClass()
+
+Alternately, an application callable may return a callable instead of
+the tuple if the server supports asynchronous execution. See
+information concerning ``web3.async`` for more information.
+
+
+The Server/Gateway Side
+-----------------------
+
+The server or gateway invokes the application callable once for each
+request it receives from an HTTP client, that is directed at the
+application. To illustrate, here is a simple CGI gateway, implemented
+as a function taking an application object. Note that this simple
+example has limited error handling, because by default an uncaught
+exception will be dumped to ``sys.stderr`` and logged by the web
+server.
+
+::
+
+ import locale
+ import os
+ import sys
+
+ encoding = locale.getpreferredencoding()
+
+ stdout = sys.stdout
+
+ if hasattr(sys.stdout, 'buffer'):
+ # Python 3 compatibility; we need to be able to push bytes out
+ stdout = sys.stdout.buffer
+
+ def get_environ():
+ d = {}
+ for k, v in os.environ.items():
+ # Python 3 compatibility
+ if not isinstance(v, bytes):
+ # We must explicitly encode the string to bytes under
+ # Python 3.1+
+ v = v.encode(encoding, 'surrogateescape')
+ d[k] = v
+ return d
+
+ def run_with_cgi(application):
+
+ environ = get_environ()
+ environ['web3.input'] = sys.stdin
+ environ['web3.errors'] = sys.stderr
+ environ['web3.version'] = (1, 0)
+ environ['web3.multithread'] = False
+ environ['web3.multiprocess'] = True
+ environ['web3.run_once'] = True
+ environ['web3.async'] = False
+
+ if environ.get('HTTPS', b'off') in (b'on', b'1'):
+ environ['web3.url_scheme'] = b'https'
+ else:
+ environ['web3.url_scheme'] = b'http'
+
+ rv = application(environ)
+ if hasattr(rv, '__call__'):
+ raise TypeError('This webserver does not support asynchronous '
+ 'responses.')
+ body, status, headers = rv
+
+ CLRF = b'\r\n'
+
+ try:
+ stdout.write(b'Status: ' + status + CRLF)
+ for header_name, header_val in headers:
+ stdout.write(header_name + b': ' + header_val + CRLF)
+ stdout.write(CRLF)
+ for chunk in body:
+ stdout.write(chunk)
+ stdout.flush()
+ finally:
+ if hasattr(body, 'close'):
+ body.close()
+
+
+Middleware: Components that Play Both Sides
+-------------------------------------------
+
+A single object may play the role of a server with respect to some
+application(s), while also acting as an application with respect to
+some server(s). Such "middleware" components can perform such
+functions as:
+
+* Routing a request to different application objects based on the
+ target URL, after rewriting the ``environ`` accordingly.
+
+* Allowing multiple applications or frameworks to run side-by-side in
+ the same process.
+
+* Load balancing and remote processing, by forwarding requests and
+ responses over a network.
+
+* Perform content postprocessing, such as applying XSL stylesheets.
+
+The presence of middleware in general is transparent to both the
+"server/gateway" and the "application/framework" sides of the
+interface, and should require no special support. A user who desires
+to incorporate middleware into an application simply provides the
+middleware component to the server, as if it were an application, and
+configures the middleware component to invoke the application, as if
+the middleware component were a server. Of course, the "application"
+that the middleware wraps may in fact be another middleware component
+wrapping another application, and so on, creating what is referred to
+as a "middleware stack".
+
+A middleware must support asychronous execution if possible or fall
+back to disabling itself.
+
+Here a middleware that changes the ``HTTP_HOST`` key if an ``X-Host``
+header exists and adds a comment to all html responses::
+
+ import time
+
+ def apply_filter(app, environ, filter_func):
+ """Helper function that passes the return value from an
+ application to a filter function when the results are
+ ready.
+ """
+ app_response = app(environ)
+
+ # synchronous response, filter now
+ if not hasattr(app_response, '__call__'):
+ return filter_func(*app_response)
+
+ # asychronous response. filter when results are ready
+ def polling_function():
+ rv = app_response()
+ if rv is not None:
+ return filter_func(*rv)
+ return polling_function
+
+ def proxy_and_timing_support(app):
+ def new_application(environ):
+ def filter_func(body, status, headers):
+ now = time.time()
+ for key, value in headers:
+ if key.lower() == b'content-type' and \
+ value.split(b';')[0] == b'text/html':
+ # assumes ascii compatible encoding in body,
+ # but the middleware should actually parse the
+ # content type header and figure out the
+ # encoding when doing that.
+ body += ('' %
+ (now - then)).encode('ascii')
+ break
+ return body, status, headers
+ then = time.time()
+ host = environ.get('HTTP_X_HOST')
+ if host is not None:
+ environ['HTTP_HOST'] = host
+
+ # use the apply_filter function that applies a given filter
+ # function for both async and sync responses.
+ return apply_filter(app, environ, filter_func)
+ return new_application
+
+ app = proxy_and_timing_support(app)
+
+
+Specification Details
+=====================
+
+The application callable must accept one positional argument. For the
+sake of illustration, we have named it ``environ``, but it is not
+required to have this name. A server or gateway **must** invoke the
+application object using a positional (not keyword) argument.
+(E.g. by calling ``status, headers, body = application(environ)`` as
+shown above.)
+
+The ``environ`` parameter is a dictionary object, containing CGI-style
+environment variables. This object **must** be a builtin Python
+dictionary (*not* a subclass, ``UserDict`` or other dictionary
+emulation), and the application is allowed to modify the dictionary in
+any way it desires. The dictionary must also include certain
+Web3-required variables (described in a later section), and may also
+include server-specific extension variables, named according to a
+convention that will be described below.
+
+When called by the server, the application object must return a tuple
+yielding three elements: ``status``, ``headers`` and ``body``, or, if
+supported by an async server, an argumentless callable which either
+returns ``None`` or a tuple of those three elements.
+
+The ``status`` element is a status in bytes of the form ``b'999
+Message here'``.
+
+``headers`` is a Python list of ``(header_name, header_value)`` pairs
+describing the HTTP response header. The ``headers`` structure must
+be a literal Python list; it must yield two-tuples. Both
+``header_name`` and ``header_value`` must be bytes values.
+
+The ``body`` is an iterable yielding zero or more bytes instances.
+This can be accomplished in a variety of ways, such as by returning a
+list containing bytes instances as ``body``, or by returning a
+generator function as ``body`` that yields bytes instances, or by the
+``body`` being an instance of a class which is iterable. Regardless
+of how it is accomplished, the application object must always return a
+``body`` iterable yielding zero or more bytes instances.
+
+The server or gateway must transmit the yielded bytes to the client in
+an unbuffered fashion, completing the transmission of each set of
+bytes before requesting another one. (In other words, applications
+**should** perform their own buffering. See the `Buffering and
+Streaming`_ section below for more on how application output must be
+handled.)
+
+The server or gateway should treat the yielded bytes as binary byte
+sequences: in particular, it should ensure that line endings are not
+altered. The application is responsible for ensuring that the
+string(s) to be written are in a format suitable for the client. (The
+server or gateway **may** apply HTTP transfer encodings, or perform
+other transformations for the purpose of implementing HTTP features
+such as byte-range transmission. See `Other HTTP Features`_, below,
+for more details.)
+
+If the ``body`` iterable returned by the application has a ``close()``
+method, the server or gateway **must** call that method upon
+completion of the current request, whether the request was completed
+normally, or terminated early due to an error. This is to support
+resource release by the application amd is intended to complement PEP
+325's generator support, and other common iterables with ``close()``
+methods.
+
+Finally, servers and gateways **must not** directly use any other
+attributes of the ``body`` iterable returned by the application.
+
+
+``environ`` Variables
+---------------------
+
+The ``environ`` dictionary is required to contain various CGI
+environment variables, as defined by the Common Gateway Interface
+specification [2]_.
+
+The following CGI variables **must** be present. Each key is a native
+string. Each value is a bytes instance.
+
+.. note::
+
+ In Python 3.1+, a "native string" is a ``str`` type decoded using
+ the ``surrogateescape`` error handler, as done by
+ ``os.environ.__getitem__``. In Python 2.6 and 2.7, a "native
+ string" is a ``str`` types representing a set of bytes.
+
+``REQUEST_METHOD``
+ The HTTP request method, such as ``"GET"`` or ``"POST"``.
+
+``SCRIPT_NAME``
+ The initial portion of the request URL's "path" that corresponds to
+ the application object, so that the application knows its virtual
+ "location". This may be the empty bytes instance if the application
+ corresponds to the "root" of the server. SCRIPT_NAME will be a
+ bytes instance representing a sequence of URL-encoded segments
+ separated by the slash character (``/``). It is assumed that
+ ``%2F`` characters will be decoded into literal slash characters
+ within ``PATH_INFO`` , as per CGI.
+
+``PATH_INFO``
+ The remainder of the request URL's "path", designating the virtual
+ "location" of the request's target within the application. This
+ **may** be a bytes instance if the request URL targets the
+ application root and does not have a trailing slash. PATH_INFO will
+ be a bytes instance representing a sequence of URL-encoded segments
+ separated by the slash character (``/``). It is assumed that
+ ``%2F`` characters will be decoded into literal slash characters
+ within ``PATH_INFO`` , as per CGI.
+
+``QUERY_STRING``
+ The portion of the request URL (in bytes) that follows the ``"?"``,
+ if any, or the empty bytes instance.
+
+``SERVER_NAME``, ``SERVER_PORT``
+ When combined with ``SCRIPT_NAME`` and ``PATH_INFO`` (or their raw
+ equivalents)`, these variables can be used to complete the URL.
+ Note, however, that ``HTTP_HOST``, if present, should be used in
+ preference to ``SERVER_NAME`` for reconstructing the request URL.
+ See the `URL Reconstruction`_ section below for more detail.
+ ``SERVER_PORT`` should be a bytes instance, not an integer.
+
+``SERVER_PROTOCOL``
+ The version of the protocol the client used to send the request.
+ Typically this will be something like ``"HTTP/1.0"`` or
+ ``"HTTP/1.1"`` and may be used by the application to determine how
+ to treat any HTTP request headers. (This variable should probably
+ be called ``REQUEST_PROTOCOL``, since it denotes the protocol used
+ in the request, and is not necessarily the protocol that will be
+ used in the server's response. However, for compatibility with CGI
+ we have to keep the existing name.)
+
+The following CGI values **may** present be in the Web3 environment.
+Each key is a native string. Each value is a bytes instances.
+
+``CONTENT_TYPE``
+ The contents of any ``Content-Type`` fields in the HTTP request.
+
+``CONTENT_LENGTH``
+ The contents of any ``Content-Length`` fields in the HTTP request.
+
+``HTTP_`` Variables
+ Variables corresponding to the client-supplied HTTP request headers
+ (i.e., variables whose names begin with ``"HTTP_"``). The presence
+ or absence of these variables should correspond with the presence or
+ absence of the appropriate HTTP header in the request.
+
+A server or gateway **should** attempt to provide as many other CGI
+variables as are applicable, each with a string for its key and a
+bytes instance for its value. In addition, if SSL is in use, the
+server or gateway **should** also provide as many of the Apache SSL
+environment variables [5]_ as are applicable, such as ``HTTPS=on`` and
+``SSL_PROTOCOL``. Note, however, that an application that uses any
+CGI variables other than the ones listed above are necessarily
+non-portable to web servers that do not support the relevant
+extensions. (For example, web servers that do not publish files will
+not be able to provide a meaningful ``DOCUMENT_ROOT`` or
+``PATH_TRANSLATED``.)
+
+A Web3-compliant server or gateway **should** document what variables
+it provides, along with their definitions as appropriate.
+Applications **should** check for the presence of any variables they
+require, and have a fallback plan in the event such a variable is
+absent.
+
+Note that CGI variable *values* must be bytes instances, if they are
+present at all. It is a violation of this specification for a CGI
+variable's value to be of any type other than ``bytes``. On Python 2,
+this means they will be of type ``str``. On Python 3, this means they
+will be of type ``bytes``.
+
+They *keys* of all CGI and non-CGI variables in the environ, however,
+must be "native strings" (on both Python 2 and Python 3, they will be
+of type ``str``).
+
+In addition to the CGI-defined variables, the ``environ`` dictionary
+**may** also contain arbitrary operating-system "environment
+variables", and **must** contain the following Web3-defined variables.
+
+===================== ===============================================
+Variable Value
+===================== ===============================================
+``web3.version`` The tuple ``(1, 0)``, representing Web3
+ version 1.0.
+
+``web3.url_scheme`` A bytes value representing the "scheme" portion of
+ the URL at which the application is being
+ invoked. Normally, this will have the value
+ ``b"http"`` or ``b"https"``, as appropriate.
+
+``web3.input`` An input stream (file-like object) from which bytes
+ constituting the HTTP request body can be read.
+ (The server or gateway may perform reads
+ on-demand as requested by the application, or
+ it may pre- read the client's request body and
+ buffer it in-memory or on disk, or use any
+ other technique for providing such an input
+ stream, according to its preference.)
+
+``web3.errors`` An output stream (file-like object) to which error
+ output text can be written, for the purpose of
+ recording program or other errors in a
+ standardized and possibly centralized location.
+ This should be a "text mode" stream; i.e.,
+ applications should use ``"\n"`` as a line
+ ending, and assume that it will be converted to
+ the correct line ending by the server/gateway.
+ Applications may *not* send bytes to the
+ 'write' method of this stream; they may only
+ send text.
+
+ For many servers, ``web3.errors`` will be the
+ server's main error log. Alternatively, this
+ may be ``sys.stderr``, or a log file of some
+ sort. The server's documentation should
+ include an explanation of how to configure this
+ or where to find the recorded output. A server
+ or gateway may supply different error streams
+ to different applications, if this is desired.
+
+``web3.multithread`` This value should evaluate true if the
+ application object may be simultaneously
+ invoked by another thread in the same process,
+ and should evaluate false otherwise.
+
+``web3.multiprocess`` This value should evaluate true if an
+ equivalent application object may be
+ simultaneously invoked by another process, and
+ should evaluate false otherwise.
+
+``web3.run_once`` This value should evaluate true if the server
+ or gateway expects (but does not guarantee!)
+ that the application will only be invoked this
+ one time during the life of its containing
+ process. Normally, this will only be true for
+ a gateway based on CGI (or something similar).
+
+``web3.script_name`` The non-URL-decoded ``SCRIPT_NAME`` value.
+ Through a historical inequity, by virtue of the
+ CGI specification, ``SCRIPT_NAME`` is present
+ within the environment as an already
+ URL-decoded string. This is the original
+ URL-encoded value derived from the request URI.
+ If the server cannot provide this value, it
+ must omit it from the environ.
+
+``web3.path_info`` The non-URL-decoded ``PATH_INFO`` value.
+ Through a historical inequity, by virtue of the
+ CGI specification, ``PATH_INFO`` is present
+ within the environment as an already
+ URL-decoded string. This is the original
+ URL-encoded value derived from the request URI.
+ If the server cannot provide this value, it
+ must omit it from the environ.
+
+``web3.async`` This is ``True`` if the webserver supports
+ async invocation. In that case an application
+ is allowed to return a callable instead of a
+ tuple with the response. The exact semantics
+ are not specified by this specification.
+
+===================== ===============================================
+
+Finally, the ``environ`` dictionary may also contain server-defined
+variables. These variables should have names which are native
+strings, composed of only lower-case letters, numbers, dots, and
+underscores, and should be prefixed with a name that is unique to the
+defining server or gateway. For example, ``mod_web3`` might define
+variables with names like ``mod_web3.some_variable``.
+
+
+Input Stream
+~~~~~~~~~~~~
+
+The input stream (``web3.input``) provided by the server must support
+the following methods:
+
+===================== ========
+Method Notes
+===================== ========
+``read(size)`` 1,4
+``readline([size])`` 1,2,4
+``readlines([size])`` 1,3,4
+``__iter__()`` 4
+===================== ========
+
+The semantics of each method are as documented in the Python Library
+Reference, except for these notes as listed in the table above:
+
+1. The server is not required to read past the client's specified
+ ``Content-Length``, and is allowed to simulate an end-of-file
+ condition if the application attempts to read past that point. The
+ application **should not** attempt to read more data than is
+ specified by the ``CONTENT_LENGTH`` variable.
+
+2. The implementation must support the optional ``size`` argument to
+ ``readline()``.
+
+3. The application is free to not supply a ``size`` argument to
+ ``readlines()``, and the server or gateway is free to ignore the
+ value of any supplied ``size`` argument.
+
+4. The ``read``, ``readline`` and ``__iter__`` methods must return a
+ bytes instance. The ``readlines`` method must return a sequence
+ which contains instances of bytes.
+
+The methods listed in the table above **must** be supported by all
+servers conforming to this specification. Applications conforming to
+this specification **must not** use any other methods or attributes of
+the ``input`` object. In particular, applications **must not**
+attempt to close this stream, even if it possesses a ``close()``
+method.
+
+The input stream should silently ignore attempts to read more than the
+content length of the request. If no content length is specified the
+stream must be a dummy stream that does not return anything.
+
+
+Error Stream
+~~~~~~~~~~~~
+
+The error stream (``web3.errors``) provided by the server must support
+the following methods:
+
+=================== ========== ========
+Method Stream Notes
+=================== ========== ========
+``flush()`` ``errors`` 1
+``write(str)`` ``errors`` 2
+``writelines(seq)`` ``errors`` 2
+=================== ========== ========
+
+The semantics of each method are as documented in the Python Library
+Reference, except for these notes as listed in the table above:
+
+1. Since the ``errors`` stream may not be rewound, servers and
+ gateways are free to forward write operations immediately, without
+ buffering. In this case, the ``flush()`` method may be a no-op.
+ Portable applications, however, cannot assume that output is
+ unbuffered or that ``flush()`` is a no-op. They must call
+ ``flush()`` if they need to ensure that output has in fact been
+ written. (For example, to minimize intermingling of data from
+ multiple processes writing to the same error log.)
+
+2. The ``write()`` method must accept a string argument, but needn't
+ necessarily accept a bytes argument. The ``writelines()`` method
+ must accept a sequence argument that consists entirely of strings,
+ but needn't necessarily accept any bytes instance as a member of
+ the sequence.
+
+The methods listed in the table above **must** be supported by all
+servers conforming to this specification. Applications conforming to
+this specification **must not** use any other methods or attributes of
+the ``errors`` object. In particular, applications **must not**
+attempt to close this stream, even if it possesses a ``close()``
+method.
+
+
+Values Returned by A Web3 Application
+-------------------------------------
+
+Web3 applications return an iterable in the form (``status``,
+``headers``, ``body``). The return value can be any iterable type
+that returns exactly three values. If the server supports
+asynchronous applications (``web3.async``), the response may be a
+callable object (which accepts no arguments).
+
+The ``status`` value is assumed by a gateway or server to be an HTTP
+"status" bytes instance like ``b'200 OK'`` or ``b'404 Not Found'``.
+That is, it is a string consisting of a Status-Code and a
+Reason-Phrase, in that order and separated by a single space, with no
+surrounding whitespace or other characters. (See RFC 2616, Section
+6.1.1 for more information.) The string **must not** contain control
+characters, and must not be terminated with a carriage return,
+linefeed, or combination thereof.
+
+The ``headers`` value is assumed by a gateway or server to be a
+literal Python list of ``(header_name, header_value)`` tuples. Each
+``header_name`` must be a bytes instance representing a valid HTTP
+header field-name (as defined by RFC 2616, Section 4.2), without a
+trailing colon or other punctuation. Each ``header_value`` must be a
+bytes instance and **must not** include any control characters,
+including carriage returns or linefeeds, either embedded or at the
+end. (These requirements are to minimize the complexity of any
+parsing that must be performed by servers, gateways, and intermediate
+response processors that need to inspect or modify response headers.)
+
+In general, the server or gateway is responsible for ensuring that
+correct headers are sent to the client: if the application omits a
+header required by HTTP (or other relevant specifications that are in
+effect), the server or gateway **must** add it. For example, the HTTP
+``Date:`` and ``Server:`` headers would normally be supplied by the
+server or gateway. The gateway must however not override values with
+the same name if they are emitted by the application.
+
+(A reminder for server/gateway authors: HTTP header names are
+case-insensitive, so be sure to take that into consideration when
+examining application-supplied headers!)
+
+Applications and middleware are forbidden from using HTTP/1.1
+"hop-by-hop" features or headers, any equivalent features in HTTP/1.0,
+or any headers that would affect the persistence of the client's
+connection to the web server. These features are the exclusive
+province of the actual web server, and a server or gateway **should**
+consider it a fatal error for an application to attempt sending them,
+and raise an error if they are supplied as return values from an
+application in the ``headers`` structure. (For more specifics on
+"hop-by-hop" features and headers, please see the `Other HTTP
+Features`_ section below.)
+
+
+Dealing with Compatibility Across Python Versions
+-------------------------------------------------
+
+Creating Web3 code that runs under both Python 2.6/2.7 and Python 3.1+
+requires some care on the part of the developer. In general, the Web3
+specification assumes a certain level of equivalence between the
+Python 2 ``str`` type and the Python 3 ``bytes`` type. For example,
+under Python 2, the values present in the Web3 ``environ`` will be
+instances of the ``str`` type; in Python 3, these will be instances of
+the ``bytes`` type. The Python 3 ``bytes`` type does not possess all
+the methods of the Python 2 ``str`` type, and some methods which it
+does possess behave differently than the Python 2 ``str`` type.
+Effectively, to ensure that Web3 middleware and applications work
+across Python versions, developers must do these things:
+
+#) Do not assume comparison equivalence between text values and bytes
+ values. If you do so, your code may work under Python 2, but it
+ will not work properly under Python 3. For example, don't write
+ ``somebytes == 'abc'``. This will sometimes be true on Python 2
+ but it will never be true on Python 3, because a sequence of bytes
+ never compares equal to a string under Python 3. Instead, always
+ compare a bytes value with a bytes value, e.g. "somebytes ==
+ b'abc'". Code which does this is compatible with and works the
+ same in Python 2.6, 2.7, and 3.1. The ``b`` in front of ``'abc'``
+ signals to Python 3 that the value is a literal bytes instance;
+ under Python 2 it's a forward compatibility placebo.
+
+#) Don't use the ``__contains__`` method (directly or indirectly) of
+ items that are meant to be byteslike without ensuring that its
+ argument is also a bytes instance. If you do so, your code may
+ work under Python 2, but it will not work properly under Python 3.
+ For example, ``'abc' in somebytes'`` will raise a ``TypeError``
+ under Python 3, but it will return ``True`` under Python 2.6 and
+ 2.7. However, ``b'abc' in somebytes`` will work the same on both
+ versions. In Python 3.2, this restriction may be partially
+ removed, as it's rumored that bytes types may obtain a ``__mod__``
+ implementation.
+
+#) ``__getitem__`` should not be used.
+
+ .. XXX
+
+#) Dont try to use the ``format`` method or the ``__mod__`` method of
+ instances of bytes (directly or indirectly). In Python 2, the
+ ``str`` type which we treat equivalently to Python 3's ``bytes``
+ supports these method but actual Python 3's ``bytes`` instances
+ don't support these methods. If you use these methods, your code
+ will work under Python 2, but not under Python 3.
+
+#) Do not try to concatenate a bytes value with a string value. This
+ may work under Python 2, but it will not work under Python 3. For
+ example, doing ``'abc' + somebytes`` will work under Python 2, but
+ it will result in a ``TypeError`` under Python 3. Instead, always
+ make sure you're concatenating two items of the same type,
+ e.g. ``b'abc' + somebytes``.
+
+Web3 expects byte values in other places, such as in all the values
+returned by an application.
+
+In short, to ensure compatibility of Web3 application code between
+Python 2 and Python 3, in Python 2, treat CGI and server variable
+values in the environment as if they had the Python 3 ``bytes`` API
+even though they actually have a more capable API. Likewise for all
+stringlike values returned by a Web3 application.
+
+
+Buffering and Streaming
+-----------------------
+
+Generally speaking, applications will achieve the best throughput by
+buffering their (modestly-sized) output and sending it all at once.
+This is a common approach in existing frameworks: the output is
+buffered in a StringIO or similar object, then transmitted all at
+once, along with the response headers.
+
+The corresponding approach in Web3 is for the application to simply
+return a single-element ``body`` iterable (such as a list) containing
+the response body as a single string. This is the recommended
+approach for the vast majority of application functions, that render
+HTML pages whose text easily fits in memory.
+
+For large files, however, or for specialized uses of HTTP streaming
+(such as multipart "server push"), an application may need to provide
+output in smaller blocks (e.g. to avoid loading a large file into
+memory). It's also sometimes the case that part of a response may be
+time-consuming to produce, but it would be useful to send ahead the
+portion of the response that precedes it.
+
+In these cases, applications will usually return a ``body`` iterator
+(often a generator-iterator) that produces the output in a
+block-by-block fashion. These blocks may be broken to coincide with
+mulitpart boundaries (for "server push"), or just before
+time-consuming tasks (such as reading another block of an on-disk
+file).
+
+Web3 servers, gateways, and middleware **must not** delay the
+transmission of any block; they **must** either fully transmit the
+block to the client, or guarantee that they will continue transmission
+even while the application is producing its next block. A
+server/gateway or middleware may provide this guarantee in one of
+three ways:
+
+1. Send the entire block to the operating system (and request that any
+ O/S buffers be flushed) before returning control to the
+ application, OR
+
+2. Use a different thread to ensure that the block continues to be
+ transmitted while the application produces the next block.
+
+3. (Middleware only) send the entire block to its parent
+ gateway/server.
+
+By providing this guarantee, Web3 allows applications to ensure that
+transmission will not become stalled at an arbitrary point in their
+output data. This is critical for proper functioning of
+e.g. multipart "server push" streaming, where data between multipart
+boundaries should be transmitted in full to the client.
+
+
+Unicode Issues
+--------------
+
+HTTP does not directly support Unicode, and neither does this
+interface. All encoding/decoding must be handled by the
+**application**; all values passed to or from the server must be of
+the Python 3 type ``bytes`` or instances of the Python 2 type ``str``,
+not Python 2 ``unicode`` or Python 3 ``str`` objects.
+
+All "bytes instances" referred to in this specification **must**:
+
+- On Python 2, be of type ``str``.
+
+- On Python 3, be of type ``bytes``.
+
+All "bytes instances" **must not** :
+
+- On Python 2, be of type ``unicode``.
+
+- On Python 3, be of type ``str``.
+
+The result of using a textlike object where a byteslike object is
+required is undefined.
+
+Values returned from a Web3 app as a status or as response headers
+**must** follow RFC 2616 with respect to encoding. That is, the bytes
+returned must contain a character stream of ISO-8859-1 characters, or
+the character stream should use RFC 2047 MIME encoding.
+
+On Python platforms which do not have a native bytes-like type
+(e.g. IronPython, etc.), but instead which generally use textlike
+strings to represent bytes data, the definition of "bytes instance"
+can be changed: their "bytes instances" must be native strings that
+contain only code points representable in ISO-8859-1 encoding
+(``\u0000`` through ``\u00FF``, inclusive). It is a fatal error for
+an application on such a platform to supply strings containing any
+other Unicode character or code point. Similarly, servers and
+gateways on those platforms **must not** supply strings to an
+application containing any other Unicode characters.
+
+.. XXX (armin: Jython now has a bytes type, we might remove this
+ section after seeing about IronPython)
+
+
+HTTP 1.1 Expect/Continue
+------------------------
+
+Servers and gateways that implement HTTP 1.1 **must** provide
+transparent support for HTTP 1.1's "expect/continue" mechanism. This
+may be done in any of several ways:
+
+1. Respond to requests containing an ``Expect: 100-continue`` request
+ with an immediate "100 Continue" response, and proceed normally.
+
+2. Proceed with the request normally, but provide the application with
+ a ``web3.input`` stream that will send the "100 Continue" response
+ if/when the application first attempts to read from the input
+ stream. The read request must then remain blocked until the client
+ responds.
+
+3. Wait until the client decides that the server does not support
+ expect/continue, and sends the request body on its own. (This is
+ suboptimal, and is not recommended.)
+
+Note that these behavior restrictions do not apply for HTTP 1.0
+requests, or for requests that are not directed to an application
+object. For more information on HTTP 1.1 Expect/Continue, see RFC
+2616, sections 8.2.3 and 10.1.1.
+
+
+Other HTTP Features
+-------------------
+
+In general, servers and gateways should "play dumb" and allow the
+application complete control over its output. They should only make
+changes that do not alter the effective semantics of the application's
+response. It is always possible for the application developer to add
+middleware components to supply additional features, so server/gateway
+developers should be conservative in their implementation. In a
+sense, a server should consider itself to be like an HTTP "gateway
+server", with the application being an HTTP "origin server". (See RFC
+2616, section 1.3, for the definition of these terms.)
+
+However, because Web3 servers and applications do not communicate via
+HTTP, what RFC 2616 calls "hop-by-hop" headers do not apply to Web3
+internal communications. Web3 applications **must not** generate any
+"hop-by-hop" headers [4]_, attempt to use HTTP features that would
+require them to generate such headers, or rely on the content of any
+incoming "hop-by-hop" headers in the ``environ`` dictionary. Web3
+servers **must** handle any supported inbound "hop-by-hop" headers on
+their own, such as by decoding any inbound ``Transfer-Encoding``,
+including chunked encoding if applicable.
+
+Applying these principles to a variety of HTTP features, it should be
+clear that a server **may** handle cache validation via the
+``If-None-Match`` and ``If-Modified-Since`` request headers and the
+``Last-Modified`` and ``ETag`` response headers. However, it is not
+required to do this, and the application **should** perform its own
+cache validation if it wants to support that feature, since the
+server/gateway is not required to do such validation.
+
+Similarly, a server **may** re-encode or transport-encode an
+application's response, but the application **should** use a suitable
+content encoding on its own, and **must not** apply a transport
+encoding. A server **may** transmit byte ranges of the application's
+response if requested by the client, and the application doesn't
+natively support byte ranges. Again, however, the application
+**should** perform this function on its own if desired.
+
+Note that these restrictions on applications do not necessarily mean
+that every application must reimplement every HTTP feature; many HTTP
+features can be partially or fully implemented by middleware
+components, thus freeing both server and application authors from
+implementing the same features over and over again.
+
+
+Thread Support
+--------------
+
+Thread support, or lack thereof, is also server-dependent. Servers
+that can run multiple requests in parallel, **should** also provide
+the option of running an application in a single-threaded fashion, so
+that applications or frameworks that are not thread-safe may still be
+used with that server.
+
+
+Implementation/Application Notes
+================================
+
+Server Extension APIs
+---------------------
+
+Some server authors may wish to expose more advanced APIs, that
+application or framework authors can use for specialized purposes.
+For example, a gateway based on ``mod_python`` might wish to expose
+part of the Apache API as a Web3 extension.
+
+In the simplest case, this requires nothing more than defining an
+``environ`` variable, such as ``mod_python.some_api``. But, in many
+cases, the possible presence of middleware can make this difficult.
+For example, an API that offers access to the same HTTP headers that
+are found in ``environ`` variables, might return different data if
+``environ`` has been modified by middleware.
+
+In general, any extension API that duplicates, supplants, or bypasses
+some portion of Web3 functionality runs the risk of being incompatible
+with middleware components. Server/gateway developers should *not*
+assume that nobody will use middleware, because some framework
+developers specifically organize their frameworks to function almost
+entirely as middleware of various kinds.
+
+So, to provide maximum compatibility, servers and gateways that
+provide extension APIs that replace some Web3 functionality, **must**
+design those APIs so that they are invoked using the portion of the
+API that they replace. For example, an extension API to access HTTP
+request headers must require the application to pass in its current
+``environ``, so that the server/gateway may verify that HTTP headers
+accessible via the API have not been altered by middleware. If the
+extension API cannot guarantee that it will always agree with
+``environ`` about the contents of HTTP headers, it must refuse service
+to the application, e.g. by raising an error, returning ``None``
+instead of a header collection, or whatever is appropriate to the API.
+
+These guidelines also apply to middleware that adds information such
+as parsed cookies, form variables, sessions, and the like to
+``environ``. Specifically, such middleware should provide these
+features as functions which operate on ``environ``, rather than simply
+stuffing values into ``environ``. This helps ensure that information
+is calculated from ``environ`` *after* any middleware has done any URL
+rewrites or other ``environ`` modifications.
+
+It is very important that these "safe extension" rules be followed by
+both server/gateway and middleware developers, in order to avoid a
+future in which middleware developers are forced to delete any and all
+extension APIs from ``environ`` to ensure that their mediation isn't
+being bypassed by applications using those extensions!
+
+
+Application Configuration
+-------------------------
+
+This specification does not define how a server selects or obtains an
+application to invoke. These and other configuration options are
+highly server-specific matters. It is expected that server/gateway
+authors will document how to configure the server to execute a
+particular application object, and with what options (such as
+threading options).
+
+Framework authors, on the other hand, should document how to create an
+application object that wraps their framework's functionality. The
+user, who has chosen both the server and the application framework,
+must connect the two together. However, since both the framework and
+the server have a common interface, this should be merely a mechanical
+matter, rather than a significant engineering effort for each new
+server/framework pair.
+
+Finally, some applications, frameworks, and middleware may wish to use
+the ``environ`` dictionary to receive simple string configuration
+options. Servers and gateways **should** support this by allowing an
+application's deployer to specify name-value pairs to be placed in
+``environ``. In the simplest case, this support can consist merely of
+copying all operating system-supplied environment variables from
+``os.environ`` into the ``environ`` dictionary, since the deployer in
+principle can configure these externally to the server, or in the CGI
+case they may be able to be set via the server's configuration files.
+
+Applications **should** try to keep such required variables to a
+minimum, since not all servers will support easy configuration of
+them. Of course, even in the worst case, persons deploying an
+application can create a script to supply the necessary configuration
+values::
+
+ from the_app import application
+
+ def new_app(environ):
+ environ['the_app.configval1'] = b'something'
+ return application(environ)
+
+But, most existing applications and frameworks will probably only need
+a single configuration value from ``environ``, to indicate the
+location of their application or framework-specific configuration
+file(s). (Of course, applications should cache such configuration, to
+avoid having to re-read it upon each invocation.)
+
+
+URL Reconstruction
+------------------
+
+If an application wishes to reconstruct a request's complete URL (as a
+bytes object), it may do so using the following algorithm::
+
+ host = environ.get('HTTP_HOST')
+
+ scheme = environ['web3.url_scheme']
+ port = environ['SERVER_PORT']
+ query = environ['QUERY_STRING']
+
+ url = scheme + b'://'
+
+ if host:
+ url += host
+ else:
+ url += environ['SERVER_NAME']
+
+ if scheme == b'https':
+ if port != b'443':
+ url += b':' + port
+ else:
+ if port != b'80':
+ url += b':' + port
+
+ if 'web3.script_name' in url:
+ url += url_quote(environ['web3.script_name'])
+ else:
+ url += environ['SCRIPT_NAME']
+ if 'web3.path_info' in environ:
+ url += url_quote(environ['web3.path_info'])
+ else:
+ url += environ['PATH_INFO']
+ if query:
+ url += b'?' + query
+
+Note that such a reconstructed URL may not be precisely the same URI
+as requested by the client. Server rewrite rules, for example, may
+have modified the client's originally requested URL to place it in a
+canonical form.
+
+
+Open Questions
+==============
+
+- ``file_wrapper`` replacement. Currently nothing is specified here
+ but it's clear that the old system of in-band signalling is broken
+ if it does not provide a way to figure out as a middleware in the
+ process if the response is a file wrapper.
+
+
+Points of Contention
+====================
+
+Outlined below are potential points of contention regarding this
+specification.
+
+
+WSGI 1.0 Compatibility
+----------------------
+
+Components written using the WSGI 1.0 specification will not
+transparently interoperate with components written using this
+specification. That's because the goals of this proposal and the
+goals of WSGI 1.0 are not directly aligned.
+
+WSGI 1.0 is obliged to provide specification-level backwards
+compatibility with versions of Python between 2.2 and 2.7. This
+specification, however, ditches Python 2.5 and lower compatibility in
+order to provide compatibility between relatively recent versions of
+Python 2 (2.6 and 2.7) as well as relatively recent versions of Python
+3 (3.1).
+
+It is currently impossible to write components which work reliably
+under both Python 2 and Python 3 using the WSGI 1.0 specification,
+because the specification implicitly posits that CGI and server
+variable values in the environ and values returned via
+``start_response`` represent a sequence of bytes that can be addressed
+using the Python 2 string API. It posits such a thing because that
+sort of data type was the sensible way to represent bytes in all
+Python 2 versions, and WSGI 1.0 was conceived before Python 3 existed.
+
+Python 3's ``str`` type supports the full API provided by the Python 2
+``str`` type, but Python 3's ``str`` type does not represent a
+sequence of bytes, it instead represents text. Therefore, using it to
+represent environ values also requires that the environ byte sequence
+be decoded to text via some encoding. We cannot decode these bytes to
+text (at least in any way where the decoding has any meaning other
+than as a tunnelling mechanism) without widening the scope of WSGI to
+include server and gateway knowledge of decoding policies and
+mechanics. WSGI 1.0 never concerned itself with encoding and
+decoding. It made statements about allowable transport values, and
+suggested that various values might be best decoded as one encoding or
+another, but it never required a server to *perform* any decoding
+before
+
+Python 3 does not have a stringlike type that can be used instead to
+represent bytes: it has a ``bytes`` type. A bytes type operates quite
+a bit like a Python 2 ``str`` in Python 3.1+, but it lacks behavior
+equivalent to ``str.__mod__`` and its iteration protocol, and
+containment, sequence treatment, and equivalence comparisons are
+different.
+
+In either case, there is no type in Python 3 that behaves just like
+the Python 2 ``str`` type, and a way to create such a type doesn't
+exist because there is no such thing as a "String ABC" which would
+allow a suitable type to be built. Due to this design
+incompatibility, existing WSGI 1.0 servers, middleware, and
+applications will not work under Python 3, even after they are run
+through ``2to3``.
+
+Existing Web-SIG discussions about updating the WSGI specification so
+that it is possible to write a WSGI application that runs in both
+Python 2 and Python 3 tend to revolve around creating a
+specification-level equivalence between the Python 2 ``str`` type
+(which represents a sequence of bytes) and the Python 3 ``str`` type
+(which represents text). Such an equivalence becomes strained in
+various areas, given the different roles of these types. An arguably
+more straightforward equivalence exists between the Python 3 ``bytes``
+type API and a subset of the Python 2 ``str`` type API. This
+specification exploits this subset equivalence.
+
+In the meantime, aside from any Python 2 vs. Python 3 compatibility
+issue, as various discussions on Web-SIG have pointed out, the WSGI
+1.0 specification is too general, providing support (via ``.write``)
+for asynchronous applications at the expense of implementation
+complexity. This specification uses the fundamental incompatibility
+between WSGI 1.0 and Python 3 as a natural divergence point to create
+a specification with reduced complexity by changing specialized
+support for asynchronous applications.
+
+To provide backwards compatibility for older WSGI 1.0 applications, so
+that they may run on a Web3 stack, it is presumed that Web3 middleware
+will be created which can be used "in front" of existing WSGI 1.0
+applications, allowing those existing WSGI 1.0 applications to run
+under a Web3 stack. This middleware will require, when under Python
+3, an equivalence to be drawn between Python 3 ``str`` types and the
+bytes values represented by the HTTP request and all the attendant
+encoding-guessing (or configuration) it implies.
+
+.. note::
+
+ Such middleware *might* in the future, instead of drawing an
+ equivalence between Python 3 ``str`` and HTTP byte values, make use
+ of a yet-to-be-created "ebytes" type (aka "bytes-with-benefits"),
+ particularly if a String ABC proposal is accepted into the Python
+ core and implemented.
+
+Conversely, it is presumed that WSGI 1.0 middleware will be created
+which will allow a Web3 application to run behind a WSGI 1.0 stack on
+the Python 2 platform.
+
+
+Environ and Response Values as Bytes
+------------------------------------
+
+Casual middleware and application writers may consider the use of
+bytes as environment values and response values inconvenient. In
+particular, they won't be able to use common string formatting
+functions such as ``('%s' % bytes_val)`` or
+``bytes_val.format('123')`` because bytes don't have the same API as
+strings on platforms such as Python 3 where the two types differ.
+Likewise, on such platforms, stdlib HTTP-related API support for using
+bytes interchangeably with text can be spotty. In places where bytes
+are inconvenient or incompatible with library APIs, middleware and
+application writers will have to decode such bytes to text explicitly.
+This is particularly inconvenient for middleware writers: to work with
+environment values as strings, they'll have to decode them from an
+implied encoding and if they need to mutate an environ value, they'll
+then need to encode the value into a byte stream before placing it
+into the environ. While the use of bytes by the specification as
+environ values might be inconvenient for casual developers, it
+provides several benefits.
+
+Using bytes types to represent HTTP and server values to an
+application most closely matches reality because HTTP is fundamentally
+a bytes-oriented protocol. If the environ values are mandated to be
+strings, each server will need to use heuristics to guess about the
+encoding of various values provided by the HTTP environment. Using
+all strings might increase casual middleware writer convenience, but
+will also lead to ambiguity and confusion when a value cannot be
+decoded to a meaningful non-surrogate string.
+
+Use of bytes as environ values avoids any potential for the need for
+the specification to mandate that a participating server be informed
+of encoding configuration parameters. If environ values are treated
+as strings, and so must be decoded from bytes, configuration
+parameters may eventually become necessary as policy clues from the
+application deployer. Such a policy would be used to guess an
+appropriate decoding strategy in various circumstances, effectively
+placing the burden for enforcing a particular application encoding
+policy upon the server. If the server must serve more than one
+application, such configuration would quickly become complex. Many
+policies would also be impossible to express declaratively.
+
+In reality, HTTP is a complicated and legacy-fraught protocol which
+requires a complex set of heuristics to make sense of. It would be
+nice if we could allow this protocol to protect us from this
+complexity, but we cannot do so reliably while still providing to
+application writers a level of control commensurate with reality.
+Python applications must often deal with data embedded in the
+environment which not only must be parsed by legacy heuristics, but
+*does not conform even to any existing HTTP specification*. While
+these eventualities are unpleasant, they crop up with regularity,
+making it impossible and undesirable to hide them from application
+developers, as application developers are the only people who are able
+to decide upon an appropriate action when an HTTP specification
+violation is detected.
+
+Some have argued for mixed use of bytes and string values as environ
+*values*. This proposal avoids that strategy. Sole use of bytes as
+environ values makes it possible to fit this specification entirely in
+one's head; you won't need to guess about which values are strings and
+which are bytes.
+
+This protocol would also fit in a developer's head if all environ
+values were strings, but this specification doesn't use that strategy.
+This will likely be the point of greatest contention regarding the use
+of bytes. In defense of bytes: developers often prefer protocols with
+consistent contracts, even if the contracts themselves are suboptimal.
+If we hide encoding issues from a developer until a value that
+contains surrogates causes problems after it has already reached
+beyond the I/O boundary of their application, they will need to do a
+lot more work to fix assumptions made by their application than if we
+were to just present the problem much earlier in terms of "here's some
+bytes, you decode them". This is also a counter-argument to the
+"bytes are inconvenient" assumption: while presenting bytes to an
+application developer may be inconvenient for a casual application
+developer who doesn't care about edge cases, they are extremely
+convenient for the application developer who needs to deal with
+complex, dirty eventualities, because use of bytes allows him the
+appropriate level of control with a clear separation of
+responsibility.
+
+If the protocol uses bytes, it is presumed that libraries will be
+created to make working with bytes-only in the environ and within
+return values more pleasant; for example, analogues of the WSGI 1.0
+libraries named "WebOb" and "Werkzeug". Such libraries will fill the
+gap between convenience and control, allowing the spec to remain
+simple and regular while still allowing casual authors a convenient
+way to create Web3 middleware and application components. This seems
+to be a reasonable alternative to baking encoding policy into the
+protocol, because many such libraries can be created independently
+from the protocol, and application developers can choose the one that
+provides them the appropriate levels of control and convenience for a
+particular job.
+
+Here are some alternatives to using all bytes:
+
+- Have the server decode all values representing CGI and server
+ environ values into strings using the ``latin-1`` encoding, which is
+ lossless. Smuggle any undecodable bytes within the resulting
+ string.
+
+- Encode all CGI and server environ values to strings using the
+ ``utf-8`` encoding with the ``surrogateescape`` error handler. This
+ does not work under any existing Python 2.
+
+- Encode some values into bytes and other values into strings, as
+ decided by their typical usages.
+
+
+Applications Should be Allowed to Read ``web3.input`` Past ``CONTENT_LENGTH``
+-----------------------------------------------------------------------------
+
+At [6]_, Graham Dumpleton makes the assertion that ``wsgi.input``
+should be required to return the empty string as a signifier of
+out-of-data, and that applications should be allowed to read past the
+number of bytes specified in ``CONTENT_LENGTH``, depending only upon
+the empty string as an EOF marker. WSGI relies on an application
+"being well behaved and once all data specified by ``CONTENT_LENGTH``
+is read, that it processes the data and returns any response. That
+same socket connection could then be used for a subsequent request."
+Graham would like WSGI adapters to be required to wrap raw socket
+connections: "this wrapper object will need to count how much data has
+been read, and when the amount of data reaches that as defined by
+``CONTENT_LENGTH``, any subsequent reads should return an empty string
+instead." This may be useful to support chunked encoding and input
+filters.
+
+
+``web3.input`` Unknown Length
+-----------------------------
+
+There's no documented way to indicate that there is content in
+``environ['web3.input']``, but the content length is unknown.
+
+
+``read()`` of ``web3.input`` Should Support No-Size Calling Convention
+----------------------------------------------------------------------
+
+At [6]_, Graham Dumpleton makes the assertion that the ``read()``
+method of ``wsgi.input`` should be callable without arguments, and
+that the result should be "all available request content". Needs
+discussion.
+
+Comment Armin: I changed the spec to require that from an
+implementation. I had too much pain with that in the past already.
+Open for discussions though.
+
+
+Input Filters should set environ ``CONTENT_LENGTH`` to -1
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At [6]_, Graham Dumpleton suggests that an input filter might set
+``environ['CONTENT_LENGTH']`` to -1 to indicate that it mutated the
+input.
+
+
+``headers`` as Literal List of Two-Tuples
+-----------------------------------------
+
+Why do we make applications return a ``headers`` structure that is a
+literal list of two-tuples? I think the iterability of ``headers``
+needs to be maintained while it moves up the stack, but I don't think
+we need to be able to mutate it in place at all times. Could we
+loosen that requirement?
+
+Comment Armin: Strong yes
+
+
+Removed Requirement that Middleware Not Block
+---------------------------------------------
+
+This requirement was removed: "middleware components **must not**
+block iteration waiting for multiple values from an application
+iterable. If the middleware needs to accumulate more data from the
+application before it can produce any output, it **must** yield an
+empty string." This requirement existed to support asynchronous
+applications and servers (see PEP 333's "Middleware Handling of Block
+Boundaries"). Asynchronous applications are now serviced explicitly
+by ``web3.async`` capable protocol (a Web3 application callable may
+itself return a callable).
+
+
+``web3.script_name`` and ``web3.path_info``
+-------------------------------------------
+
+These values are required to be placed into the environment by an
+origin server under this specification. Unlike ``SCRIPT_NAME`` and
+``PATH_INFO``, these must be the original *URL-encoded* variants
+derived from the request URI. We probably need to figure out how
+these should be computed originally, and what their values should be
+if the server performs URL rewriting.
+
+
+Long Response Headers
+---------------------
+
+Bob Brewer notes on Web-SIG [7]_:
+
+ Each header_value must not include any control characters,
+ including carriage returns or linefeeds, either embedded or at the
+ end. (These requirements are to minimize the complexity of any
+ parsing that must be performed by servers, gateways, and
+ intermediate response processors that need to inspect or modify
+ response headers.) [1]_
+
+That's understandable, but HTTP headers are defined as (mostly)
+\*TEXT, and "words of \*TEXT MAY contain characters from character
+sets other than ISO-8859-1 only when encoded according to the rules of
+RFC 2047." [2]_ And RFC 2047 specifies that "an 'encoded-word' may
+not be more than 75 characters long... If it is desirable to encode
+more text than will fit in an 'encoded-word' of 75 characters,
+multiple 'encoded-word's (separated by CRLF SPACE) may be used." [3]_
+This satisfies HTTP header folding rules, as well: "Header fields can
+be extended over multiple lines by preceding each extra line with at
+least one SP or HT." [1]_
+
+So in my reading of HTTP, some code somewhere should introduce
+newlines in longish, encoded response header values. I see three
+options:
+
+1. Keep things as they are and disallow response header values if they
+ contain words over 75 chars that are outside the ISO-8859-1
+ character set.
+
+2. Allow newline characters in WSGI response headers.
+
+3. Require/strongly suggest WSGI servers to do the encoding and
+ folding before sending the value over HTTP.
+
+
+Request Trailers and Chunked Transfer Encoding
+----------------------------------------------
+
+When using chunked transfer encoding on request content, the RFCs
+allow there to be request trailers. These are like request headers
+but come after the final null data chunk. These trailers are only
+available when the chunked data stream is finite length and when it
+has all been read in. Neither WSGI nor Web3 currently supports them.
+
+.. XXX (armin) yield from application iterator should be specify write
+ plus flush by server.
+
+.. XXX (armin) websocket API.
+
+
+References
+==========
+
+.. [1] PEP 333: Python Web Services Gateway Interface
+ (http://www.python.org/dev/peps/pep-0333/)
+
+.. [2] The Common Gateway Interface Specification, v 1.1, 3rd Draft
+ (http://cgi-spec.golux.com/draft-coar-cgi-v11-03.txt)
+
+.. [3] "Chunked Transfer Coding" -- HTTP/1.1, section 3.6.1
+ (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1)
+
+.. [4] "End-to-end and Hop-by-hop Headers" -- HTTP/1.1, Section 13.5.1
+ (http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1)
+
+.. [5] mod_ssl Reference, "Environment Variables"
+ (http://www.modssl.org/docs/2.8/ssl_reference.html#ToC25)
+
+.. [6] Details on WSGI 1.0 amendments/clarifications.
+ (http://blog.dscpl.com.au/2009/10/details-on-wsgi-10-amendmentsclarificat.html)
+
+.. [7] [Web-SIG] WSGI and long response header values
+ http://mail.python.org/pipermail/web-sig/2006-September/002244.html
+
+Copyright
+=========
+
+This document has been placed in the public domain.
+
+
+
+..
+ Local Variables:
+ mode: indented-text
+ indent-tabs-mode: nil
+ sentence-end-double-space: t
+ fill-column: 70
+ coding: utf-8
+ End:
From brett at python.org Thu Sep 16 01:15:33 2010
From: brett at python.org (Brett Cannon)
Date: Wed, 15 Sep 2010 16:15:33 -0700
Subject: [Python-checkins] r84842 - peps/trunk/pep-0444.txt
In-Reply-To: <20100915224038.95AECC5D5@mail.python.org>
References: <20100915224038.95AECC5D5@mail.python.org>
Message-ID:
Can I just ask why 444 since 392 was the last assigned Python 2 number?
On Wed, Sep 15, 2010 at 15:40, georg.brandl wrote:
> Author: georg.brandl
> Date: Thu Sep 16 00:40:38 2010
> New Revision: 84842
>
> Log:
> Add PEP 444, Python Web3 Interface.
>
> Added:
> ? peps/trunk/pep-0444.txt ? (contents, props changed)
>
> Added: peps/trunk/pep-0444.txt
> ==============================================================================
> --- (empty file)
> +++ peps/trunk/pep-0444.txt ? ? Thu Sep 16 00:40:38 2010
> @@ -0,0 +1,1570 @@
> +PEP: 444
> +Title: Python Web3 Interface
> +Version: $Revision$
> +Last-Modified: $Date$
> +Author: Chris McDonough ,
> + ? ? ? ?Armin Ronacher
> +Discussions-To: Python Web-SIG
> +Status: Draft
> +Type: Informational
> +Content-Type: text/x-rst
> +Created: 19-Jul-2010
> +
> +
> +Abstract
> +========
> +
> +This document specifies a proposed second-generation standard
> +interface between web servers and Python web applications or
> +frameworks.
> +
> +
> +Rationale and Goals
> +===================
> +
> +This protocol and specification is influenced heavily by the Web
> +Services Gateway Interface (WSGI) 1.0 standard described in PEP 333
> +[1]_ . ?The high-level rationale for having any standard that allows
> +Python-based web servers and applications to interoperate is outlined
> +in PEP 333. ?This document essentially uses PEP 333 as a template, and
> +changes its wording in various places for the purpose of forming a
> +different standard.
> +
> +Python currently boasts a wide variety of web application frameworks
> +which use the WSGI 1.0 protocol. ?However, due to changes in the
> +language, the WSGI 1.0 protocol is not compatible with Python 3. ?This
> +specification describes a standardized WSGI-like protocol that lets
> +Python 2.6, 2.7 and 3.1+ applications communicate with web servers.
> +Web3 is clearly a WSGI derivative; it only uses a different name than
> +"WSGI" in order to indicate that it is not in any way backwards
> +compatible.
> +
> +Applications and servers which are written to this specification are
> +meant to work properly under Python 2.6.X, Python 2.7.X and Python
> +3.1+. ?Neither an application nor a server that implements the Web3
> +specification can be easily written which will work under Python 2
> +versions earlier than 2.6 nor Python 3 versions earlier than 3.1.
> +
> +.. note::
> +
> + ? Whatever Python 3 version fixed http://bugs.python.org/issue4006 so
> + ? ``os.environ['foo']`` returns surrogates (ala PEP 383) when the
> + ? value of 'foo' cannot be decoded using the current locale instead
> + ? of failing with a KeyError is the *true* minimum Python 3 version.
> + ? In particular, however, Python 3.0 is not supported.
> +
> +.. note::
> +
> + ? Python 2.6 is the first Python version that supported an alias for
> + ? ``bytes`` and the ``b"foo"`` literal syntax. ?This is why it is the
> + ? minimum version supported by Web3.
> +
> +Explicability and documentability are the main technical drivers for
> +the decisions made within the standard.
> +
> +
> +Differences from WSGI
> +=====================
> +
> +- All protocol-specific environment names are prefixed with ``web3.``
> + ?rather than ``wsgi.``, eg. ``web3.input`` rather than
> + ?``wsgi.input``.
> +
> +- All values present as environment dictionary *values* are explicitly
> + ?*bytes* instances instead of native strings. ?(Environment *keys*
> + ?however are native strings, always ``str`` regardless of
> + ?platform).
> +
> +- All values returned by an application must be bytes instances,
> + ?including status code, header names and values, and the body.
> +
> +- Wherever WSGI 1.0 referred to an ``app_iter``, this specification
> + ?refers to a ``body``.
> +
> +- No ``start_response()`` callback (and therefore no ``write()``
> + ?callable nor ``exc_info`` data).
> +
> +- The ``readline()`` function of ``web3.input`` must support a size
> + ?hint parameter.
> +
> +- The ``read()`` function of ``web3.input`` must be length delimited.
> + ?A call without a size argument must not read more than the content
> + ?length header specifies. ?In case a content length header is absent
> + ?the stream must not return anything on read. ?It must never request
> + ?more data than specified from the client.
> +
> +- No requirement for middleware to yield an empty string if it needs
> + ?more information from an application to produce output (e.g. no
> + ?"Middleware Handling of Block Boundaries").
> +
> +- Filelike objects passed to a "file_wrapper" must have an
> + ?``__iter__`` which returns bytes (never text).
> +
> +- ``wsgi.file_wrapper`` is not supported.
> +
> +- ``QUERY_STRING``, ``SCRIPT_NAME``, ``PATH_INFO`` values required to
> + ?be placed in environ by server (each as the empty bytes instance if
> + ?no associated value is received in the HTTP request).
> +
> +- ``web3.path_info`` and ``web3.script_name`` should be put into the
> + ?Web3 environment, if possible, by the origin Web3 server. ?When
> + ?available, each is the original, plain 7-bit ASCII, URL-encoded
> + ?variant of its CGI equivalent derived directly from the request URI
> + ?(with %2F segment markers and other meta-characters intact). ?If the
> + ?server cannot provide one (or both) of these values, it must omit
> + ?the value(s) it cannot provide from the environment.
> +
> +- This requirement was removed: "middleware components **must not**
> + ?block iteration waiting for multiple values from an application
> + ?iterable. ?If the middleware needs to accumulate more data from the
> + ?application before it can produce any output, it **must** yield an
> + ?empty string."
> +
> +- ``SERVER_PORT`` must be a bytes instance (not an integer).
> +
> +- The server must not inject an additional ``Content-Length`` header
> + ?by guessing the length from the response iterable. ?This must be set
> + ?by the application itself in all situations.
> +
> +- If the origin server advertises that it has the ``web3.async``
> + ?capability, a Web3 application callable used by the server is
> + ?permitted to return a callable that accepts no arguments. ?When it
> + ?does so, this callable is to be called periodically by the origin
> + ?server until it returns a non-``None`` response, which must be a
> + ?normal Web3 response tuple.
> +
> + ?.. XXX (chrism) Needs a section of its own for explanation.
> +
> +
> +Specification Overview
> +======================
> +
> +The Web3 interface has two sides: the "server" or "gateway" side, and
> +the "application" or "framework" side. ?The server side invokes a
> +callable object that is provided by the application side. ?The
> +specifics of how that object is provided are up to the server or
> +gateway. ?It is assumed that some servers or gateways will require an
> +application's deployer to write a short script to create an instance
> +of the server or gateway, and supply it with the application object.
> +Other servers and gateways may use configuration files or other
> +mechanisms to specify where an application object should be imported
> +from, or otherwise obtained.
> +
> +In addition to "pure" servers/gateways and applications/frameworks, it
> +is also possible to create "middleware" components that implement both
> +sides of this specification. ?Such components act as an application to
> +their containing server, and as a server to a contained application,
> +and can be used to provide extended APIs, content transformation,
> +navigation, and other useful functions.
> +
> +Throughout this specification, we will use the term "application
> +callable" to mean "a function, a method, or an instance with a
> +``__call__`` method". ?It is up to the server, gateway, or application
> +implementing the application callable to choose the appropriate
> +implementation technique for their needs. ?Conversely, a server,
> +gateway, or application that is invoking a callable **must not** have
> +any dependency on what kind of callable was provided to it.
> +Application callables are only to be called, not introspected upon.
> +
> +
> +The Application/Framework Side
> +------------------------------
> +
> +The application object is simply a callable object that accepts one
> +argument. ?The term "object" should not be misconstrued as requiring
> +an actual object instance: a function, method, or instance with a
> +``__call__`` method are all acceptable for use as an application
> +object. ?Application objects must be able to be invoked more than
> +once, as virtually all servers/gateways (other than CGI) will make
> +such repeated requests. ?It this cannot be guaranteed by the
> +implementation of the actual application, it has to be wrapped in a
> +function that creates a new instance on each call.
> +
> +.. note::
> +
> + ? Although we refer to it as an "application" object, this should not
> + ? be construed to mean that application developers will use Web3 as a
> + ? web programming API. ?It is assumed that application developers
> + ? will continue to use existing, high-level framework services to
> + ? develop their applications. ?Web3 is a tool for framework and
> + ? server developers, and is not intended to directly support
> + ? application developers.)
> +
> +An example of an application which is a function (``simple_app``)::
> +
> + ? ?def simple_app(environ):
> + ? ? ? ?"""Simplest possible application object"""
> + ? ? ? ?status = b'200 OK'
> + ? ? ? ?headers = [(b'Content-type', b'text/plain')]
> + ? ? ? ?body = [b'Hello world!\n']
> + ? ? ? ?return body, status, headers
> +
> +An example of an application which is an instance (``simple_app``)::
> +
> + ? ?class AppClass(object):
> +
> + ? ? ? ?"""Produce the same output, but using an instance. ?An
> + ? ? ? ?instance of this class must be instantiated before it is
> + ? ? ? ?passed to the server. ?"""
> +
> + ? ? ?def __call__(self, environ):
> + ? ? ? ? ? ?status = b'200 OK'
> + ? ? ? ? ? ?headers = [(b'Content-type', b'text/plain')]
> + ? ? ? ? ? ?body = [b'Hello world!\n']
> + ? ? ? ? ? ?return body, status, headers
> +
> + ? ?simple_app = AppClass()
> +
> +Alternately, an application callable may return a callable instead of
> +the tuple if the server supports asynchronous execution. ?See
> +information concerning ``web3.async`` for more information.
> +
> +
> +The Server/Gateway Side
> +-----------------------
> +
> +The server or gateway invokes the application callable once for each
> +request it receives from an HTTP client, that is directed at the
> +application. ?To illustrate, here is a simple CGI gateway, implemented
> +as a function taking an application object. ?Note that this simple
> +example has limited error handling, because by default an uncaught
> +exception will be dumped to ``sys.stderr`` and logged by the web
> +server.
> +
> +::
> +
> + ? ?import locale
> + ? ?import os
> + ? ?import sys
> +
> + ? ?encoding = locale.getpreferredencoding()
> +
> + ? ?stdout = sys.stdout
> +
> + ? ?if hasattr(sys.stdout, 'buffer'):
> + ? ? ? ?# Python 3 compatibility; we need to be able to push bytes out
> + ? ? ? ?stdout = sys.stdout.buffer
> +
> + ? ?def get_environ():
> + ? ? ? ?d = {}
> + ? ? ? ?for k, v in os.environ.items():
> + ? ? ? ? ? ?# Python 3 compatibility
> + ? ? ? ? ? ?if not isinstance(v, bytes):
> + ? ? ? ? ? ? ? ?# We must explicitly encode the string to bytes under
> + ? ? ? ? ? ? ? ?# Python 3.1+
> + ? ? ? ? ? ? ? ?v = v.encode(encoding, 'surrogateescape')
> + ? ? ? ? ? ?d[k] = v
> + ? ? ? ?return d
> +
> + ? ?def run_with_cgi(application):
> +
> + ? ? ? ?environ = get_environ()
> + ? ? ? ?environ['web3.input'] ? ? ? ?= sys.stdin
> + ? ? ? ?environ['web3.errors'] ? ? ? = sys.stderr
> + ? ? ? ?environ['web3.version'] ? ? ?= (1, 0)
> + ? ? ? ?environ['web3.multithread'] ?= False
> + ? ? ? ?environ['web3.multiprocess'] = True
> + ? ? ? ?environ['web3.run_once'] ? ? = True
> + ? ? ? ?environ['web3.async'] ? ? ? ?= False
> +
> + ? ? ? ?if environ.get('HTTPS', b'off') in (b'on', b'1'):
> + ? ? ? ? ? ?environ['web3.url_scheme'] = b'https'
> + ? ? ? ?else:
> + ? ? ? ? ? ?environ['web3.url_scheme'] = b'http'
> +
> + ? ? ? ?rv = application(environ)
> + ? ? ? ?if hasattr(rv, '__call__'):
> + ? ? ? ? ? ?raise TypeError('This webserver does not support asynchronous '
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?'responses.')
> + ? ? ? ?body, status, headers = rv
> +
> + ? ? ? ?CLRF = b'\r\n'
> +
> + ? ? ? ?try:
> + ? ? ? ? ? ?stdout.write(b'Status: ' + status + CRLF)
> + ? ? ? ? ? ?for header_name, header_val in headers:
> + ? ? ? ? ? ? ? ?stdout.write(header_name + b': ' + header_val + CRLF)
> + ? ? ? ? ? ?stdout.write(CRLF)
> + ? ? ? ? ? ?for chunk in body:
> + ? ? ? ? ? ? ? ?stdout.write(chunk)
> + ? ? ? ? ? ? ? ?stdout.flush()
> + ? ? ? ?finally:
> + ? ? ? ? ? ?if hasattr(body, 'close'):
> + ? ? ? ? ? ? ? ?body.close()
> +
> +
> +Middleware: Components that Play Both Sides
> +-------------------------------------------
> +
> +A single object may play the role of a server with respect to some
> +application(s), while also acting as an application with respect to
> +some server(s). ?Such "middleware" components can perform such
> +functions as:
> +
> +* Routing a request to different application objects based on the
> + ?target URL, after rewriting the ``environ`` accordingly.
> +
> +* Allowing multiple applications or frameworks to run side-by-side in
> + ?the same process.
> +
> +* Load balancing and remote processing, by forwarding requests and
> + ?responses over a network.
> +
> +* Perform content postprocessing, such as applying XSL stylesheets.
> +
> +The presence of middleware in general is transparent to both the
> +"server/gateway" and the "application/framework" sides of the
> +interface, and should require no special support. ?A user who desires
> +to incorporate middleware into an application simply provides the
> +middleware component to the server, as if it were an application, and
> +configures the middleware component to invoke the application, as if
> +the middleware component were a server. ?Of course, the "application"
> +that the middleware wraps may in fact be another middleware component
> +wrapping another application, and so on, creating what is referred to
> +as a "middleware stack".
> +
> +A middleware must support asychronous execution if possible or fall
> +back to disabling itself.
> +
> +Here a middleware that changes the ``HTTP_HOST`` key if an ``X-Host``
> +header exists and adds a comment to all html responses::
> +
> + ? ?import time
> +
> + ? ?def apply_filter(app, environ, filter_func):
> + ? ? ? ?"""Helper function that passes the return value from an
> + ? ? ? ?application to a filter function when the results are
> + ? ? ? ?ready.
> + ? ? ? ?"""
> + ? ? ? ?app_response = app(environ)
> +
> + ? ? ? ?# synchronous response, filter now
> + ? ? ? ?if not hasattr(app_response, '__call__'):
> + ? ? ? ? ? ?return filter_func(*app_response)
> +
> + ? ? ? ?# asychronous response. ?filter when results are ready
> + ? ? ? ?def polling_function():
> + ? ? ? ? ? ?rv = app_response()
> + ? ? ? ? ? ?if rv is not None:
> + ? ? ? ? ? ? ? ?return filter_func(*rv)
> + ? ? ? ?return polling_function
> +
> + ? ?def proxy_and_timing_support(app):
> + ? ? ? ?def new_application(environ):
> + ? ? ? ? ? ?def filter_func(body, status, headers):
> + ? ? ? ? ? ? ? ?now = time.time()
> + ? ? ? ? ? ? ? ?for key, value in headers:
> + ? ? ? ? ? ? ? ? ? ?if key.lower() == b'content-type' and \
> + ? ? ? ? ? ? ? ? ? ? ? value.split(b';')[0] == b'text/html':
> + ? ? ? ? ? ? ? ? ? ? ? ?# assumes ascii compatible encoding in body,
> + ? ? ? ? ? ? ? ? ? ? ? ?# but the middleware should actually parse the
> + ? ? ? ? ? ? ? ? ? ? ? ?# content type header and figure out the
> + ? ? ? ? ? ? ? ? ? ? ? ?# encoding when doing that.
> + ? ? ? ? ? ? ? ? ? ? ? ?body += ('' %
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (now - then)).encode('ascii')
> + ? ? ? ? ? ? ? ? ? ? ? ?break
> + ? ? ? ? ? ? ? ?return body, status, headers
> + ? ? ? ? ? ?then = time.time()
> + ? ? ? ? ? ?host = environ.get('HTTP_X_HOST')
> + ? ? ? ? ? ?if host is not None:
> + ? ? ? ? ? ? ? ?environ['HTTP_HOST'] = host
> +
> + ? ? ? ? ? ?# use the apply_filter function that applies a given filter
> + ? ? ? ? ? ?# function for both async and sync responses.
> + ? ? ? ? ? ?return apply_filter(app, environ, filter_func)
> + ? ? ? ?return new_application
> +
> + ? ?app = proxy_and_timing_support(app)
> +
> +
> +Specification Details
> +=====================
> +
> +The application callable must accept one positional argument. ?For the
> +sake of illustration, we have named it ``environ``, but it is not
> +required to have this name. ?A server or gateway **must** invoke the
> +application object using a positional (not keyword) argument.
> +(E.g. by calling ``status, headers, body = application(environ)`` as
> +shown above.)
> +
> +The ``environ`` parameter is a dictionary object, containing CGI-style
> +environment variables. ?This object **must** be a builtin Python
> +dictionary (*not* a subclass, ``UserDict`` or other dictionary
> +emulation), and the application is allowed to modify the dictionary in
> +any way it desires. ?The dictionary must also include certain
> +Web3-required variables (described in a later section), and may also
> +include server-specific extension variables, named according to a
> +convention that will be described below.
> +
> +When called by the server, the application object must return a tuple
> +yielding three elements: ``status``, ``headers`` and ``body``, or, if
> +supported by an async server, an argumentless callable which either
> +returns ``None`` or a tuple of those three elements.
> +
> +The ``status`` element is a status in bytes of the form ``b'999
> +Message here'``.
> +
> +``headers`` is a Python list of ``(header_name, header_value)`` pairs
> +describing the HTTP response header. ?The ``headers`` structure must
> +be a literal Python list; it must yield two-tuples. ?Both
> +``header_name`` and ``header_value`` must be bytes values.
> +
> +The ``body`` is an iterable yielding zero or more bytes instances.
> +This can be accomplished in a variety of ways, such as by returning a
> +list containing bytes instances as ``body``, or by returning a
> +generator function as ``body`` that yields bytes instances, or by the
> +``body`` being an instance of a class which is iterable. ?Regardless
> +of how it is accomplished, the application object must always return a
> +``body`` iterable yielding zero or more bytes instances.
> +
> +The server or gateway must transmit the yielded bytes to the client in
> +an unbuffered fashion, completing the transmission of each set of
> +bytes before requesting another one. ?(In other words, applications
> +**should** perform their own buffering. ?See the `Buffering and
> +Streaming`_ section below for more on how application output must be
> +handled.)
> +
> +The server or gateway should treat the yielded bytes as binary byte
> +sequences: in particular, it should ensure that line endings are not
> +altered. ?The application is responsible for ensuring that the
> +string(s) to be written are in a format suitable for the client. ?(The
> +server or gateway **may** apply HTTP transfer encodings, or perform
> +other transformations for the purpose of implementing HTTP features
> +such as byte-range transmission. ?See `Other HTTP Features`_, below,
> +for more details.)
> +
> +If the ``body`` iterable returned by the application has a ``close()``
> +method, the server or gateway **must** call that method upon
> +completion of the current request, whether the request was completed
> +normally, or terminated early due to an error. ?This is to support
> +resource release by the application amd is intended to complement PEP
> +325's generator support, and other common iterables with ``close()``
> +methods.
> +
> +Finally, servers and gateways **must not** directly use any other
> +attributes of the ``body`` iterable returned by the application.
> +
> +
> +``environ`` Variables
> +---------------------
> +
> +The ``environ`` dictionary is required to contain various CGI
> +environment variables, as defined by the Common Gateway Interface
> +specification [2]_.
> +
> +The following CGI variables **must** be present. ?Each key is a native
> +string. ?Each value is a bytes instance.
> +
> +.. note::
> +
> + ? In Python 3.1+, a "native string" is a ``str`` type decoded using
> + ? the ``surrogateescape`` error handler, as done by
> + ? ``os.environ.__getitem__``. ?In Python 2.6 and 2.7, a "native
> + ? string" is a ``str`` types representing a set of bytes.
> +
> +``REQUEST_METHOD``
> + ?The HTTP request method, such as ``"GET"`` or ``"POST"``.
> +
> +``SCRIPT_NAME``
> + ?The initial portion of the request URL's "path" that corresponds to
> + ?the application object, so that the application knows its virtual
> + ?"location". ?This may be the empty bytes instance if the application
> + ?corresponds to the "root" of the server. ?SCRIPT_NAME will be a
> + ?bytes instance representing a sequence of URL-encoded segments
> + ?separated by the slash character (``/``). ?It is assumed that
> + ?``%2F`` characters will be decoded into literal slash characters
> + ?within ``PATH_INFO`` , as per CGI.
> +
> +``PATH_INFO``
> + ?The remainder of the request URL's "path", designating the virtual
> + ?"location" of the request's target within the application. ?This
> + ?**may** be a bytes instance if the request URL targets the
> + ?application root and does not have a trailing slash. ?PATH_INFO will
> + ?be a bytes instance representing a sequence of URL-encoded segments
> + ?separated by the slash character (``/``). ?It is assumed that
> + ?``%2F`` characters will be decoded into literal slash characters
> + ?within ``PATH_INFO`` , as per CGI.
> +
> +``QUERY_STRING``
> + ?The portion of the request URL (in bytes) that follows the ``"?"``,
> + ?if any, or the empty bytes instance.
> +
> +``SERVER_NAME``, ``SERVER_PORT``
> + ?When combined with ``SCRIPT_NAME`` and ``PATH_INFO`` (or their raw
> + ?equivalents)`, these variables can be used to complete the URL.
> + ?Note, however, that ``HTTP_HOST``, if present, should be used in
> + ?preference to ``SERVER_NAME`` for reconstructing the request URL.
> + ?See the `URL Reconstruction`_ section below for more detail.
> + ?``SERVER_PORT`` should be a bytes instance, not an integer.
> +
> +``SERVER_PROTOCOL``
> + ?The version of the protocol the client used to send the request.
> + ?Typically this will be something like ``"HTTP/1.0"`` or
> + ?``"HTTP/1.1"`` and may be used by the application to determine how
> + ?to treat any HTTP request headers. ?(This variable should probably
> + ?be called ``REQUEST_PROTOCOL``, since it denotes the protocol used
> + ?in the request, and is not necessarily the protocol that will be
> + ?used in the server's response. ?However, for compatibility with CGI
> + ?we have to keep the existing name.)
> +
> +The following CGI values **may** present be in the Web3 environment.
> +Each key is a native string. ?Each value is a bytes instances.
> +
> +``CONTENT_TYPE``
> + ?The contents of any ``Content-Type`` fields in the HTTP request.
> +
> +``CONTENT_LENGTH``
> + ?The contents of any ``Content-Length`` fields in the HTTP request.
> +
> +``HTTP_`` Variables
> + ?Variables corresponding to the client-supplied HTTP request headers
> + ?(i.e., variables whose names begin with ``"HTTP_"``). ?The presence
> + ?or absence of these variables should correspond with the presence or
> + ?absence of the appropriate HTTP header in the request.
> +
> +A server or gateway **should** attempt to provide as many other CGI
> +variables as are applicable, each with a string for its key and a
> +bytes instance for its value. ?In addition, if SSL is in use, the
> +server or gateway **should** also provide as many of the Apache SSL
> +environment variables [5]_ as are applicable, such as ``HTTPS=on`` and
> +``SSL_PROTOCOL``. ?Note, however, that an application that uses any
> +CGI variables other than the ones listed above are necessarily
> +non-portable to web servers that do not support the relevant
> +extensions. ?(For example, web servers that do not publish files will
> +not be able to provide a meaningful ``DOCUMENT_ROOT`` or
> +``PATH_TRANSLATED``.)
> +
> +A Web3-compliant server or gateway **should** document what variables
> +it provides, along with their definitions as appropriate.
> +Applications **should** check for the presence of any variables they
> +require, and have a fallback plan in the event such a variable is
> +absent.
> +
> +Note that CGI variable *values* must be bytes instances, if they are
> +present at all. ?It is a violation of this specification for a CGI
> +variable's value to be of any type other than ``bytes``. ?On Python 2,
> +this means they will be of type ``str``. ?On Python 3, this means they
> +will be of type ``bytes``.
> +
> +They *keys* of all CGI and non-CGI variables in the environ, however,
> +must be "native strings" (on both Python 2 and Python 3, they will be
> +of type ``str``).
> +
> +In addition to the CGI-defined variables, the ``environ`` dictionary
> +**may** also contain arbitrary operating-system "environment
> +variables", and **must** contain the following Web3-defined variables.
> +
> +===================== ?===============================================
> +Variable ? ? ? ? ? ? ? Value
> +===================== ?===============================================
> +``web3.version`` ? ? ? The tuple ``(1, 0)``, representing Web3
> + ? ? ? ? ? ? ? ? ? ? ? version 1.0.
> +
> +``web3.url_scheme`` ? ?A bytes value representing the "scheme" portion of
> + ? ? ? ? ? ? ? ? ? ? ? the URL at which the application is being
> + ? ? ? ? ? ? ? ? ? ? ? invoked. ?Normally, this will have the value
> + ? ? ? ? ? ? ? ? ? ? ? ``b"http"`` or ``b"https"``, as appropriate.
> +
> +``web3.input`` ? ? ? ? An input stream (file-like object) from which bytes
> + ? ? ? ? ? ? ? ? ? ? ? constituting the HTTP request body can be read.
> + ? ? ? ? ? ? ? ? ? ? ? (The server or gateway may perform reads
> + ? ? ? ? ? ? ? ? ? ? ? on-demand as requested by the application, or
> + ? ? ? ? ? ? ? ? ? ? ? it may pre- read the client's request body and
> + ? ? ? ? ? ? ? ? ? ? ? buffer it in-memory or on disk, or use any
> + ? ? ? ? ? ? ? ? ? ? ? other technique for providing such an input
> + ? ? ? ? ? ? ? ? ? ? ? stream, according to its preference.)
> +
> +``web3.errors`` ? ? ? ?An output stream (file-like object) to which error
> + ? ? ? ? ? ? ? ? ? ? ? output text can be written, for the purpose of
> + ? ? ? ? ? ? ? ? ? ? ? recording program or other errors in a
> + ? ? ? ? ? ? ? ? ? ? ? standardized and possibly centralized location.
> + ? ? ? ? ? ? ? ? ? ? ? This should be a "text mode" stream; i.e.,
> + ? ? ? ? ? ? ? ? ? ? ? applications should use ``"\n"`` as a line
> + ? ? ? ? ? ? ? ? ? ? ? ending, and assume that it will be converted to
> + ? ? ? ? ? ? ? ? ? ? ? the correct line ending by the server/gateway.
> + ? ? ? ? ? ? ? ? ? ? ? Applications may *not* send bytes to the
> + ? ? ? ? ? ? ? ? ? ? ? 'write' method of this stream; they may only
> + ? ? ? ? ? ? ? ? ? ? ? send text.
> +
> + ? ? ? ? ? ? ? ? ? ? ? For many servers, ``web3.errors`` will be the
> + ? ? ? ? ? ? ? ? ? ? ? server's main error log. Alternatively, this
> + ? ? ? ? ? ? ? ? ? ? ? may be ``sys.stderr``, or a log file of some
> + ? ? ? ? ? ? ? ? ? ? ? sort. ?The server's documentation should
> + ? ? ? ? ? ? ? ? ? ? ? include an explanation of how to configure this
> + ? ? ? ? ? ? ? ? ? ? ? or where to find the recorded output. ?A server
> + ? ? ? ? ? ? ? ? ? ? ? or gateway may supply different error streams
> + ? ? ? ? ? ? ? ? ? ? ? to different applications, if this is desired.
> +
> +``web3.multithread`` ? This value should evaluate true if the
> + ? ? ? ? ? ? ? ? ? ? ? application object may be simultaneously
> + ? ? ? ? ? ? ? ? ? ? ? invoked by another thread in the same process,
> + ? ? ? ? ? ? ? ? ? ? ? and should evaluate false otherwise.
> +
> +``web3.multiprocess`` ?This value should evaluate true if an
> + ? ? ? ? ? ? ? ? ? ? ? equivalent application object may be
> + ? ? ? ? ? ? ? ? ? ? ? simultaneously invoked by another process, and
> + ? ? ? ? ? ? ? ? ? ? ? should evaluate false otherwise.
> +
> +``web3.run_once`` ? ? ?This value should evaluate true if the server
> + ? ? ? ? ? ? ? ? ? ? ? or gateway expects (but does not guarantee!)
> + ? ? ? ? ? ? ? ? ? ? ? that the application will only be invoked this
> + ? ? ? ? ? ? ? ? ? ? ? one time during the life of its containing
> + ? ? ? ? ? ? ? ? ? ? ? process. ?Normally, this will only be true for
> + ? ? ? ? ? ? ? ? ? ? ? a gateway based on CGI (or something similar).
> +
> +``web3.script_name`` ? The non-URL-decoded ``SCRIPT_NAME`` value.
> + ? ? ? ? ? ? ? ? ? ? ? Through a historical inequity, by virtue of the
> + ? ? ? ? ? ? ? ? ? ? ? CGI specification, ``SCRIPT_NAME`` is present
> + ? ? ? ? ? ? ? ? ? ? ? within the environment as an already
> + ? ? ? ? ? ? ? ? ? ? ? URL-decoded string. ?This is the original
> + ? ? ? ? ? ? ? ? ? ? ? URL-encoded value derived from the request URI.
> + ? ? ? ? ? ? ? ? ? ? ? If the server cannot provide this value, it
> + ? ? ? ? ? ? ? ? ? ? ? must omit it from the environ.
> +
> +``web3.path_info`` ? ? The non-URL-decoded ``PATH_INFO`` value.
> + ? ? ? ? ? ? ? ? ? ? ? Through a historical inequity, by virtue of the
> + ? ? ? ? ? ? ? ? ? ? ? CGI specification, ``PATH_INFO`` is present
> + ? ? ? ? ? ? ? ? ? ? ? within the environment as an already
> + ? ? ? ? ? ? ? ? ? ? ? URL-decoded string. ?This is the original
> + ? ? ? ? ? ? ? ? ? ? ? URL-encoded value derived from the request URI.
> + ? ? ? ? ? ? ? ? ? ? ? If the server cannot provide this value, it
> + ? ? ? ? ? ? ? ? ? ? ? must omit it from the environ.
> +
> +``web3.async`` ? ? ? ? This is ``True`` if the webserver supports
> + ? ? ? ? ? ? ? ? ? ? ? async invocation. ?In that case an application
> + ? ? ? ? ? ? ? ? ? ? ? is allowed to return a callable instead of a
> + ? ? ? ? ? ? ? ? ? ? ? tuple with the response. ?The exact semantics
> + ? ? ? ? ? ? ? ? ? ? ? are not specified by this specification.
> +
> +===================== ?===============================================
> +
> +Finally, the ``environ`` dictionary may also contain server-defined
> +variables. ?These variables should have names which are native
> +strings, composed of only lower-case letters, numbers, dots, and
> +underscores, and should be prefixed with a name that is unique to the
> +defining server or gateway. ?For example, ``mod_web3`` might define
> +variables with names like ``mod_web3.some_variable``.
> +
> +
> +Input Stream
> +~~~~~~~~~~~~
> +
> +The input stream (``web3.input``) provided by the server must support
> +the following methods:
> +
> +===================== ?========
> +Method ? ? ? ? ? ? ? ? Notes
> +===================== ?========
> +``read(size)`` ? ? ? ? 1,4
> +``readline([size])`` ? 1,2,4
> +``readlines([size])`` ?1,3,4
> +``__iter__()`` ? ? ? ? 4
> +===================== ?========
> +
> +The semantics of each method are as documented in the Python Library
> +Reference, except for these notes as listed in the table above:
> +
> +1. The server is not required to read past the client's specified
> + ? ``Content-Length``, and is allowed to simulate an end-of-file
> + ? condition if the application attempts to read past that point. ?The
> + ? application **should not** attempt to read more data than is
> + ? specified by the ``CONTENT_LENGTH`` variable.
> +
> +2. The implementation must support the optional ``size`` argument to
> + ? ``readline()``.
> +
> +3. The application is free to not supply a ``size`` argument to
> + ? ``readlines()``, and the server or gateway is free to ignore the
> + ? value of any supplied ``size`` argument.
> +
> +4. The ``read``, ``readline`` and ``__iter__`` methods must return a
> + ? bytes instance. ?The ``readlines`` method must return a sequence
> + ? which contains instances of bytes.
> +
> +The methods listed in the table above **must** be supported by all
> +servers conforming to this specification. ?Applications conforming to
> +this specification **must not** use any other methods or attributes of
> +the ``input`` object. ?In particular, applications **must not**
> +attempt to close this stream, even if it possesses a ``close()``
> +method.
> +
> +The input stream should silently ignore attempts to read more than the
> +content length of the request. ?If no content length is specified the
> +stream must be a dummy stream that does not return anything.
> +
> +
> +Error Stream
> +~~~~~~~~~~~~
> +
> +The error stream (``web3.errors``) provided by the server must support
> +the following methods:
> +
> +=================== ? ========== ?========
> +Method ? ? ? ? ? ? ? ?Stream ? ? ?Notes
> +=================== ? ========== ?========
> +``flush()`` ? ? ? ? ? ``errors`` ?1
> +``write(str)`` ? ? ? ?``errors`` ?2
> +``writelines(seq)`` ? ``errors`` ?2
> +=================== ? ========== ?========
> +
> +The semantics of each method are as documented in the Python Library
> +Reference, except for these notes as listed in the table above:
> +
> +1. Since the ``errors`` stream may not be rewound, servers and
> + ? gateways are free to forward write operations immediately, without
> + ? buffering. ?In this case, the ``flush()`` method may be a no-op.
> + ? Portable applications, however, cannot assume that output is
> + ? unbuffered or that ``flush()`` is a no-op. ?They must call
> + ? ``flush()`` if they need to ensure that output has in fact been
> + ? written. ?(For example, to minimize intermingling of data from
> + ? multiple processes writing to the same error log.)
> +
> +2. The ``write()`` method must accept a string argument, but needn't
> + ? necessarily accept a bytes argument. ?The ``writelines()`` method
> + ? must accept a sequence argument that consists entirely of strings,
> + ? but needn't necessarily accept any bytes instance as a member of
> + ? the sequence.
> +
> +The methods listed in the table above **must** be supported by all
> +servers conforming to this specification. ?Applications conforming to
> +this specification **must not** use any other methods or attributes of
> +the ``errors`` object. ?In particular, applications **must not**
> +attempt to close this stream, even if it possesses a ``close()``
> +method.
> +
> +
> +Values Returned by A Web3 Application
> +-------------------------------------
> +
> +Web3 applications return an iterable in the form (``status``,
> +``headers``, ``body``). ?The return value can be any iterable type
> +that returns exactly three values. ?If the server supports
> +asynchronous applications (``web3.async``), the response may be a
> +callable object (which accepts no arguments).
> +
> +The ``status`` value is assumed by a gateway or server to be an HTTP
> +"status" bytes instance like ``b'200 OK'`` or ``b'404 Not Found'``.
> +That is, it is a string consisting of a Status-Code and a
> +Reason-Phrase, in that order and separated by a single space, with no
> +surrounding whitespace or other characters. ?(See RFC 2616, Section
> +6.1.1 for more information.) ?The string **must not** contain control
> +characters, and must not be terminated with a carriage return,
> +linefeed, or combination thereof.
> +
> +The ``headers`` value is assumed by a gateway or server to be a
> +literal Python list of ``(header_name, header_value)`` tuples. ?Each
> +``header_name`` must be a bytes instance representing a valid HTTP
> +header field-name (as defined by RFC 2616, Section 4.2), without a
> +trailing colon or other punctuation. ?Each ``header_value`` must be a
> +bytes instance and **must not** include any control characters,
> +including carriage returns or linefeeds, either embedded or at the
> +end. ?(These requirements are to minimize the complexity of any
> +parsing that must be performed by servers, gateways, and intermediate
> +response processors that need to inspect or modify response headers.)
> +
> +In general, the server or gateway is responsible for ensuring that
> +correct headers are sent to the client: if the application omits a
> +header required by HTTP (or other relevant specifications that are in
> +effect), the server or gateway **must** add it. ?For example, the HTTP
> +``Date:`` and ``Server:`` headers would normally be supplied by the
> +server or gateway. ?The gateway must however not override values with
> +the same name if they are emitted by the application.
> +
> +(A reminder for server/gateway authors: HTTP header names are
> +case-insensitive, so be sure to take that into consideration when
> +examining application-supplied headers!)
> +
> +Applications and middleware are forbidden from using HTTP/1.1
> +"hop-by-hop" features or headers, any equivalent features in HTTP/1.0,
> +or any headers that would affect the persistence of the client's
> +connection to the web server. ?These features are the exclusive
> +province of the actual web server, and a server or gateway **should**
> +consider it a fatal error for an application to attempt sending them,
> +and raise an error if they are supplied as return values from an
> +application in the ``headers`` structure. ?(For more specifics on
> +"hop-by-hop" features and headers, please see the `Other HTTP
> +Features`_ section below.)
> +
> +
> +Dealing with Compatibility Across Python Versions
> +-------------------------------------------------
> +
> +Creating Web3 code that runs under both Python 2.6/2.7 and Python 3.1+
> +requires some care on the part of the developer. ?In general, the Web3
> +specification assumes a certain level of equivalence between the
> +Python 2 ``str`` type and the Python 3 ``bytes`` type. ?For example,
> +under Python 2, the values present in the Web3 ``environ`` will be
> +instances of the ``str`` type; in Python 3, these will be instances of
> +the ``bytes`` type. ?The Python 3 ``bytes`` type does not possess all
> +the methods of the Python 2 ``str`` type, and some methods which it
> +does possess behave differently than the Python 2 ``str`` type.
> +Effectively, to ensure that Web3 middleware and applications work
> +across Python versions, developers must do these things:
> +
> +#) Do not assume comparison equivalence between text values and bytes
> + ? values. ?If you do so, your code may work under Python 2, but it
> + ? will not work properly under Python 3. ?For example, don't write
> + ? ``somebytes == 'abc'``. ?This will sometimes be true on Python 2
> + ? but it will never be true on Python 3, because a sequence of bytes
> + ? never compares equal to a string under Python 3. ?Instead, always
> + ? compare a bytes value with a bytes value, e.g. "somebytes ==
> + ? b'abc'". ?Code which does this is compatible with and works the
> + ? same in Python 2.6, 2.7, and 3.1. ?The ``b`` in front of ``'abc'``
> + ? signals to Python 3 that the value is a literal bytes instance;
> + ? under Python 2 it's a forward compatibility placebo.
> +
> +#) Don't use the ``__contains__`` method (directly or indirectly) of
> + ? items that are meant to be byteslike without ensuring that its
> + ? argument is also a bytes instance. ?If you do so, your code may
> + ? work under Python 2, but it will not work properly under Python 3.
> + ? For example, ``'abc' in somebytes'`` will raise a ``TypeError``
> + ? under Python 3, but it will return ``True`` under Python 2.6 and
> + ? 2.7. ?However, ``b'abc' in somebytes`` will work the same on both
> + ? versions. ?In Python 3.2, this restriction may be partially
> + ? removed, as it's rumored that bytes types may obtain a ``__mod__``
> + ? implementation.
> +
> +#) ``__getitem__`` should not be used.
> +
> + ? .. XXX
> +
> +#) Dont try to use the ``format`` method or the ``__mod__`` method of
> + ? instances of bytes (directly or indirectly). ?In Python 2, the
> + ? ``str`` type which we treat equivalently to Python 3's ``bytes``
> + ? supports these method but actual Python 3's ``bytes`` instances
> + ? don't support these methods. ?If you use these methods, your code
> + ? will work under Python 2, but not under Python 3.
> +
> +#) Do not try to concatenate a bytes value with a string value. ?This
> + ? may work under Python 2, but it will not work under Python 3. ?For
> + ? example, doing ``'abc' + somebytes`` will work under Python 2, but
> + ? it will result in a ``TypeError`` under Python 3. ?Instead, always
> + ? make sure you're concatenating two items of the same type,
> + ? e.g. ``b'abc' + somebytes``.
> +
> +Web3 expects byte values in other places, such as in all the values
> +returned by an application.
> +
> +In short, to ensure compatibility of Web3 application code between
> +Python 2 and Python 3, in Python 2, treat CGI and server variable
> +values in the environment as if they had the Python 3 ``bytes`` API
> +even though they actually have a more capable API. ?Likewise for all
> +stringlike values returned by a Web3 application.
> +
> +
> +Buffering and Streaming
> +-----------------------
> +
> +Generally speaking, applications will achieve the best throughput by
> +buffering their (modestly-sized) output and sending it all at once.
> +This is a common approach in existing frameworks: the output is
> +buffered in a StringIO or similar object, then transmitted all at
> +once, along with the response headers.
> +
> +The corresponding approach in Web3 is for the application to simply
> +return a single-element ``body`` iterable (such as a list) containing
> +the response body as a single string. ?This is the recommended
> +approach for the vast majority of application functions, that render
> +HTML pages whose text easily fits in memory.
> +
> +For large files, however, or for specialized uses of HTTP streaming
> +(such as multipart "server push"), an application may need to provide
> +output in smaller blocks (e.g. to avoid loading a large file into
> +memory). ?It's also sometimes the case that part of a response may be
> +time-consuming to produce, but it would be useful to send ahead the
> +portion of the response that precedes it.
> +
> +In these cases, applications will usually return a ``body`` iterator
> +(often a generator-iterator) that produces the output in a
> +block-by-block fashion. ?These blocks may be broken to coincide with
> +mulitpart boundaries (for "server push"), or just before
> +time-consuming tasks (such as reading another block of an on-disk
> +file).
> +
> +Web3 servers, gateways, and middleware **must not** delay the
> +transmission of any block; they **must** either fully transmit the
> +block to the client, or guarantee that they will continue transmission
> +even while the application is producing its next block. ?A
> +server/gateway or middleware may provide this guarantee in one of
> +three ways:
> +
> +1. Send the entire block to the operating system (and request that any
> + ? O/S buffers be flushed) before returning control to the
> + ? application, OR
> +
> +2. Use a different thread to ensure that the block continues to be
> + ? transmitted while the application produces the next block.
> +
> +3. (Middleware only) send the entire block to its parent
> + ? gateway/server.
> +
> +By providing this guarantee, Web3 allows applications to ensure that
> +transmission will not become stalled at an arbitrary point in their
> +output data. ?This is critical for proper functioning of
> +e.g. multipart "server push" streaming, where data between multipart
> +boundaries should be transmitted in full to the client.
> +
> +
> +Unicode Issues
> +--------------
> +
> +HTTP does not directly support Unicode, and neither does this
> +interface. ?All encoding/decoding must be handled by the
> +**application**; all values passed to or from the server must be of
> +the Python 3 type ``bytes`` or instances of the Python 2 type ``str``,
> +not Python 2 ``unicode`` or Python 3 ``str`` objects.
> +
> +All "bytes instances" referred to in this specification **must**:
> +
> +- On Python 2, be of type ``str``.
> +
> +- On Python 3, be of type ``bytes``.
> +
> +All "bytes instances" **must not** :
> +
> +- On Python 2, ?be of type ``unicode``.
> +
> +- On Python 3, be of type ``str``.
> +
> +The result of using a textlike object where a byteslike object is
> +required is undefined.
> +
> +Values returned from a Web3 app as a status or as response headers
> +**must** follow RFC 2616 with respect to encoding. ?That is, the bytes
> +returned must contain a character stream of ISO-8859-1 characters, or
> +the character stream should use RFC 2047 MIME encoding.
> +
> +On Python platforms which do not have a native bytes-like type
> +(e.g. IronPython, etc.), but instead which generally use textlike
> +strings to represent bytes data, the definition of "bytes instance"
> +can be changed: their "bytes instances" must be native strings that
> +contain only code points representable in ISO-8859-1 encoding
> +(``\u0000`` through ``\u00FF``, inclusive). ?It is a fatal error for
> +an application on such a platform to supply strings containing any
> +other Unicode character or code point. ?Similarly, servers and
> +gateways on those platforms **must not** supply strings to an
> +application containing any other Unicode characters.
> +
> +.. XXX (armin: Jython now has a bytes type, we might remove this
> + ? section after seeing about IronPython)
> +
> +
> +HTTP 1.1 Expect/Continue
> +------------------------
> +
> +Servers and gateways that implement HTTP 1.1 **must** provide
> +transparent support for HTTP 1.1's "expect/continue" mechanism. ?This
> +may be done in any of several ways:
> +
> +1. Respond to requests containing an ``Expect: 100-continue`` request
> + ? with an immediate "100 Continue" response, and proceed normally.
> +
> +2. Proceed with the request normally, but provide the application with
> + ? a ``web3.input`` stream that will send the "100 Continue" response
> + ? if/when the application first attempts to read from the input
> + ? stream. ?The read request must then remain blocked until the client
> + ? responds.
> +
> +3. Wait until the client decides that the server does not support
> + ? expect/continue, and sends the request body on its own. ?(This is
> + ? suboptimal, and is not recommended.)
> +
> +Note that these behavior restrictions do not apply for HTTP 1.0
> +requests, or for requests that are not directed to an application
> +object. ?For more information on HTTP 1.1 Expect/Continue, see RFC
> +2616, sections 8.2.3 and 10.1.1.
> +
> +
> +Other HTTP Features
> +-------------------
> +
> +In general, servers and gateways should "play dumb" and allow the
> +application complete control over its output. ?They should only make
> +changes that do not alter the effective semantics of the application's
> +response. ?It is always possible for the application developer to add
> +middleware components to supply additional features, so server/gateway
> +developers should be conservative in their implementation. ?In a
> +sense, a server should consider itself to be like an HTTP "gateway
> +server", with the application being an HTTP "origin server". ?(See RFC
> +2616, section 1.3, for the definition of these terms.)
> +
> +However, because Web3 servers and applications do not communicate via
> +HTTP, what RFC 2616 calls "hop-by-hop" headers do not apply to Web3
> +internal communications. ?Web3 applications **must not** generate any
> +"hop-by-hop" headers [4]_, attempt to use HTTP features that would
> +require them to generate such headers, or rely on the content of any
> +incoming "hop-by-hop" headers in the ``environ`` dictionary. ?Web3
> +servers **must** handle any supported inbound "hop-by-hop" headers on
> +their own, such as by decoding any inbound ``Transfer-Encoding``,
> +including chunked encoding if applicable.
> +
> +Applying these principles to a variety of HTTP features, it should be
> +clear that a server **may** handle cache validation via the
> +``If-None-Match`` and ``If-Modified-Since`` request headers and the
> +``Last-Modified`` and ``ETag`` response headers. ?However, it is not
> +required to do this, and the application **should** perform its own
> +cache validation if it wants to support that feature, since the
> +server/gateway is not required to do such validation.
> +
> +Similarly, a server **may** re-encode or transport-encode an
> +application's response, but the application **should** use a suitable
> +content encoding on its own, and **must not** apply a transport
> +encoding. ?A server **may** transmit byte ranges of the application's
> +response if requested by the client, and the application doesn't
> +natively support byte ranges. ?Again, however, the application
> +**should** perform this function on its own if desired.
> +
> +Note that these restrictions on applications do not necessarily mean
> +that every application must reimplement every HTTP feature; many HTTP
> +features can be partially or fully implemented by middleware
> +components, thus freeing both server and application authors from
> +implementing the same features over and over again.
> +
> +
> +Thread Support
> +--------------
> +
> +Thread support, or lack thereof, is also server-dependent. ?Servers
> +that can run multiple requests in parallel, **should** also provide
> +the option of running an application in a single-threaded fashion, so
> +that applications or frameworks that are not thread-safe may still be
> +used with that server.
> +
> +
> +Implementation/Application Notes
> +================================
> +
> +Server Extension APIs
> +---------------------
> +
> +Some server authors may wish to expose more advanced APIs, that
> +application or framework authors can use for specialized purposes.
> +For example, a gateway based on ``mod_python`` might wish to expose
> +part of the Apache API as a Web3 extension.
> +
> +In the simplest case, this requires nothing more than defining an
> +``environ`` variable, such as ``mod_python.some_api``. ?But, in many
> +cases, the possible presence of middleware can make this difficult.
> +For example, an API that offers access to the same HTTP headers that
> +are found in ``environ`` variables, might return different data if
> +``environ`` has been modified by middleware.
> +
> +In general, any extension API that duplicates, supplants, or bypasses
> +some portion of Web3 functionality runs the risk of being incompatible
> +with middleware components. ?Server/gateway developers should *not*
> +assume that nobody will use middleware, because some framework
> +developers specifically organize their frameworks to function almost
> +entirely as middleware of various kinds.
> +
> +So, to provide maximum compatibility, servers and gateways that
> +provide extension APIs that replace some Web3 functionality, **must**
> +design those APIs so that they are invoked using the portion of the
> +API that they replace. ?For example, an extension API to access HTTP
> +request headers must require the application to pass in its current
> +``environ``, so that the server/gateway may verify that HTTP headers
> +accessible via the API have not been altered by middleware. ?If the
> +extension API cannot guarantee that it will always agree with
> +``environ`` about the contents of HTTP headers, it must refuse service
> +to the application, e.g. by raising an error, returning ``None``
> +instead of a header collection, or whatever is appropriate to the API.
> +
> +These guidelines also apply to middleware that adds information such
> +as parsed cookies, form variables, sessions, and the like to
> +``environ``. ?Specifically, such middleware should provide these
> +features as functions which operate on ``environ``, rather than simply
> +stuffing values into ``environ``. ?This helps ensure that information
> +is calculated from ``environ`` *after* any middleware has done any URL
> +rewrites or other ``environ`` modifications.
> +
> +It is very important that these "safe extension" rules be followed by
> +both server/gateway and middleware developers, in order to avoid a
> +future in which middleware developers are forced to delete any and all
> +extension APIs from ``environ`` to ensure that their mediation isn't
> +being bypassed by applications using those extensions!
> +
> +
> +Application Configuration
> +-------------------------
> +
> +This specification does not define how a server selects or obtains an
> +application to invoke. ?These and other configuration options are
> +highly server-specific matters. ?It is expected that server/gateway
> +authors will document how to configure the server to execute a
> +particular application object, and with what options (such as
> +threading options).
> +
> +Framework authors, on the other hand, should document how to create an
> +application object that wraps their framework's functionality. ?The
> +user, who has chosen both the server and the application framework,
> +must connect the two together. ?However, since both the framework and
> +the server have a common interface, this should be merely a mechanical
> +matter, rather than a significant engineering effort for each new
> +server/framework pair.
> +
> +Finally, some applications, frameworks, and middleware may wish to use
> +the ``environ`` dictionary to receive simple string configuration
> +options. ?Servers and gateways **should** support this by allowing an
> +application's deployer to specify name-value pairs to be placed in
> +``environ``. ?In the simplest case, this support can consist merely of
> +copying all operating system-supplied environment variables from
> +``os.environ`` into the ``environ`` dictionary, since the deployer in
> +principle can configure these externally to the server, or in the CGI
> +case they may be able to be set via the server's configuration files.
> +
> +Applications **should** try to keep such required variables to a
> +minimum, since not all servers will support easy configuration of
> +them. ?Of course, even in the worst case, persons deploying an
> +application can create a script to supply the necessary configuration
> +values::
> +
> + ? from the_app import application
> +
> + ? def new_app(environ):
> + ? ? ? environ['the_app.configval1'] = b'something'
> + ? ? ? return application(environ)
> +
> +But, most existing applications and frameworks will probably only need
> +a single configuration value from ``environ``, to indicate the
> +location of their application or framework-specific configuration
> +file(s). ?(Of course, applications should cache such configuration, to
> +avoid having to re-read it upon each invocation.)
> +
> +
> +URL Reconstruction
> +------------------
> +
> +If an application wishes to reconstruct a request's complete URL (as a
> +bytes object), it may do so using the following algorithm::
> +
> + ? ?host = environ.get('HTTP_HOST')
> +
> + ? ?scheme = environ['web3.url_scheme']
> + ? ?port = environ['SERVER_PORT']
> + ? ?query = environ['QUERY_STRING']
> +
> + ? ?url = scheme + b'://'
> +
> + ? ?if host:
> + ? ? ? ?url += host
> + ? ?else:
> + ? ? ? ?url += environ['SERVER_NAME']
> +
> + ? ? ? ?if scheme == b'https':
> + ? ? ? ? ? ?if port != b'443':
> + ? ? ? ? ? ? ? url += b':' + port
> + ? ? ? ?else:
> + ? ? ? ? ? ?if port != b'80':
> + ? ? ? ? ? ? ? url += b':' + port
> +
> + ? ?if 'web3.script_name' in url:
> + ? ? ? ?url += url_quote(environ['web3.script_name'])
> + ? ?else:
> + ? ? ? ?url += environ['SCRIPT_NAME']
> + ? ?if 'web3.path_info' in environ:
> + ? ? ? ?url += url_quote(environ['web3.path_info'])
> + ? ?else:
> + ? ? ? ?url += environ['PATH_INFO']
> + ? ?if query:
> + ? ? ? ?url += b'?' + query
> +
> +Note that such a reconstructed URL may not be precisely the same URI
> +as requested by the client. ?Server rewrite rules, for example, may
> +have modified the client's originally requested URL to place it in a
> +canonical form.
> +
> +
> +Open Questions
> +==============
> +
> +- ``file_wrapper`` replacement. ?Currently nothing is specified here
> + ?but it's clear that the old system of in-band signalling is broken
> + ?if it does not provide a way to figure out as a middleware in the
> + ?process if the response is a file wrapper.
> +
> +
> +Points of Contention
> +====================
> +
> +Outlined below are potential points of contention regarding this
> +specification.
> +
> +
> +WSGI 1.0 Compatibility
> +----------------------
> +
> +Components written using the WSGI 1.0 specification will not
> +transparently interoperate with components written using this
> +specification. ?That's because the goals of this proposal and the
> +goals of WSGI 1.0 are not directly aligned.
> +
> +WSGI 1.0 is obliged to provide specification-level backwards
> +compatibility with versions of Python between 2.2 and 2.7. ?This
> +specification, however, ditches Python 2.5 and lower compatibility in
> +order to provide compatibility between relatively recent versions of
> +Python 2 (2.6 and 2.7) as well as relatively recent versions of Python
> +3 (3.1).
> +
> +It is currently impossible to write components which work reliably
> +under both Python 2 and Python 3 using the WSGI 1.0 specification,
> +because the specification implicitly posits that CGI and server
> +variable values in the environ and values returned via
> +``start_response`` represent a sequence of bytes that can be addressed
> +using the Python 2 string API. ?It posits such a thing because that
> +sort of data type was the sensible way to represent bytes in all
> +Python 2 versions, and WSGI 1.0 was conceived before Python 3 existed.
> +
> +Python 3's ``str`` type supports the full API provided by the Python 2
> +``str`` type, but Python 3's ``str`` type does not represent a
> +sequence of bytes, it instead represents text. ?Therefore, using it to
> +represent environ values also requires that the environ byte sequence
> +be decoded to text via some encoding. ?We cannot decode these bytes to
> +text (at least in any way where the decoding has any meaning other
> +than as a tunnelling mechanism) without widening the scope of WSGI to
> +include server and gateway knowledge of decoding policies and
> +mechanics. ?WSGI 1.0 never concerned itself with encoding and
> +decoding. ?It made statements about allowable transport values, and
> +suggested that various values might be best decoded as one encoding or
> +another, but it never required a server to *perform* any decoding
> +before
> +
> +Python 3 does not have a stringlike type that can be used instead to
> +represent bytes: it has a ``bytes`` type. ?A bytes type operates quite
> +a bit like a Python 2 ``str`` in Python 3.1+, but it lacks behavior
> +equivalent to ``str.__mod__`` and its iteration protocol, and
> +containment, sequence treatment, and equivalence comparisons are
> +different.
> +
> +In either case, there is no type in Python 3 that behaves just like
> +the Python 2 ``str`` type, and a way to create such a type doesn't
> +exist because there is no such thing as a "String ABC" which would
> +allow a suitable type to be built. ?Due to this design
> +incompatibility, existing WSGI 1.0 servers, middleware, and
> +applications will not work under Python 3, even after they are run
> +through ``2to3``.
> +
> +Existing Web-SIG discussions about updating the WSGI specification so
> +that it is possible to write a WSGI application that runs in both
> +Python 2 and Python 3 tend to revolve around creating a
> +specification-level equivalence between the Python 2 ``str`` type
> +(which represents a sequence of bytes) and the Python 3 ``str`` type
> +(which represents text). ?Such an equivalence becomes strained in
> +various areas, given the different roles of these types. ?An arguably
> +more straightforward equivalence exists between the Python 3 ``bytes``
> +type API and a subset of the Python 2 ``str`` type API. ?This
> +specification exploits this subset equivalence.
> +
> +In the meantime, aside from any Python 2 vs. Python 3 compatibility
> +issue, as various discussions on Web-SIG have pointed out, the WSGI
> +1.0 specification is too general, providing support (via ``.write``)
> +for asynchronous applications at the expense of implementation
> +complexity. ?This specification uses the fundamental incompatibility
> +between WSGI 1.0 and Python 3 as a natural divergence point to create
> +a specification with reduced complexity by changing specialized
> +support for asynchronous applications.
> +
> +To provide backwards compatibility for older WSGI 1.0 applications, so
> +that they may run on a Web3 stack, it is presumed that Web3 middleware
> +will be created which can be used "in front" of existing WSGI 1.0
> +applications, allowing those existing WSGI 1.0 applications to run
> +under a Web3 stack. ?This middleware will require, when under Python
> +3, an equivalence to be drawn between Python 3 ``str`` types and the
> +bytes values represented by the HTTP request and all the attendant
> +encoding-guessing (or configuration) it implies.
> +
> +.. note::
> +
> + ? Such middleware *might* in the future, instead of drawing an
> + ? equivalence between Python 3 ``str`` and HTTP byte values, make use
> + ? of a yet-to-be-created "ebytes" type (aka "bytes-with-benefits"),
> + ? particularly if a String ABC proposal is accepted into the Python
> + ? core and implemented.
> +
> +Conversely, it is presumed that WSGI 1.0 middleware will be created
> +which will allow a Web3 application to run behind a WSGI 1.0 stack on
> +the Python 2 platform.
> +
> +
> +Environ and Response Values as Bytes
> +------------------------------------
> +
> +Casual middleware and application writers may consider the use of
> +bytes as environment values and response values inconvenient. ?In
> +particular, they won't be able to use common string formatting
> +functions such as ``('%s' % bytes_val)`` or
> +``bytes_val.format('123')`` because bytes don't have the same API as
> +strings on platforms such as Python 3 where the two types differ.
> +Likewise, on such platforms, stdlib HTTP-related API support for using
> +bytes interchangeably with text can be spotty. ?In places where bytes
> +are inconvenient or incompatible with library APIs, middleware and
> +application writers will have to decode such bytes to text explicitly.
> +This is particularly inconvenient for middleware writers: to work with
> +environment values as strings, they'll have to decode them from an
> +implied encoding and if they need to mutate an environ value, they'll
> +then need to encode the value into a byte stream before placing it
> +into the environ. ?While the use of bytes by the specification as
> +environ values might be inconvenient for casual developers, it
> +provides several benefits.
> +
> +Using bytes types to represent HTTP and server values to an
> +application most closely matches reality because HTTP is fundamentally
> +a bytes-oriented protocol. ?If the environ values are mandated to be
> +strings, each server will need to use heuristics to guess about the
> +encoding of various values provided by the HTTP environment. ?Using
> +all strings might increase casual middleware writer convenience, but
> +will also lead to ambiguity and confusion when a value cannot be
> +decoded to a meaningful non-surrogate string.
> +
> +Use of bytes as environ values avoids any potential for the need for
> +the specification to mandate that a participating server be informed
> +of encoding configuration parameters. ?If environ values are treated
> +as strings, and so must be decoded from bytes, configuration
> +parameters may eventually become necessary as policy clues from the
> +application deployer. ?Such a policy would be used to guess an
> +appropriate decoding strategy in various circumstances, effectively
> +placing the burden for enforcing a particular application encoding
> +policy upon the server. ?If the server must serve more than one
> +application, such configuration would quickly become complex. ?Many
> +policies would also be impossible to express declaratively.
> +
> +In reality, HTTP is a complicated and legacy-fraught protocol which
> +requires a complex set of heuristics to make sense of. It would be
> +nice if we could allow this protocol to protect us from this
> +complexity, but we cannot do so reliably while still providing to
> +application writers a level of control commensurate with reality.
> +Python applications must often deal with data embedded in the
> +environment which not only must be parsed by legacy heuristics, but
> +*does not conform even to any existing HTTP specification*. ?While
> +these eventualities are unpleasant, they crop up with regularity,
> +making it impossible and undesirable to hide them from application
> +developers, as application developers are the only people who are able
> +to decide upon an appropriate action when an HTTP specification
> +violation is detected.
> +
> +Some have argued for mixed use of bytes and string values as environ
> +*values*. ?This proposal avoids that strategy. ?Sole use of bytes as
> +environ values makes it possible to fit this specification entirely in
> +one's head; you won't need to guess about which values are strings and
> +which are bytes.
> +
> +This protocol would also fit in a developer's head if all environ
> +values were strings, but this specification doesn't use that strategy.
> +This will likely be the point of greatest contention regarding the use
> +of bytes. ?In defense of bytes: developers often prefer protocols with
> +consistent contracts, even if the contracts themselves are suboptimal.
> +If we hide encoding issues from a developer until a value that
> +contains surrogates causes problems after it has already reached
> +beyond the I/O boundary of their application, they will need to do a
> +lot more work to fix assumptions made by their application than if we
> +were to just present the problem much earlier in terms of "here's some
> +bytes, you decode them". ?This is also a counter-argument to the
> +"bytes are inconvenient" assumption: while presenting bytes to an
> +application developer may be inconvenient for a casual application
> +developer who doesn't care about edge cases, they are extremely
> +convenient for the application developer who needs to deal with
> +complex, dirty eventualities, because use of bytes allows him the
> +appropriate level of control with a clear separation of
> +responsibility.
> +
> +If the protocol uses bytes, it is presumed that libraries will be
> +created to make working with bytes-only in the environ and within
> +return values more pleasant; for example, analogues of the WSGI 1.0
> +libraries named "WebOb" and "Werkzeug". ?Such libraries will fill the
> +gap between convenience and control, allowing the spec to remain
> +simple and regular while still allowing casual authors a convenient
> +way to create Web3 middleware and application components. ?This seems
> +to be a reasonable alternative to baking encoding policy into the
> +protocol, because many such libraries can be created independently
> +from the protocol, and application developers can choose the one that
> +provides them the appropriate levels of control and convenience for a
> +particular job.
> +
> +Here are some alternatives to using all bytes:
> +
> +- Have the server decode all values representing CGI and server
> + ?environ values into strings using the ``latin-1`` encoding, which is
> + ?lossless. ?Smuggle any undecodable bytes within the resulting
> + ?string.
> +
> +- Encode all CGI and server environ values to strings using the
> + ?``utf-8`` encoding with the ``surrogateescape`` error handler. ?This
> + ?does not work under any existing Python 2.
> +
> +- Encode some values into bytes and other values into strings, as
> + ?decided by their typical usages.
> +
> +
> +Applications Should be Allowed to Read ``web3.input`` Past ``CONTENT_LENGTH``
> +-----------------------------------------------------------------------------
> +
> +At [6]_, Graham Dumpleton makes the assertion that ``wsgi.input``
> +should be required to return the empty string as a signifier of
> +out-of-data, and that applications should be allowed to read past the
> +number of bytes specified in ``CONTENT_LENGTH``, depending only upon
> +the empty string as an EOF marker. ?WSGI relies on an application
> +"being well behaved and once all data specified by ``CONTENT_LENGTH``
> +is read, that it processes the data and returns any response. That
> +same socket connection could then be used for a subsequent request."
> +Graham would like WSGI adapters to be required to wrap raw socket
> +connections: "this wrapper object will need to count how much data has
> +been read, and when the amount of data reaches that as defined by
> +``CONTENT_LENGTH``, any subsequent reads should return an empty string
> +instead." ?This may be useful to support chunked encoding and input
> +filters.
> +
> +
> +``web3.input`` Unknown Length
> +-----------------------------
> +
> +There's no documented way to indicate that there is content in
> +``environ['web3.input']``, but the content length is unknown.
> +
> +
> +``read()`` of ``web3.input`` Should Support No-Size Calling Convention
> +----------------------------------------------------------------------
> +
> +At [6]_, Graham Dumpleton makes the assertion that the ``read()``
> +method of ``wsgi.input`` should be callable without arguments, and
> +that the result should be "all available request content". ?Needs
> +discussion.
> +
> +Comment Armin: I changed the spec to require that from an
> +implementation. ?I had too much pain with that in the past already.
> +Open for discussions though.
> +
> +
> +Input Filters should set environ ``CONTENT_LENGTH`` to -1
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +At [6]_, Graham Dumpleton suggests that an input filter might set
> +``environ['CONTENT_LENGTH']`` to -1 to indicate that it mutated the
> +input.
> +
> +
> +``headers`` as Literal List of Two-Tuples
> +-----------------------------------------
> +
> +Why do we make applications return a ``headers`` structure that is a
> +literal list of two-tuples? ?I think the iterability of ``headers``
> +needs to be maintained while it moves up the stack, but I don't think
> +we need to be able to mutate it in place at all times. ?Could we
> +loosen that requirement?
> +
> +Comment Armin: Strong yes
> +
> +
> +Removed Requirement that Middleware Not Block
> +---------------------------------------------
> +
> +This requirement was removed: "middleware components **must not**
> +block iteration waiting for multiple values from an application
> +iterable. ?If the middleware needs to accumulate more data from the
> +application before it can produce any output, it **must** yield an
> +empty string." ?This requirement existed to support asynchronous
> +applications and servers (see PEP 333's "Middleware Handling of Block
> +Boundaries"). ?Asynchronous applications are now serviced explicitly
> +by ``web3.async`` capable protocol (a Web3 application callable may
> +itself return a callable).
> +
> +
> +``web3.script_name`` and ``web3.path_info``
> +-------------------------------------------
> +
> +These values are required to be placed into the environment by an
> +origin server under this specification. ?Unlike ``SCRIPT_NAME`` and
> +``PATH_INFO``, these must be the original *URL-encoded* variants
> +derived from the request URI. ?We probably need to figure out how
> +these should be computed originally, and what their values should be
> +if the server performs URL rewriting.
> +
> +
> +Long Response Headers
> +---------------------
> +
> +Bob Brewer notes on Web-SIG [7]_:
> +
> + ? ?Each header_value must not include any control characters,
> + ? ?including carriage returns or linefeeds, either embedded or at the
> + ? ?end. ?(These requirements are to minimize the complexity of any
> + ? ?parsing that must be performed by servers, gateways, and
> + ? ?intermediate response processors that need to inspect or modify
> + ? ?response headers.) [1]_
> +
> +That's understandable, but HTTP headers are defined as (mostly)
> +\*TEXT, and "words of \*TEXT MAY contain characters from character
> +sets other than ISO-8859-1 only when encoded according to the rules of
> +RFC 2047." ?[2]_ And RFC 2047 specifies that "an 'encoded-word' may
> +not be more than 75 characters long... ?If it is desirable to encode
> +more text than will fit in an 'encoded-word' of 75 characters,
> +multiple 'encoded-word's (separated by CRLF SPACE) may be used." [3]_
> +This satisfies HTTP header folding rules, as well: "Header fields can
> +be extended over multiple lines by preceding each extra line with at
> +least one SP or HT." [1]_
> +
> +So in my reading of HTTP, some code somewhere should introduce
> +newlines in longish, encoded response header values. ?I see three
> +options:
> +
> +1. Keep things as they are and disallow response header values if they
> + ? contain words over 75 chars that are outside the ISO-8859-1
> + ? character set.
> +
> +2. Allow newline characters in WSGI response headers.
> +
> +3. Require/strongly suggest WSGI servers to do the encoding and
> + ? folding before sending the value over HTTP.
> +
> +
> +Request Trailers and Chunked Transfer Encoding
> +----------------------------------------------
> +
> +When using chunked transfer encoding on request content, the RFCs
> +allow there to be request trailers. ?These are like request headers
> +but come after the final null data chunk. ?These trailers are only
> +available when the chunked data stream is finite length and when it
> +has all been read in. ?Neither WSGI nor Web3 currently supports them.
> +
> +.. XXX (armin) yield from application iterator should be specify write
> + ? plus flush by server.
> +
> +.. XXX (armin) websocket API.
> +
> +
> +References
> +==========
> +
> +.. [1] PEP 333: Python Web Services Gateway Interface
> + ? (http://www.python.org/dev/peps/pep-0333/)
> +
> +.. [2] The Common Gateway Interface Specification, v 1.1, 3rd Draft
> + ? (http://cgi-spec.golux.com/draft-coar-cgi-v11-03.txt)
> +
> +.. [3] "Chunked Transfer Coding" -- HTTP/1.1, section 3.6.1
> + ? (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1)
> +
> +.. [4] "End-to-end and Hop-by-hop Headers" -- HTTP/1.1, Section 13.5.1
> + ? (http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1)
> +
> +.. [5] mod_ssl Reference, "Environment Variables"
> + ? (http://www.modssl.org/docs/2.8/ssl_reference.html#ToC25)
> +
> +.. [6] Details on WSGI 1.0 amendments/clarifications.
> + ? (http://blog.dscpl.com.au/2009/10/details-on-wsgi-10-amendmentsclarificat.html)
> +
> +.. [7] [Web-SIG] WSGI and long response header values
> + ? http://mail.python.org/pipermail/web-sig/2006-September/002244.html
> +
> +Copyright
> +=========
> +
> +This document has been placed in the public domain.
> +
> +
> +
> +..
> + ? Local Variables:
> + ? mode: indented-text
> + ? indent-tabs-mode: nil
> + ? sentence-end-double-space: t
> + ? fill-column: 70
> + ? coding: utf-8
> + ? End:
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins
>
From benjamin at python.org Thu Sep 16 01:17:21 2010
From: benjamin at python.org (Benjamin Peterson)
Date: Wed, 15 Sep 2010 18:17:21 -0500
Subject: [Python-checkins] r84842 - peps/trunk/pep-0444.txt
In-Reply-To:
References: <20100915224038.95AECC5D5@mail.python.org>
Message-ID:
2010/9/15 Brett Cannon