This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Named widget has NoneType after single line creation
Type: behavior Stage: resolved
Components: Tkinter Versions: Python 3.9
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: rcrosser, steven.daprano
Priority: normal Keywords:

Created on 2021-08-21 14:55 by rcrosser, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
test_pack.py rcrosser, 2021-08-21 14:55 python code. Works with the top 3 buttons, crashes with the lower 3 buttons.
Messages (2)
msg400032 - (view) Author: Russell Crosser (rcrosser) Date: 2021-08-21 14:55
Declaring a widget in the following form:
...
label2 = ttk.Label(root, text='Show2 Label').pack()
...
leaves the widget with a NoneType, and unable to be assigned to (for instance to assign new text). If giving a widget a name, I expect to use it later in the program.
This declaration works correctly:
...
label2 = ttk.Label(root, text='Show2 Label')
label2.pack()
...
Simple tkinter program attached. Only tested with 3.9.6 on Win 10.
msg400034 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2021-08-21 16:00
I'm sorry if you don't like the design of the pack() method, but all the examples in the documentation show how it behaves. It is behaving as documented and designed.

https://docs.python.org/3/library/tkinter.html


The bug here is in your own code. You already know the correct way to write this, as you already stated:

    label2 = ttk.Label(root, text='Show2 Label')
    label2.pack()

Writing it as ttk.Label(root, text='Show2 Label').pack() returns None, as designed, which then consequently fails when you try to operate on None.

You say:

"If giving a widget a name, I expect to use it later in the program."

But you don't give the widget a name. What you are doing is the equivalent of this:

    temp = ttk.Label(root, text='Show2 Label')  # hidden temp object
    label = temp.pack()  # Returns None
    del temp  # hidden temp object is garbage collected

except that `temp` is never directly accessible by you.

Or if you prefer another analogy:

    number = (1 + 2) - 3

and then get surprised that number is zero rather than 3 because "I gave (1+2) a name". No, you gave a name to the *whole expression*, which evaluates to 0, not 3. And in the Label case, the *whole expression* evaluates to None.

Also, the code doesn't crash. It raises an exception, which is the expected behaviour for trying to access non-existent attributes.
History
Date User Action Args
2022-04-11 14:59:49adminsetgithub: 89134
2021-08-21 16:00:34steven.dapranosetstatus: open -> closed

type: crash -> behavior

nosy: + steven.daprano
messages: + msg400034
resolution: not a bug
stage: resolved
2021-08-21 14:55:34rcrossercreate