Skip to content

Commit

Permalink
Merge pull request #41 from bukzor/buck-less-deadlock
Browse files Browse the repository at this point in the history
avoid infinite regress in __getattr__
  • Loading branch information
ionrock committed Sep 17, 2014
2 parents 1c83d6c + 7534ba4 commit 042ae8c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
6 changes: 5 additions & 1 deletion cachecontrol/filewrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ def __init__(self, fp, callback):
self.__callback = callback

def __getattr__(self, name):
return getattr(self.__fp, name)
# The vaguaries of garbage collection means that self.__fp is not always set.
# This strange style lets us throw AttributeError in that case, rather than
# recursing infinitely
fp = self.__getattribute__('_CallbackFileWrapper__fp')
return getattr(fp, name)

def __is_fp_closed(self):
try:
Expand Down
13 changes: 13 additions & 0 deletions tests/test_regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from cachecontrol import CacheControl
from cachecontrol.caches.file_cache import FileCache
from cachecontrol.filewrapper import CallbackFileWrapper
from requests import Session


Expand All @@ -16,3 +17,15 @@ def test_file_cache_recognizes_consumed_file_handle(self):
s.get('http://httpbin.org/cache/60')
r = s.get('http://httpbin.org/cache/60')
assert r.from_cache


def test_getattr_during_gc():
s = CallbackFileWrapper(None, None)
# normal behavior:
with pytest.raises(AttributeError):
s.x

# this previously had caused an infinite recursion
vars(s).clear() # gc does this.
with pytest.raises(AttributeError):
s.x

0 comments on commit 042ae8c

Please sign in to comment.