Skip to content

Commit

Permalink
Catch AttributeError in utils.super_len (psf#5239)
Browse files Browse the repository at this point in the history
* Catch AttributeError in utils.super_len

This allows it to handle files obtained via `Tarfile.extractfile()`.
  • Loading branch information
dimbleby authored and nateprewitt committed Nov 28, 2021
1 parent e77dd8d commit 2d2447e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
7 changes: 5 additions & 2 deletions HISTORY.md
Expand Up @@ -11,6 +11,9 @@ dev
backwards compatible as it inherits from previously thrown exceptions.
Can be caught from `requests.exceptions.RequestException` as well.

- Catch `AttributeError` when calculating length of files obtained by
`Tarfile.extractfile()`

2.26.0 (2021-07-13)
-------------------

Expand Down Expand Up @@ -1702,7 +1705,7 @@ This is not a backwards compatible change.
- Automatic Authentication API Change
- Smarter Query URL Parameterization
- Allow file uploads and POST data together
-
-

New Authentication Manager System

Expand All @@ -1721,7 +1724,7 @@ This is not a backwards compatible change.
0.2.3 (2011-02-15)
------------------

-
-

New HTTPHandling Methods

Expand Down
5 changes: 4 additions & 1 deletion requests/utils.py
Expand Up @@ -124,7 +124,10 @@ def super_len(o):
elif hasattr(o, 'fileno'):
try:
fileno = o.fileno()
except io.UnsupportedOperation:
except (io.UnsupportedOperation, AttributeError):
# AttributeError is a surprising exception, seeing as how we've just checked
# that `hasattr(o, 'fileno')`. It happens for objects obtained via
# `Tarfile.extractfile()`, per issue 5229.
pass
else:
total_length = os.fstat(fileno).st_size
Expand Down
13 changes: 13 additions & 0 deletions tests/test_utils.py
Expand Up @@ -4,6 +4,7 @@
import copy
import filecmp
from io import BytesIO
import tarfile
import zipfile
from collections import deque

Expand Down Expand Up @@ -86,6 +87,18 @@ def test_file(self, tmpdir, mode, warnings_num, recwarn):
assert super_len(fd) == 4
assert len(recwarn) == warnings_num

def test_tarfile_member(self, tmpdir):
file_obj = tmpdir.join('test.txt')
file_obj.write('Test')

tar_obj = str(tmpdir.join('test.tar'))
with tarfile.open(tar_obj, 'w') as tar:
tar.add(str(file_obj), arcname='test.txt')

with tarfile.open(tar_obj) as tar:
member = tar.extractfile('test.txt')
assert super_len(member) == 4

def test_super_len_with__len__(self):
foo = [1,2,3,4]
len_foo = super_len(foo)
Expand Down

0 comments on commit 2d2447e

Please sign in to comment.