diff --git a/pep-0204.txt b/pep-0204.txt index 186be9885..a78eab324 100644 --- a/pep-0204.txt +++ b/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: diff --git a/pep-0248.txt b/pep-0248.txt index ed9651f32..f837d66bc 100644 --- a/pep-0248.txt +++ b/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: diff --git a/pep-0283.txt b/pep-0283.txt index 8615f497b..fb8f57157 100644 --- a/pep-0283.txt +++ b/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: diff --git a/pep-0314.txt b/pep-0314.txt index fd2ef69e9..6355b4388 100644 --- a/pep-0314.txt +++ b/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 - - 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" - - 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 - 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" - 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: diff --git a/pep-3115.txt b/pep-3115.txt index 7285ed520..790c97944 100644 --- a/pep-3115.txt +++ b/pep-3115.txt @@ -5,309 +5,327 @@ Last-Modified: $Date$ Author: Talin 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: