From 8e844a86504346a55aca24a68a726cd6a2e0446b Mon Sep 17 00:00:00 2001 From: Ronnie Villanueva Date: Sun, 5 Feb 2023 10:32:46 +0800 Subject: [PATCH 01/10] Added Path as accepted argument type --- filext/utils.py | 5 ++++- requirements.txt | 3 +++ tests/test_utils.py | 7 ++++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/filext/utils.py b/filext/utils.py index fbdf9b5..ba9500e 100644 --- a/filext/utils.py +++ b/filext/utils.py @@ -1,8 +1,9 @@ from concurrent.futures import ThreadPoolExecutor, as_completed +from pathlib import Path from typing import Callable, Dict, Union -def get_bytes(file: Union[str, bytes]) -> bytes: +def get_bytes(file: Union[str, bytes, Path]) -> bytes: """ Returns the raw bytes of a given file. @@ -20,6 +21,8 @@ def get_bytes(file: Union[str, bytes]) -> bytes: file_bytes = fh.read() elif isinstance(file, bytes): file_bytes = file + elif isinstance(file, Path): + file_bytes = file.read_bytes() else: raise TypeError return file_bytes diff --git a/requirements.txt b/requirements.txt index e69de29..4dbfffa 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,3 @@ +coverage +pre-commit +pytest diff --git a/tests/test_utils.py b/tests/test_utils.py index a5f8624..cd692c7 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,9 +1,14 @@ +from pathlib import Path + import pytest from filext.utils import get_bytes -@pytest.mark.parametrize("file", ["tests/files/image.png"]) +@pytest.mark.parametrize( + "file", + ["tests/files/image.png", Path("tests/files/image.png")], +) def test_get_bytes_valid(file): assert isinstance(get_bytes(file), bytes) From d3efeb8c7052a9022fb3892130467a384a9a1950 Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:02:54 +0800 Subject: [PATCH 02/10] build(requirements): separate package from dev requirements --- requirements-dev.txt | 5 +++++ requirements.txt | 3 --- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 requirements-dev.txt diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..db5c8fb --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,5 @@ +-r requirements.txt +commitizen +coverage +pre-commit +pytest diff --git a/requirements.txt b/requirements.txt index 4dbfffa..e69de29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +0,0 @@ -coverage -pre-commit -pytest From e643c552642f8014ea9225cda64320944d7c9990 Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:05:24 +0800 Subject: [PATCH 03/10] ci(settings.json): add vscode pytest integration --- .vscode/settings.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a3a1838 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.unittestEnabled": false, + "python.testing.pytestEnabled": true +} From 0ea98a6e71b3abf13d850c846667cefb6226ba41 Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:10:09 +0800 Subject: [PATCH 04/10] ci(.pre-commit-config.yaml): change linter to ruff --- .pre-commit-config.yaml | 23 ++++++++--------------- requirements-dev.txt | 1 + 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 58d0934..cf37b2d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,19 +5,12 @@ repos: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace -- repo: https://github.com/psf/black - rev: 22.8.0 + +- repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.11.5 hooks: - - id: black -- repo: https://github.com/pycqa/isort - rev: 5.12.0 - hooks: - - id: isort - name: isort (python) - args: ["--profile", "black"] -- repo: https://github.com/pycqa/flake8 - rev: 5.0.4 - hooks: - - id: flake8 - args: [--max-line-length=100, "-j8", "--ignore=E203,E501,P103,F403,F405,W503"] - additional_dependencies: [flake8-isort] + - id: ruff + types_or: [ python, pyi ] + args: [ --fix ] + - id: ruff-format + types_or: [ python, pyi ] diff --git a/requirements-dev.txt b/requirements-dev.txt index db5c8fb..fbac2ec 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,3 +3,4 @@ commitizen coverage pre-commit pytest +ruff From 343b0f7b7c916a7e8e5a01a9364c88615bdaa49d Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:15:36 +0800 Subject: [PATCH 05/10] refactor(functions.py): move entry points --- filext/__init__.py | 72 ++++------------------------------------ filext/functions.py | 81 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 66 deletions(-) create mode 100644 filext/functions.py diff --git a/filext/__init__.py b/filext/__init__.py index d778716..01953b7 100644 --- a/filext/__init__.py +++ b/filext/__init__.py @@ -1,67 +1,7 @@ -from typing import Union +from filext.functions import whatdoc, whatimage, whatfile -from filext.classifiers import * -from filext.utils import lookup_file_type - - -def whatfile(file: Union[str, bytes]) -> Union[str, None]: - """ - Identifies the file type by calling each classifier - - Args: - file (Union[str, bytes]): path to file or bytes of file - - Returns: - str: found file type or None - """ - classifiers = ( - whatdoc, - whatimage, - ) - for classifier in classifiers: - result = classifier(file) - if result: - return result - - -def whatdoc(file: Union[str, bytes]) -> Union[str, None]: - """ - Identifies the file type by calling each document classifier - - Args: - file (Union[str, bytes]): path to file or bytes of file - - Returns: - Union[str,None]: found file type or None - """ - file_types = { - "docx": is_docx, - "pptx": is_pptx, - "xlsx": is_xlsx, - "pdf": is_pdf, - "doc": is_doc, - "xls": is_xls, - "ppt": is_ppt, - } - return lookup_file_type(file, file_types) - - -def whatimage(file: Union[str, bytes]) -> Union[str, None]: - """ - Identifies the file type by calling each image classifier - - Args: - file (Union[str, bytes]): path to file or bytes of file - - Returns: - Union[str,None]: found file type or None - """ - file_types = { - "bmp": is_bmp, - "gif": is_gif, - "heic": is_heic, - "jpg": is_jpg, - "png": is_png, - "tif": is_tif, - } - return lookup_file_type(file, file_types) +__all__ = [ + "whatdoc", + "whatimage", + "whatfile", +] diff --git a/filext/functions.py b/filext/functions.py new file mode 100644 index 0000000..159a1f0 --- /dev/null +++ b/filext/functions.py @@ -0,0 +1,81 @@ +from typing import Union + +from filext.classifiers import ( + is_bmp, + is_doc, + is_docx, + is_gif, + is_heic, + is_jpg, + is_pdf, + is_png, + is_ppt, + is_pptx, + is_tif, + is_xls, + is_xlsx, +) +from filext.utils import lookup_file_type + + +def whatfile(file: Union[str, bytes]) -> Union[str, None]: + """ + Identifies the file type by calling each classifier + + Args: + file (Union[str, bytes]): path to file or bytes of file + + Returns: + str: found file type or None + """ + classifiers = ( + whatdoc, + whatimage, + ) + for classifier in classifiers: + result = classifier(file) + if result: + return result + + +def whatdoc(file: Union[str, bytes]) -> Union[str, None]: + """ + Identifies the file type by calling each document classifier + + Args: + file (Union[str, bytes]): path to file or bytes of file + + Returns: + Union[str,None]: found file type or None + """ + file_types = { + "docx": is_docx, + "pptx": is_pptx, + "xlsx": is_xlsx, + "pdf": is_pdf, + "doc": is_doc, + "xls": is_xls, + "ppt": is_ppt, + } + return lookup_file_type(file, file_types) + + +def whatimage(file: Union[str, bytes]) -> Union[str, None]: + """ + Identifies the file type by calling each image classifier + + Args: + file (Union[str, bytes]): path to file or bytes of file + + Returns: + Union[str,None]: found file type or None + """ + file_types = { + "bmp": is_bmp, + "gif": is_gif, + "heic": is_heic, + "jpg": is_jpg, + "png": is_png, + "tif": is_tif, + } + return lookup_file_type(file, file_types) From 7cdcb3ef2c434c79d126ffe82ee1ab808103fa9b Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:17:12 +0800 Subject: [PATCH 06/10] ci(python-app.yml): change python-versions --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 1540957..6582967 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 From db652e925cc68ef752e7c0b1774519c75ca39562 Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:20:44 +0800 Subject: [PATCH 07/10] ci(python-app.yml): change linter to ruff --- .github/workflows/python-app.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 6582967..f824ed7 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -28,12 +28,8 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Lint with ruff + uses: astral-sh/ruff-action@v3 - name: Test with pytest run: | pytest From b7cd8d4d0c45cb53db72005b501b5a90f0cea08a Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:27:52 +0800 Subject: [PATCH 08/10] ci(python-app.yml): add ruff check args --- .github/workflows/python-app.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index f824ed7..b6e7de0 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -30,6 +30,8 @@ jobs: if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with ruff uses: astral-sh/ruff-action@v3 + with: + args: check - name: Test with pytest run: | pytest From 74270e9a3981bc56aec2ba6fe47a92f030ead1df Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:42:27 +0800 Subject: [PATCH 09/10] ci(python-app.yml): show code coverage --- .github/workflows/python-app.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index b6e7de0..6ebf2db 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -34,4 +34,7 @@ jobs: args: check - name: Test with pytest run: | - pytest + coverage run -m pytest + - name: Show coverage report + run: | + coverage report -mi --fail-under=${{ vars.COVERAGE_FAIL_UNDER}} From 86b367a9b2fd36d69423fa62602119b1def938ff Mon Sep 17 00:00:00 2001 From: Ronnie V Date: Sun, 13 Apr 2025 08:44:21 +0800 Subject: [PATCH 10/10] ci(python-app.yml): fix missing dependencies --- .github/workflows/python-app.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 6ebf2db..6f945a2 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install flake8 pytest + pip install coverage pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - name: Lint with ruff uses: astral-sh/ruff-action@v3