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: Exception AttributeError: "'NoneType'.... thrown on exit
Type: behavior Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Terry Garyet, r.david.murray
Priority: normal Keywords:

Created on 2015-11-13 19:08 by Terry Garyet, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
bug.py Terry Garyet, 2015-11-13 19:08 code to show problem
Messages (5)
msg254612 - (view) Author: terry (Terry Garyet) Date: 2015-11-13 19:08
The attached code generates this output:

init called
finished init
init called
finished init
init called
finished init
initPorts done
alldone
destroying /sys/class/gpio/gpio16/
destroying /sys/class/gpio/gpio6/
Exception AttributeError: "'NoneType' object has no attribute 'path'" in <bound method sysfsGpio.__del__ of <__main__.sysfsGpio instance at 0xb6c90e68>> ignored
destroying /sys/class/gpio/gpio13/
Exception AttributeError: "'NoneType' object has no attribute 'path'" in <bound method sysfsGpio.__del__ of <__main__.sysfsGpio instance at 0xb6c90e40>> ignored

It is necessary to have two functions defined (railVarRes() and batleveltopct()) and further more changing the name of railVarRes to arailVarRes changes the behavior:


init called
finished init
init called
finished init
init called
finished init
initPorts done
alldone
destroying /sys/class/gpio/gpio16/
destroying /sys/class/gpio/gpio13/
destroying /sys/class/gpio/gpio6/
Exception AttributeError: "'NoneType' object has no attribute 'path'" in <bound method sysfsGpio.__del__ of <__main__.sysfsGpio instance at 0xb6c10e68>> ignored


notice that the order of the class destruction has changed.
msg254616 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-11-13 19:41
Yes, python2 shutdown has this problem: modules and their attributes are set to None during interpreter shutdown.  Things are much better in python3.  If you want to avoid the error messages, finalize the objects explicitly (making sure to break gc cycles) before the end of your program, or keep explicit references to the objects you need during __del__ (eg: os_path = os.path in the global scope of your module).

As for your last comment, you are correct, the GC cleanup order is not deterministic.
msg254617 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-11-13 19:42
Best practice, by the way, is to be explicit about the scope of any resource and clean it up before program end...this is often done by using the context manager protocol.
msg254642 - (view) Author: terry (Terry Garyet) Date: 2015-11-14 04:24
My real application (not this example code that also 'breaks') is a battery monitor that starts at boot time and only exits when the battery is near death. 

So there is effectively a while(batlevelgood) loop that polls the battery level and doesn't exit until  near battery death.

I only encounters this while debugging and having to kill (ctrl-c) the script, having no chance to clean up properly.

Admittedly I'm not very experienced in Python but I am an experienced programmer.  I will look up context mgr protocol, but this was certainly odd behavior.  It isn't every day that the name of a  function not even called changes observed program behavior.

Terry

> On Nov 13, 2015, at 1:42 PM, R. David Murray <report@bugs.python.org> wrote:
> 
> 
> R. David Murray added the comment:
> 
> Best practice, by the way, is to be explicit about the scope of any resource and clean it up before program end...this is often done by using the context manager protocol.
> 
> ----------
> 
> _______________________________________
> Python tracker <report@bugs.python.org>
> <http://bugs.python.org/issue25619>
> _______________________________________
msg254669 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2015-11-14 20:00
Yes, well, that is part of the fragility of python2's shutdown garbage collection, and one of the reasons it got improved.  Changing the name of a function can change the order things get retrieved from various internal dictionaries, because they are hash tables.
History
Date User Action Args
2022-04-11 14:58:23adminsetgithub: 69805
2015-11-14 20:00:46r.david.murraysetmessages: + msg254669
2015-11-14 04:24:29Terry Garyetsetmessages: + msg254642
title: Exception AttributeError: "'NoneType'.... thrown on exit -> Exception AttributeError: "'NoneType'.... thrown on exit
2015-11-13 19:42:48r.david.murraysetmessages: + msg254617
2015-11-13 19:41:26r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg254616

resolution: not a bug
stage: resolved
2015-11-13 19:08:03Terry Garyetcreate