bastianraschke / pyfingerprint

Python library for ZhianTec fingerprint sensors (e.g. ZFM-20, ZFM-60)
Other
190 stars 115 forks source link

Examples sometimes exit with TypeError: 'NoneType' object is not callable #111

Open avian2 opened 4 years ago

avian2 commented 4 years ago

The following error happens intermittently on my system (Linux). It has also been reported in https://github.com/bastianraschke/pyfingerprint/issues/57#issuecomment-453005626:

$ python3 --version
Python 3.5.3
$ python3 example_search.py 
Currently used templates: 1/3000
Waiting for finger...
No match found!
Exception ignored in: <bound method PyFingerprint.__del__ of <pyfingerprint.pyfingerprint.PyFingerprint object at 0x7f802b56a5f8>>
Traceback (most recent call last):
  File ".../pyfingerprint/src/files/pyfingerprint/pyfingerprint.py", line 180, in __del__
  File ".../pyfingerprint/src/venv/lib/python3.5/site-packages/serial/serialposix.py", line 451, in close
TypeError: 'NoneType' object is not callable

I believe this is caused by the fact that PyFingerprint object calls serial.close() from its __del__ method.

It is generally not safe to close files in __del__. If the object is destroyed during interpreter shutdown, the order of global object destruction isn't guaranteed 1. In the case above with example_search.py this happens because the example calls exit() while PyFingerprint object still exists. serial.close() called from __del__ in term tries to call functions from os module, which have already been destroyed at that point in time and point to None. The error is intermittent because exact order of object destruction varies between runs.

I'm not sure if this can be solved without changing the library interface. General practice in Python is to use with statement for managing resources 2 3, but that would require a major change.

So far it also seems to me that for most uses this is only a cosmetic error. Exceptions in __del__ are ignored. If a device file isn't getting closed in interpreter destruction it will be closed by OS anyway after the process exits (at least on Linux).

bastianraschke commented 4 years ago

Thanks for your hint. We will check it out for the next release.