On Fri, Aug 21, 2020 at 09:35:14AM -0000, Gustav O wrote:

> If a file named "tkinter.py" is created and tkinter is imported and used 
> within the file, the following exception is raised:
> "AttributeError: partially initialized module 'tkinter' has no attribute 'Tk' 
> (most likely due to a circular import)"
> 

> I've spoken to multiple beginners who got stuck on this and just 
> couldn't figure out what was happening.

Alas, I think that this is an error that won't be obvious to a 
beginner no matter how we word it.

* It's unusual enough that googling for the error message comes up with 
lots of false positives and few correct hits.

(I couldn't find anything relevant in the first half dozen results when 
using DuckDuckGo, although Google's first result gave the correct 
solution but the wrong error message!)

* The concept of a "partially initialized module" requires a pretty 
sophisticated understanding of the difference between a module "spam.py" 
as a source file and a module `spam` initialised in memory.

* It requires an understanding of circular imports and how they can go 
wrong.

It's also tricky to word the error message in a way that leads beginners 
to a solution without hiding information or being misleading in other 
cases. The *actual error* here is that the imported module tkinter 
doesn't have a Tk attribute -- everything else is a guess as to what the 
problem *might* be:

- a module importing itself is not necessarily wrong;

- not all circular imports are modules importing themselves;

- loading a partially imported module is a normal consequence of 
  circular imports;

- a module not containing an attribute doesn't necessarily mean you have 
  shadowed the real module, it might just mean a typo or bug in your 
  code.


The other factor is that *beginners don't read error messages*.

Obviously there are exceptions, but beginners tend to be really, really 
bad at reading error messages even when the messages are clear, succint, 
to the point, and tell them exactly what is wrong. So I'm reluctant to 
spend to much time or energy trying to craft the perfect error message 
to help beginners given that the ones who most need the help are the 
least likely to read it.

Debugging code is a skill and there really is no substitute for time and 
experience to learn it. One of those lessons is first to learn that you 
must read the error message and second how to interpret it.

Having said all that, I cannot help but feel that shadowing of modules 
is such an issue that maybe we need to make a special case of this. Not 
specifically tkinter, of course, but if a module attempts to directly 
import a module with the same name, and that import fails for any 
reason, we should include a message about shadowing in addition to the 
normal exception traceback.


> I think the following would be an option:
> "ImportError: partially initialized module 'tkinter' can't import itself"

That's a regression. In this specific case it doesn't matter because you 
know that the error actually is shadowing (the user named their own file 
"tkinter.py") but in the general case we lose the information of what 
name was being looked up:

AttributeError: partially initialized module 'spam' has no attribute 
'egsg' (most likely due to a circular import)

If the error wasn't due to shadowing or a circular import, then knowing 
that I had misspelled 'eggs' would be very useful.


-- 
Steve
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/OY66Y2LDUOMPWLAT37NW55Y4HS3X3TU3/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to