Whoops. I totally misread that! My brain unhelpfully supplied string quotes in the return statement of the `eggs` methods, rather than parsing them as function calls. ...for some reason I could not explain to you.

Maybe I've grown too dependent on syntax highlighting!

I see what Steven meant now. Ignore what I typed earlier, then.

To be honest, I do completely agree. I think the most useful and least surprising implementation would be to give the namespace block its own temporary scope (with outer names still available), and then only at the end of the block just before the scope is destroyed do any names bound to it get set on the parent scope.

So:

def spam():
    return "spam spam spam!"


def eggs():
    return spam()


namespace Shop:
    old_spam = spam  # No NameError, the `spam` from module scope is still accessible here if we want it!

    def spam():
        return "There's not much call for spam here."

    new_spam = spam  # this now refers to the function defined immediately above

    def eggs():
        return spam()  # this refers to the same object as `new_spam`, not the `spam` from globals()

    # at this point globals()['Shop.spam'] would still raise a NameError. It doesn't exist yet!

    namespace Shelf:
        this_is_shop_spam = spam  # However, we can access it from inside another nested namespace as a simple name. The scoping rules on nested classes would not allow this!

# at this point globals()['Shop.spam'] exists!

Sorry Steven! I totally misunderstood your example. It was a really good point. Thanks :)




On Wed, May 5, 2021 at 12:06 PM Paul Moore <p.f.moore@gmail.com> wrote:
On Wed, 5 May 2021 at 11:33, Matt del Valle <matthewgdv@gmail.com> wrote:

>> To give an example:
>>
>>     def spam():
>>         return "spam spam spam!"
>>
>>     def eggs():
>>         return spam()
>>
>>     namespace Shop:
>>         def spam():
>>             return "There's not much call for spam here."
>>         def eggs():
>>             return spam()
>>
>>     print(eggs())
>>     # should print "spam spam spam!"
>>     print(Shop.eggs())
>>     # should print "There's not much call for spam here."
>
>
> I'm guessing this was a typo and you meant to type:
>
>     print(spam())
>     # should print "spam spam spam!"
>     print(Shop.spam())
>     # should print "There's not much call for spam here."
>
> Because if you did, then this is precisely how it would work under this proposal. :)

I'm not the OP, but I read their question precisely as it was written.
The global eggs() returns the value from calling spam() and should use
the *global* spam. The eggs in namespace Shop calls spam and returns
its value, and I'd expect that call to resolve to Shop.spam, using the
namespace eggs is defined in. If that's not how you imagine namespaces
working, I think they are going to be quite non-intuitive for at least
a certain set of users (including me...)

Paul