Convert PEPs 204, 248, 283, 314, 3115 (#215)
This commit is contained in:
parent
1e727b0662
commit
73e6ac628e
469
pep-0204.txt
469
pep-0204.txt
|
@ -5,293 +5,304 @@ Last-Modified: $Date$
|
|||
Author: thomas@python.org (Thomas Wouters)
|
||||
Status: Rejected
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
Created: 14-Jul-2000
|
||||
Python-Version: 2.0
|
||||
Post-History:
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This PEP describes the `range literal' proposal for Python 2.0.
|
||||
This PEP tracks the status and ownership of this feature, slated
|
||||
for introduction in Python 2.0. It contains a description of the
|
||||
feature and outlines changes necessary to support the feature.
|
||||
This PEP summarizes discussions held in mailing list forums, and
|
||||
provides URLs for further information, where appropriate. The CVS
|
||||
revision history of this file contains the definitive historical
|
||||
record.
|
||||
This PEP describes the "range literal" proposal for Python 2.0.
|
||||
This PEP tracks the status and ownership of this feature, slated
|
||||
for introduction in Python 2.0. It contains a description of the
|
||||
feature and outlines changes necessary to support the feature.
|
||||
This PEP summarizes discussions held in mailing list forums, and
|
||||
provides URLs for further information, where appropriate. The CVS
|
||||
revision history of this file contains the definitive historical
|
||||
record.
|
||||
|
||||
|
||||
List ranges
|
||||
===========
|
||||
|
||||
Ranges are sequences of numbers of a fixed stepping, often used in
|
||||
for-loops. The Python for-loop is designed to iterate over a
|
||||
sequence directly:
|
||||
|
||||
>>> l = ['a', 'b', 'c', 'd']
|
||||
>>> for item in l:
|
||||
... print item
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
|
||||
However, this solution is not always prudent. Firstly, problems
|
||||
arise when altering the sequence in the body of the for-loop,
|
||||
resulting in the for-loop skipping items. Secondly, it is not
|
||||
possible to iterate over, say, every second element of the
|
||||
sequence. And thirdly, it is sometimes necessary to process an
|
||||
element based on its index, which is not readily available in the
|
||||
above construct.
|
||||
|
||||
For these instances, and others where a range of numbers is
|
||||
desired, Python provides the `range' builtin function, which
|
||||
creates a list of numbers. The `range' function takes three
|
||||
arguments, `start', `end' and `step'. `start' and `step' are
|
||||
optional, and default to 0 and 1, respectively.
|
||||
|
||||
The `range' function creates a list of numbers, starting at
|
||||
`start', with a step of `step', up to, but not including `end', so
|
||||
that `range(10)' produces a list that has exactly 10 items, the
|
||||
numbers 0 through 9.
|
||||
|
||||
Using the `range' function, the above example would look like
|
||||
this:
|
||||
|
||||
>>> for i in range(len(l)):
|
||||
... print l[i]
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
|
||||
Or, to start at the second element of `l' and processing only
|
||||
every second element from then on:
|
||||
|
||||
>>> for i in range(1, len(l), 2):
|
||||
... print l[i]
|
||||
b
|
||||
d
|
||||
|
||||
There are several disadvantages with this approach:
|
||||
|
||||
- Clarity of purpose: Adding another function call, possibly with
|
||||
extra arithmetic to determine the desired length and step of the
|
||||
list, does not improve readability of the code. Also, it is
|
||||
possible to `shadow' the builtin `range' function by supplying a
|
||||
local or global variable with the same name, effectively
|
||||
replacing it. This may or may not be a desired effect.
|
||||
|
||||
- Efficiency: because the `range' function can be overridden, the
|
||||
Python compiler cannot make assumptions about the for-loop, and
|
||||
has to maintain a separate loop counter.
|
||||
|
||||
- Consistency: There already is a syntax that is used to denote
|
||||
ranges, as shown below. This syntax uses the exact same
|
||||
arguments, though all optional, in the exact same way. It seems
|
||||
logical to extend this syntax to ranges, to form `range
|
||||
literals'.
|
||||
Ranges are sequences of numbers of a fixed stepping, often used in
|
||||
for-loops. The Python for-loop is designed to iterate over a
|
||||
sequence directly::
|
||||
|
||||
>>> l = ['a', 'b', 'c', 'd']
|
||||
>>> for item in l:
|
||||
... print item
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
|
||||
However, this solution is not always prudent. Firstly, problems
|
||||
arise when altering the sequence in the body of the for-loop,
|
||||
resulting in the for-loop skipping items. Secondly, it is not
|
||||
possible to iterate over, say, every second element of the
|
||||
sequence. And thirdly, it is sometimes necessary to process an
|
||||
element based on its index, which is not readily available in the
|
||||
above construct.
|
||||
|
||||
For these instances, and others where a range of numbers is
|
||||
desired, Python provides the ``range`` builtin function, which
|
||||
creates a list of numbers. The ``range`` function takes three
|
||||
arguments, ``start``, ``end`` and ``step``. ``start`` and ``step`` are
|
||||
optional, and default to 0 and 1, respectively.
|
||||
|
||||
The ``range`` function creates a list of numbers, starting at
|
||||
``start``, with a step of ``step``, up to, but not including ``end``, so
|
||||
that ``range(10)`` produces a list that has exactly 10 items, the
|
||||
numbers 0 through 9.
|
||||
|
||||
Using the ``range`` function, the above example would look like
|
||||
this::
|
||||
|
||||
>>> for i in range(len(l)):
|
||||
... print l[i]
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
|
||||
Or, to start at the second element of ``l`` and processing only
|
||||
every second element from then on::
|
||||
|
||||
>>> for i in range(1, len(l), 2):
|
||||
... print l[i]
|
||||
b
|
||||
d
|
||||
|
||||
There are several disadvantages with this approach:
|
||||
|
||||
- Clarity of purpose: Adding another function call, possibly with
|
||||
extra arithmetic to determine the desired length and step of the
|
||||
list, does not improve readability of the code. Also, it is
|
||||
possible to "shadow" the builtin ``range`` function by supplying a
|
||||
local or global variable with the same name, effectively
|
||||
replacing it. This may or may not be a desired effect.
|
||||
|
||||
- Efficiency: because the ``range`` function can be overridden, the
|
||||
Python compiler cannot make assumptions about the for-loop, and
|
||||
has to maintain a separate loop counter.
|
||||
|
||||
- Consistency: There already is a syntax that is used to denote
|
||||
ranges, as shown below. This syntax uses the exact same
|
||||
arguments, though all optional, in the exact same way. It seems
|
||||
logical to extend this syntax to ranges, to form "range
|
||||
literals".
|
||||
|
||||
|
||||
Slice Indices
|
||||
=============
|
||||
|
||||
In Python, a sequence can be indexed in one of two ways:
|
||||
retrieving a single item, or retrieving a range of items.
|
||||
Retrieving a range of items results in a new object of the same
|
||||
type as the original sequence, containing zero or more items from
|
||||
the original sequence. This is done using a `range notation':
|
||||
|
||||
>>> l[2:4]
|
||||
['c', 'd']
|
||||
|
||||
This range notation consists of zero, one or two indices separated
|
||||
by a colon. The first index is the `start' index, the second the
|
||||
`end'. When either is left out, they default to respectively the
|
||||
start and the end of the sequence.
|
||||
|
||||
There is also an extended range notation, which incorporates
|
||||
`step' as well. Though this notation is not currently supported
|
||||
by most builtin types, if it were, it would work as follows:
|
||||
|
||||
>>> l[1:4:2]
|
||||
['b', 'd']
|
||||
In Python, a sequence can be indexed in one of two ways:
|
||||
retrieving a single item, or retrieving a range of items.
|
||||
Retrieving a range of items results in a new object of the same
|
||||
type as the original sequence, containing zero or more items from
|
||||
the original sequence. This is done using a "range notation"::
|
||||
|
||||
The third `argument' to the slice syntax is exactly the same as
|
||||
the `step' argument to range(). The underlying mechanisms of the
|
||||
standard, and these extended slices, are sufficiently different
|
||||
and inconsistent that many classes and extensions outside of
|
||||
mathematical packages do not implement support for the extended
|
||||
variant. While this should be resolved, it is beyond the scope of
|
||||
this PEP.
|
||||
|
||||
Extended slices do show, however, that there is already a
|
||||
perfectly valid and applicable syntax to denote ranges in a way
|
||||
that solve all of the earlier stated disadvantages of the use of
|
||||
the range() function:
|
||||
|
||||
- It is clearer, more concise syntax, which has already proven to
|
||||
be both intuitive and easy to learn.
|
||||
|
||||
- It is consistent with the other use of ranges in Python
|
||||
(e.g. slices).
|
||||
|
||||
- Because it is built-in syntax, instead of a builtin function, it
|
||||
cannot be overridden. This means both that a viewer can be
|
||||
certain about what the code does, and that an optimizer will not
|
||||
have to worry about range() being `shadowed'.
|
||||
>>> l[2:4]
|
||||
['c', 'd']
|
||||
|
||||
This range notation consists of zero, one or two indices separated
|
||||
by a colon. The first index is the ``start`` index, the second the
|
||||
``end``. When either is left out, they default to respectively the
|
||||
start and the end of the sequence.
|
||||
|
||||
There is also an extended range notation, which incorporates
|
||||
``step`` as well. Though this notation is not currently supported
|
||||
by most builtin types, if it were, it would work as follows::
|
||||
|
||||
>>> l[1:4:2]
|
||||
['b', 'd']
|
||||
|
||||
The third "argument" to the slice syntax is exactly the same as
|
||||
the ``step`` argument to ``range()``. The underlying mechanisms of the
|
||||
standard, and these extended slices, are sufficiently different
|
||||
and inconsistent that many classes and extensions outside of
|
||||
mathematical packages do not implement support for the extended
|
||||
variant. While this should be resolved, it is beyond the scope of
|
||||
this PEP.
|
||||
|
||||
Extended slices do show, however, that there is already a
|
||||
perfectly valid and applicable syntax to denote ranges in a way
|
||||
that solve all of the earlier stated disadvantages of the use of
|
||||
the ``range()`` function:
|
||||
|
||||
- It is clearer, more concise syntax, which has already proven to
|
||||
be both intuitive and easy to learn.
|
||||
|
||||
- It is consistent with the other use of ranges in Python
|
||||
(e.g. slices).
|
||||
|
||||
- Because it is built-in syntax, instead of a builtin function, it
|
||||
cannot be overridden. This means both that a viewer can be
|
||||
certain about what the code does, and that an optimizer will not
|
||||
have to worry about ``range()`` being "shadowed".
|
||||
|
||||
|
||||
The Proposed Solution
|
||||
=====================
|
||||
|
||||
The proposed implementation of range-literals combines the syntax
|
||||
for list literals with the syntax for (extended) slices, to form
|
||||
range literals:
|
||||
|
||||
>>> [1:10]
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
>>> [:5]
|
||||
[0, 1, 2, 3, 4]
|
||||
>>> [5:1:-1]
|
||||
[5, 4, 3, 2]
|
||||
|
||||
There is one minor difference between range literals and the slice
|
||||
syntax: though it is possible to omit all of `start', `end' and
|
||||
`step' in slices, it does not make sense to omit `end' in range
|
||||
literals. In slices, `end' would default to the end of the list,
|
||||
but this has no meaning in range literals.
|
||||
The proposed implementation of range-literals combines the syntax
|
||||
for list literals with the syntax for (extended) slices, to form
|
||||
range literals::
|
||||
|
||||
>>> [1:10]
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
>>> [:5]
|
||||
[0, 1, 2, 3, 4]
|
||||
>>> [5:1:-1]
|
||||
[5, 4, 3, 2]
|
||||
|
||||
There is one minor difference between range literals and the slice
|
||||
syntax: though it is possible to omit all of ``start``, ``end`` and
|
||||
``step`` in slices, it does not make sense to omit ``end`` in range
|
||||
literals. In slices, ``end`` would default to the end of the list,
|
||||
but this has no meaning in range literals.
|
||||
|
||||
|
||||
Reference Implementation
|
||||
========================
|
||||
|
||||
The proposed implementation can be found on SourceForge[1]. It
|
||||
adds a new bytecode, BUILD_RANGE, that takes three arguments from
|
||||
the stack and builds a list on the bases of those. The list is
|
||||
pushed back on the stack.
|
||||
|
||||
The use of a new bytecode is necessary to be able to build ranges
|
||||
based on other calculations, whose outcome is not known at compile
|
||||
time.
|
||||
|
||||
The code introduces two new functions to listobject.c, which are
|
||||
currently hovering between private functions and full-fledged API
|
||||
calls.
|
||||
The proposed implementation can be found on SourceForge [1]_. It
|
||||
adds a new bytecode, ``BUILD_RANGE``, that takes three arguments from
|
||||
the stack and builds a list on the bases of those. The list is
|
||||
pushed back on the stack.
|
||||
|
||||
PyList_FromRange() builds a list from start, end and step,
|
||||
returning NULL if an error occurs. Its prototype is:
|
||||
The use of a new bytecode is necessary to be able to build ranges
|
||||
based on other calculations, whose outcome is not known at compile
|
||||
time.
|
||||
|
||||
PyObject * PyList_FromRange(long start, long end, long step)
|
||||
|
||||
PyList_GetLenOfRange() is a helper function used to determine the
|
||||
length of a range. Previously, it was a static function in
|
||||
bltinmodule.c, but is now necessary in both listobject.c and
|
||||
bltinmodule.c (for xrange). It is made non-static solely to avoid
|
||||
code duplication. Its prototype is:
|
||||
The code introduces two new functions to listobject.c, which are
|
||||
currently hovering between private functions and full-fledged API
|
||||
calls.
|
||||
|
||||
long PyList_GetLenOfRange(long start, long end, long step)
|
||||
``PyList_FromRange()`` builds a list from start, end and step,
|
||||
returning NULL if an error occurs. Its prototype is::
|
||||
|
||||
PyObject * PyList_FromRange(long start, long end, long step)
|
||||
|
||||
``PyList_GetLenOfRange()`` is a helper function used to determine the
|
||||
length of a range. Previously, it was a static function in
|
||||
bltinmodule.c, but is now necessary in both listobject.c and
|
||||
bltinmodule.c (for ``xrange``). It is made non-static solely to avoid
|
||||
code duplication. Its prototype is::
|
||||
|
||||
long PyList_GetLenOfRange(long start, long end, long step)
|
||||
|
||||
|
||||
Open issues
|
||||
===========
|
||||
|
||||
- One possible solution to the discrepancy of requiring the `end'
|
||||
argument in range literals is to allow the range syntax to
|
||||
create a `generator', rather than a list, such as the `xrange'
|
||||
builtin function does. However, a generator would not be a
|
||||
list, and it would be impossible, for instance, to assign to
|
||||
items in the generator, or append to it.
|
||||
- One possible solution to the discrepancy of requiring the ``end``
|
||||
argument in range literals is to allow the range syntax to
|
||||
create a "generator", rather than a list, such as the ``xrange``
|
||||
builtin function does. However, a generator would not be a
|
||||
list, and it would be impossible, for instance, to assign to
|
||||
items in the generator, or append to it.
|
||||
|
||||
The range syntax could conceivably be extended to include tuples
|
||||
(i.e. immutable lists), which could then be safely implemented
|
||||
as generators. This may be a desirable solution, especially for
|
||||
large number arrays: generators require very little in the way
|
||||
of storage and initialization, and there is only a small
|
||||
performance impact in calculating and creating the appropriate
|
||||
number on request. (TBD: is there any at all? Cursory testing
|
||||
suggests equal performance even in the case of ranges of length
|
||||
1)
|
||||
The range syntax could conceivably be extended to include tuples
|
||||
(i.e. immutable lists), which could then be safely implemented
|
||||
as generators. This may be a desirable solution, especially for
|
||||
large number arrays: generators require very little in the way
|
||||
of storage and initialization, and there is only a small
|
||||
performance impact in calculating and creating the appropriate
|
||||
number on request. (TBD: is there any at all? Cursory testing
|
||||
suggests equal performance even in the case of ranges of length
|
||||
1)
|
||||
|
||||
However, even if idea was adopted, would it be wise to `special
|
||||
case' the second argument, making it optional in one instance of
|
||||
the syntax, and non-optional in other cases ?
|
||||
However, even if idea was adopted, would it be wise to "special
|
||||
case" the second argument, making it optional in one instance of
|
||||
the syntax, and non-optional in other cases ?
|
||||
|
||||
- Should it be possible to mix range syntax with normal list
|
||||
literals, creating a single list? E.g.:
|
||||
- Should it be possible to mix range syntax with normal list
|
||||
literals, creating a single list? E.g.::
|
||||
|
||||
>>> [5, 6, 1:6, 7, 9]
|
||||
>>> [5, 6, 1:6, 7, 9]
|
||||
|
||||
to create
|
||||
to create::
|
||||
|
||||
[5, 6, 1, 2, 3, 4, 5, 7, 9]
|
||||
[5, 6, 1, 2, 3, 4, 5, 7, 9]
|
||||
|
||||
- How should range literals interact with another proposed new
|
||||
feature, `list comprehensions'[2]? Specifically, should it be
|
||||
possible to create lists in list comprehensions? E.g.:
|
||||
|
||||
>>> [x:y for x in (1, 2) y in (3, 4)]
|
||||
- How should range literals interact with another proposed new
|
||||
feature, "list comprehensions" [2]_? Specifically, should it be
|
||||
possible to create lists in list comprehensions? E.g.::
|
||||
|
||||
Should this example return a single list with multiple ranges:
|
||||
>>> [x:y for x in (1, 2) y in (3, 4)]
|
||||
|
||||
[1, 2, 1, 2, 3, 2, 2, 3]
|
||||
Should this example return a single list with multiple ranges::
|
||||
|
||||
Or a list of lists, like so:
|
||||
[1, 2, 1, 2, 3, 2, 2, 3]
|
||||
|
||||
[[1, 2], [1, 2, 3], [2], [2, 3]]
|
||||
Or a list of lists, like so::
|
||||
|
||||
However, as the syntax and semantics of list comprehensions are
|
||||
still subject of hot debate, these issues are probably best
|
||||
addressed by the `list comprehensions' PEP.
|
||||
[[1, 2], [1, 2, 3], [2]_, [2, 3]]
|
||||
|
||||
- Range literals accept objects other than integers: it performs
|
||||
PyInt_AsLong() on the objects passed in, so as long as the
|
||||
objects can be coerced into integers, they will be accepted.
|
||||
The resulting list, however, is always composed of standard
|
||||
integers.
|
||||
However, as the syntax and semantics of list comprehensions are
|
||||
still subject of hot debate, these issues are probably best
|
||||
addressed by the "list comprehensions" PEP.
|
||||
|
||||
Should range literals create a list of the passed-in type? It
|
||||
might be desirable in the cases of other builtin types, such as
|
||||
longs and strings:
|
||||
- Range literals accept objects other than integers: it performs
|
||||
``PyInt_AsLong()`` on the objects passed in, so as long as the
|
||||
objects can be coerced into integers, they will be accepted.
|
||||
The resulting list, however, is always composed of standard
|
||||
integers.
|
||||
|
||||
>>> [ 1L : 2L<<64 : 2<<32L ]
|
||||
>>> ["a":"z":"b"]
|
||||
>>> ["a":"z":2]
|
||||
Should range literals create a list of the passed-in type? It
|
||||
might be desirable in the cases of other builtin types, such as
|
||||
longs and strings::
|
||||
|
||||
However, this might be too much `magic' to be obvious. It might
|
||||
also present problems with user-defined classes: even if the
|
||||
base class can be found and a new instance created, the instance
|
||||
may require additional arguments to __init__, causing the
|
||||
creation to fail.
|
||||
|
||||
- The PyList_FromRange() and PyList_GetLenOfRange() functions need
|
||||
to be classified: are they part of the API, or should they be
|
||||
made private functions?
|
||||
>>> [ 1L : 2L<<64 : 2<<32L ]
|
||||
>>> ["a":"z":"b"]
|
||||
>>> ["a":"z":2]
|
||||
|
||||
However, this might be too much "magic" to be obvious. It might
|
||||
also present problems with user-defined classes: even if the
|
||||
base class can be found and a new instance created, the instance
|
||||
may require additional arguments to ``__init__``, causing the
|
||||
creation to fail.
|
||||
|
||||
- The ``PyList_FromRange()`` and ``PyList_GetLenOfRange()`` functions need
|
||||
to be classified: are they part of the API, or should they be
|
||||
made private functions?
|
||||
|
||||
|
||||
Rejection
|
||||
=========
|
||||
|
||||
After careful consideration, and a period of meditation, this
|
||||
proposal has been rejected. The open issues, as well as some
|
||||
confusion between ranges and slice syntax, raised enough questions
|
||||
for Guido not to accept it for Python 2.0, and later to reject the
|
||||
proposal altogether. The new syntax and its intentions were deemed
|
||||
not obvious enough.
|
||||
After careful consideration, and a period of meditation, this
|
||||
proposal has been rejected. The open issues, as well as some
|
||||
confusion between ranges and slice syntax, raised enough questions
|
||||
for Guido not to accept it for Python 2.0, and later to reject the
|
||||
proposal altogether. The new syntax and its intentions were deemed
|
||||
not obvious enough.
|
||||
|
||||
[ TBD: Guido, amend/confirm this, please. Preferably both; this
|
||||
is a PEP, it should contain *all* the reasons for rejection
|
||||
and/or reconsideration, for future reference. ]
|
||||
[ TBD: Guido, amend/confirm this, please. Preferably both; this
|
||||
is a PEP, it should contain *all* the reasons for rejection
|
||||
and/or reconsideration, for future reference. ]
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the Public Domain.
|
||||
This document has been placed in the Public Domain.
|
||||
|
||||
|
||||
References:
|
||||
References
|
||||
==========
|
||||
|
||||
[1] http://sourceforge.net/patch/?func=detailpatch&patch_id=100902&group_id=5470
|
||||
[2] PEP 202, List Comprehensions
|
||||
.. [1] http://sourceforge.net/patch/?func=detailpatch&patch_id=100902&group_id=5470
|
||||
.. [2] PEP 202, List Comprehensions
|
||||
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
|
501
pep-0248.txt
501
pep-0248.txt
|
@ -6,321 +6,308 @@ Author: mal@lemburg.com (Marc-André Lemburg)
|
|||
Discussions-To: db-sig@python.org
|
||||
Status: Final
|
||||
Type: Informational
|
||||
Content-Type: text/x-rst
|
||||
Created:
|
||||
Post-History:
|
||||
Superseded-By: 249
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This API has been defined to encourage similarity between the
|
||||
Python modules that are used to access databases. By doing this,
|
||||
we hope to achieve a consistency leading to more easily understood
|
||||
modules, code that is generally more portable across databases,
|
||||
and a broader reach of database connectivity from Python.
|
||||
|
||||
This interface specification consists of several items:
|
||||
This API has been defined to encourage similarity between the
|
||||
Python modules that are used to access databases. By doing this,
|
||||
we hope to achieve a consistency leading to more easily understood
|
||||
modules, code that is generally more portable across databases,
|
||||
and a broader reach of database connectivity from Python.
|
||||
|
||||
* Module Interface
|
||||
* Connection Objects
|
||||
* Cursor Objects
|
||||
* DBI Helper Objects
|
||||
|
||||
Comments and questions about this specification may be directed to
|
||||
the SIG on Tabular Databases in Python
|
||||
(http://www.python.org/sigs/db-sig).
|
||||
This interface specification consists of several items:
|
||||
|
||||
This specification document was last updated on: April 9, 1996.
|
||||
It will be known as Version 1.0 of this specification.
|
||||
* Module Interface
|
||||
* Connection Objects
|
||||
* Cursor Objects
|
||||
* DBI Helper Objects
|
||||
|
||||
Comments and questions about this specification may be directed to
|
||||
the SIG on Tabular Databases in Python
|
||||
(http://www.python.org/sigs/db-sig).
|
||||
|
||||
This specification document was last updated on: April 9, 1996.
|
||||
It will be known as Version 1.0 of this specification.
|
||||
|
||||
|
||||
Module Interface
|
||||
================
|
||||
|
||||
The database interface modules should typically be named with
|
||||
something terminated by 'db'. Existing examples are: 'oracledb',
|
||||
'informixdb', and 'pg95db'. These modules should export several
|
||||
names:
|
||||
|
||||
modulename(connection_string)
|
||||
The database interface modules should typically be named with
|
||||
something terminated by ``db``. Existing examples are: ``oracledb``,
|
||||
``informixdb``, and ``pg95db``. These modules should export several
|
||||
names:
|
||||
|
||||
Constructor for creating a connection to the database.
|
||||
Returns a Connection Object.
|
||||
|
||||
error
|
||||
|
||||
Exception raised for errors from the database module.
|
||||
modulename(connection_string)
|
||||
Constructor for creating a connection to the database.
|
||||
Returns a Connection Object.
|
||||
|
||||
error
|
||||
Exception raised for errors from the database module.
|
||||
|
||||
|
||||
Connection Objects
|
||||
==================
|
||||
|
||||
Connection Objects should respond to the following methods:
|
||||
|
||||
close()
|
||||
Connection Objects should respond to the following methods:
|
||||
|
||||
Close the connection now (rather than whenever __del__ is
|
||||
called). The connection will be unusable from this point
|
||||
forward; an exception will be raised if any operation is
|
||||
attempted with the connection.
|
||||
|
||||
commit()
|
||||
close()
|
||||
Close the connection now (rather than whenever ``__del__`` is
|
||||
called). The connection will be unusable from this point
|
||||
forward; an exception will be raised if any operation is
|
||||
attempted with the connection.
|
||||
|
||||
Commit any pending transaction to the database.
|
||||
|
||||
rollback()
|
||||
commit()
|
||||
Commit any pending transaction to the database.
|
||||
|
||||
Roll the database back to the start of any pending
|
||||
transaction.
|
||||
|
||||
cursor()
|
||||
rollback()
|
||||
Roll the database back to the start of any pending
|
||||
transaction.
|
||||
|
||||
Return a new Cursor Object. An exception may be thrown if
|
||||
the database does not support a cursor concept.
|
||||
|
||||
callproc([params])
|
||||
cursor()
|
||||
Return a new Cursor Object. An exception may be thrown if
|
||||
the database does not support a cursor concept.
|
||||
|
||||
(Note: this method is not well-defined yet.) Call a
|
||||
stored database procedure with the given (optional)
|
||||
parameters. Returns the result of the stored procedure.
|
||||
|
||||
(all Cursor Object attributes and methods)
|
||||
callproc([params])
|
||||
(Note: this method is not well-defined yet.) Call a
|
||||
stored database procedure with the given (optional)
|
||||
parameters. Returns the result of the stored procedure.
|
||||
|
||||
(all Cursor Object attributes and methods)
|
||||
For databases that do not have cursors and for simple
|
||||
applications that do not require the complexity of a
|
||||
cursor, a Connection Object should respond to each of the
|
||||
attributes and methods of the Cursor Object. Databases
|
||||
that have cursor can implement this by using an implicit,
|
||||
internal cursor.
|
||||
|
||||
For databases that do not have cursors and for simple
|
||||
applications that do not require the complexity of a
|
||||
cursor, a Connection Object should respond to each of the
|
||||
attributes and methods of the Cursor Object. Databases
|
||||
that have cursor can implement this by using an implicit,
|
||||
internal cursor.
|
||||
|
||||
|
||||
Cursor Objects
|
||||
==============
|
||||
|
||||
These objects represent a database cursor, which is used to manage
|
||||
the context of a fetch operation.
|
||||
|
||||
Cursor Objects should respond to the following methods and
|
||||
attributes:
|
||||
|
||||
arraysize
|
||||
These objects represent a database cursor, which is used to manage
|
||||
the context of a fetch operation.
|
||||
|
||||
This read/write attribute specifies the number of rows to
|
||||
fetch at a time with fetchmany(). This value is also used
|
||||
when inserting multiple rows at a time (passing a
|
||||
tuple/list of tuples/lists as the params value to
|
||||
execute()). This attribute will default to a single row.
|
||||
|
||||
Note that the arraysize is optional and is merely provided
|
||||
for higher performance database interactions.
|
||||
Implementations should observe it with respect to the
|
||||
fetchmany() method, but are free to interact with the
|
||||
database a single row at a time.
|
||||
|
||||
description
|
||||
Cursor Objects should respond to the following methods and
|
||||
attributes:
|
||||
|
||||
This read-only attribute is a tuple of 7-tuples. Each
|
||||
7-tuple contains information describing each result
|
||||
column: (name, type_code, display_size, internal_size,
|
||||
precision, scale, null_ok). This attribute will be None
|
||||
for operations that do not return rows or if the cursor
|
||||
has not had an operation invoked via the execute() method
|
||||
yet.
|
||||
|
||||
The 'type_code' is one of the 'dbi' values specified in
|
||||
the section below.
|
||||
|
||||
Note: this is a bit in flux. Generally, the first two
|
||||
items of the 7-tuple will always be present; the others
|
||||
may be database specific.
|
||||
|
||||
close()
|
||||
arraysize
|
||||
This read/write attribute specifies the number of rows to
|
||||
fetch at a time with ``fetchmany()``. This value is also used
|
||||
when inserting multiple rows at a time (passing a
|
||||
tuple/list of tuples/lists as the params value to
|
||||
``execute()``). This attribute will default to a single row.
|
||||
|
||||
Close the cursor now (rather than whenever __del__ is
|
||||
called). The cursor will be unusable from this point
|
||||
forward; an exception will be raised if any operation is
|
||||
attempted with the cursor.
|
||||
|
||||
execute(operation [,params])
|
||||
Note that the arraysize is optional and is merely provided
|
||||
for higher performance database interactions.
|
||||
Implementations should observe it with respect to the
|
||||
``fetchmany()`` method, but are free to interact with the
|
||||
database a single row at a time.
|
||||
|
||||
Execute (prepare) a database operation (query or command).
|
||||
Parameters may be provided (as a sequence
|
||||
(e.g. tuple/list)) and will be bound to variables in the
|
||||
operation. Variables are specified in a database-specific
|
||||
notation that is based on the index in the parameter tuple
|
||||
(position-based rather than name-based).
|
||||
|
||||
The parameters may also be specified as a sequence of
|
||||
sequences (e.g. a list of tuples) to insert multiple rows
|
||||
in a single operation.
|
||||
|
||||
A reference to the operation will be retained by the
|
||||
cursor. If the same operation object is passed in again,
|
||||
then the cursor can optimize its behavior. This is most
|
||||
effective for algorithms where the same operation is used,
|
||||
but different parameters are bound to it (many times).
|
||||
|
||||
For maximum efficiency when reusing an operation, it is
|
||||
best to use the setinputsizes() method to specify the
|
||||
parameter types and sizes ahead of time. It is legal for
|
||||
a parameter to not match the predefined information; the
|
||||
implementation should compensate, possibly with a loss of
|
||||
efficiency.
|
||||
|
||||
Using SQL terminology, these are the possible result
|
||||
values from the execute() method:
|
||||
description
|
||||
This read-only attribute is a tuple of 7-tuples. Each
|
||||
7-tuple contains information describing each result
|
||||
column: (name, type_code, display_size, internal_size,
|
||||
precision, scale, null_ok). This attribute will be None
|
||||
for operations that do not return rows or if the cursor
|
||||
has not had an operation invoked via the ``execute()`` method
|
||||
yet.
|
||||
|
||||
If the statement is DDL (e.g. CREATE TABLE), then 1 is
|
||||
returned.
|
||||
The 'type_code' is one of the 'dbi' values specified in
|
||||
the section below.
|
||||
|
||||
If the statement is DML (e.g. UPDATE or INSERT), then the
|
||||
number of rows affected is returned (0 or a positive
|
||||
integer).
|
||||
Note: this is a bit in flux. Generally, the first two
|
||||
items of the 7-tuple will always be present; the others
|
||||
may be database specific.
|
||||
|
||||
If the statement is DQL (e.g. SELECT), None is returned,
|
||||
indicating that the statement is not really complete until
|
||||
you use one of the 'fetch' methods.
|
||||
close()
|
||||
Close the cursor now (rather than whenever ``__del__`` is
|
||||
called). The cursor will be unusable from this point
|
||||
forward; an exception will be raised if any operation is
|
||||
attempted with the cursor.
|
||||
|
||||
fetchone()
|
||||
execute(operation [,params])
|
||||
Execute (prepare) a database operation (query or command).
|
||||
Parameters may be provided (as a sequence
|
||||
(e.g. tuple/list)) and will be bound to variables in the
|
||||
operation. Variables are specified in a database-specific
|
||||
notation that is based on the index in the parameter tuple
|
||||
(position-based rather than name-based).
|
||||
|
||||
Fetch the next row of a query result, returning a single
|
||||
tuple.
|
||||
The parameters may also be specified as a sequence of
|
||||
sequences (e.g. a list of tuples) to insert multiple rows
|
||||
in a single operation.
|
||||
|
||||
fetchmany([size])
|
||||
A reference to the operation will be retained by the
|
||||
cursor. If the same operation object is passed in again,
|
||||
then the cursor can optimize its behavior. This is most
|
||||
effective for algorithms where the same operation is used,
|
||||
but different parameters are bound to it (many times).
|
||||
|
||||
Fetch the next set of rows of a query result, returning as
|
||||
a list of tuples. An empty list is returned when no more
|
||||
rows are available. The number of rows to fetch is
|
||||
specified by the parameter. If it is None, then the
|
||||
cursor's arraysize determines the number of rows to be
|
||||
fetched.
|
||||
|
||||
Note there are performance considerations involved with
|
||||
the size parameter. For optimal performance, it is
|
||||
usually best to use the arraysize attribute. If the size
|
||||
parameter is used, then it is best for it to retain the
|
||||
same value from one fetchmany() call to the next.
|
||||
|
||||
fetchall()
|
||||
For maximum efficiency when reusing an operation, it is
|
||||
best to use the ``setinputsizes()`` method to specify the
|
||||
parameter types and sizes ahead of time. It is legal for
|
||||
a parameter to not match the predefined information; the
|
||||
implementation should compensate, possibly with a loss of
|
||||
efficiency.
|
||||
|
||||
Fetch all rows of a query result, returning as a list of
|
||||
tuples. Note that the cursor's arraysize attribute can
|
||||
affect the performance of this operation.
|
||||
|
||||
setinputsizes(sizes)
|
||||
Using SQL terminology, these are the possible result
|
||||
values from the ``execute()`` method:
|
||||
|
||||
(Note: this method is not well-defined yet.) This can be
|
||||
used before a call to 'execute()' to predefine memory
|
||||
areas for the operation's parameters. sizes is specified
|
||||
as a tuple -- one item for each input parameter. The item
|
||||
should be a Type object that corresponds to the input that
|
||||
will be used, or it should be an integer specifying the
|
||||
maximum length of a string parameter. If the item is
|
||||
'None', then no predefined memory area will be reserved
|
||||
for that column (this is useful to avoid predefined areas
|
||||
for large inputs).
|
||||
|
||||
This method would be used before the execute() method is
|
||||
invoked.
|
||||
|
||||
Note that this method is optional and is merely provided
|
||||
for higher performance database interaction.
|
||||
Implementations are free to do nothing and users are free
|
||||
to not use it.
|
||||
|
||||
setoutputsize(size [,col])
|
||||
- If the statement is DDL (e.g. CREATE TABLE), then 1 is
|
||||
returned.
|
||||
|
||||
(Note: this method is not well-defined yet.)
|
||||
- If the statement is DML (e.g. UPDATE or INSERT), then the
|
||||
number of rows affected is returned (0 or a positive
|
||||
integer).
|
||||
|
||||
- If the statement is DQL (e.g. SELECT), None is returned,
|
||||
indicating that the statement is not really complete until
|
||||
you use one of the 'fetch' methods.
|
||||
|
||||
fetchone()
|
||||
Fetch the next row of a query result, returning a single
|
||||
tuple.
|
||||
|
||||
fetchmany([size])
|
||||
Fetch the next set of rows of a query result, returning as
|
||||
a list of tuples. An empty list is returned when no more
|
||||
rows are available. The number of rows to fetch is
|
||||
specified by the parameter. If it is None, then the
|
||||
cursor's arraysize determines the number of rows to be
|
||||
fetched.
|
||||
|
||||
Note there are performance considerations involved with
|
||||
the size parameter. For optimal performance, it is
|
||||
usually best to use the arraysize attribute. If the size
|
||||
parameter is used, then it is best for it to retain the
|
||||
same value from one ``fetchmany()`` call to the next.
|
||||
|
||||
fetchall()
|
||||
Fetch all rows of a query result, returning as a list of
|
||||
tuples. Note that the cursor's arraysize attribute can
|
||||
affect the performance of this operation.
|
||||
|
||||
setinputsizes(sizes)
|
||||
(Note: this method is not well-defined yet.) This can be
|
||||
used before a call to ``execute()`` to predefine memory
|
||||
areas for the operation's parameters. sizes is specified
|
||||
as a tuple -- one item for each input parameter. The item
|
||||
should be a Type object that corresponds to the input that
|
||||
will be used, or it should be an integer specifying the
|
||||
maximum length of a string parameter. If the item is
|
||||
'None', then no predefined memory area will be reserved
|
||||
for that column (this is useful to avoid predefined areas
|
||||
for large inputs).
|
||||
|
||||
This method would be used before the ``execute()`` method is
|
||||
invoked.
|
||||
|
||||
Note that this method is optional and is merely provided
|
||||
for higher performance database interaction.
|
||||
Implementations are free to do nothing and users are free
|
||||
to not use it.
|
||||
|
||||
setoutputsize(size [,col])
|
||||
(Note: this method is not well-defined yet.)
|
||||
|
||||
Set a column buffer size for fetches of large columns
|
||||
(e.g. LONG). The column is specified as an index into the
|
||||
result tuple. Using a column of None will set the default
|
||||
size for all large columns in the cursor.
|
||||
|
||||
This method would be used before the ``execute()`` method is
|
||||
invoked.
|
||||
|
||||
Note that this method is optional and is merely provided
|
||||
for higher performance database interaction.
|
||||
Implementations are free to do nothing and users are free
|
||||
to not use it.
|
||||
|
||||
Set a column buffer size for fetches of large columns
|
||||
(e.g. LONG). The column is specified as an index into the
|
||||
result tuple. Using a column of None will set the default
|
||||
size for all large columns in the cursor.
|
||||
|
||||
This method would be used before the 'execute()' method is
|
||||
invoked.
|
||||
|
||||
Note that this method is optional and is merely provided
|
||||
for higher performance database interaction.
|
||||
Implementations are free to do nothing and users are free
|
||||
to not use it.
|
||||
|
||||
|
||||
DBI Helper Objects
|
||||
==================
|
||||
|
||||
Many databases need to have the input in a particular format for
|
||||
binding to an operation's input parameters. For example, if an
|
||||
input is destined for a DATE column, then it must be bound to the
|
||||
database in a particular string format. Similar problems exist
|
||||
for "Row ID" columns or large binary items (e.g. blobs or RAW
|
||||
columns). This presents problems for Python since the parameters
|
||||
to the 'execute()' method are untyped. When the database module
|
||||
sees a Python string object, it doesn't know if it should be bound
|
||||
as a simple CHAR column, as a raw binary item, or as a DATE.
|
||||
|
||||
To overcome this problem, the 'dbi' module was created. This
|
||||
module specifies some basic database interface types for working
|
||||
with databases. There are two classes: 'dbiDate' and 'dbiRaw'.
|
||||
These are simple container classes that wrap up a value. When
|
||||
passed to the database modules, the module can then detect that
|
||||
the input parameter is intended as a DATE or a RAW. For symmetry,
|
||||
the database modules will return DATE and RAW columns as instances
|
||||
of these classes.
|
||||
|
||||
A Cursor Object's 'description' attribute returns information
|
||||
about each of the result columns of a query. The 'type_code is
|
||||
defined to be one of five types exported by this module: 'STRING',
|
||||
'RAW', 'NUMBER', 'DATE', or 'ROWID'.
|
||||
|
||||
The module exports the following names:
|
||||
|
||||
dbiDate(value)
|
||||
Many databases need to have the input in a particular format for
|
||||
binding to an operation's input parameters. For example, if an
|
||||
input is destined for a DATE column, then it must be bound to the
|
||||
database in a particular string format. Similar problems exist
|
||||
for "Row ID" columns or large binary items (e.g. blobs or RAW
|
||||
columns). This presents problems for Python since the parameters
|
||||
to the ``execute()`` method are untyped. When the database module
|
||||
sees a Python string object, it doesn't know if it should be bound
|
||||
as a simple CHAR column, as a raw binary item, or as a DATE.
|
||||
|
||||
This function constructs a 'dbiDate' instance that holds a
|
||||
date value. The value should be specified as an integer
|
||||
number of seconds since the "epoch" (e.g. time.time()).
|
||||
|
||||
dbiRaw(value)
|
||||
To overcome this problem, the 'dbi' module was created. This
|
||||
module specifies some basic database interface types for working
|
||||
with databases. There are two classes: 'dbiDate' and 'dbiRaw'.
|
||||
These are simple container classes that wrap up a value. When
|
||||
passed to the database modules, the module can then detect that
|
||||
the input parameter is intended as a DATE or a RAW. For symmetry,
|
||||
the database modules will return DATE and RAW columns as instances
|
||||
of these classes.
|
||||
|
||||
This function constructs a 'dbiRaw' instance that holds a
|
||||
raw (binary) value. The value should be specified as a
|
||||
Python string.
|
||||
A Cursor Object's 'description' attribute returns information
|
||||
about each of the result columns of a query. The 'type_code is
|
||||
defined to be one of five types exported by this module: 'STRING',
|
||||
'RAW', 'NUMBER', 'DATE', or 'ROWID'.
|
||||
|
||||
STRING
|
||||
The module exports the following names:
|
||||
|
||||
This object is used to describe columns in a database that
|
||||
are string-based (e.g. CHAR).
|
||||
|
||||
RAW
|
||||
dbiDate(value)
|
||||
This function constructs a 'dbiDate' instance that holds a
|
||||
date value. The value should be specified as an integer
|
||||
number of seconds since the "epoch" (e.g. ``time.time()``).
|
||||
|
||||
This object is used to describe (large) binary columns in
|
||||
a database (e.g. LONG RAW, blobs).
|
||||
|
||||
NUMBER
|
||||
dbiRaw(value)
|
||||
This function constructs a 'dbiRaw' instance that holds a
|
||||
raw (binary) value. The value should be specified as a
|
||||
Python string.
|
||||
|
||||
This object is used to describe numeric columns in a
|
||||
database.
|
||||
|
||||
DATE
|
||||
STRING
|
||||
This object is used to describe columns in a database that
|
||||
are string-based (e.g. CHAR).
|
||||
|
||||
This object is used to describe date columns in a
|
||||
database.
|
||||
|
||||
ROWID
|
||||
RAW
|
||||
This object is used to describe (large) binary columns in
|
||||
a database (e.g. LONG RAW, blobs).
|
||||
|
||||
NUMBER
|
||||
This object is used to describe numeric columns in a
|
||||
database.
|
||||
|
||||
DATE
|
||||
This object is used to describe date columns in a
|
||||
database.
|
||||
|
||||
ROWID
|
||||
This object is used to describe the "Row ID" column in a
|
||||
database.
|
||||
|
||||
This object is used to describe the "Row ID" column in a
|
||||
database.
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
Many thanks go to Andrew Kuchling who converted the Python
|
||||
Database API Specification 1.0 from the original HTML format into
|
||||
the PEP format.
|
||||
Many thanks go to Andrew Kuchling who converted the Python
|
||||
Database API Specification 1.0 from the original HTML format into
|
||||
the PEP format.
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the Public Domain.
|
||||
This document has been placed in the Public Domain.
|
||||
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
|
414
pep-0283.txt
414
pep-0283.txt
|
@ -5,303 +5,325 @@ Last-Modified: $Date$
|
|||
Author: Guido van Rossum
|
||||
Status: Final
|
||||
Type: Informational
|
||||
Content-Type: text/x-rst
|
||||
Created: 27-Feb-2002
|
||||
Python-Version: 2.3
|
||||
Post-History: 27-Feb-2002
|
||||
|
||||
|
||||
Abstract
|
||||
========
|
||||
|
||||
This document describes the development and release schedule for
|
||||
Python 2.3. The schedule primarily concerns itself with PEP-sized
|
||||
items. Small features may be added up to and including the first
|
||||
beta release. Bugs may be fixed until the final release.
|
||||
This document describes the development and release schedule for
|
||||
Python 2.3. The schedule primarily concerns itself with PEP-sized
|
||||
items. Small features may be added up to and including the first
|
||||
beta release. Bugs may be fixed until the final release.
|
||||
|
||||
There will be at least two alpha releases, two beta releases, and
|
||||
one release candidate. Alpha and beta releases will be spaced at
|
||||
least 4 weeks apart (except if an emergency release must be made
|
||||
to correct a blunder in the previous release; then the blunder
|
||||
release does not count). Release candidates will be spaced at
|
||||
least one week apart (excepting again blunder corrections).
|
||||
There will be at least two alpha releases, two beta releases, and
|
||||
one release candidate. Alpha and beta releases will be spaced at
|
||||
least 4 weeks apart (except if an emergency release must be made
|
||||
to correct a blunder in the previous release; then the blunder
|
||||
release does not count). Release candidates will be spaced at
|
||||
least one week apart (excepting again blunder corrections).
|
||||
|
||||
alpha 1 -- 31 Dec 2002
|
||||
alpha 2 -- 19 Feb 2003
|
||||
beta 1 -- 25 Apr 2003
|
||||
beta 2 -- 29 Jun 2003
|
||||
candidate 1 -- 18 Jul 2003
|
||||
candidate 2 -- 24 Jul 2003
|
||||
final -- 29 Jul 2003
|
||||
=========== ===========
|
||||
alpha 1 31 Dec 2002
|
||||
alpha 2 19 Feb 2003
|
||||
beta 1 25 Apr 2003
|
||||
beta 2 29 Jun 2003
|
||||
candidate 1 18 Jul 2003
|
||||
candidate 2 24 Jul 2003
|
||||
final 29 Jul 2003
|
||||
=========== ===========
|
||||
|
||||
Release Manager
|
||||
===============
|
||||
|
||||
Barry Warsaw, Jeremy Hylton, Tim Peters
|
||||
Barry Warsaw, Jeremy Hylton, Tim Peters
|
||||
|
||||
|
||||
Completed features for 2.3
|
||||
==========================
|
||||
|
||||
This list is not complete. See Doc/whatsnew/whatsnew23.tex in CVS
|
||||
for more, and of course Misc/NEWS for the full list.
|
||||
This list is not complete. See Doc/whatsnew/whatsnew23.tex in CVS
|
||||
for more, and of course Misc/NEWS for the full list.
|
||||
|
||||
- Tk 8.4 update.
|
||||
- Tk 8.4 update.
|
||||
|
||||
- The bool type and its constants, True and False (PEP 285).
|
||||
- The bool type and its constants, True and False (PEP 285).
|
||||
|
||||
- PyMalloc was greatly enhanced and is enabled by default.
|
||||
- ``PyMalloc`` was greatly enhanced and is enabled by default.
|
||||
|
||||
- Universal newline support (PEP 278).
|
||||
- Universal newline support (PEP 278).
|
||||
|
||||
- PEP 263 Defining Python Source Code Encodings Lemburg
|
||||
- PEP 263 Defining Python Source Code Encodings, Lemburg
|
||||
|
||||
Implemented (at least phase 1, which is all that's planned for
|
||||
2.3).
|
||||
Implemented (at least phase 1, which is all that's planned for
|
||||
2.3).
|
||||
|
||||
- Extended slice notation for all built-in sequences. The patch
|
||||
by Michael Hudson is now all checked in.
|
||||
- Extended slice notation for all built-in sequences. The patch
|
||||
by Michael Hudson is now all checked in.
|
||||
|
||||
- Speed up list iterations by filling tp_iter and other tweaks.
|
||||
See http://www.python.org/sf/560736; also done for xrange and
|
||||
tuples.
|
||||
- Speed up list iterations by filling ``tp_iter`` and other tweaks.
|
||||
See http://www.python.org/sf/560736; also done for ``xrange`` and
|
||||
tuples.
|
||||
|
||||
- Timeout sockets. http://www.python.org/sf/555085
|
||||
- Timeout sockets. http://www.python.org/sf/555085
|
||||
|
||||
- Stage B0 of the int/long integration (PEP 237). This means
|
||||
issuing a FutureWarning about situations where hex or oct
|
||||
conversions or left shifts returns a different value for an int
|
||||
than for a long with the same value. The semantics do *not*
|
||||
change in Python 2.3; that will happen in Python 2.4.
|
||||
- Stage B0 of the int/long integration (PEP 237). This means
|
||||
issuing a ``FutureWarning`` about situations where hex or oct
|
||||
conversions or left shifts returns a different value for an int
|
||||
than for a long with the same value. The semantics do *not*
|
||||
change in Python 2.3; that will happen in Python 2.4.
|
||||
|
||||
- Nuke SET_LINENO from all code objects (providing a different way
|
||||
to set debugger breakpoints). This can boost pystone by >5%.
|
||||
http://www.python.org/sf/587993, now checked in. (Unfortunately
|
||||
the pystone boost didn't happen. What happened?)
|
||||
- Nuke ``SET_LINENO`` from all code objects (providing a different way
|
||||
to set debugger breakpoints). This can boost ``pystone`` by >5%.
|
||||
http://www.python.org/sf/587993, now checked in. (Unfortunately
|
||||
the ``pystone`` boost didn't happen. What happened?)
|
||||
|
||||
- Write a pymemcompat.h that people can bundle with their
|
||||
extensions and then use the 2.3 memory interface with all
|
||||
Pythons in the range 1.5.2 to 2.3. (Michael Hudson checked in
|
||||
Misc/pymemcompat.h.)
|
||||
- Write a pymemcompat.h that people can bundle with their
|
||||
extensions and then use the 2.3 memory interface with all
|
||||
Pythons in the range 1.5.2 to 2.3. (Michael Hudson checked in
|
||||
Misc/pymemcompat.h.)
|
||||
|
||||
- Add a new concept, "pending deprecation", with associated
|
||||
warning PendingDeprecationWarning. This warning is normally
|
||||
suppressed, but can be enabled by a suitable -W option. Only a
|
||||
few things use this at this time.
|
||||
- Add a new concept, "pending deprecation", with associated
|
||||
warning ``PendingDeprecationWarning``. This warning is normally
|
||||
suppressed, but can be enabled by a suitable ``-W`` option. Only a
|
||||
few things use this at this time.
|
||||
|
||||
- Warn when an extension type's tp_compare returns anything except
|
||||
-1, 0 or 1. http://www.python.org/sf/472523
|
||||
- Warn when an extension type's ``tp_compare`` returns anything except
|
||||
-1, 0 or 1. http://www.python.org/sf/472523
|
||||
|
||||
- Warn for assignment to None (in various forms).
|
||||
- Warn for assignment to None (in various forms).
|
||||
|
||||
- PEP 218 Adding a Built-In Set Object Type Wilson
|
||||
- PEP 218 Adding a Built-In Set Object Type, Wilson
|
||||
|
||||
Alex Martelli contributed a new version of Greg Wilson's
|
||||
prototype, and I've reworked that quite a bit. It's in the
|
||||
standard library now as the module "sets", although some details
|
||||
may still change until the first beta release. (There are no
|
||||
plans to make this a built-in type, for now.)
|
||||
Alex Martelli contributed a new version of Greg Wilson's
|
||||
prototype, and I've reworked that quite a bit. It's in the
|
||||
standard library now as the module "sets", although some details
|
||||
may still change until the first beta release. (There are no
|
||||
plans to make this a built-in type, for now.)
|
||||
|
||||
- PEP 293 Codec error handling callbacks Dörwald
|
||||
- PEP 293 Codec error handling callbacks, Dörwald
|
||||
|
||||
Fully implemented. Error handling in unicode.encode or
|
||||
str.decode can now be customized.
|
||||
Fully implemented. Error handling in ``unicode.encode`` or
|
||||
``str.decode`` can now be customized.
|
||||
|
||||
- PEP 282 A Logging System Mick
|
||||
- PEP 282 A Logging System, Mick
|
||||
|
||||
Vinay Sajip's implementation has been packagized and imported.
|
||||
(Documentation and unit tests still pending.)
|
||||
http://www.python.org/sf/578494
|
||||
Vinay Sajip's implementation has been packagized and imported.
|
||||
(Documentation and unit tests still pending.)
|
||||
http://www.python.org/sf/578494
|
||||
|
||||
- A modified MRO (Method Resolution Order) algorithm. Consensus
|
||||
is that we should adopt C3. Samuele Pedroni has contributed a
|
||||
draft implementation in C, see http://www.python.org/sf/619475
|
||||
This has now been checked in.
|
||||
- A modified MRO (Method Resolution Order) algorithm. Consensus
|
||||
is that we should adopt C3. Samuele Pedroni has contributed a
|
||||
draft implementation in C, see http://www.python.org/sf/619475
|
||||
This has now been checked in.
|
||||
|
||||
- A new command line option parser. Greg Ward's Optik package
|
||||
(http://optik.sf.net) has been adopted, converted to a single
|
||||
module named optparse. See also
|
||||
http://www.python.org/sigs/getopt-sig/
|
||||
- A new command line option parser. Greg Ward's Optik package
|
||||
(http://optik.sf.net) has been adopted, converted to a single
|
||||
module named ``optparse``. See also
|
||||
http://www.python.org/sigs/getopt-sig/
|
||||
|
||||
- A standard datetime type. This started as a wiki:
|
||||
http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage . A
|
||||
prototype was coded in nondist/sandbox/datetime/. Tim Peters
|
||||
has finished the C implementation and checked it in.
|
||||
- A standard ``datetime`` type. This started as a wiki:
|
||||
http://www.zope.org/Members/fdrake/DateTimeWiki/FrontPage. A
|
||||
prototype was coded in nondist/sandbox/datetime/. Tim Peters
|
||||
has finished the C implementation and checked it in.
|
||||
|
||||
- PEP 273 Import Modules from Zip Archives Ahlstrom
|
||||
- PEP 273 Import Modules from Zip Archives, Ahlstrom
|
||||
|
||||
Implemented as a part of the PEP 302 implementation work.
|
||||
Implemented as a part of the PEP 302 implementation work.
|
||||
|
||||
- PEP 302 New Import Hooks JvR
|
||||
- PEP 302 New Import Hooks, JvR
|
||||
|
||||
Implemented (though the 2.3a1 release contained some bugs that
|
||||
have been fixed post-release).
|
||||
Implemented (though the 2.3a1 release contained some bugs that
|
||||
have been fixed post-release).
|
||||
|
||||
- A new pickling protocol. See PEP 307.
|
||||
- A new pickling protocol. See PEP 307.
|
||||
|
||||
- PEP 305 (CSV File API, by Skip Montanaro et al.) is in; this is
|
||||
the csv module.
|
||||
- PEP 305 (CSV File API, by Skip Montanaro et al.) is in; this is
|
||||
the csv module.
|
||||
|
||||
- Raymond Hettinger's itertools module is in.
|
||||
- Raymond Hettinger's ``itertools`` module is in.
|
||||
|
||||
- PEP 311 (Simplified GIL Acquisition for Extensions, by Mark
|
||||
Hammond) has been included in beta 1.
|
||||
- PEP 311 (Simplified GIL Acquisition for Extensions, by Mark
|
||||
Hammond) has been included in beta 1.
|
||||
|
||||
- Two new PyArg_Parse*() format codes, 'k' returns an unsigned C
|
||||
long int that receives the lower LONG_BIT bits of the Python
|
||||
argument, truncating without range checking. 'K' returns an
|
||||
unsigned C long long int that receives the lower LONG_LONG_BIT
|
||||
bits, truncating without range checking. (SF 595026; Thomas
|
||||
Heller did this work.)
|
||||
- Two new ``PyArg_Parse*()`` format codes, 'k' returns an unsigned C
|
||||
long int that receives the lower ``LONG_BIT`` bits of the Python
|
||||
argument, truncating without range checking. 'K' returns an
|
||||
unsigned C long long int that receives the lower ``LONG_LONG_BIT``
|
||||
bits, truncating without range checking. (SF 595026; Thomas
|
||||
Heller did this work.)
|
||||
|
||||
- A new version of IDLE was imported from the IDLEfork project
|
||||
(http://idlefork.sf.net). The code now lives in the idlelib
|
||||
package in the standard library and the idle script is installed
|
||||
by setup.py.
|
||||
|
||||
- A new version of IDLE was imported from the IDLEfork project
|
||||
(http://idlefork.sf.net). The code now lives in the idlelib
|
||||
package in the standard library and the idle script is installed
|
||||
by setup.py.
|
||||
|
||||
Planned features for 2.3
|
||||
========================
|
||||
|
||||
Too late for anything more to get done here.
|
||||
Too late for anything more to get done here.
|
||||
|
||||
|
||||
Ongoing tasks
|
||||
=============
|
||||
|
||||
The following are ongoing TO-DO items which we should attempt to
|
||||
work on without hoping for completion by any particular date.
|
||||
The following are ongoing TO-DO items which we should attempt to
|
||||
work on without hoping for completion by any particular date.
|
||||
|
||||
- Documentation: complete the distribution and installation
|
||||
manuals.
|
||||
- Documentation: complete the distribution and installation
|
||||
manuals.
|
||||
|
||||
- Documentation: complete the documentation for new-style
|
||||
classes.
|
||||
- Documentation: complete the documentation for new-style
|
||||
classes.
|
||||
|
||||
- Look over the Demos/ directory and update where required (Andrew
|
||||
Kuchling has done a lot of this)
|
||||
- Look over the Demos/ directory and update where required (Andrew
|
||||
Kuchling has done a lot of this)
|
||||
|
||||
- New tests.
|
||||
- New tests.
|
||||
|
||||
- Fix doc bugs on SF.
|
||||
- Fix doc bugs on SF.
|
||||
|
||||
- Remove use of deprecated features in the core.
|
||||
- Remove use of deprecated features in the core.
|
||||
|
||||
- Document deprecated features appropriately.
|
||||
- Document deprecated features appropriately.
|
||||
|
||||
- Mark deprecated C APIs with Py_DEPRECATED.
|
||||
- Mark deprecated C APIs with ``Py_DEPRECATED``.
|
||||
|
||||
- Deprecate modules which are unmaintained, or perhaps make a new
|
||||
category for modules 'Unmaintained'
|
||||
- Deprecate modules which are unmaintained, or perhaps make a new
|
||||
category for modules 'Unmaintained'
|
||||
|
||||
- In general, lots of cleanup so it is easier to move forward.
|
||||
- In general, lots of cleanup so it is easier to move forward.
|
||||
|
||||
|
||||
Open issues
|
||||
===========
|
||||
|
||||
There are some issues that may need more work and/or thought
|
||||
before the final release (and preferably before the first beta
|
||||
release): No issues remaining.
|
||||
There are some issues that may need more work and/or thought
|
||||
before the final release (and preferably before the first beta
|
||||
release): No issues remaining.
|
||||
|
||||
|
||||
Features that did not make it into Python 2.3
|
||||
=============================================
|
||||
|
||||
- The import lock could use some redesign. (SF 683658.)
|
||||
- The import lock could use some redesign. (SF 683658.)
|
||||
|
||||
- Set API issues; is the sets module perfect?
|
||||
- Set API issues; is the sets module perfect?
|
||||
|
||||
I expect it's good enough to stop polishing it until we've had
|
||||
more widespread user experience.
|
||||
I expect it's good enough to stop polishing it until we've had
|
||||
more widespread user experience.
|
||||
|
||||
- A nicer API to open text files, replacing the ugly (in some
|
||||
people's eyes) "U" mode flag. There's a proposal out there to
|
||||
have a new built-in type textfile(filename, mode, encoding).
|
||||
(Shouldn't it have a bufsize argument too?)
|
||||
- A nicer API to open text files, replacing the ugly (in some
|
||||
people's eyes) "U" mode flag. There's a proposal out there to
|
||||
have a new built-in type textfile(filename, mode, encoding).
|
||||
(Shouldn't it have a bufsize argument too?)
|
||||
|
||||
Ditto.
|
||||
Ditto.
|
||||
|
||||
- New widgets for Tkinter???
|
||||
- New widgets for Tkinter???
|
||||
|
||||
Has anyone gotten the time for this? *Are* there any new
|
||||
widgets in Tk 8.4? Note that we've got better Tix support
|
||||
already (though not on Windows yet).
|
||||
Has anyone gotten the time for this? *Are* there any new
|
||||
widgets in Tk 8.4? Note that we've got better Tix support
|
||||
already (though not on Windows yet).
|
||||
|
||||
- Fredrik Lundh's basetime proposal:
|
||||
http://effbot.org/ideas/time-type.htm
|
||||
- Fredrik Lundh's basetime proposal:
|
||||
|
||||
I believe this is dead now.
|
||||
http://effbot.org/ideas/time-type.htm
|
||||
|
||||
- PEP 304 (Controlling Generation of Bytecode Files by Montanaro)
|
||||
seems to have lost steam.
|
||||
I believe this is dead now.
|
||||
|
||||
- For a class defined inside another class, the __name__ should be
|
||||
"outer.inner", and pickling should work. (SF 633930. I'm no
|
||||
longer certain this is easy or even right.)
|
||||
- PEP 304 (Controlling Generation of Bytecode Files by Montanaro)
|
||||
seems to have lost steam.
|
||||
|
||||
- reST is going to be used a lot in Zope3. Maybe it could become
|
||||
a standard library module? (Since reST's author thinks it's too
|
||||
instable, I'm inclined not to do this.)
|
||||
- For a class defined inside another class, the ``__name__`` should be
|
||||
"outer.inner", and pickling should work. (SF 633930. I'm no
|
||||
longer certain this is easy or even right.)
|
||||
|
||||
- Decide on a clearer deprecation policy (especially for modules)
|
||||
and act on it. For a start, see this message from Neal Norwitz:
|
||||
http://mail.python.org/pipermail/python-dev/2002-April/023165.html
|
||||
There seems insufficient interest in moving this further in an
|
||||
organized fashion, and it's not particularly important.
|
||||
- reST is going to be used a lot in Zope3. Maybe it could become
|
||||
a standard library module? (Since reST's author thinks it's too
|
||||
unstable, I'm inclined not to do this.)
|
||||
|
||||
- Provide alternatives for common uses of the types module;
|
||||
Skip Montanaro has posted a proto-PEP for this idea:
|
||||
http://mail.python.org/pipermail/python-dev/2002-May/024346.html
|
||||
There hasn't been any progress on this, AFAICT.
|
||||
- Decide on a clearer deprecation policy (especially for modules)
|
||||
and act on it. For a start, see this message from Neal Norwitz:
|
||||
http://mail.python.org/pipermail/python-dev/2002-April/023165.html
|
||||
There seems insufficient interest in moving this further in an
|
||||
organized fashion, and it's not particularly important.
|
||||
|
||||
- Use pending deprecation for the types and string modules. This
|
||||
requires providing alternatives for the parts that aren't
|
||||
covered yet (e.g. string.whitespace and types.TracebackType).
|
||||
It seems we can't get consensus on this.
|
||||
- Provide alternatives for common uses of the types module;
|
||||
|
||||
- Deprecate the buffer object.
|
||||
http://mail.python.org/pipermail/python-dev/2002-July/026388.html
|
||||
http://mail.python.org/pipermail/python-dev/2002-July/026408.html
|
||||
It seems that this is never going to be resolved.
|
||||
Skip Montanaro has posted a proto-PEP for this idea:
|
||||
http://mail.python.org/pipermail/python-dev/2002-May/024346.html
|
||||
|
||||
- PEP 269 Pgen Module for Python Riehl
|
||||
There hasn't been any progress on this, AFAICT.
|
||||
|
||||
(Some necessary changes are in; the pgen module itself needs to
|
||||
mature more.)
|
||||
- Use pending deprecation for the types and string modules. This
|
||||
requires providing alternatives for the parts that aren't
|
||||
covered yet (e.g. ``string.whitespace`` and ``types.TracebackType``).
|
||||
It seems we can't get consensus on this.
|
||||
|
||||
- Add support for the long-awaited Python catalog. Kapil
|
||||
Thangavelu has a Zope-based implementation that he demoed at
|
||||
OSCON 2002. Now all we need is a place to host it and a person
|
||||
to champion it. (Some changes to distutils to support this are
|
||||
in, at least.)
|
||||
- Deprecate the buffer object.
|
||||
|
||||
- PEP 266 Optimizing Global Variable/Attribute Access Montanaro
|
||||
PEP 267 Optimized Access to Module Namespaces Hylton
|
||||
PEP 280 Optimizing access to globals van Rossum
|
||||
- http://mail.python.org/pipermail/python-dev/2002-July/026388.html
|
||||
- http://mail.python.org/pipermail/python-dev/2002-July/026408.html
|
||||
|
||||
These are basically three friendly competing proposals. Jeremy
|
||||
has made a little progress with a new compiler, but it's going
|
||||
slow and the compiler is only the first step. Maybe we'll be
|
||||
able to refactor the compiler in this release. I'm tempted to
|
||||
say we won't hold our breath. In the mean time, Oren Tirosh has
|
||||
a much simpler idea that may give a serious boost to the
|
||||
performance of accessing globals and built-ins, by optimizing
|
||||
and inlining the dict access:
|
||||
http://tothink.com/python/fastnames/
|
||||
It seems that this is never going to be resolved.
|
||||
|
||||
- Lazily tracking tuples?
|
||||
http://mail.python.org/pipermail/python-dev/2002-May/023926.html
|
||||
http://www.python.org/sf/558745
|
||||
Not much enthusiasm I believe.
|
||||
- PEP 269 Pgen Module for Python, Riehl
|
||||
|
||||
- PEP 286 Enhanced Argument Tuples von Loewis
|
||||
(Some necessary changes are in; the ``pgen`` module itself needs to
|
||||
mature more.)
|
||||
|
||||
I haven't had the time to review this thoroughly. It seems a
|
||||
deep optimization hack (also makes better correctness guarantees
|
||||
though).
|
||||
- Add support for the long-awaited Python catalog. Kapil
|
||||
Thangavelu has a Zope-based implementation that he demoed at
|
||||
OSCON 2002. Now all we need is a place to host it and a person
|
||||
to champion it. (Some changes to distutils to support this are
|
||||
in, at least.)
|
||||
|
||||
- Make 'as' a keyword. It has been a pseudo-keyword long enough.
|
||||
Too much effort to bother.
|
||||
- PEP 266 Optimizing Global Variable/Attribute Access, Montanaro
|
||||
|
||||
PEP 267 Optimized Access to Module Namespaces, Hylton
|
||||
|
||||
PEP 280 Optimizing access to globals, van Rossum
|
||||
|
||||
These are basically three friendly competing proposals. Jeremy
|
||||
has made a little progress with a new compiler, but it's going
|
||||
slow and the compiler is only the first step. Maybe we'll be
|
||||
able to refactor the compiler in this release. I'm tempted to
|
||||
say we won't hold our breath. In the mean time, Oren Tirosh has
|
||||
a much simpler idea that may give a serious boost to the
|
||||
performance of accessing globals and built-ins, by optimizing
|
||||
and inlining the dict access: http://tothink.com/python/fastnames/
|
||||
|
||||
- Lazily tracking tuples?
|
||||
|
||||
- http://mail.python.org/pipermail/python-dev/2002-May/023926.html
|
||||
- http://www.python.org/sf/558745
|
||||
|
||||
Not much enthusiasm I believe.
|
||||
|
||||
- PEP 286 Enhanced Argument Tuples, von Loewis
|
||||
|
||||
I haven't had the time to review this thoroughly. It seems a
|
||||
deep optimization hack (also makes better correctness guarantees
|
||||
though).
|
||||
|
||||
- Make 'as' a keyword. It has been a pseudo-keyword long enough.
|
||||
Too much effort to bother.
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the public domain.
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
|
441
pep-0314.txt
441
pep-0314.txt
|
@ -5,311 +5,338 @@ Last-Modified: $Date$
|
|||
Author: A.M. Kuchling, Richard Jones
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Content-Type: text/plain
|
||||
Content-Type: text/x-rst
|
||||
Created: 12-Apr-2003
|
||||
Python-Version: 2.5
|
||||
Post-History: 29-Apr-2003
|
||||
Replaces: 241
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This PEP describes a mechanism for adding metadata to Python
|
||||
packages. It includes specifics of the field names, and their
|
||||
semantics and usage.
|
||||
This PEP describes a mechanism for adding metadata to Python
|
||||
packages. It includes specifics of the field names, and their
|
||||
semantics and usage.
|
||||
|
||||
This document specifies version 1.1 of the metadata format.
|
||||
Version 1.0 is specified in PEP 241.
|
||||
This document specifies version 1.1 of the metadata format.
|
||||
Version 1.0 is specified in PEP 241.
|
||||
|
||||
|
||||
Including Metadata in Packages
|
||||
==============================
|
||||
|
||||
The Distutils 'sdist' command will extract the metadata fields
|
||||
from the arguments and write them to a file in the generated
|
||||
zipfile or tarball. This file will be named PKG-INFO and will be
|
||||
placed in the top directory of the source distribution (where the
|
||||
README, INSTALL, and other files usually go).
|
||||
The Distutils ``sdist`` command will extract the metadata fields
|
||||
from the arguments and write them to a file in the generated
|
||||
zipfile or tarball. This file will be named PKG-INFO and will be
|
||||
placed in the top directory of the source distribution (where the
|
||||
README, INSTALL, and other files usually go).
|
||||
|
||||
Developers may not provide their own PKG-INFO file. The "sdist"
|
||||
command will, if it detects an existing PKG-INFO file, terminate
|
||||
with an appropriate error message. This should prevent confusion
|
||||
caused by the PKG-INFO and setup.py files being out of sync.
|
||||
Developers may not provide their own PKG-INFO file. The ``sdist``
|
||||
command will, if it detects an existing PKG-INFO file, terminate
|
||||
with an appropriate error message. This should prevent confusion
|
||||
caused by the PKG-INFO and setup.py files being out of sync.
|
||||
|
||||
The PKG-INFO file format is a single set of RFC-822 headers
|
||||
parseable by the rfc822.py module. The field names listed in the
|
||||
following section are used as the header names.
|
||||
|
||||
The PKG-INFO file format is a single set of RFC-822 headers
|
||||
parseable by the rfc822.py module. The field names listed in the
|
||||
following section are used as the header names.
|
||||
|
||||
|
||||
Fields
|
||||
======
|
||||
|
||||
This section specifies the names and semantics of each of the
|
||||
supported metadata fields.
|
||||
|
||||
Fields marked with "(Multiple use)" may be specified multiple
|
||||
times in a single PKG-INFO file. Other fields may only occur
|
||||
once in a PKG-INFO file. Fields marked with "(optional)" are
|
||||
not required to appear in a valid PKG-INFO file; all other
|
||||
fields must be present.
|
||||
This section specifies the names and semantics of each of the
|
||||
supported metadata fields.
|
||||
|
||||
Metadata-Version
|
||||
Fields marked with "(Multiple use)" may be specified multiple
|
||||
times in a single PKG-INFO file. Other fields may only occur
|
||||
once in a PKG-INFO file. Fields marked with "(optional)" are
|
||||
not required to appear in a valid PKG-INFO file; all other
|
||||
fields must be present.
|
||||
|
||||
Version of the file format; currently "1.0" and "1.1" are the
|
||||
only legal values here.
|
||||
Metadata-Version
|
||||
----------------
|
||||
|
||||
Example:
|
||||
Version of the file format; currently "1.0" and "1.1" are the
|
||||
only legal values here.
|
||||
|
||||
Metadata-Version: 1.1
|
||||
Example::
|
||||
|
||||
Name
|
||||
Metadata-Version: 1.1
|
||||
|
||||
The name of the package.
|
||||
Name
|
||||
----
|
||||
|
||||
Example:
|
||||
The name of the package.
|
||||
|
||||
Name: BeagleVote
|
||||
|
||||
Version
|
||||
Example::
|
||||
|
||||
A string containing the package's version number. This
|
||||
field should be parseable by one of the Version classes
|
||||
(StrictVersion or LooseVersion) in the distutils.version
|
||||
module.
|
||||
Name: BeagleVote
|
||||
|
||||
Example:
|
||||
Version
|
||||
-------
|
||||
|
||||
Version: 1.0a2
|
||||
|
||||
Platform (multiple use)
|
||||
A string containing the package's version number. This
|
||||
field should be parseable by one of the Version classes
|
||||
(StrictVersion or LooseVersion) in the distutils.version
|
||||
module.
|
||||
|
||||
A comma-separated list of platform specifications, summarizing
|
||||
the operating systems supported by the package which are not
|
||||
listed in the "Operating System" Trove classifiers. See
|
||||
"Classifier" below.
|
||||
Example::
|
||||
|
||||
Example:
|
||||
Version: 1.0a2
|
||||
|
||||
Platform: ObscureUnix, RareDOS
|
||||
Platform (multiple use)
|
||||
-----------------------
|
||||
|
||||
Supported-Platform (multiple use)
|
||||
A comma-separated list of platform specifications, summarizing
|
||||
the operating systems supported by the package which are not
|
||||
listed in the "Operating System" Trove classifiers. See
|
||||
"Classifier" below.
|
||||
|
||||
Binary distributions containing a PKG-INFO file will use the
|
||||
Supported-Platform field in their metadata to specify the OS and
|
||||
CPU for which the binary package was compiled. The semantics of
|
||||
the Supported-Platform field are not specified in this PEP.
|
||||
Example::
|
||||
|
||||
Example:
|
||||
Platform: ObscureUnix, RareDOS
|
||||
|
||||
Supported-Platform: RedHat 7.2
|
||||
Supported-Platform: i386-win32-2791
|
||||
Supported-Platform (multiple use)
|
||||
---------------------------------
|
||||
|
||||
Summary
|
||||
Binary distributions containing a PKG-INFO file will use the
|
||||
Supported-Platform field in their metadata to specify the OS and
|
||||
CPU for which the binary package was compiled. The semantics of
|
||||
the Supported-Platform field are not specified in this PEP.
|
||||
|
||||
A one-line summary of what the package does.
|
||||
Example::
|
||||
|
||||
Example:
|
||||
Supported-Platform: RedHat 7.2
|
||||
Supported-Platform: i386-win32-2791
|
||||
|
||||
Summary: A module for collecting votes from beagles.
|
||||
|
||||
Description (optional)
|
||||
Summary
|
||||
-------
|
||||
|
||||
A longer description of the package that can run to several
|
||||
paragraphs. Software that deals with metadata should not assume
|
||||
any maximum size for this field, though people shouldn't include
|
||||
their instruction manual as the description.
|
||||
A one-line summary of what the package does.
|
||||
|
||||
The contents of this field can be written using reStructuredText
|
||||
markup [1]. For programs that work with the metadata,
|
||||
supporting markup is optional; programs can also display the
|
||||
contents of the field as-is. This means that authors should be
|
||||
conservative in the markup they use.
|
||||
Example::
|
||||
|
||||
Example:
|
||||
|
||||
Description: This module collects votes from beagles
|
||||
in order to determine their electoral wishes.
|
||||
Do *not* try to use this module with basset hounds;
|
||||
it makes them grumpy.
|
||||
|
||||
Keywords (optional)
|
||||
Summary: A module for collecting votes from beagles.
|
||||
|
||||
A list of additional keywords to be used to assist searching
|
||||
for the package in a larger catalog.
|
||||
Description (optional)
|
||||
----------------------
|
||||
|
||||
Example:
|
||||
A longer description of the package that can run to several
|
||||
paragraphs. Software that deals with metadata should not assume
|
||||
any maximum size for this field, though people shouldn't include
|
||||
their instruction manual as the description.
|
||||
|
||||
Keywords: dog puppy voting election
|
||||
|
||||
Home-page (optional)
|
||||
The contents of this field can be written using reStructuredText
|
||||
markup [1]_. For programs that work with the metadata,
|
||||
supporting markup is optional; programs can also display the
|
||||
contents of the field as-is. This means that authors should be
|
||||
conservative in the markup they use.
|
||||
|
||||
A string containing the URL for the package's home page.
|
||||
Example::
|
||||
|
||||
Example:
|
||||
Description: This module collects votes from beagles
|
||||
in order to determine their electoral wishes.
|
||||
Do *not* try to use this module with basset hounds;
|
||||
it makes them grumpy.
|
||||
|
||||
Home-page: http://www.example.com/~cschultz/bvote/
|
||||
|
||||
Download-URL
|
||||
|
||||
A string containing the URL from which this version of the package
|
||||
can be downloaded. (This means that the URL can't be something like
|
||||
".../package-latest.tgz", but instead must be "../package-0.45.tgz".)
|
||||
|
||||
Author (optional)
|
||||
Keywords (optional)
|
||||
-------------------
|
||||
|
||||
A string containing the author's name at a minimum; additional
|
||||
contact information may be provided.
|
||||
A list of additional keywords to be used to assist searching
|
||||
for the package in a larger catalog.
|
||||
|
||||
Example:
|
||||
Example::
|
||||
|
||||
Author: C. Schultz, Universal Features Syndicate,
|
||||
Los Angeles, CA <cschultz@peanuts.example.com>
|
||||
|
||||
Author-email
|
||||
Keywords: dog puppy voting election
|
||||
|
||||
A string containing the author's e-mail address. It can contain
|
||||
a name and e-mail address in the legal forms for a RFC-822
|
||||
'From:' header. It's not optional because cataloging systems
|
||||
can use the e-mail portion of this field as a unique key
|
||||
representing the author. A catalog might provide authors the
|
||||
ability to store their GPG key, personal home page, and other
|
||||
additional metadata *about the author*, and optionally the
|
||||
ability to associate several e-mail addresses with the same
|
||||
person. Author-related metadata fields are not covered by this
|
||||
PEP.
|
||||
Home-page (optional)
|
||||
--------------------
|
||||
|
||||
Example:
|
||||
A string containing the URL for the package's home page.
|
||||
|
||||
Author-email: "C. Schultz" <cschultz@example.com>
|
||||
|
||||
License
|
||||
|
||||
Text indicating the license covering the package where the license
|
||||
is not a selection from the "License" Trove classifiers. See
|
||||
"Classifier" below.
|
||||
Example::
|
||||
|
||||
Example:
|
||||
Home-page: http://www.example.com/~cschultz/bvote/
|
||||
|
||||
License: This software may only be obtained by sending the
|
||||
author a postcard, and then the user promises not
|
||||
to redistribute it.
|
||||
Download-URL
|
||||
------------
|
||||
|
||||
Classifier (multiple use)
|
||||
A string containing the URL from which this version of the package
|
||||
can be downloaded. (This means that the URL can't be something like
|
||||
".../package-latest.tgz", but instead must be "../package-0.45.tgz".)
|
||||
|
||||
Each entry is a string giving a single classification value
|
||||
for the package. Classifiers are described in PEP 301 [2].
|
||||
Author (optional)
|
||||
-----------------
|
||||
|
||||
Examples:
|
||||
A string containing the author's name at a minimum; additional
|
||||
contact information may be provided.
|
||||
|
||||
Classifier: Development Status :: 4 - Beta
|
||||
Classifier: Environment :: Console (Text Based)
|
||||
Example::
|
||||
|
||||
|
||||
Requires (multiple use)
|
||||
|
||||
Each entry contains a string describing some other module or
|
||||
package required by this package.
|
||||
Author: C. Schultz, Universal Features Syndicate,
|
||||
Los Angeles, CA <cschultz@peanuts.example.com>
|
||||
|
||||
The format of a requirement string is identical to that of a
|
||||
module or package name usable with the 'import' statement,
|
||||
optionally followed by a version declaration within parentheses.
|
||||
Author-email
|
||||
------------
|
||||
|
||||
A version declaration is a series of conditional operators and
|
||||
version numbers, separated by commas. Conditional operators
|
||||
must be one of "<", ">", "<=", ">=", "==", and "!=". Version
|
||||
numbers must be in the format accepted by the
|
||||
distutils.version.StrictVersion class: two or three
|
||||
dot-separated numeric components, with an optional "pre-release"
|
||||
tag on the end consisting of the letter 'a' or 'b' followed by a
|
||||
number. Example version numbers are "1.0", "2.3a2", "1.3.99",
|
||||
A string containing the author's e-mail address. It can contain
|
||||
a name and e-mail address in the legal forms for a RFC-822
|
||||
'From:' header. It's not optional because cataloging systems
|
||||
can use the e-mail portion of this field as a unique key
|
||||
representing the author. A catalog might provide authors the
|
||||
ability to store their GPG key, personal home page, and other
|
||||
additional metadata *about the author*, and optionally the
|
||||
ability to associate several e-mail addresses with the same
|
||||
person. Author-related metadata fields are not covered by this
|
||||
PEP.
|
||||
|
||||
Any number of conditional operators can be specified, e.g.
|
||||
the string ">1.0, !=1.3.4, <2.0" is a legal version declaration.
|
||||
Example::
|
||||
|
||||
All of the following are possible requirement strings: "rfc822",
|
||||
"zlib (>=1.1.4)", "zope".
|
||||
Author-email: "C. Schultz" <cschultz@example.com>
|
||||
|
||||
There's no canonical list of what strings should be used; the
|
||||
Python community is left to choose its own standards.
|
||||
License
|
||||
-------
|
||||
|
||||
Example:
|
||||
Text indicating the license covering the package where the license
|
||||
is not a selection from the "License" Trove classifiers. See
|
||||
"Classifier" below.
|
||||
|
||||
Requires: re
|
||||
Requires: sys
|
||||
Requires: zlib
|
||||
Requires: xml.parsers.expat (>1.0)
|
||||
Requires: psycopg
|
||||
|
||||
Provides (multiple use)
|
||||
Example::
|
||||
|
||||
Each entry contains a string describing a package or module that
|
||||
will be provided by this package once it is installed. These
|
||||
strings should match the ones used in Requirements fields. A
|
||||
version declaration may be supplied (without a comparison
|
||||
operator); the package's version number will be implied if none
|
||||
is specified.
|
||||
License: This software may only be obtained by sending the
|
||||
author a postcard, and then the user promises not
|
||||
to redistribute it.
|
||||
|
||||
Example:
|
||||
Classifier (multiple use)
|
||||
-------------------------
|
||||
|
||||
Provides: xml
|
||||
Provides: xml.utils
|
||||
Provides: xml.utils.iso8601
|
||||
Provides: xml.dom
|
||||
Provides: xmltools (1.3)
|
||||
Each entry is a string giving a single classification value
|
||||
for the package. Classifiers are described in PEP 301 [2]_.
|
||||
|
||||
Obsoletes (multiple use)
|
||||
Examples::
|
||||
|
||||
Each entry contains a string describing a package or module
|
||||
that this package renders obsolete, meaning that the two packages
|
||||
should not be installed at the same time. Version declarations
|
||||
can be supplied.
|
||||
Classifier: Development Status :: 4 - Beta
|
||||
Classifier: Environment :: Console (Text Based)
|
||||
|
||||
The most common use of this field will be in case a package name
|
||||
changes, e.g. Gorgon 2.3 gets subsumed into Torqued Python 1.0.
|
||||
When you install Torqued Python, the Gorgon package should be
|
||||
removed.
|
||||
|
||||
Example:
|
||||
|
||||
Obsoletes: Gorgon
|
||||
Requires (multiple use)
|
||||
-----------------------
|
||||
|
||||
Each entry contains a string describing some other module or
|
||||
package required by this package.
|
||||
|
||||
The format of a requirement string is identical to that of a
|
||||
module or package name usable with the 'import' statement,
|
||||
optionally followed by a version declaration within parentheses.
|
||||
|
||||
A version declaration is a series of conditional operators and
|
||||
version numbers, separated by commas. Conditional operators
|
||||
must be one of "<", ">", "<=", ">=", "==", and "!=". Version
|
||||
numbers must be in the format accepted by the
|
||||
distutils.version.StrictVersion class: two or three
|
||||
dot-separated numeric components, with an optional "pre-release"
|
||||
tag on the end consisting of the letter 'a' or 'b' followed by a
|
||||
number. Example version numbers are "1.0", "2.3a2", "1.3.99",
|
||||
|
||||
Any number of conditional operators can be specified, e.g.
|
||||
the string ">1.0, !=1.3.4, <2.0" is a legal version declaration.
|
||||
|
||||
All of the following are possible requirement strings: "rfc822",
|
||||
"zlib (>=1.1.4)", "zope".
|
||||
|
||||
There's no canonical list of what strings should be used; the
|
||||
Python community is left to choose its own standards.
|
||||
|
||||
Example::
|
||||
|
||||
Requires: re
|
||||
Requires: sys
|
||||
Requires: zlib
|
||||
Requires: xml.parsers.expat (>1.0)
|
||||
Requires: psycopg
|
||||
|
||||
Provides (multiple use)
|
||||
-----------------------
|
||||
|
||||
Each entry contains a string describing a package or module that
|
||||
will be provided by this package once it is installed. These
|
||||
strings should match the ones used in Requirements fields. A
|
||||
version declaration may be supplied (without a comparison
|
||||
operator); the package's version number will be implied if none
|
||||
is specified.
|
||||
|
||||
Example::
|
||||
|
||||
Provides: xml
|
||||
Provides: xml.utils
|
||||
Provides: xml.utils.iso8601
|
||||
Provides: xml.dom
|
||||
Provides: xmltools (1.3)
|
||||
|
||||
Obsoletes (multiple use)
|
||||
------------------------
|
||||
|
||||
Each entry contains a string describing a package or module
|
||||
that this package renders obsolete, meaning that the two packages
|
||||
should not be installed at the same time. Version declarations
|
||||
can be supplied.
|
||||
|
||||
The most common use of this field will be in case a package name
|
||||
changes, e.g. Gorgon 2.3 gets subsumed into Torqued Python 1.0.
|
||||
When you install Torqued Python, the Gorgon package should be
|
||||
removed.
|
||||
|
||||
Example::
|
||||
|
||||
Obsoletes: Gorgon
|
||||
|
||||
|
||||
Summary of Differences From PEP 241
|
||||
===================================
|
||||
|
||||
* Metadata-Version is now 1.1.
|
||||
* Metadata-Version is now 1.1.
|
||||
|
||||
* Added the Classifiers field from PEP 301.
|
||||
* Added the Classifiers field from PEP 301.
|
||||
|
||||
* The License and Platform files should now only be used if the
|
||||
platform or license can't be handled by an appropriate Classifier
|
||||
value.
|
||||
* The License and Platform files should now only be used if the
|
||||
platform or license can't be handled by an appropriate Classifier
|
||||
value.
|
||||
|
||||
* Added fields: Download-URL, Requires, Provides, Obsoletes.
|
||||
* Added fields: Download-URL, Requires, Provides, Obsoletes.
|
||||
|
||||
|
||||
Open issues
|
||||
===========
|
||||
|
||||
None.
|
||||
None.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
None.
|
||||
None.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] reStructuredText
|
||||
http://docutils.sourceforge.net/
|
||||
.. [1] reStructuredText
|
||||
http://docutils.sourceforge.net/
|
||||
|
||||
[2] PEP 301
|
||||
http://www.python.org/dev/peps/pep-0301/
|
||||
.. [2] PEP 301
|
||||
http://www.python.org/dev/peps/pep-0301/
|
||||
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the public domain.
|
||||
This document has been placed in the public domain.
|
||||
|
||||
|
||||
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
End:
|
||||
|
|
464
pep-3115.txt
464
pep-3115.txt
|
@ -5,309 +5,327 @@ Last-Modified: $Date$
|
|||
Author: Talin <viridia@gmail.com>
|
||||
Status: Final
|
||||
Type: Standards Track
|
||||
Content-Type: text/plain
|
||||
Content-Type: text/x-rst
|
||||
Created: 07-Mar-2007
|
||||
Python-Version: 3.0
|
||||
Post-History: 11-March-2007, 14-March-2007
|
||||
|
||||
Abstract
|
||||
|
||||
This PEP proposes changing the syntax for declaring metaclasses,
|
||||
and alters the semantics for how classes with metaclasses are
|
||||
constructed.
|
||||
Abstract
|
||||
========
|
||||
|
||||
This PEP proposes changing the syntax for declaring metaclasses,
|
||||
and alters the semantics for how classes with metaclasses are
|
||||
constructed.
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
||||
There are two rationales for this PEP, both of which are somewhat
|
||||
subtle.
|
||||
There are two rationales for this PEP, both of which are somewhat
|
||||
subtle.
|
||||
|
||||
The primary reason for changing the way metaclasses work, is that
|
||||
there are a number of interesting use cases that require the
|
||||
metaclass to get involved earlier in the class construction process
|
||||
than is currently possible. Currently, the metaclass mechanism is
|
||||
essentially a post-processing step. With the advent of class
|
||||
decorators, much of these post-processing chores can be taken over
|
||||
by the decorator mechanism.
|
||||
The primary reason for changing the way metaclasses work, is that
|
||||
there are a number of interesting use cases that require the
|
||||
metaclass to get involved earlier in the class construction process
|
||||
than is currently possible. Currently, the metaclass mechanism is
|
||||
essentially a post-processing step. With the advent of class
|
||||
decorators, much of these post-processing chores can be taken over
|
||||
by the decorator mechanism.
|
||||
|
||||
In particular, there is an important body of use cases where it
|
||||
would be useful to preserve the order in which a class members are
|
||||
declared. Ordinary Python objects store their members in a
|
||||
dictionary, in which ordering is unimportant, and members are
|
||||
accessed strictly by name. However, Python is often used to
|
||||
interface with external systems in which the members are organized
|
||||
according to an implicit ordering. Examples include declaration of C
|
||||
structs; COM objects; Automatic translation of Python classes into
|
||||
IDL or database schemas, such as used in an ORM; and so on.
|
||||
In particular, there is an important body of use cases where it
|
||||
would be useful to preserve the order in which a class members are
|
||||
declared. Ordinary Python objects store their members in a
|
||||
dictionary, in which ordering is unimportant, and members are
|
||||
accessed strictly by name. However, Python is often used to
|
||||
interface with external systems in which the members are organized
|
||||
according to an implicit ordering. Examples include declaration of C
|
||||
structs; COM objects; Automatic translation of Python classes into
|
||||
IDL or database schemas, such as used in an ORM; and so on.
|
||||
|
||||
In such cases, it would be useful for a Python programmer to specify
|
||||
such ordering directly using the declaration order of class members.
|
||||
Currently, such orderings must be specified explicitly, using some
|
||||
other mechanism (see the ctypes module for an example.)
|
||||
In such cases, it would be useful for a Python programmer to specify
|
||||
such ordering directly using the declaration order of class members.
|
||||
Currently, such orderings must be specified explicitly, using some
|
||||
other mechanism (see the ctypes module for an example.)
|
||||
|
||||
Unfortunately, the current method for declaring a metaclass does
|
||||
not allow for this, since the ordering information has already been
|
||||
lost by the time the metaclass comes into play. By allowing the
|
||||
metaclass to get involved in the class construction process earlier,
|
||||
the new system allows the ordering or other early artifacts of
|
||||
construction to be preserved and examined.
|
||||
Unfortunately, the current method for declaring a metaclass does
|
||||
not allow for this, since the ordering information has already been
|
||||
lost by the time the metaclass comes into play. By allowing the
|
||||
metaclass to get involved in the class construction process earlier,
|
||||
the new system allows the ordering or other early artifacts of
|
||||
construction to be preserved and examined.
|
||||
|
||||
There proposed metaclass mechanism also supports a number of other
|
||||
interesting use cases beyond preserving the ordering of declarations.
|
||||
One use case is to insert symbols into the namespace of the class
|
||||
body which are only valid during class construction. An example of
|
||||
this might be "field constructors", small functions that are used in
|
||||
the creation of class members. Another interesting possibility is
|
||||
supporting forward references, i.e. references to Python
|
||||
symbols that are declared further down in the class body.
|
||||
There proposed metaclass mechanism also supports a number of other
|
||||
interesting use cases beyond preserving the ordering of declarations.
|
||||
One use case is to insert symbols into the namespace of the class
|
||||
body which are only valid during class construction. An example of
|
||||
this might be "field constructors", small functions that are used in
|
||||
the creation of class members. Another interesting possibility is
|
||||
supporting forward references, i.e. references to Python
|
||||
symbols that are declared further down in the class body.
|
||||
|
||||
The other, weaker, rationale is purely cosmetic: The current method
|
||||
for specifying a metaclass is by assignment to the special variable
|
||||
__metaclass__, which is considered by some to be aesthetically less
|
||||
than ideal. Others disagree strongly with that opinion. This PEP
|
||||
will not address this issue, other than to note it, since aesthetic
|
||||
debates cannot be resolved via logical proofs.
|
||||
The other, weaker, rationale is purely cosmetic: The current method
|
||||
for specifying a metaclass is by assignment to the special variable
|
||||
``__metaclass__``, which is considered by some to be aesthetically less
|
||||
than ideal. Others disagree strongly with that opinion. This PEP
|
||||
will not address this issue, other than to note it, since aesthetic
|
||||
debates cannot be resolved via logical proofs.
|
||||
|
||||
|
||||
Specification
|
||||
=============
|
||||
|
||||
In the new model, the syntax for specifying a metaclass is via a
|
||||
keyword argument in the list of base classes:
|
||||
In the new model, the syntax for specifying a metaclass is via a
|
||||
keyword argument in the list of base classes::
|
||||
|
||||
class Foo(base1, base2, metaclass=mymeta):
|
||||
...
|
||||
class Foo(base1, base2, metaclass=mymeta):
|
||||
...
|
||||
|
||||
Additional keywords will also be allowed here, and will be passed to
|
||||
the metaclass, as in the following example:
|
||||
Additional keywords will also be allowed here, and will be passed to
|
||||
the metaclass, as in the following example::
|
||||
|
||||
class Foo(base1, base2, metaclass=mymeta, private=True):
|
||||
...
|
||||
class Foo(base1, base2, metaclass=mymeta, private=True):
|
||||
...
|
||||
|
||||
Note that this PEP makes no attempt to define what these other
|
||||
keywords might be - that is up to metaclass implementors to
|
||||
determine.
|
||||
Note that this PEP makes no attempt to define what these other
|
||||
keywords might be - that is up to metaclass implementors to
|
||||
determine.
|
||||
|
||||
More generally, the parameter list passed to a class definition will
|
||||
now support all of the features of a function call, meaning that you
|
||||
can now use *args and **kwargs-style arguments in the class base
|
||||
list:
|
||||
More generally, the parameter list passed to a class definition will
|
||||
now support all of the features of a function call, meaning that you
|
||||
can now use ``*args`` and ``**kwargs``-style arguments in the class base
|
||||
list::
|
||||
|
||||
class Foo(*bases, **kwds):
|
||||
...
|
||||
|
||||
class Foo(*bases, **kwds):
|
||||
...
|
||||
|
||||
Invoking the Metaclass
|
||||
======================
|
||||
|
||||
In the current metaclass system, the metaclass object can be any
|
||||
callable type. This does not change, however in order to fully
|
||||
exploit all of the new features the metaclass will need to have an
|
||||
extra attribute which is used during class pre-construction.
|
||||
In the current metaclass system, the metaclass object can be any
|
||||
callable type. This does not change, however in order to fully
|
||||
exploit all of the new features the metaclass will need to have an
|
||||
extra attribute which is used during class pre-construction.
|
||||
|
||||
This attribute is named __prepare__, which is invoked as a function
|
||||
before the evaluation of the class body. The __prepare__ function
|
||||
takes two positional arguments, and an arbitrary number of keyword
|
||||
arguments. The two positional arguments are:
|
||||
This attribute is named ``__prepare__``, which is invoked as a function
|
||||
before the evaluation of the class body. The ``__prepare__`` function
|
||||
takes two positional arguments, and an arbitrary number of keyword
|
||||
arguments. The two positional arguments are:
|
||||
|
||||
'name' - the name of the class being created.
|
||||
'bases' - the list of base classes.
|
||||
========= ====================================
|
||||
``name`` the name of the class being created.
|
||||
``bases`` the list of base classes.
|
||||
========= ====================================
|
||||
|
||||
The interpreter always tests for the existence of __prepare__ before
|
||||
calling it; If it is not present, then a regular dictionary is used,
|
||||
as illustrated in the following Python snippet.
|
||||
The interpreter always tests for the existence of ``__prepare__`` before
|
||||
calling it; If it is not present, then a regular dictionary is used,
|
||||
as illustrated in the following Python snippet.
|
||||
|
||||
def prepare_class(name, *bases, metaclass=None, **kwargs):
|
||||
if metaclass is None:
|
||||
metaclass = compute_default_metaclass(bases)
|
||||
prepare = getattr(metaclass, '__prepare__', None)
|
||||
if prepare is not None:
|
||||
return prepare(name, bases, **kwargs)
|
||||
else:
|
||||
return dict()
|
||||
::
|
||||
|
||||
The example above illustrates how the arguments to 'class' are
|
||||
interpreted. The class name is the first argument, followed by
|
||||
an arbitrary length list of base classes. After the base classes,
|
||||
there may be one or more keyword arguments, one of which can be
|
||||
'metaclass'. Note that the 'metaclass' argument is not included
|
||||
in kwargs, since it is filtered out by the normal parameter
|
||||
assignment algorithm. (Note also that 'metaclass' is a keyword-
|
||||
only argument as per PEP 3102 [6].)
|
||||
def prepare_class(name, *bases, metaclass=None, **kwargs):
|
||||
if metaclass is None:
|
||||
metaclass = compute_default_metaclass(bases)
|
||||
prepare = getattr(metaclass, '__prepare__', None)
|
||||
if prepare is not None:
|
||||
return prepare(name, bases, **kwargs)
|
||||
else:
|
||||
return dict()
|
||||
|
||||
Even though __prepare__ is not required, the default metaclass
|
||||
('type') implements it, for the convenience of subclasses calling
|
||||
it via super().
|
||||
The example above illustrates how the arguments to 'class' are
|
||||
interpreted. The class name is the first argument, followed by
|
||||
an arbitrary length list of base classes. After the base classes,
|
||||
there may be one or more keyword arguments, one of which can be
|
||||
'metaclass'. Note that the 'metaclass' argument is not included
|
||||
in kwargs, since it is filtered out by the normal parameter
|
||||
assignment algorithm. (Note also that 'metaclass' is a keyword-
|
||||
only argument as per PEP 3102 [6]_.)
|
||||
|
||||
__prepare__ returns a dictionary-like object which is used to store
|
||||
the class member definitions during evaluation of the class body.
|
||||
In other words, the class body is evaluated as a function block
|
||||
(just like it is now), except that the local variables dictionary
|
||||
is replaced by the dictionary returned from __prepare__. This
|
||||
dictionary object can be a regular dictionary or a custom mapping
|
||||
type.
|
||||
Even though ``__prepare__`` is not required, the default metaclass
|
||||
('type') implements it, for the convenience of subclasses calling
|
||||
it via super().
|
||||
|
||||
This dictionary-like object is not required to support the full
|
||||
dictionary interface. A dictionary which supports a limited set of
|
||||
dictionary operations will restrict what kinds of actions can occur
|
||||
during evaluation of the class body. A minimal implementation might
|
||||
only support adding and retrieving values from the dictionary - most
|
||||
class bodies will do no more than that during evaluation. For some
|
||||
classes, it may be desirable to support deletion as well. Many
|
||||
metaclasses will need to make a copy of this dictionary afterwards,
|
||||
so iteration or other means for reading out the dictionary contents
|
||||
may also be useful.
|
||||
``__prepare__`` returns a dictionary-like object which is used to store
|
||||
the class member definitions during evaluation of the class body.
|
||||
In other words, the class body is evaluated as a function block
|
||||
(just like it is now), except that the local variables dictionary
|
||||
is replaced by the dictionary returned from ``__prepare__``. This
|
||||
dictionary object can be a regular dictionary or a custom mapping
|
||||
type.
|
||||
|
||||
The __prepare__ method will most often be implemented as a class
|
||||
method rather than an instance method because it is called before
|
||||
the metaclass instance (i.e. the class itself) is created.
|
||||
This dictionary-like object is not required to support the full
|
||||
dictionary interface. A dictionary which supports a limited set of
|
||||
dictionary operations will restrict what kinds of actions can occur
|
||||
during evaluation of the class body. A minimal implementation might
|
||||
only support adding and retrieving values from the dictionary - most
|
||||
class bodies will do no more than that during evaluation. For some
|
||||
classes, it may be desirable to support deletion as well. Many
|
||||
metaclasses will need to make a copy of this dictionary afterwards,
|
||||
so iteration or other means for reading out the dictionary contents
|
||||
may also be useful.
|
||||
|
||||
Once the class body has finished evaluating, the metaclass will be
|
||||
called (as a callable) with the class dictionary, which is no
|
||||
different from the current metaclass mechanism.
|
||||
The ``__prepare__`` method will most often be implemented as a class
|
||||
method rather than an instance method because it is called before
|
||||
the metaclass instance (i.e. the class itself) is created.
|
||||
|
||||
Typically, a metaclass will create a custom dictionary - either a
|
||||
subclass of dict, or a wrapper around it - that will contain
|
||||
additional properties that are set either before or during the
|
||||
evaluation of the class body. Then in the second phase, the
|
||||
metaclass can use these additional properties to further customize
|
||||
the class.
|
||||
Once the class body has finished evaluating, the metaclass will be
|
||||
called (as a callable) with the class dictionary, which is no
|
||||
different from the current metaclass mechanism.
|
||||
|
||||
An example would be a metaclass that uses information about the
|
||||
ordering of member declarations to create a C struct. The metaclass
|
||||
would provide a custom dictionary that simply keeps a record of the
|
||||
order of insertions. This does not need to be a full 'ordered dict'
|
||||
implementation, but rather just a Python list of (key,value) pairs
|
||||
that is appended to for each insertion.
|
||||
Typically, a metaclass will create a custom dictionary - either a
|
||||
subclass of dict, or a wrapper around it - that will contain
|
||||
additional properties that are set either before or during the
|
||||
evaluation of the class body. Then in the second phase, the
|
||||
metaclass can use these additional properties to further customize
|
||||
the class.
|
||||
|
||||
Note that in such a case, the metaclass would be required to deal
|
||||
with the possibility of duplicate keys, but in most cases that is
|
||||
trivial. The metaclass can use the first declaration, the last,
|
||||
combine them in some fashion, or simply throw an exception. It's up
|
||||
to the metaclass to decide how it wants to handle that case.
|
||||
An example would be a metaclass that uses information about the
|
||||
ordering of member declarations to create a C struct. The metaclass
|
||||
would provide a custom dictionary that simply keeps a record of the
|
||||
order of insertions. This does not need to be a full 'ordered dict'
|
||||
implementation, but rather just a Python list of (key,value) pairs
|
||||
that is appended to for each insertion.
|
||||
|
||||
Example:
|
||||
Note that in such a case, the metaclass would be required to deal
|
||||
with the possibility of duplicate keys, but in most cases that is
|
||||
trivial. The metaclass can use the first declaration, the last,
|
||||
combine them in some fashion, or simply throw an exception. It's up
|
||||
to the metaclass to decide how it wants to handle that case.
|
||||
|
||||
Here's a simple example of a metaclass which creates a list of
|
||||
the names of all class members, in the order that they were
|
||||
declared:
|
||||
|
||||
# The custom dictionary
|
||||
class member_table(dict):
|
||||
def __init__(self):
|
||||
Example
|
||||
=======
|
||||
|
||||
Here's a simple example of a metaclass which creates a list of
|
||||
the names of all class members, in the order that they were
|
||||
declared::
|
||||
|
||||
# The custom dictionary
|
||||
class member_table(dict):
|
||||
def __init__(self):
|
||||
self.member_names = []
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
def __setitem__(self, key, value):
|
||||
# if the key is not already defined, add to the
|
||||
# list of keys.
|
||||
if key not in self:
|
||||
self.member_names.append(key)
|
||||
self.member_names.append(key)
|
||||
|
||||
# Call superclass
|
||||
dict.__setitem__(self, key, value)
|
||||
|
||||
# The metaclass
|
||||
class OrderedClass(type):
|
||||
# The metaclass
|
||||
class OrderedClass(type):
|
||||
|
||||
# The prepare function
|
||||
@classmethod
|
||||
def __prepare__(metacls, name, bases): # No keywords in this case
|
||||
return member_table()
|
||||
# The prepare function
|
||||
@classmethod
|
||||
def __prepare__(metacls, name, bases): # No keywords in this case
|
||||
return member_table()
|
||||
|
||||
# The metaclass invocation
|
||||
def __new__(cls, name, bases, classdict):
|
||||
# Note that we replace the classdict with a regular
|
||||
# dict before passing it to the superclass, so that we
|
||||
# don't continue to record member names after the class
|
||||
# has been created.
|
||||
result = type.__new__(cls, name, bases, dict(classdict))
|
||||
result.member_names = classdict.member_names
|
||||
return result
|
||||
# The metaclass invocation
|
||||
def __new__(cls, name, bases, classdict):
|
||||
# Note that we replace the classdict with a regular
|
||||
# dict before passing it to the superclass, so that we
|
||||
# don't continue to record member names after the class
|
||||
# has been created.
|
||||
result = type.__new__(cls, name, bases, dict(classdict))
|
||||
result.member_names = classdict.member_names
|
||||
return result
|
||||
|
||||
class MyClass(metaclass=OrderedClass):
|
||||
# method1 goes in array element 0
|
||||
def method1(self):
|
||||
class MyClass(metaclass=OrderedClass):
|
||||
# method1 goes in array element 0
|
||||
def method1(self):
|
||||
pass
|
||||
|
||||
# method2 goes in array element 1
|
||||
def method2(self):
|
||||
# method2 goes in array element 1
|
||||
def method2(self):
|
||||
pass
|
||||
|
||||
Sample Implementation:
|
||||
|
||||
Guido van Rossum has created a patch which implements the new
|
||||
functionality:
|
||||
|
||||
http://python.org/sf/1681101
|
||||
Sample Implementation
|
||||
=====================
|
||||
|
||||
Guido van Rossum has created a patch which implements the new
|
||||
functionality: http://python.org/sf/1681101
|
||||
|
||||
|
||||
Alternate Proposals
|
||||
===================
|
||||
|
||||
Josiah Carlson proposed using the name 'type' instead of
|
||||
'metaclass', on the theory that what is really being specified is
|
||||
the type of the type. While this is technically correct, it is also
|
||||
confusing from the point of view of a programmer creating a new
|
||||
class. From the application programmer's point of view, the 'type'
|
||||
that they are interested in is the class that they are writing; the
|
||||
type of that type is the metaclass.
|
||||
Josiah Carlson proposed using the name 'type' instead of
|
||||
'metaclass', on the theory that what is really being specified is
|
||||
the type of the type. While this is technically correct, it is also
|
||||
confusing from the point of view of a programmer creating a new
|
||||
class. From the application programmer's point of view, the 'type'
|
||||
that they are interested in is the class that they are writing; the
|
||||
type of that type is the metaclass.
|
||||
|
||||
There were some objections in the discussion to the 'two-phase'
|
||||
creation process, where the metaclass is invoked twice, once to
|
||||
create the class dictionary and once to 'finish' the class. Some
|
||||
people felt that these two phases should be completely separate, in
|
||||
that there ought to be separate syntax for specifying the custom
|
||||
dict as for specifying the metaclass. However, in most cases, the
|
||||
two will be intimately tied together, and the metaclass will most
|
||||
likely have an intimate knowledge of the internal details of the
|
||||
class dict. Requiring the programmer to insure that the correct dict
|
||||
type and the correct metaclass type are used together creates an
|
||||
additional and unneeded burden on the programmer.
|
||||
There were some objections in the discussion to the 'two-phase'
|
||||
creation process, where the metaclass is invoked twice, once to
|
||||
create the class dictionary and once to 'finish' the class. Some
|
||||
people felt that these two phases should be completely separate, in
|
||||
that there ought to be separate syntax for specifying the custom
|
||||
dict as for specifying the metaclass. However, in most cases, the
|
||||
two will be intimately tied together, and the metaclass will most
|
||||
likely have an intimate knowledge of the internal details of the
|
||||
class dict. Requiring the programmer to insure that the correct dict
|
||||
type and the correct metaclass type are used together creates an
|
||||
additional and unneeded burden on the programmer.
|
||||
|
||||
Another good suggestion was to simply use an ordered dict for all
|
||||
classes, and skip the whole 'custom dict' mechanism. This was based
|
||||
on the observation that most use cases for a custom dict were for
|
||||
the purposes of preserving order information. However, this idea has
|
||||
several drawbacks, first because it means that an ordered dict
|
||||
implementation would have to be added to the set of built-in types
|
||||
in Python, and second because it would impose a slight speed (and
|
||||
complexity) penalty on all class declarations. Later, several people
|
||||
came up with ideas for use cases for custom dictionaries other
|
||||
than preserving field orderings, so this idea was dropped.
|
||||
Another good suggestion was to simply use an ordered dict for all
|
||||
classes, and skip the whole 'custom dict' mechanism. This was based
|
||||
on the observation that most use cases for a custom dict were for
|
||||
the purposes of preserving order information. However, this idea has
|
||||
several drawbacks, first because it means that an ordered dict
|
||||
implementation would have to be added to the set of built-in types
|
||||
in Python, and second because it would impose a slight speed (and
|
||||
complexity) penalty on all class declarations. Later, several people
|
||||
came up with ideas for use cases for custom dictionaries other
|
||||
than preserving field orderings, so this idea was dropped.
|
||||
|
||||
|
||||
Backwards Compatibility
|
||||
=======================
|
||||
|
||||
It would be possible to leave the existing __metaclass__ syntax in
|
||||
place. Alternatively, it would not be too difficult to modify the
|
||||
syntax rules of the Py3K translation tool to convert from the old to
|
||||
the new syntax.
|
||||
It would be possible to leave the existing ``__metaclass__`` syntax in
|
||||
place. Alternatively, it would not be too difficult to modify the
|
||||
syntax rules of the Py3K translation tool to convert from the old to
|
||||
the new syntax.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] [Python-3000] Metaclasses in Py3K (original proposal)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005030.html
|
||||
.. [1] [Python-3000] Metaclasses in Py3K (original proposal)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005030.html
|
||||
|
||||
[2] [Python-3000] Metaclasses in Py3K (Guido's suggested syntax)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005033.html
|
||||
.. [2] [Python-3000] Metaclasses in Py3K (Guido's suggested syntax)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005033.html
|
||||
|
||||
[3] [Python-3000] Metaclasses in Py3K (Objections to two-phase init)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005108.html
|
||||
.. [3] [Python-3000] Metaclasses in Py3K (Objections to two-phase init)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005108.html
|
||||
|
||||
[4] [Python-3000] Metaclasses in Py3K (Always use an ordered dict)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005118.html
|
||||
.. [4] [Python-3000] Metaclasses in Py3K (Always use an ordered dict)
|
||||
http://mail.python.org/pipermail/python-3000/2006-December/005118.html
|
||||
|
||||
[5] PEP 359: The 'make' statement -
|
||||
http://www.python.org/dev/peps/pep-0359/
|
||||
.. [5] PEP 359: The 'make' statement -
|
||||
http://www.python.org/dev/peps/pep-0359/
|
||||
|
||||
[6] PEP 3102: Keyword-only arguments -
|
||||
http://www.python.org/dev/peps/pep-3102/
|
||||
.. [6] PEP 3102: Keyword-only arguments -
|
||||
http://www.python.org/dev/peps/pep-3102/
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
This document has been placed in the public domain.
|
||||
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:
|
||||
|
||||
..
|
||||
Local Variables:
|
||||
mode: indented-text
|
||||
indent-tabs-mode: nil
|
||||
sentence-end-double-space: t
|
||||
fill-column: 70
|
||||
coding: utf-8
|
||||
End:
|
||||
|
|
Loading…
Reference in New Issue