Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0449f63

Browse files
committed
Merged revisions 59488-59511 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r59489 | christian.heimes | 2007-12-14 03:33:57 +0100 (Fri, 14 Dec 2007) | 1 line Silence a warning about an unsed variable in debug builds ........ r59490 | christian.heimes | 2007-12-14 03:35:23 +0100 (Fri, 14 Dec 2007) | 2 lines Fixed bug #1620: New @spam.getter property syntax modifies the property in place. I added also the feature that a @prop.getter decorator does not overwrite the doc string of the property if it was given as an argument to property(). ........ r59491 | raymond.hettinger | 2007-12-14 03:49:47 +0100 (Fri, 14 Dec 2007) | 1 line Cleaner method naming convention ........ r59492 | christian.heimes | 2007-12-14 04:02:34 +0100 (Fri, 14 Dec 2007) | 1 line Fixed a warning in _codecs_iso2022.c and some non C89 conform // comments. ........ r59493 | christian.heimes | 2007-12-14 05:38:13 +0100 (Fri, 14 Dec 2007) | 1 line Fixed warning in ssl module ........ r59500 | raymond.hettinger | 2007-12-14 19:08:20 +0100 (Fri, 14 Dec 2007) | 1 line Add line spacing for readability ........ r59501 | raymond.hettinger | 2007-12-14 19:12:21 +0100 (Fri, 14 Dec 2007) | 3 lines Update method names for named tuples. ........ r59503 | georg.brandl | 2007-12-14 20:03:36 +0100 (Fri, 14 Dec 2007) | 3 lines Add a section about nested listcomps to the tutorial. Thanks to Ian Bruntlett and Robert Lehmann. ........ r59504 | raymond.hettinger | 2007-12-14 20:19:59 +0100 (Fri, 14 Dec 2007) | 1 line Faster and simpler _replace() method ........ r59505 | raymond.hettinger | 2007-12-14 22:51:50 +0100 (Fri, 14 Dec 2007) | 1 line Add usage note ........ r59507 | andrew.kuchling | 2007-12-14 23:41:18 +0100 (Fri, 14 Dec 2007) | 1 line Remove warning about URL ........ r59510 | andrew.kuchling | 2007-12-14 23:52:36 +0100 (Fri, 14 Dec 2007) | 1 line Bump the version number, and make a few small edits ........ r59511 | christian.heimes | 2007-12-15 00:42:36 +0100 (Sat, 15 Dec 2007) | 2 lines Fixed bug #1628 The detection now works on Unix with Makefile, Makefile with VPATH and on Windows. ........
1 parent 54cc54c commit 0449f63

16 files changed

Lines changed: 299 additions & 103 deletions

File tree

Doc/ACKS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ [email protected]), and we'll be glad to correct the problem.
2828
* Aaron Brancotti
2929
* Georg Brandl
3030
* Keith Briggs
31+
* Ian Bruntlett
3132
* Lee Busby
3233
* Lorenzo M. Catucci
3334
* Carl Cerecke

Doc/howto/functional.rst

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@
33
********************************
44

55
:Author: \A. M. Kuchling
6-
:Release: 0.30
6+
:Release: 0.31
77

88
(This is a first draft. Please send comments/error reports/suggestions to
9-
[email protected]. This URL is probably not going to be the final location of the
10-
document, so be careful about linking to it -- you may want to add a
11-
disclaimer.)
9+
1210

1311
In this document, we'll take a tour of Python's features suitable for
1412
implementing programs in a functional style. After an introduction to the
@@ -49,17 +47,19 @@ Programming languages support decomposing problems in several different ways:
4947
functional languages include the ML family (Standard ML, OCaml, and other
5048
variants) and Haskell.
5149

52-
The designers of some computer languages have chosen one approach to programming
53-
that's emphasized. This often makes it difficult to write programs that use a
54-
different approach. Other languages are multi-paradigm languages that support
55-
several different approaches. Lisp, C++, and Python are multi-paradigm; you can
56-
write programs or libraries that are largely procedural, object-oriented, or
57-
functional in all of these languages. In a large program, different sections
58-
might be written using different approaches; the GUI might be object-oriented
59-
while the processing logic is procedural or functional, for example.
50+
The designers of some computer languages choose to emphasize one
51+
particular approach to programming. This often makes it difficult to
52+
write programs that use a different approach. Other languages are
53+
multi-paradigm languages that support several different approaches.
54+
Lisp, C++, and Python are multi-paradigm; you can write programs or
55+
libraries that are largely procedural, object-oriented, or functional
56+
in all of these languages. In a large program, different sections
57+
might be written using different approaches; the GUI might be
58+
object-oriented while the processing logic is procedural or
59+
functional, for example.
6060

6161
In a functional program, input flows through a set of functions. Each function
62-
operates on its input and produces some output. Functional style frowns upon
62+
operates on its input and produces some output. Functional style discourages
6363
functions with side effects that modify internal state or make other changes
6464
that aren't visible in the function's return value. Functions that have no side
6565
effects at all are called **purely functional**. Avoiding side effects means
@@ -616,7 +616,7 @@ Built-in functions
616616

617617
Let's look in more detail at built-in functions often used with iterators.
618618

619-
Two Python's built-in functions, :func:`map` and :func:`filter`, are somewhat
619+
Two of Python's built-in functions, :func:`map` and :func:`filter`, are somewhat
620620
obsolete; they duplicate the features of list comprehensions but return actual
621621
lists instead of iterators.
622622

@@ -842,8 +842,8 @@ Fredrik Lundh once suggested the following set of rules for refactoring uses of
842842
4) Convert the lambda to a def statement, using that name.
843843
5) Remove the comment.
844844

845-
I really like these rules, but you're free to disagree that this lambda-free
846-
style is better.
845+
I really like these rules, but you're free to disagree
846+
about whether this lambda-free style is better.
847847

848848

849849
The itertools module

Doc/library/collections.rst

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ they add the ability to access fields by name instead of position index.
403403
can be specified as a list of strings (such as ['x', 'y']).
404404

405405
Any valid Python identifier may be used for a fieldname except for names
406-
starting and ending with double underscores. Valid identifiers consist of
407-
letters, digits, and underscores but do not start with a digit and cannot be
406+
starting with an underscore. Valid identifiers consist of letters, digits,
407+
and underscores but do not start with a digit or underscore and cannot be
408408
a :mod:`keyword` such as *class*, *for*, *return*, *global*, *pass*, *print*,
409409
or *raise*.
410410

@@ -418,18 +418,25 @@ Example::
418418
>>> Point = namedtuple('Point', 'x y', verbose=True)
419419
class Point(tuple):
420420
'Point(x, y)'
421+
421422
__slots__ = ()
422-
__fields__ = ('x', 'y')
423+
424+
_fields = ('x', 'y')
425+
423426
def __new__(cls, x, y):
424427
return tuple.__new__(cls, (x, y))
428+
425429
def __repr__(self):
426430
return 'Point(x=%r, y=%r)' % self
427-
def __asdict__(self):
428-
'Return a new dict mapping field names to their values'
431+
432+
def _asdict(self):
433+
'Return a new dict which maps field names to their values'
429434
return dict(zip(('x', 'y'), self))
430-
def __replace__(self, **kwds):
435+
436+
def _replace(self, **kwds):
431437
'Return a new Point object replacing specified fields with new values'
432-
return Point(**dict(zip(('x', 'y'), self), **kwds))
438+
return Point(*map(kwds.get, ('x', 'y'), self))
439+
433440
x = property(itemgetter(0))
434441
y = property(itemgetter(1))
435442

@@ -477,43 +484,51 @@ When casting a dictionary to a named tuple, use the double-star-operator::
477484
In addition to the methods inherited from tuples, named tuples support
478485
two additonal methods and a read-only attribute.
479486

480-
.. method:: somenamedtuple.__asdict__()
487+
.. method:: somenamedtuple._asdict()
481488

482489
Return a new dict which maps field names to their corresponding values:
483490

484491
::
485492

486-
>>> p.__asdict__()
493+
>>> p._asdict()
487494
{'x': 11, 'y': 22}
488495
489-
.. method:: somenamedtuple.__replace__(kwargs)
496+
.. method:: somenamedtuple._replace(kwargs)
490497

491498
Return a new instance of the named tuple replacing specified fields with new values:
492499

493500
::
494501

495502
>>> p = Point(x=11, y=22)
496-
>>> p.__replace__(x=33)
503+
>>> p._replace(x=33)
497504
Point(x=33, y=22)
498505

499506
>>> for partnum, record in inventory.items():
500-
... inventory[partnum] = record.__replace__(price=newprices[partnum], updated=time.now())
507+
... inventory[partnum] = record._replace(price=newprices[partnum], updated=time.now())
501508

502-
.. attribute:: somenamedtuple.__fields__
509+
.. attribute:: somenamedtuple._fields
503510

504511
Return a tuple of strings listing the field names. This is useful for introspection
505512
and for creating new named tuple types from existing named tuples.
506513

507514
::
508515

509-
>>> p.__fields__ # view the field names
516+
>>> p._fields # view the field names
510517
('x', 'y')
511518

512519
>>> Color = namedtuple('Color', 'red green blue')
513-
>>> Pixel = namedtuple('Pixel', Point.__fields__ + Color.__fields__)
520+
>>> Pixel = namedtuple('Pixel', Point._fields + Color._fields)
514521
>>> Pixel(11, 22, 128, 255, 0)
515522
Pixel(x=11, y=22, red=128, green=255, blue=0)'
516523

524+
To retrieve a field whose name is stored in a string, use the :func:`getattr`
525+
function:
526+
527+
::
528+
529+
>>> getattr(p, 'x')
530+
11
531+
517532
Since a named tuple is a regular Python class, it is easy to add or change
518533
functionality. For example, the display format can be changed by overriding
519534
the :meth:`__repr__` method:
@@ -522,17 +537,17 @@ the :meth:`__repr__` method:
522537

523538
>>> Point = namedtuple('Point', 'x y')
524539
>>> Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self
525-
>>> Point(x=10, y=20)
526-
Point(10.000, 20.000)
540+
>>> Point(x=11, y=22)
541+
Point(11.000, 22.000)
527542

528543
Default values can be implemented by starting with a prototype instance
529-
and customizing it with :meth:`__replace__`:
544+
and customizing it with :meth:`_replace`:
530545

531546
::
532547

533548
>>> Account = namedtuple('Account', 'owner balance transaction_count')
534549
>>> model_account = Account('<owner name>', 0.0, 0)
535-
>>> johns_account = model_account.__replace__(owner='John')
550+
>>> johns_account = model_account._replace(owner='John')
536551

537552
.. rubric:: Footnotes
538553

Doc/tutorial/datastructures.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,48 @@ List comprehensions can be applied to complex expressions and nested functions::
277277
['3.1', '3.14', '3.142', '3.1416', '3.14159']
278278

279279

280+
Nested List Comprehensions
281+
--------------------------
282+
283+
If you've got the stomach for it, list comprehensions can be nested. They are a
284+
powerful tool but -- like all powerful tools -- they need to be used carefully,
285+
if at all.
286+
287+
Consider the following example of a 3x3 matrix held as a list containing three
288+
lists, one list per row::
289+
290+
>>> mat = [
291+
... [1, 2, 3],
292+
... [4, 5, 6],
293+
... [7, 8, 9],
294+
... ]
295+
296+
Now, if you wanted to swap rows and columns, you could use a list
297+
comprehension::
298+
299+
>>> print [[row[i] for row in mat] for i in [0, 1, 2]]
300+
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
301+
302+
Special care has to be taken for the *nested* list comprehension:
303+
304+
To avoid apprehension when nesting list comprehensions, read from right to
305+
left.
306+
307+
A more verbose version of this snippet shows the flow explicitly::
308+
309+
for i in [0, 1, 2]:
310+
for row in mat:
311+
print row[i],
312+
print
313+
314+
In real world, you should prefer builtin functions to complex flow statements.
315+
The :func:`zip` function would do a great job for this use case::
316+
317+
>>> zip(*mat)
318+
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
319+
320+
See :ref:`tut-unpacking-arguments` for details on the asterisk in this line.
321+
280322
.. _tut-del:
281323

282324
The :keyword:`del` statement

Doc/whatsnew/2.6.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -528,17 +528,17 @@ complete list of changes, or look through the CVS logs for all the details.
528528
... 'id name type size')
529529
# Names are separated by spaces or commas.
530530
# 'id, name, type, size' would also work.
531-
>>> var_type.__fields__
531+
>>> var_type._fields
532532
('id', 'name', 'type', 'size')
533533

534534
>>> var = var_type(1, 'frequency', 'int', 4)
535535
>>> print var[0], var.id # Equivalent
536536
1 1
537537
>>> print var[2], var.type # Equivalent
538538
int int
539-
>>> var.__asdict__()
539+
>>> var._asdict()
540540
{'size': 4, 'type': 'int', 'id': 1, 'name': 'frequency'}
541-
>>> v2 = var.__replace__('name', 'amplitude')
541+
>>> v2 = var._replace('name', 'amplitude')
542542
>>> v2
543543
variable(id=1, name='amplitude', type='int', size=4)
544544

Lib/collections.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ def namedtuple(typename, field_names, verbose=False):
2626
(11, 22)
2727
>>> p.x + p.y # fields also accessable by name
2828
33
29-
>>> d = p.__asdict__() # convert to a dictionary
29+
>>> d = p._asdict() # convert to a dictionary
3030
>>> d['x']
3131
11
3232
>>> Point(**d) # convert from a dictionary
3333
Point(x=11, y=22)
34-
>>> p.__replace__(x=100) # __replace__() is like str.replace() but targets named fields
34+
>>> p._replace(x=100) # _replace() is like str.replace() but targets named fields
3535
Point(x=100, y=22)
3636
3737
"""
@@ -49,8 +49,8 @@ def namedtuple(typename, field_names, verbose=False):
4949
raise ValueError('Type names and field names cannot start with a number: %r' % name)
5050
seen_names = set()
5151
for name in field_names:
52-
if name.startswith('__') and name.endswith('__') and len(name) > 3:
53-
raise ValueError('Field names cannot start and end with double underscores: %r' % name)
52+
if name.startswith('_'):
53+
raise ValueError('Field names cannot start with an underscore: %r' % name)
5454
if name in seen_names:
5555
raise ValueError('Encountered duplicate field name: %r' % name)
5656
seen_names.add(name)
@@ -59,19 +59,19 @@ def namedtuple(typename, field_names, verbose=False):
5959
argtxt = repr(field_names).replace("'", "")[1:-1] # tuple repr without parens or quotes
6060
reprtxt = ', '.join('%s=%%r' % name for name in field_names)
6161
template = '''class %(typename)s(tuple):
62-
'%(typename)s(%(argtxt)s)'
63-
__slots__ = ()
64-
__fields__ = property(lambda self: %(field_names)r)
62+
'%(typename)s(%(argtxt)s)' \n
63+
__slots__ = () \n
64+
_fields = property(lambda self: %(field_names)r) \n
6565
def __new__(cls, %(argtxt)s):
66-
return tuple.__new__(cls, (%(argtxt)s))
66+
return tuple.__new__(cls, (%(argtxt)s)) \n
6767
def __repr__(self):
68-
return '%(typename)s(%(reprtxt)s)' %% self
69-
def __asdict__(self, dict=dict, zip=zip):
70-
'Return a new dict mapping field names to their values'
71-
return dict(zip(%(field_names)r, self))
72-
def __replace__(self, **kwds):
68+
return '%(typename)s(%(reprtxt)s)' %% self \n
69+
def _asdict(self, dict=dict, zip=zip):
70+
'Return a new dict which maps field names to their values'
71+
return dict(zip(%(field_names)r, self)) \n
72+
def _replace(self, **kwds):
7373
'Return a new %(typename)s object replacing specified fields with new values'
74-
return %(typename)s(**dict(zip(%(field_names)r, self), **kwds)) \n''' % locals()
74+
return %(typename)s(*map(kwds.get, %(field_names)r, self)) \n\n''' % locals()
7575
for i, name in enumerate(field_names):
7676
template += ' %s = property(itemgetter(%d))\n' % (name, i)
7777
if verbose:

Lib/distutils/sysconfig.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
# python_build: (Boolean) if true, we're either building Python or
3232
# building an extension with an un-installed Python, so we use
3333
# different (hard-wired) directories.
34-
python_build = os.path.isfile(os.path.join(project_base, "Modules",
35-
"Setup.local"))
34+
# Setup.local is available for Makefile builds including VPATH builds,
35+
# Setup.dist is available on Windows
36+
python_build = any(os.path.isfile(os.path.join(project_base, "Modules", fn))
37+
for fn in ("Setup.dist", "Setup.local"))
3638

3739
def get_python_version():
3840
"""Return a string containing the major and minor Python version,

Lib/distutils/tests/test_sysconfig.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def test_get_config_h_filename(self):
1515

1616
def test_get_python_lib(self):
1717
lib_dir = sysconfig.get_python_lib()
18-
# XXX doesn't work on Inux when Python was never installed before
18+
# XXX doesn't work on Linux when Python was never installed before
1919
#self.assert_(os.path.isdir(lib_dir), lib_dir)
2020
# test for pythonxx.lib?
2121

Lib/test/test_collections.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ def test_factory(self):
2828
self.assertRaises(ValueError, namedtuple, 'abc', 'efg g%hi') # field with non-alpha char
2929
self.assertRaises(ValueError, namedtuple, 'abc', 'abc class') # field has keyword
3030
self.assertRaises(ValueError, namedtuple, 'abc', '8efg 9ghi') # field starts with digit
31-
self.assertRaises(ValueError, namedtuple, 'abc', '__efg__ ghi') # field with double underscores
31+
self.assertRaises(ValueError, namedtuple, 'abc', '_efg ghi') # field with leading underscore
3232
self.assertRaises(ValueError, namedtuple, 'abc', 'efg efg ghi') # duplicate field
3333

3434
namedtuple('Point0', 'x1 y2') # Verify that numbers are allowed in names
35-
namedtuple('_', '_ __ ___') # Verify that underscores are allowed
35+
namedtuple('_', 'a b c') # Test leading underscores in a typename
3636

3737
def test_instance(self):
3838
Point = namedtuple('Point', 'x y')
@@ -49,17 +49,17 @@ def test_instance(self):
4949
self.assertEqual(repr(p), 'Point(x=11, y=22)')
5050
self.assert_('__dict__' not in dir(p)) # verify instance has no dict
5151
self.assert_('__weakref__' not in dir(p))
52-
self.assertEqual(p.__fields__, ('x', 'y')) # test __fields__ attribute
53-
self.assertEqual(p.__replace__(x=1), (1, 22)) # test __replace__ method
54-
self.assertEqual(p.__asdict__(), dict(x=11, y=22)) # test __dict__ method
52+
self.assertEqual(p._fields, ('x', 'y')) # test _fields attribute
53+
self.assertEqual(p._replace(x=1), (1, 22)) # test _replace method
54+
self.assertEqual(p._asdict(), dict(x=11, y=22)) # test _asdict method
5555

56-
# Verify that __fields__ is read-only
56+
# Verify that _fields is read-only
5757
try:
58-
p.__fields__ = ('F1' ,'F2')
58+
p._fields = ('F1' ,'F2')
5959
except AttributeError:
6060
pass
6161
else:
62-
self.fail('The __fields__ attribute needs to be read-only')
62+
self.fail('The _fields attribute needs to be read-only')
6363

6464
# verify that field string can have commas
6565
Point = namedtuple('Point', 'x, y')

0 commit comments

Comments
 (0)