Repository: h2non/filetype.py

Issue:
"1.0.13" --> "1.1.0" regression. `filetype.guess` stopped working with output from `read(file_path, "rb")`
## Reproducible code sample
```python
import filetype

photo_path = "image.jpeg"

with open(str(photo_path), "rb") as photo_object:
    result = filetype.guess(photo_object)
```
## "1.0.13" result

All works as expected:
```
<filetype.types.image.Jpeg object at 0x7fbe8e9d4190>
```
## "1.1.0" result

```
/opt/pysetup/.venv/lib/python3.10/site-packages/filetype/filetype.py:28: in guess
    return match(obj) if obj else None
/opt/pysetup/.venv/lib/python3.10/site-packages/filetype/match.py:29: in match
    buf = get_bytes(obj)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
obj = <_io.BufferedReader name='/builds/codeavors/traveltech/backend_common/tests/google/test_photo_paris.jpeg'>
    def get_bytes(obj):
        """
        Infers the input type and reads the first 262 bytes,
        returning a sliced bytearray.
    
        Args:
            obj: path to readable, file, bytes, bytearray or memoryview.
    
        Returns:
            First 262 bytes of the file content as bytearray type.
    
        Raises:
            TypeError: if obj is not a supported type.
        """
        if isinstance(obj, bytearray):
            return signature(obj)
    
        if isinstance(obj, str):
            return get_signature_bytes(obj)
    
        if isinstance(obj, bytes):
            return signature(obj)
```

Discussion:

Patch:
diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index 5cf8442..0000000
--- a/.coveragerc
+++ /dev/null
@@ -1,14 +0,0 @@
-[run]
-branch = True
-
-omit =
-    examples/*
-    tests/*
-
-source = filetype
-
-[report]
-exclude_lines =
-    # Don't complain if non-runnable code isn't run:
-    if __name__ == ['"]+__main__['"]+:
-    if ['"]+__main__['"]+ == __name__:
diff --git a/filetype/utils.py b/filetype/utils.py
index c345c9c..787b4cc 100644
--- a/filetype/utils.py
+++ b/filetype/utils.py
@@ -48,7 +48,7 @@ def get_bytes(obj):
     returning a sliced bytearray.
 
     Args:
-        obj: path to readable, file, bytes, bytearray or memoryview.
+        obj: path to readable, file-like object(with read() method), bytes, bytearray or memoryview
 
     Returns:
         First 8192 bytes of the file content as bytearray type.
@@ -71,4 +71,7 @@ def get_bytes(obj):
     if isinstance(obj, pathlib.PurePath):
         return get_signature_bytes(obj)
 
+    if hasattr(obj, 'read'):
+        return get_bytes(obj.read(_NUM_SIGNATURE_BYTES))
+
     raise TypeError('Unsupported type as file input: %s' % type(obj))


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index 6147e38..0000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,68 +0,0 @@
-# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
-# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
-
-name: CI
-
-on:
-  push:
-    branches: [ master ]
-  pull_request:
-    branches: [ master ]
-
-jobs:
-
-# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-
-  release_test:
-
-    runs-on: ${{ matrix.os }}
-    strategy:
-      fail-fast: false
-      matrix:
-        os: [ ubuntu-latest ]
-        python-version: ["3.9"]
-
-    steps:
-
-    - name: Checkout
-      uses: actions/checkout@v2
-      with:
-        fetch-depth: 0
-        ref: ${{ github.event.pull_request.head.sha }}
-
-    - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
-      with:
-        python-version: ${{ matrix.python-version }}
-
-    - name: Upgrade PIP
-      run: python -m pip install --upgrade pip
-
-    - name: Install application with ML
-      run: python -m pip install .
-
-    - name: CLI tool check
-      run: filetype --help
-
-    - name: Install test framework dependencies
-      run: python -m pip install pytest pytest-random-order pytest-cov pytest-html
-
-    - name: UnitTest with pytest and coverage
-      run: |
-        pytest \
-            --random-order \
-            --random-order-bucket=global \
-            --ignore=examples \
-            --ignore=tests/test_benchmark.py \
-            --cov=filetype \
-            --cov-report html:coverage/ \
-            tests \
-            ;
-
-    - name: HTML coverage reports
-      if: always()
-      uses: actions/upload-artifact@v2
-      with:
-        name: coverage_${{ matrix.python-version }}
-        path: coverage
-
diff --git a/tests/test_types.py b/tests/test_types.py
index 70178cd..9160ff3 100644
--- a/tests/test_types.py
+++ b/tests/test_types.py
@@ -13,10 +13,12 @@ FIXTURES = os.path.dirname(os.path.abspath(__file__)) + '/fixtures'
 
 class TestFileType(unittest.TestCase):
     def test_guess_jpeg(self):
-        kind = filetype.guess(FIXTURES + '/sample.jpg')
-        self.assertTrue(kind is not None)
-        self.assertEqual(kind.mime, 'image/jpeg')
-        self.assertEqual(kind.extension, 'jpg')
+        img_path = FIXTURES + '/sample.jpg'
+        for obj in (img_path, open(img_path, 'rb')):
+            kind = filetype.guess(obj)
+            self.assertTrue(kind is not None)
+            self.assertEqual(kind.mime, 'image/jpeg')
+            self.assertEqual(kind.extension, 'jpg')
 
     def test_guess_jpx(self):
         kind = filetype.guess(FIXTURES + '/sample.jpx')
@@ -60,7 +62,6 @@ class TestFileType(unittest.TestCase):
         self.assertEqual(kind.mime, 'video/quicktime')
         self.assertEqual(kind.extension, 'mov')
 
-    @unittest.skip(reason="fails")
     def test_guess_zstd(self):
         for name in 'sample.zst', 'sample_skippable.zst':
             kind = filetype.guess(FIXTURES + '/' + name)
@@ -84,8 +85,8 @@ class TestFileType(unittest.TestCase):
         kind = filetype.guess(FIXTURES + '/sample.odt')
         self.assertTrue(kind is not None)
         self.assertEqual(kind.mime, 'application/vnd.oasis.opendocument.text')
-        self.assertEqual(kind.extension, 'odt')    
-        
+        self.assertEqual(kind.extension, 'odt')
+
     def test_guess_xls(self):
         kind = filetype.guess(FIXTURES + '/sample.xls')
         self.assertTrue(kind is not None)
@@ -102,7 +103,7 @@ class TestFileType(unittest.TestCase):
         kind = filetype.guess(FIXTURES + '/sample.ods')
         self.assertTrue(kind is not None)
         self.assertEqual(kind.mime, 'application/vnd.oasis.opendocument.spreadsheet')
-        self.assertEqual(kind.extension, 'ods') 
+        self.assertEqual(kind.extension, 'ods')
 
     def test_guess_ppt(self):
         kind = filetype.guess(FIXTURES + '/sample.ppt')
@@ -120,4 +121,4 @@ class TestFileType(unittest.TestCase):
         kind = filetype.guess(FIXTURES + '/sample.odp')
         self.assertTrue(kind is not None)
         self.assertEqual(kind.mime, 'application/vnd.oasis.opendocument.presentation')
-        self.assertEqual(kind.extension, 'odp') 
+        self.assertEqual(kind.extension, 'odp')