Repository navigation
raise AttributeError if loading fails in ctypes.LibraryLoader.__getattr__ #78997
Description
Activity
The following creates an OSError:
import ctypes hasattr(ctypes.windll, 'test')
The expected behavior would be to return "False"
- added3.7 (EOL)end of lifeend of lifetype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
on Sep 27, 2018 ctypes.windll is an instance of ctypes.LibraryLoader, which has a __getattr__ method that calls ctypes.WinDLL(name) and caches the result as an instance attribute. I suppose with chained exceptions it's reasonable to handle OSError in __getattr__ by raising AttributeError. For example:
class A: def __init__(self, name): raise OSError class B: def __getattr__(self, name): try: A(name) except OSError: raise AttributeError
Demo:
>>> b = B() >>> b.test Traceback (most recent call last): File "<stdin>", line 4, in __getattr__ File "<stdin>", line 3, in __init__ OSError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in __getattr__ AttributeError >>> hasattr(b, 'test') FalseFYI, I recommend avoiding the cdll and windll LibraryLoader instances. I wish they were deprecated because globally caching CDLL and WinDLL instances leads to conflicts between projects that use the same shared libraries.
Thank you for your reply.
I am not sure if I understood correctly:
Do you suggest to modify ctypes.__init__.py so that the __getattr__ method of LibraryLoader catches the OSError and raises an AttributeError instead, as in your example?__getattr__ method of LibraryLoader catches the OSError and
raises an AttributeErrorYes. It seems no one was keen to work on this. I think it's relatively easy, so I'll add that flag in case someone is looking for an easy issue.
- added3.9 (EOL)end of lifeend of life3.10 (EOL)end of lifeend of lifeand removed3.7 (EOL)end of lifeend of life
on Mar 28, 2021 - changed the title
[-]ctypes + hasattr[/-][+]raise AttributeError if loading fails in ctypes.LibraryLoader.__getattr__[/+]on Mar 28, 2021 First patch fixing only the issue at hand on master. LibraryLoader now catches OSError for FileNotFoundError and raises AttributeError.
- added a commit that references this issue
on Dec 15, 2022 - added a commit that references this issue
on Dec 16, 2022 - added a commit that references this issue
on Dec 22, 2022 - added a commit that references this issue
on Dec 28, 2022 Thanks, looks like this was fixed!
For the record, why was a backwards incompatible change made in just a point release without any deprecation warnings? We can work around this change from throwing OSError to AttrbteError in cdll but why on earth was this change added in a minor release?
This change was really communicated badly in the windows section of the changelog:
[bpo-34816](https://bugs.python.org/issue?@action=redirect&bpo=34816): hasattr(ctypes.windll, 'nonexistant') now returns False instead of raising [OSError](https://docs.python.org/3/library/exceptions.html#OSError).
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:
bugs.python.org fields:
Linked PRs