diff options
author | Lisa Roach <lisaroach14@gmail.com> | 2017-06-08 11:43:26 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2017-06-08 11:43:26 (GMT) |
commit | 64505a1f6c0af4574e17e823b27ffe24eca44df5 (patch) | |
tree | d2b40e19b44e4ab50f92440a54facc59038da4b3 | |
parent | 6cca5c8459cc439cb050010ffa762a03859d3051 (diff) | |
download | cpython-64505a1f6c0af4574e17e823b27ffe24eca44df5.zip cpython-64505a1f6c0af4574e17e823b27ffe24eca44df5.tar.gz cpython-64505a1f6c0af4574e17e823b27ffe24eca44df5.tar.bz2 |
bpo-30486: Allow setting cell value (#1840)
The cell_contents attribute of the cell object is now writable.
-rw-r--r-- | Doc/reference/datamodel.rst | 6 | ||||
-rw-r--r-- | Lib/test/test_funcattrs.py | 20 | ||||
-rw-r--r-- | Misc/NEWS | 8 | ||||
-rw-r--r-- | Objects/cellobject.c | 11 |
4 files changed, 41 insertions, 4 deletions
diff --git a/Doc/reference/datamodel.rst b/Doc/reference/datamodel.rst index 9708688..24a2618 100644 --- a/Doc/reference/datamodel.rst +++ b/Doc/reference/datamodel.rst @@ -510,6 +510,9 @@ Callable types | :attr:`__closure__` | ``None`` or a tuple of cells | Read-only | | | that contain bindings for the | | | | function's free variables. | | + | | See below for information on | | + | | the ``cell_contents`` | | + | | attribute. | | +-------------------------+-------------------------------+-----------+ | :attr:`__annotations__` | A dict containing annotations | Writable | | | of parameters. The keys of | | @@ -530,6 +533,9 @@ Callable types implementation only supports function attributes on user-defined functions. Function attributes on built-in functions may be supported in the future.* + A cell object has the attribute ``cell_contents``. This can be used to get + the value of the cell, as well as set the value. + Additional information about a function's definition can be retrieved from its code object; see the description of internal types below. diff --git a/Lib/test/test_funcattrs.py b/Lib/test/test_funcattrs.py index 8f481bb..35fd657 100644 --- a/Lib/test/test_funcattrs.py +++ b/Lib/test/test_funcattrs.py @@ -93,6 +93,26 @@ class FunctionPropertiesTest(FuncAttrsTest): self.fail("shouldn't be able to read an empty cell") a = 12 + def test_set_cell(self): + a = 12 + def f(): return a + c = f.__closure__ + c[0].cell_contents = 9 + self.assertEqual(c[0].cell_contents, 9) + self.assertEqual(f(), 9) + self.assertEqual(a, 9) + del c[0].cell_contents + try: + c[0].cell_contents + except ValueError: + pass + else: + self.fail("shouldn't be able to read an empty cell") + with self.assertRaises(NameError): + f() + with self.assertRaises(UnboundLocalError): + print(a) + def test___name__(self): self.assertEqual(self.b.__name__, 'b') self.b.__name__ = 'c' @@ -10,6 +10,11 @@ What's New in Python 3.7.0 alpha 1? Core and Builtins ----------------- +- bpo-30486: Allows setting cell values for __closure__. Patch by Lisa Roach. + +- bpo-30537: itertools.islice now accepts integer-like objects (having + an __index__ method) as start, stop, and slice arguments + - bpo-25324: Tokens needed for parsing in Python moved to C. ``COMMENT``, ``NL`` and ``ENCODING``. This way the tokens and tok_names in the token module don't get changed when you import the tokenize module. @@ -128,9 +133,6 @@ Core and Builtins - bpo-29546: Improve from-import error message with location -- bpo-30537: itertools.islice now accepts integer-like objects (having - an __index__ method) as start, stop, and slice arguments - - Issue #29319: Prevent RunMainFromImporter overwriting sys.path[0]. - Issue #29337: Fixed possible BytesWarning when compare the code objects. diff --git a/Objects/cellobject.c b/Objects/cellobject.c index 9f4eddb..6af93b0 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -140,8 +140,17 @@ cell_get_contents(PyCellObject *op, void *closure) return op->ob_ref; } +int +cell_set_contents(PyCellObject *op, PyObject *obj) +{ + Py_XINCREF(obj); + Py_XSETREF(op->ob_ref, obj); + return 0; +} + static PyGetSetDef cell_getsetlist[] = { - {"cell_contents", (getter)cell_get_contents, NULL}, + {"cell_contents", (getter)cell_get_contents, + (setter)cell_set_contents, NULL}, {NULL} /* sentinel */ }; |