summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLisa Roach <lisaroach14@gmail.com>2017-06-08 11:43:26 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2017-06-08 11:43:26 (GMT)
commit64505a1f6c0af4574e17e823b27ffe24eca44df5 (patch)
treed2b40e19b44e4ab50f92440a54facc59038da4b3
parent6cca5c8459cc439cb050010ffa762a03859d3051 (diff)
downloadcpython-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.rst6
-rw-r--r--Lib/test/test_funcattrs.py20
-rw-r--r--Misc/NEWS8
-rw-r--r--Objects/cellobject.c11
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'
diff --git a/Misc/NEWS b/Misc/NEWS
index 0bc33bb..29c0005 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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 */
};