Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
8170e8c0
Kaydet (Commit)
8170e8c0
authored
May 09, 2015
tarafından
Yury Selivanov
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
PEP 479: Change StopIteration handling inside generators.
Closes issue #22906.
üst
bd60e8de
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
103 additions
and
15 deletions
+103
-15
functional.rst
Doc/howto/functional.rst
+4
-4
__future__.rst
Doc/library/__future__.rst
+3
-0
exceptions.rst
Doc/library/exceptions.rst
+8
-0
expressions.rst
Doc/reference/expressions.rst
+6
-6
code.h
Include/code.h
+1
-0
compile.h
Include/compile.h
+1
-0
pythonrun.h
Include/pythonrun.h
+2
-1
__future__.py
Lib/__future__.py
+6
-0
contextlib.py
Lib/contextlib.py
+9
-2
difflib.py
Lib/difflib.py
+1
-2
test_contextlib.py
Lib/test/test_contextlib.py
+34
-0
NEWS
Misc/NEWS
+2
-0
genobject.c
Objects/genobject.c
+24
-0
future.c
Python/future.c
+2
-0
No files found.
Doc/howto/functional.rst
Dosyayı görüntüle @
8170e8c0
...
@@ -481,10 +481,10 @@ Here's a sample usage of the ``generate_ints()`` generator:
...
@@ -481,10 +481,10 @@ Here's a sample usage of the ``generate_ints()`` generator:
You could equally write ``for i in generate_ints(5)``, or ``a,b,c =
You could equally write ``for i in generate_ints(5)``, or ``a,b,c =
generate_ints(3)``.
generate_ints(3)``.
Inside a generator function, ``return value``
is semantically equivalent to
Inside a generator function, ``return value``
causes ``StopIteration(value)``
``raise StopIteration(value)``. If no value is returned or the bottom of the
to be raised from the :meth:`~generator.__next__` method. Once this happens, or
function is reached, the procession of values ends and the generator cannot
the bottom of the function is reached, the procession of values ends and the
return
any further values.
generator cannot yield
any further values.
You could achieve the effect of generators manually by writing your own class
You could achieve the effect of generators manually by writing your own class
and storing all the local variables of the generator as instance variables. For
and storing all the local variables of the generator as instance variables. For
...
...
Doc/library/__future__.rst
Dosyayı görüntüle @
8170e8c0
...
@@ -87,6 +87,9 @@ language using this mechanism:
...
@@ -87,6 +87,9 @@ language using this mechanism:
| unicode_literals | 2.6.0a2 | 3.0 | :pep:`3112`: |
| unicode_literals | 2.6.0a2 | 3.0 | :pep:`3112`: |
| | | | *Bytes literals in Python 3000* |
| | | | *Bytes literals in Python 3000* |
+------------------+-------------+--------------+---------------------------------------------+
+------------------+-------------+--------------+---------------------------------------------+
| generator_stop | 3.5.0b1 | 3.7 | :pep:`479`: |
| | | | *StopIteration handling inside generators* |
+------------------+-------------+--------------+---------------------------------------------+
.. seealso::
.. seealso::
...
...
Doc/library/exceptions.rst
Dosyayı görüntüle @
8170e8c0
...
@@ -310,10 +310,18 @@ The following exceptions are the exceptions that are usually raised.
...
@@ -310,10 +310,18 @@ The following exceptions are the exceptions that are usually raised.
raised, and the value returned by the function is used as the
raised, and the value returned by the function is used as the
:attr:`value` parameter to the constructor of the exception.
:attr:`value` parameter to the constructor of the exception.
If a generator function defined in the presence of a ``from __future__
import generator_stop`` directive raises :exc:`StopIteration`, it will be
converted into a :exc:`RuntimeError` (retaining the :exc:`StopIteration`
as the new exception's cause).
.. versionchanged:: 3.3
.. versionchanged:: 3.3
Added ``value`` attribute and the ability for generator functions to
Added ``value`` attribute and the ability for generator functions to
use it to return a value.
use it to return a value.
.. versionchanged:: 3.5
Introduced the RuntimeError transformation.
.. exception:: SyntaxError
.. exception:: SyntaxError
Raised when the parser encounters a syntax error. This may occur in an
Raised when the parser encounters a syntax error. This may occur in an
...
...
Doc/reference/expressions.rst
Dosyayı görüntüle @
8170e8c0
...
@@ -443,12 +443,12 @@ is already executing raises a :exc:`ValueError` exception.
...
@@ -443,12 +443,12 @@ is already executing raises a :exc:`ValueError` exception.
.. method:: generator.close()
.. method:: generator.close()
Raises a :exc:`GeneratorExit` at the point where the generator function was
Raises a :exc:`GeneratorExit` at the point where the generator function was
paused. If the generator function then
raises :exc:`StopIteration` (by
paused. If the generator function then
exits gracefully, is already closed,
exiting normally, or due to already being closed) or :exc:`GeneratorExit` (by
or raises :exc:`GeneratorExit` (by not catching the exception), close
not catching the exception), close returns to its caller. If the generator
returns to its caller. If the generator yields a value, a
yields a value, a :exc:`RuntimeError` is raised. If the generator raises any
:exc:`RuntimeError` is raised. If the generator raises any other exception,
other exception, it is propagated to the caller. :meth:`close` does nothing
it is propagated to the caller. :meth:`close` does nothing if the generator
if the generator
has already exited due to an exception or normal exit.
has already exited due to an exception or normal exit.
.. index:: single: yield; examples
.. index:: single: yield; examples
...
...
Include/code.h
Dosyayı görüntüle @
8170e8c0
...
@@ -62,6 +62,7 @@ typedef struct {
...
@@ -62,6 +62,7 @@ typedef struct {
#define CO_FUTURE_UNICODE_LITERALS 0x20000
#define CO_FUTURE_UNICODE_LITERALS 0x20000
#define CO_FUTURE_BARRY_AS_BDFL 0x40000
#define CO_FUTURE_BARRY_AS_BDFL 0x40000
#define CO_FUTURE_GENERATOR_STOP 0x80000
/* This value is found in the co_cell2arg array when the associated cell
/* This value is found in the co_cell2arg array when the associated cell
variable does not correspond to an argument. The maximum number of
variable does not correspond to an argument. The maximum number of
...
...
Include/compile.h
Dosyayı görüntüle @
8170e8c0
...
@@ -27,6 +27,7 @@ typedef struct {
...
@@ -27,6 +27,7 @@ typedef struct {
#define FUTURE_PRINT_FUNCTION "print_function"
#define FUTURE_PRINT_FUNCTION "print_function"
#define FUTURE_UNICODE_LITERALS "unicode_literals"
#define FUTURE_UNICODE_LITERALS "unicode_literals"
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
#define FUTURE_BARRY_AS_BDFL "barry_as_FLUFL"
#define FUTURE_GENERATOR_STOP "generator_stop"
struct
_mod
;
/* Declare the existence of this type */
struct
_mod
;
/* Declare the existence of this type */
#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar)
#define PyAST_Compile(mod, s, f, ar) PyAST_CompileEx(mod, s, f, -1, ar)
...
...
Include/pythonrun.h
Dosyayı görüntüle @
8170e8c0
...
@@ -9,7 +9,8 @@ extern "C" {
...
@@ -9,7 +9,8 @@ extern "C" {
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
#define PyCF_MASK (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT | \
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION | \
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL)
CO_FUTURE_UNICODE_LITERALS | CO_FUTURE_BARRY_AS_BDFL | \
CO_FUTURE_GENERATOR_STOP)
#define PyCF_MASK_OBSOLETE (CO_NESTED)
#define PyCF_MASK_OBSOLETE (CO_NESTED)
#define PyCF_SOURCE_IS_UTF8 0x0100
#define PyCF_SOURCE_IS_UTF8 0x0100
#define PyCF_DONT_IMPLY_DEDENT 0x0200
#define PyCF_DONT_IMPLY_DEDENT 0x0200
...
...
Lib/__future__.py
Dosyayı görüntüle @
8170e8c0
...
@@ -56,6 +56,7 @@ all_feature_names = [
...
@@ -56,6 +56,7 @@ all_feature_names = [
"print_function"
,
"print_function"
,
"unicode_literals"
,
"unicode_literals"
,
"barry_as_FLUFL"
,
"barry_as_FLUFL"
,
"generator_stop"
,
]
]
__all__
=
[
"all_feature_names"
]
+
all_feature_names
__all__
=
[
"all_feature_names"
]
+
all_feature_names
...
@@ -72,6 +73,7 @@ CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement
...
@@ -72,6 +73,7 @@ CO_FUTURE_WITH_STATEMENT = 0x8000 # with statement
CO_FUTURE_PRINT_FUNCTION
=
0x10000
# print function
CO_FUTURE_PRINT_FUNCTION
=
0x10000
# print function
CO_FUTURE_UNICODE_LITERALS
=
0x20000
# unicode string literals
CO_FUTURE_UNICODE_LITERALS
=
0x20000
# unicode string literals
CO_FUTURE_BARRY_AS_BDFL
=
0x40000
CO_FUTURE_BARRY_AS_BDFL
=
0x40000
CO_FUTURE_GENERATOR_STOP
=
0x80000
# StopIteration becomes RuntimeError in generators
class
_Feature
:
class
_Feature
:
def
__init__
(
self
,
optionalRelease
,
mandatoryRelease
,
compiler_flag
):
def
__init__
(
self
,
optionalRelease
,
mandatoryRelease
,
compiler_flag
):
...
@@ -132,3 +134,7 @@ unicode_literals = _Feature((2, 6, 0, "alpha", 2),
...
@@ -132,3 +134,7 @@ unicode_literals = _Feature((2, 6, 0, "alpha", 2),
barry_as_FLUFL
=
_Feature
((
3
,
1
,
0
,
"alpha"
,
2
),
barry_as_FLUFL
=
_Feature
((
3
,
1
,
0
,
"alpha"
,
2
),
(
3
,
9
,
0
,
"alpha"
,
0
),
(
3
,
9
,
0
,
"alpha"
,
0
),
CO_FUTURE_BARRY_AS_BDFL
)
CO_FUTURE_BARRY_AS_BDFL
)
generator_stop
=
_Feature
((
3
,
5
,
0
,
"beta"
,
1
),
(
3
,
7
,
0
,
"alpha"
,
0
),
CO_FUTURE_GENERATOR_STOP
)
Lib/contextlib.py
Dosyayı görüntüle @
8170e8c0
...
@@ -77,10 +77,17 @@ class _GeneratorContextManager(ContextDecorator):
...
@@ -77,10 +77,17 @@ class _GeneratorContextManager(ContextDecorator):
self
.
gen
.
throw
(
type
,
value
,
traceback
)
self
.
gen
.
throw
(
type
,
value
,
traceback
)
raise
RuntimeError
(
"generator didn't stop after throw()"
)
raise
RuntimeError
(
"generator didn't stop after throw()"
)
except
StopIteration
as
exc
:
except
StopIteration
as
exc
:
# Suppress
the excep
tion *unless* it's the same exception that
# Suppress
StopItera
tion *unless* it's the same exception that
# was passed to throw(). This prevents a StopIteration
# was passed to throw(). This prevents a StopIteration
# raised inside the "with" statement from being suppressed
# raised inside the "with" statement from being suppressed
.
return
exc
is
not
value
return
exc
is
not
value
except
RuntimeError
as
exc
:
# Likewise, avoid suppressing if a StopIteration exception
# was passed to throw() and later wrapped into a RuntimeError
# (see PEP 479).
if
exc
.
__cause__
is
value
:
return
False
raise
except
:
except
:
# only re-raise if it's *not* the exception that was
# only re-raise if it's *not* the exception that was
# passed to throw(), because __exit__() must not raise
# passed to throw(), because __exit__() must not raise
...
...
Lib/difflib.py
Dosyayı görüntüle @
8170e8c0
...
@@ -1596,8 +1596,7 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None,
...
@@ -1596,8 +1596,7 @@ def _mdiff(fromlines, tolines, context=None, linejunk=None,
# them up without doing anything else with them.
# them up without doing anything else with them.
line_pair_iterator
=
_line_pair_iterator
()
line_pair_iterator
=
_line_pair_iterator
()
if
context
is
None
:
if
context
is
None
:
while
True
:
yield
from
line_pair_iterator
yield
next
(
line_pair_iterator
)
# Handle case where user wants context differencing. We must do some
# Handle case where user wants context differencing. We must do some
# storage of lines until we know for sure that they are to be yielded.
# storage of lines until we know for sure that they are to be yielded.
else
:
else
:
...
...
Lib/test/test_contextlib.py
Dosyayı görüntüle @
8170e8c0
...
@@ -83,6 +83,40 @@ class ContextManagerTestCase(unittest.TestCase):
...
@@ -83,6 +83,40 @@ class ContextManagerTestCase(unittest.TestCase):
raise
ZeroDivisionError
(
999
)
raise
ZeroDivisionError
(
999
)
self
.
assertEqual
(
state
,
[
1
,
42
,
999
])
self
.
assertEqual
(
state
,
[
1
,
42
,
999
])
def
test_contextmanager_except_stopiter
(
self
):
stop_exc
=
StopIteration
(
'spam'
)
@contextmanager
def
woohoo
():
yield
try
:
with
woohoo
():
raise
stop_exc
except
Exception
as
ex
:
self
.
assertIs
(
ex
,
stop_exc
)
else
:
self
.
fail
(
'StopIteration was suppressed'
)
def
test_contextmanager_except_pep479
(
self
):
code
=
"""
\
from __future__ import generator_stop
from contextlib import contextmanager
@contextmanager
def woohoo():
yield
"""
locals
=
{}
exec
(
code
,
locals
,
locals
)
woohoo
=
locals
[
'woohoo'
]
stop_exc
=
StopIteration
(
'spam'
)
try
:
with
woohoo
():
raise
stop_exc
except
Exception
as
ex
:
self
.
assertIs
(
ex
,
stop_exc
)
else
:
self
.
fail
(
'StopIteration was suppressed'
)
def
_create_contextmanager_attribs
(
self
):
def
_create_contextmanager_attribs
(
self
):
def
attribs
(
**
kw
):
def
attribs
(
**
kw
):
def
decorate
(
func
):
def
decorate
(
func
):
...
...
Misc/NEWS
Dosyayı görüntüle @
8170e8c0
...
@@ -33,6 +33,8 @@ Core and Builtins
...
@@ -33,6 +33,8 @@ Core and Builtins
- Issue #9951: Added a hex() method to bytes, bytearray, and memoryview.
- Issue #9951: Added a hex() method to bytes, bytearray, and memoryview.
- Issue #22906: PEP 479: Change StopIteration handling inside generators.
Library
Library
-------
-------
...
...
Objects/genobject.c
Dosyayı görüntüle @
8170e8c0
...
@@ -130,6 +130,30 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
...
@@ -130,6 +130,30 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc)
}
}
Py_CLEAR
(
result
);
Py_CLEAR
(
result
);
}
}
else
if
(
!
result
)
{
/* Check for __future__ generator_stop and conditionally turn
* a leaking StopIteration into RuntimeError (with its cause
* set appropriately). */
if
((((
PyCodeObject
*
)
gen
->
gi_code
)
->
co_flags
&
CO_FUTURE_GENERATOR_STOP
)
&&
PyErr_ExceptionMatches
(
PyExc_StopIteration
))
{
PyObject
*
exc
,
*
val
,
*
val2
,
*
tb
;
PyErr_Fetch
(
&
exc
,
&
val
,
&
tb
);
PyErr_NormalizeException
(
&
exc
,
&
val
,
&
tb
);
if
(
tb
!=
NULL
)
PyException_SetTraceback
(
val
,
tb
);
Py_DECREF
(
exc
);
Py_XDECREF
(
tb
);
PyErr_SetString
(
PyExc_RuntimeError
,
"generator raised StopIteration"
);
PyErr_Fetch
(
&
exc
,
&
val2
,
&
tb
);
PyErr_NormalizeException
(
&
exc
,
&
val2
,
&
tb
);
PyException_SetCause
(
val2
,
val
);
PyException_SetContext
(
val2
,
val
);
PyErr_Restore
(
exc
,
val2
,
tb
);
}
}
if
(
!
result
||
f
->
f_stacktop
==
NULL
)
{
if
(
!
result
||
f
->
f_stacktop
==
NULL
)
{
/* generator can't be rerun, so release the frame */
/* generator can't be rerun, so release the frame */
...
...
Python/future.c
Dosyayı görüntüle @
8170e8c0
...
@@ -40,6 +40,8 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
...
@@ -40,6 +40,8 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
continue
;
continue
;
}
else
if
(
strcmp
(
feature
,
FUTURE_BARRY_AS_BDFL
)
==
0
)
{
}
else
if
(
strcmp
(
feature
,
FUTURE_BARRY_AS_BDFL
)
==
0
)
{
ff
->
ff_features
|=
CO_FUTURE_BARRY_AS_BDFL
;
ff
->
ff_features
|=
CO_FUTURE_BARRY_AS_BDFL
;
}
else
if
(
strcmp
(
feature
,
FUTURE_GENERATOR_STOP
)
==
0
)
{
ff
->
ff_features
|=
CO_FUTURE_GENERATOR_STOP
;
}
else
if
(
strcmp
(
feature
,
"braces"
)
==
0
)
{
}
else
if
(
strcmp
(
feature
,
"braces"
)
==
0
)
{
PyErr_SetString
(
PyExc_SyntaxError
,
PyErr_SetString
(
PyExc_SyntaxError
,
"not a chance"
);
"not a chance"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment