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
43c47fe0
Unverified
Kaydet (Commit)
43c47fe0
authored
Ock 26, 2018
tarafından
Yury Selivanov
Kaydeden (comit)
GitHub
Ock 26, 2018
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
bpo-32670: Enforce PEP 479. (#5327)
üst
dba976b8
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
38 additions
and
80 deletions
+38
-80
exceptions.rst
Doc/library/exceptions.rst
+9
-5
3.7.rst
Doc/whatsnew/3.7.rst
+6
-0
test_generators.py
Lib/test/test_generators.py
+3
-19
test_with.py
Lib/test/test_with.py
+6
-5
2018-01-25-17-03-46.bpo-32670.YsqJUC.rst
...ore and Builtins/2018-01-25-17-03-46.bpo-32670.YsqJUC.rst
+5
-0
genobject.c
Objects/genobject.c
+8
-50
future.c
Python/future.c
+1
-1
No files found.
Doc/library/exceptions.rst
Dosyayı görüntüle @
43c47fe0
...
...
@@ -367,17 +367,21 @@ The following exceptions are the exceptions that are usually raised.
raised, and the value returned by the function is used as the
: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).
If a generator code directly or indirectly raises :exc:`StopIteration`,
it is converted into a :exc:`RuntimeError` (retaining the
:exc:`StopIteration` as the new exception's cause).
.. versionchanged:: 3.3
Added ``value`` attribute and the ability for generator functions to
use it to return a value.
.. versionchanged:: 3.5
Introduced the RuntimeError transformation.
Introduced the RuntimeError transformation via
``from __future__ import generator_stop``, see :pep:`479`.
.. versionchanged:: 3.7
Enable :pep:`479` for all code by default: a :exc:`StopIteration`
error raised in a generator is transformed into a :exc:`RuntimeError`.
.. exception:: StopAsyncIteration
...
...
Doc/whatsnew/3.7.rst
Dosyayı görüntüle @
43c47fe0
...
...
@@ -935,6 +935,12 @@ that may require changes to your code.
Changes in Python behavior
--------------------------
* :pep:`479` is enabled for all code in Python 3.7, meaning that
:exc:`StopIteration` exceptions raised directly or indirectly in
coroutines and generators are transformed into :exc:`RuntimeError`
exceptions.
(Contributed by Yury Selivanov in :issue:`32670`.)
* Due to an oversight, earlier Python versions erroneously accepted the
following syntax::
...
...
Lib/test/test_generators.py
Dosyayı görüntüle @
43c47fe0
...
...
@@ -265,26 +265,16 @@ class ExceptionTest(unittest.TestCase):
self
.
assertEqual
(
next
(
g
),
"done"
)
self
.
assertEqual
(
sys
.
exc_info
(),
(
None
,
None
,
None
))
def
test_stopiteration_
warning
(
self
):
def
test_stopiteration_
error
(
self
):
# See also PEP 479.
def
gen
():
raise
StopIteration
yield
with
self
.
assertRaises
(
StopIteration
),
\
self
.
assertWarnsRegex
(
DeprecationWarning
,
"StopIteration"
):
next
(
gen
())
with
self
.
assertRaisesRegex
(
DeprecationWarning
,
"generator .* raised StopIteration"
),
\
warnings
.
catch_warnings
():
warnings
.
simplefilter
(
'error'
)
with
self
.
assertRaisesRegex
(
RuntimeError
,
'raised StopIteration'
):
next
(
gen
())
def
test_tutorial_stopiteration
(
self
):
# Raise StopIteration" stops the generator too:
...
...
@@ -296,13 +286,7 @@ class ExceptionTest(unittest.TestCase):
g
=
f
()
self
.
assertEqual
(
next
(
g
),
1
)
with
self
.
assertWarnsRegex
(
DeprecationWarning
,
"StopIteration"
):
with
self
.
assertRaises
(
StopIteration
):
next
(
g
)
with
self
.
assertRaises
(
StopIteration
):
# This time StopIteration isn't raised from the generator's body,
# hence no warning.
with
self
.
assertRaisesRegex
(
RuntimeError
,
'raised StopIteration'
):
next
(
g
)
def
test_return_tuple
(
self
):
...
...
Lib/test/test_with.py
Dosyayı görüntüle @
43c47fe0
...
...
@@ -458,8 +458,8 @@ class ExceptionalTestCase(ContextmanagerAssertionMixin, unittest.TestCase):
with
cm
():
raise
StopIteration
(
"from with"
)
with
self
.
assert
WarnsRegex
(
DeprecationWarning
,
"StopIteration"
):
s
elf
.
assertRaises
(
StopIteration
,
shouldThrow
)
with
self
.
assert
RaisesRegex
(
StopIteration
,
'from with'
):
s
houldThrow
(
)
def
testRaisedStopIteration2
(
self
):
# From bug 1462485
...
...
@@ -473,7 +473,8 @@ class ExceptionalTestCase(ContextmanagerAssertionMixin, unittest.TestCase):
with
cm
():
raise
StopIteration
(
"from with"
)
self
.
assertRaises
(
StopIteration
,
shouldThrow
)
with
self
.
assertRaisesRegex
(
StopIteration
,
'from with'
):
shouldThrow
()
def
testRaisedStopIteration3
(
self
):
# Another variant where the exception hasn't been instantiated
...
...
@@ -486,8 +487,8 @@ class ExceptionalTestCase(ContextmanagerAssertionMixin, unittest.TestCase):
with
cm
():
raise
next
(
iter
([]))
with
self
.
assert
WarnsRegex
(
DeprecationWarning
,
"StopIteration"
):
s
elf
.
assertRaises
(
StopIteration
,
shouldThrow
)
with
self
.
assert
Raises
(
StopIteration
):
s
houldThrow
(
)
def
testRaisedGeneratorExit1
(
self
):
# From bug 1462485
...
...
Misc/NEWS.d/next/Core and Builtins/2018-01-25-17-03-46.bpo-32670.YsqJUC.rst
0 → 100644
Dosyayı görüntüle @
43c47fe0
Enforce PEP 479 for all code.
This means that manually raising a StopIteration exception from a generator
is prohibited for all code, regardless of whether 'from __future__ import
generator_stop' was used or not.
Objects/genobject.c
Dosyayı görüntüle @
43c47fe0
...
...
@@ -248,59 +248,17 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, int exc, int closing)
Py_CLEAR
(
result
);
}
else
if
(
!
result
&&
PyErr_ExceptionMatches
(
PyExc_StopIteration
))
{
/* Check for __future__ generator_stop and conditionally turn
* a leaking StopIteration into RuntimeError (with its cause
* set appropriately). */
const
int
check_stop_iter_error_flags
=
CO_FUTURE_GENERATOR_STOP
|
CO_COROUTINE
|
CO_ITERABLE_COROUTINE
|
CO_ASYNC_GENERATOR
;
if
(
gen
->
gi_code
!=
NULL
&&
((
PyCodeObject
*
)
gen
->
gi_code
)
->
co_flags
&
check_stop_iter_error_flags
)
{
/* `gen` is either:
* a generator with CO_FUTURE_GENERATOR_STOP flag;
* a coroutine;
* a generator with CO_ITERABLE_COROUTINE flag
(decorated with types.coroutine decorator);
* an async generator.
*/
const
char
*
msg
=
"generator raised StopIteration"
;
if
(
PyCoro_CheckExact
(
gen
))
{
msg
=
"coroutine raised StopIteration"
;
}
else
if
PyAsyncGen_CheckExact
(
gen
)
{
msg
=
"async generator raised StopIteration"
;
}
_PyErr_FormatFromCause
(
PyExc_RuntimeError
,
"%s"
,
msg
);
const
char
*
msg
=
"generator raised StopIteration"
;
if
(
PyCoro_CheckExact
(
gen
))
{
msg
=
"coroutine raised StopIteration"
;
}
else
{
/* `gen` is an ordinary generator without
CO_FUTURE_GENERATOR_STOP flag.
*/
PyObject
*
exc
,
*
val
,
*
tb
;
/* Pop the exception before issuing a warning. */
PyErr_Fetch
(
&
exc
,
&
val
,
&
tb
);
if
(
PyErr_WarnFormat
(
PyExc_DeprecationWarning
,
1
,
"generator '%.50S' raised StopIteration"
,
gen
->
gi_qualname
))
{
/* Warning was converted to an error. */
Py_XDECREF
(
exc
);
Py_XDECREF
(
val
);
Py_XDECREF
(
tb
);
}
else
{
PyErr_Restore
(
exc
,
val
,
tb
);
}
else
if
PyAsyncGen_CheckExact
(
gen
)
{
msg
=
"async generator raised StopIteration"
;
}
_PyErr_FormatFromCause
(
PyExc_RuntimeError
,
"%s"
,
msg
);
}
else
if
(
PyAsyncGen_CheckExact
(
gen
)
&&
!
result
&&
else
if
(
!
result
&&
PyAsyncGen_CheckExact
(
gen
)
&&
PyErr_ExceptionMatches
(
PyExc_StopAsyncIteration
))
{
/* code in `gen` raised a StopAsyncIteration error:
...
...
Python/future.c
Dosyayı görüntüle @
43c47fe0
...
...
@@ -41,7 +41,7 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
}
else
if
(
strcmp
(
feature
,
FUTURE_BARRY_AS_BDFL
)
==
0
)
{
ff
->
ff_features
|=
CO_FUTURE_BARRY_AS_BDFL
;
}
else
if
(
strcmp
(
feature
,
FUTURE_GENERATOR_STOP
)
==
0
)
{
ff
->
ff_features
|=
CO_FUTURE_GENERATOR_STOP
;
continue
;
}
else
if
(
strcmp
(
feature
,
FUTURE_ANNOTATIONS
)
==
0
)
{
ff
->
ff_features
|=
CO_FUTURE_ANNOTATIONS
;
}
else
if
(
strcmp
(
feature
,
"braces"
)
==
0
)
{
...
...
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