Repository navigation
make function __closure__ writable #58577
Copy link
Copy link
Open
Labels
3.15bugs and security fixesbugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)triagedThe issue has been accepted as valid by a triager.The issue has been accepted as valid by a triager.type-featureA feature request or enhancementA feature request or enhancement
Description
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = None
created_at = <Date 2012-03-19.17:51:16.433>
labels = ['interpreter-core', 'type-feature', '3.7']
title = 'make function __closure__ writable'
updated_at = <Date 2022-03-28.16:35:30.895>
user = 'https://bugs.python.org/YurySelivanov'bugs.python.org fields:
activity = <Date 2022-03-28.16:35:30.895>
actor = 'vstinner'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2012-03-19.17:51:16.433>
creator = 'Yury.Selivanov'
dependencies = []
files = ['24946', '24947', '24962', '24975', '25363']
hgrepos = []
issue_num = 14369
keywords = ['patch']
message_count = 14.0
messages = ['156350', '156357', '156404', '156412', '156452', '159117', '159182', '159235', '159238', '159287', '159519', '304056', '304106', '304199']
nosy_count = 10.0
nosy_names = ['rhettinger', 'ncoghlan', 'pitrou', 'benjamin.peterson', 'asvetlov', 'meador.inge', 'Yury.Selivanov', 'sbt', 'eric.snow', 'akvadrako']
pr_nums = []
priority = 'normal'
resolution = None
stage = 'patch review'
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue14369'
versions = ['Python 3.7']Linked PRs
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
3.15bugs and security fixesbugs and security fixesinterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)triagedThe issue has been accepted as valid by a triager.The issue has been accepted as valid by a triager.type-featureA feature request or enhancementA feature request or enhancement
Activity
YurySelivanov commentedon Mar 19, 2012
__code__ and __closure__ are designed to work together. There is no point in allowing to completely substitute the __code__ object, but protecting the __closure__.
YurySelivanov commentedon Mar 19, 2012
Updated patch as per Andrew's code review. Thank you.
asvetlov commentedon Mar 20, 2012
Please update the doc also. I think changing from 'Read-only' to 'Writable' in Doc/reference/datamodel.rst is enough.
YurySelivanov commentedon Mar 20, 2012
Updated in writable_closure_03.patch. Thanks.
YurySelivanov commentedon Mar 20, 2012
Updated patch per Benjamin's review. See writable_closure_04.patch.
ncoghlan commentedon Apr 24, 2012
Another use case for a writeable __closure__ attribute is to make it possible to manually break reference cycles:
http://blog.ccpgames.com/kristjan/2012/04/23/reference-cycles-with-closures/
sbt commentedon Apr 24, 2012
Shouldn't test___closure__() also test what happens when the closure is replaced with None, or a tuple which is too long or too short or contains non-cell objects?
All of these things seem to be checked when you create a new function using types.FunctionType:
I think the setter should make similar checks. Maybe there is C code which assumes "broken" closures never happen.
sbt commentedon Apr 24, 2012
The patch causes crashes. If I define
then I find
YurySelivanov commentedon Apr 24, 2012
Yes, that's known.
First, we need to check, that we can only write tuple of cell objects or None in __closure__ (that's easy to add). Secondly, perhaps, we can check __closure__ correctness each time we start evaluating a code object. The latter would offer us better stability, but may also introduce some slowdowns -- need to find some time to implement and benchmark this.
sbt commentedon Apr 25, 2012
Version of patch which checks invariants in the setter and adds tests.
asvetlov commentedon Apr 28, 2012
sbt, looks good for me.
akvadrako commentedon Oct 10, 2017
Any updates on this? I'm trying to implement hot module reloading using code from IPython, which tries to modify __closure__ in place. It fails silently and doesn't work, but indeed would be nice to have.
ncoghlan commentedon Oct 11, 2017
This still seems like a reasonable enhancement, but would presumably need updates to apply against the 3.7 development branch.
ncoghlan commentedon Oct 12, 2017
Thinking about the interaction between this idea and https://bugs.python.org/issue30744 made me realise that there's a subtlety here that would probably need to be spelled out more clearly in the docs for __closure__ than it is for __code__: any changes made to a function object (whether it's a synchronous function, a generator, or a coroutine) will only affect *future* function invocations, as execution frames capture references to both the code object and all the closure cells when they're created.
(Thought prompted by asking myself "What would happen to existing generator-iterators if you rebound the closure on the generator function?". The answer is "Nothing", but I figure if I had to think about it, that answer likely isn't going to be obvious to folks that are less familiar with how the eval loop works in practice)
[-]make __closure__ writable[/-][+]make function __closure__ writable[/+]