reSTify PEP 319 (#350)

This commit is contained in:
Huang Huang 2017-08-19 02:56:24 +08:00 committed by Brett Cannon
parent cc56b43dcb
commit 86a462a7b4
1 changed files with 307 additions and 293 deletions

View File

@ -5,25 +5,27 @@ Last-Modified: $Date$
Author: Michel Pelletier <michel@users.sourceforge.net> Author: Michel Pelletier <michel@users.sourceforge.net>
Status: Rejected Status: Rejected
Type: Standards Track Type: Standards Track
Content-Type: text/x-rst
Created: 24-Feb-2003 Created: 24-Feb-2003
Python-Version: 2.4? Python-Version: 2.4?
Post-History: Post-History:
Abstract Abstract
========
This PEP proposes adding two new keywords to Python, `synchronize' This PEP proposes adding two new keywords to Python, 'synchronize'
and 'asynchronize'. and 'asynchronize'.
Pronouncement Pronouncement
=============
This PEP is rejected in favor of PEP 343. This PEP is rejected in favor of PEP 343.
The `synchronize' Keyword The 'synchronize' Keyword
The concept of code synchronization in Python is too low-level. The concept of code synchronization in Python is too low-level.
To synchronize code a programmer must be aware of the details of To synchronize code a programmer must be aware of the details of
the following pseudo-code pattern: the following pseudo-code pattern::
initialize_lock() initialize_lock()
@ -37,7 +39,7 @@ The `synchronize' Keyword
This synchronized block pattern is not the only pattern (more This synchronized block pattern is not the only pattern (more
discussed below) but it is very common. This PEP proposes discussed below) but it is very common. This PEP proposes
replacing the above code with the following equivalent: replacing the above code with the following equivalent::
synchronize: synchronize:
change_shared_data() change_shared_data()
@ -49,13 +51,12 @@ The `synchronize' Keyword
thread locking issues. thread locking issues.
The `asynchronize' Keyword The 'asynchronize' Keyword
While executing a 'synchronize' block of code a programmer may
While executing a `synchronize' block of code a programmer may
want to "drop back" to running asynchronously momentarily to run want to "drop back" to running asynchronously momentarily to run
blocking input/output routines or something else that might take a blocking input/output routines or something else that might take a
indeterminate amount of time and does not require synchronization. indeterminate amount of time and does not require synchronization.
This code usually follows the pattern: This code usually follows the pattern::
initialize_lock() initialize_lock()
@ -75,7 +76,7 @@ The `asynchronize' Keyword
The asynchronous section of the code is not very obvious visually, The asynchronous section of the code is not very obvious visually,
so it is marked up with comments. Using the proposed so it is marked up with comments. Using the proposed
'asynchronize' keyword this code becomes much cleaner, easier to 'asynchronize' keyword this code becomes much cleaner, easier to
understand, and less prone to error: understand, and less prone to error::
synchronize: synchronize:
change_shared_data() change_shared_data()
@ -85,10 +86,10 @@ The `asynchronize' Keyword
change_shared_data2() change_shared_data2()
Encountering an `asynchronize' keyword inside a non-synchronized Encountering an 'asynchronize' keyword inside a non-synchronized
block can raise either an error or issue a warning (as all code block can raise either an error or issue a warning (as all code
blocks are implicitly asynchronous anyway). It is important to blocks are implicitly asynchronous anyway). It is important to
note that the above example is *not* the same as: note that the above example is **not** the same as::
synchronize: synchronize:
change_shared_data() change_shared_data()
@ -99,7 +100,7 @@ The `asynchronize' Keyword
change_shared_data2() change_shared_data2()
Because both synchronized blocks of code may be running inside the Because both synchronized blocks of code may be running inside the
same iteration of a loop, Consider: same iteration of a loop, Consider::
while in_main_loop(): while in_main_loop():
synchronize: synchronize:
@ -118,15 +119,16 @@ The `asynchronize' Keyword
Synchronization Targets Synchronization Targets
=======================
As proposed the `synchronize' and `asynchronize' keywords As proposed the 'synchronize' and 'asynchronize' keywords
synchronize a block of code. However programmers may want to synchronize a block of code. However programmers may want to
specify a target object that threads synchronize on. Any object specify a target object that threads synchronize on. Any object
can be a synchronization target. can be a synchronization target.
Consider a two-way queue object: two different objects are used by Consider a two-way queue object: two different objects are used by
the same `synchronize' code block to synchronize both queues the same 'synchronize' code block to synchronize both queues
separately in the 'get' method: separately in the 'get' method::
class TwoWayQueue: class TwoWayQueue:
def __init__(self): def __init__(self):
@ -158,7 +160,7 @@ Synchronization Targets
return item return item
Here is the equivalent code in Python as it is now without a Here is the equivalent code in Python as it is now without a
`synchronize' keyword: 'synchronize' keyword::
import thread import thread
@ -204,23 +206,24 @@ Synchronization Targets
queue.lock.release() queue.lock.release()
The last example had to define an extra class to associate a lock The last example had to define an extra class to associate a lock
with the queue where the first example the `synchronize' keyword with the queue where the first example the 'synchronize' keyword
does this association internally and transparently. does this association internally and transparently.
Other Patterns that Synchronize Other Patterns that Synchronize
===============================
There are some situations where the `synchronize' and There are some situations where the 'synchronize' and
`asynchronize' keywords cannot entirely replace the use of lock 'asynchronize' keywords cannot entirely replace the use of lock
methods like `acquire' and `release'. Some examples are if the methods like ``acquire`` and ``release``. Some examples are if the
programmer wants to provide arguments for `acquire' or if a lock programmer wants to provide arguments for ``acquire`` or if a lock
is acquired in one code block but released in another, as shown is acquired in one code block but released in another, as shown
below. below.
Here is a class from Zope modified to use both the `synchronize' Here is a class from Zope modified to use both the 'synchronize'
and `asynchronize' keywords and also uses a pool of explicit locks and 'asynchronize' keywords and also uses a pool of explicit locks
that are acquired and released in different code blocks and thus that are acquired and released in different code blocks and thus
don't use `synchronize': don't use 'synchronize'::
import thread import thread
from ZServerPublisher import ZServerPublisher from ZServerPublisher import ZServerPublisher
@ -268,7 +271,7 @@ Other Patterns that Synchronize
Here is the original class as found in the Here is the original class as found in the
'Zope/ZServer/PubCore/ZRendevous.py' module. The "convenience" of 'Zope/ZServer/PubCore/ZRendevous.py' module. The "convenience" of
the '_a' and '_r' shortcut names obscure the code: the '_a' and '_r' shortcut names obscure the code::
import thread import thread
from ZServerPublisher import ZServerPublisher from ZServerPublisher import ZServerPublisher
@ -321,18 +324,19 @@ Other Patterns that Synchronize
l.release() l.release()
finally: self._r() finally: self._r()
In particular the asynchronize section of the `accept' method is In particular the asynchronize section of the ``accept`` method is
not very obvious. To beginner programmers, `synchronize' and not very obvious. To beginner programmers, 'synchronize' and
`asynchronize' remove many of the problems encountered when 'asynchronize' remove many of the problems encountered when
juggling multiple `acquire' and `release' methods on different juggling multiple ``acquire`` and ``release`` methods on different
locks in different `try/finally' blocks. locks in different ``try/finally`` blocks.
Formal Syntax Formal Syntax
=============
Python syntax is defined in a modified BNF grammar notation Python syntax is defined in a modified BNF grammar notation
described in the Python Language Reference [1]. This section described in the Python Language Reference [1]_. This section
describes the proposed synchronization syntax using this grammar: describes the proposed synchronization syntax using this grammar::
synchronize_stmt: 'synchronize' [test] ':' suite synchronize_stmt: 'synchronize' [test] ':' suite
asynchronize_stmt: 'asynchronize' [test] ':' suite asynchronize_stmt: 'asynchronize' [test] ':' suite
@ -342,6 +346,7 @@ Formal Syntax
Proposed Implementation Proposed Implementation
=======================
The author of this PEP has not explored an implementation yet. The author of this PEP has not explored an implementation yet.
There are several implementation issues that must be resolved. There are several implementation issues that must be resolved.
@ -349,12 +354,12 @@ Proposed Implementation
unlocked during a synchronized block. unlocked during a synchronized block.
During an unqualified synchronized block (the use of the During an unqualified synchronized block (the use of the
`synchronize' keyword without a target argument) a lock could be 'synchronize' keyword without a target argument) a lock could be
created and associated with the synchronized code block object. created and associated with the synchronized code block object.
Any threads that are to execute the block must first acquire the Any threads that are to execute the block must first acquire the
code block lock. code block lock.
When an `asynchronize' keyword is encountered in a `synchronize' When an 'asynchronize' keyword is encountered in a 'synchronize'
block the code block lock is unlocked before the inner block is block the code block lock is unlocked before the inner block is
executed and re-locked when the inner block terminates. executed and re-locked when the inner block terminates.
@ -367,35 +372,37 @@ Proposed Implementation
Backward Compatibility Backward Compatibility
======================
Backward compatibility is solved with the new `from __future__' Backward compatibility is solved with the new ``from __future__``
Python syntax [2], and the new warning framework [3] to evolve the Python syntax [2]_, and the new warning framework [3]_ to evolve the
Python language into phasing out any conflicting names that use Python language into phasing out any conflicting names that use
the new keywords `synchronize' and `asynchronize'. To use the the new keywords 'synchronize' and 'asynchronize'. To use the
syntax now, a developer could use the statement: syntax now, a developer could use the statement::
from __future__ import threadsync # or whatever from __future__ import threadsync # or whatever
In addition, any code that uses the keyword `synchronize' or In addition, any code that uses the keyword 'synchronize' or
`asynchronize' as an identifier will be issued a warning from 'asynchronize' as an identifier will be issued a warning from
Python. After the appropriate period of time, the syntax would Python. After the appropriate period of time, the syntax would
become standard, the above import statement would do nothing, and become standard, the above import statement would do nothing, and
any identifiers named `synchronize' or `asynchronize' would raise any identifiers named 'synchronize' or 'asynchronize' would raise
an exception. an exception.
PEP 310 Reliable Acquisition/Release Pairs PEP 310 Reliable Acquisition/Release Pairs
==========================================
PEP 310 [4] proposes the 'with' keyword that can serve the same PEP 310 [4]_ proposes the 'with' keyword that can serve the same
function as 'synchronize' (but no facility for 'asynchronize'). function as 'synchronize' (but no facility for 'asynchronize').
The pattern: The pattern::
initialize_lock() initialize_lock()
with the_lock: with the_lock:
change_shared_data() change_shared_data()
is equivalent to the proposed: is equivalent to the proposed::
synchronize the_lock: synchronize the_lock:
change_shared_data() change_shared_data()
@ -405,11 +412,11 @@ PEP 310 Reliable Acquisition/Release Pairs
a global, internal, transparent lock in addition to qualifiled a global, internal, transparent lock in addition to qualifiled
'synchronize' statements. The 'with' statement also requires lock 'synchronize' statements. The 'with' statement also requires lock
initialization, while the 'synchronize' statement can synchronize initialization, while the 'synchronize' statement can synchronize
on any target object *including* locks. on any target object **including** locks.
While limited in this fashion, the 'with' statement is more While limited in this fashion, the 'with' statement is more
abstract and serves more purposes than synchronization. For abstract and serves more purposes than synchronization. For
example, transactions could be used with the 'with' keyword: example, transactions could be used with the 'with' keyword::
initialize_transaction() initialize_transaction()
@ -424,10 +431,11 @@ PEP 310 Reliable Acquisition/Release Pairs
How Java Does It How Java Does It
================
Java defines a 'synchronized' keyword (note the grammatical tense Java defines a 'synchronized' keyword (note the grammatical tense
different between the Java keyword and this PEP's 'synchronize') different between the Java keyword and this PEP's 'synchronize')
which must be qualified on any object. The syntax is: which must be qualified on any object. The syntax is::
synchronized (Expression) Block synchronized (Expression) Block
@ -437,6 +445,7 @@ How Java Does It
How Jython Does It How Jython Does It
==================
Jython uses a 'synchronize' class with the static method Jython uses a 'synchronize' class with the static method
'make_synchronized' that accepts one callable argument and returns 'make_synchronized' that accepts one callable argument and returns
@ -445,12 +454,14 @@ How Jython Does It
Summary of Proposed Changes to Python Summary of Proposed Changes to Python
=====================================
Adding new `synchronize' and `asynchronize' keywords to the Adding new 'synchronize' and 'asynchronize' keywords to the
language. language.
Risks Risks
=====
This PEP proposes adding two keywords to the Python language. This This PEP proposes adding two keywords to the Python language. This
may break code. may break code.
@ -467,31 +478,34 @@ Risks
Dissenting Opinion Dissenting Opinion
==================
This PEP has not been discussed on python-dev. This PEP has not been discussed on python-dev.
References References
==========
[1] The Python Language Reference .. [1] The Python Language Reference
http://docs.python.org/reference/ http://docs.python.org/reference/
[2] PEP 236, Back to the __future__, Peters .. [2] PEP 236, Back to the __future__, Peters
http://www.python.org/dev/peps/pep-0236/ http://www.python.org/dev/peps/pep-0236/
[3] PEP 230, Warning Framework, van Rossum .. [3] PEP 230, Warning Framework, van Rossum
http://www.python.org/dev/peps/pep-0230/ http://www.python.org/dev/peps/pep-0230/
[4] PEP 310, Reliable Acquisition/Release Pairs, Hudson, Moore .. [4] PEP 310, Reliable Acquisition/Release Pairs, Hudson, Moore
http://www.python.org/dev/peps/pep-0310/ http://www.python.org/dev/peps/pep-0310/
Copyright Copyright
=========
This document has been placed in the public domain. This document has been placed in the public domain.
..
Local Variables: Local Variables:
mode: indented-text mode: indented-text
indent-tabs-mode: nil indent-tabs-mode: nil