Questions about `locals` builtin

Dan Stromberg drsalists at gmail.com
Mon Feb 26 20:05:46 EST 2018


On Mon, Feb 26, 2018 at 4:25 PM, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> On Mon, 26 Feb 2018 21:55:35 +0300, Kirill Balunov wrote:
>> 2. The documentation has a note that "The contents of this dictionary
>> should not be modified". Which implies that it is a read only mapping.
>> So the question why it is `dict` instead of `types.MappingProxyType`?
>
> Mostly because locals() predates MappingProxyType by many years, and also
> because that restriction doesn't apply to other implementations of Python
> such as Jython and IronPython.
>
> In CPython, the dict returned by locals() is a copy of the local
> namespace, so modifying the dict doesn't modify the real local variables.
>
> (Well, sometimes it does, but not always. The story in Python 2 is really
> complex.)
>
> But in Jython and IronPython, it actually is the namespace, so writing to
> it works like writing to globals.
>
> So writing to locals *sometimes* works, and cannot be prohibited
> outright, but if you want portable code, you have to avoid it.

I find this interesting.

So I decided to write a little test program, to see it first hand.

I don't have IronPython handy, but according my (quite possibly
flawed) test program, locals() is a copy on CPython 3, CPython 2,
Pypy3, Pypy, Jython and MicroPython.

I didn't see any interpreters that returned the namespace itself.

What am I missing?

Here's the test program.  Perhaps there's something wrong in it?

#!/usr/local/cpython-3.6/bin/python3

"""Test whether locals() is a copy of the local namespace, or a reference."""

import sys


def main():
    """Run the test."""
    var = 1

    locs = locals()
    locs['var'] = 2

    if var == 2:
        sys.stdout.write('locals not just a copy\n')
    else:
        sys.stdout.write('locals is just a copy\n')


main()



More information about the Python-list mailing list