GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — NameError assigning to class in a func · Issue #36300 · python/cpython

NameError assigning to class in a func #36300

New issue
Copy link
New issue
Copy link
Closed
Closed
NameError assigning to class in a func#36300
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)

Description

spiv
mannequin
opened on Mar 21, 2002
Issue body actions
BPO 532860

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 = <Date 2002-04-22.18:43:12.000>
created_at = <Date 2002-03-21.01:27:24.000>
labels = ['interpreter-core']
title = 'NameError assigning to class in a func'
updated_at = <Date 2002-04-22.18:43:12.000>
user = 'https://bugs.python.org/spiv'

bugs.python.org fields:

activity = <Date 2002-04-22.18:43:12.000>
actor = 'jhylton'
assignee = 'jhylton'
closed = True
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2002-03-21.01:27:24.000>
creator = 'spiv'
dependencies = []
files = []
hgrepos = []
issue_num = 532860
keywords = []
message_count = 5.0
messages = ['9853', '9854', '9855', '9856', '9857']
nosy_count = 2.0
nosy_names = ['jhylton', 'spiv']
pr_nums = []
priority = 'normal'
resolution = 'wont fix'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue532860'
versions = ['Python 2.2']

Activity

  1. spiv commented on Mar 21, 2002

    @spiv
    spivmannequin
    on Mar 21, 2002
    MannequinAuthor
    More actions

    This fails with a NameError:

    def f(x)
        class Private:
            x = x
        return Private
    f(17)

    But this works:

    def f(x):
        y = x
        class Private:
            x = y
        return Private
    f(17)

    But this fails:

    def f(x):
        y = x
        class Private:
            y = y
        return Private
    f(17)

    See also the newsgroup thread:
    http://groups.google.com/groups?hl=en&ie=ISO-8859-1&oe=ISO-8859-1&threadm=Xns

    (All tested on Python 2.2 on Win2k)

  2. spiv
    closed this as completedon Mar 21, 2002
  3. spiv
    assigned
    jhylton
    on Mar 21, 2002
  4. spiv
    added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    on Mar 21, 2002
  5. spiv
    closed this as completedon Mar 21, 2002
  6. spiv
    assigned
    jhylton
    on Mar 21, 2002
  7. spiv
    added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    on Mar 21, 2002
  8. jhylton commented on Apr 19, 2002

    @jhylton
    jhyltonmannequin
    on Apr 19, 2002
    Mannequin
    More actions

    Logged In: YES
    user_id=31392

    This is actually working as intended, although the reference
    manual no longer describes this case at all. It has been a
    long standing "feature" of Python that module and class
    blocks use the LOAD_NAME opcode, which has weird scoping
    rules.

    The documentation should be updated to describe the cases in
    which LOAD_NAME is used and its behavior. (It checks
    locals, globals, builtins in that order, and never raises a
    NameError unless the name isn't found in any of those
    namespaces. In particular, an unbound local is simply
    ignored.)

    I don't actually know what these rules are used. Guido--
    should we get rid of LOAD_NAME?

  9. spiv commented on Apr 22, 2002

    @spiv
    spivmannequin
    on Apr 22, 2002
    MannequinAuthor
    More actions

    Logged In: YES
    user_id=50945

    Apologies for re-opening the bug.

    This behaviour still seems like a bug to me, because while
    this dies:

    >>> def f(x):
    ...     class Private:
    ...         x = x
    ...     return Private
    ... 
    >>> f(17)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 2, in f
      File "<stdin>", line 3, in Private
    NameError: name 'x' is not defined

    This works:

    >>> x = 1 
    >>> class C:
    ...     x = x
    ... 
    >>> C()
    <__main__.C instance at 0x806aeac>

    Actually, having the global "x = 1" also makes the first
    case work.

    This seems inconsistent enough to me to warrant it being
    called a bug, regardless of the underlying implementation
    details (which I know little of). I'd expect it work in
    both cases, or neither case.

    Feel free to close the bug again if you disagree :)

    It's quite easy to work around, so I'm not worried greatly
    by it.
    (workaround:
    def f(x):
    class Private:
    pass
    Private.x = x
    return Private
    )

  10. jhylton commented on Apr 22, 2002

    @jhylton
    jhyltonmannequin
    on Apr 22, 2002
    Mannequin
    More actions

    Logged In: YES
    user_id=31392

    The behavior bugs me too, but I don't expect it will get
    fixed because of the need for backwards compatibility. The
    local namespace for classes, modules, and functions that
    contain exec or import * are searched using the LOAD_NAME
    opcode. This opcode implements the old locals, globals,
    builtin search for a name using dict lookup. If the dict
    lookup fails at any level, the next level up is searched.
    This means an unbound local error will never occur in a
    class block, because the dict lookup just returns NULL and
    the search proceeds to globals.

    If anything, the bug is the was "x=x" behaves at the class
    level, but I'm loathe to change it. It will probably break
    existing code and will require substantial implementation
    effort (I think) because class namespaces aren't
    implemented using the same technique as a function
    namespace.

    I'd rather document the existing wart and live with it. In
    particular, I might document it with the following weasle
    words: "The result of reference an unbound local name in a
    class block is undefined."

  11. jhylton commented on Apr 22, 2002

    @jhylton
    jhyltonmannequin
    on Apr 22, 2002
    Mannequin
    More actions

    Logged In: YES
    user_id=31392

    Indeed, after conversation with GvR, we are in agreement
    that it would break too much old code to "fix" this. Just
    don't write code that abuses the wart at the module level,
    and you'll never feel its a bug when nested inside a
    function <0.1 wink>.

  12. ezio-melotti
    transferred this issue fromon Apr 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.