From db29b95db12386f2f65bb9bcaa39032f8840bbf6 Mon Sep 17 00:00:00 2001 From: Andrey Nikiforov Date: Fri, 27 Dec 2024 18:31:09 -0800 Subject: [PATCH] chore: update python requirements and dependencies (#1028) * bump python 3.12->3.13 * bump dependencies * bump min py 3.8->3.9 * downgrade libs for py3.9 compatibility --- .devcontainer/python/devcontainer.json | 2 +- .github/workflows/build-docs.yml | 4 +- .github/workflows/build-package.yml | 50 ++++++++--------- .github/workflows/publish.yml | 4 +- .github/workflows/quality-checks.yml | 8 +-- CHANGELOG.md | 2 + Dockerfile.build | 2 +- Dockerfile.build-musl | 2 +- binary_dist/pyproject.toml | 4 +- pyproject.toml | 78 ++++++++++++++------------ scripts/type_check | 2 +- src/icloudpd/authentication.py | 6 +- src/icloudpd/autodelete.py | 6 +- src/icloudpd/base.py | 29 +++++----- src/icloudpd/config.py | 3 +- src/icloudpd/download.py | 10 ++-- src/icloudpd/xmp_sidecar.py | 1 + src/starters/icloudpd_ex.py | 1 + tests/helpers/__init__.py | 1 + tests/test_authentication.py | 6 +- tests/test_autodelete_photos.py | 6 +- tests/test_cli.py | 2 +- tests/test_download_live_photos.py | 2 +- tests/test_download_photos.py | 10 ++-- tests/test_download_photos_id.py | 10 ++-- tests/test_email_notifications.py | 2 +- tests/test_folder_structure.py | 2 +- tests/test_listing_albums.py | 2 +- tests/test_listing_libraries.py | 2 +- tests/test_listing_recent_photos.py | 2 +- tests/test_logger.py | 1 + tests/test_two_step_auth.py | 4 +- 32 files changed, 137 insertions(+), 129 deletions(-) diff --git a/.devcontainer/python/devcontainer.json b/.devcontainer/python/devcontainer.json index edf4b3f30..7f80192be 100644 --- a/.devcontainer/python/devcontainer.json +++ b/.devcontainer/python/devcontainer.json @@ -3,7 +3,7 @@ { "name": "Python 3", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "mcr.microsoft.com/devcontainers/python:3.12", + "image": "mcr.microsoft.com/devcontainers/python:3.13", "features": { "ghcr.io/devcontainers/features/docker-in-docker:2": {} }, diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 37e5f56a9..293a42042 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -12,10 +12,10 @@ jobs: id: pages uses: actions/configure-pages@v5 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | diff --git a/.github/workflows/build-package.yml b/.github/workflows/build-package.yml index 1607a2fdb..725e0b037 100644 --- a/.github/workflows/build-package.yml +++ b/.github/workflows/build-package.yml @@ -26,10 +26,10 @@ jobs: path: | src/foundation - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -64,10 +64,10 @@ jobs: path: | src/foundation - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: > @@ -105,7 +105,7 @@ jobs: - name: Run version uses: addnab/docker-run-action@v3 with: - image: python:3.12-alpine3.18 + image: python:3.13-alpine3.19 shell: sh options: -v ${{ github.workspace }}:/work run: > @@ -144,10 +144,10 @@ jobs: path: | src/foundation - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -276,10 +276,10 @@ jobs: path: | dist - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -317,10 +317,10 @@ jobs: path: | dist - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -357,10 +357,10 @@ jobs: path: | dist - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -397,10 +397,10 @@ jobs: path: | dist - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -522,10 +522,10 @@ jobs: path: | src/foundation - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -564,10 +564,10 @@ jobs: path: | src/foundation - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | @@ -680,8 +680,8 @@ jobs: matrix: image: - [ - "python3_12", #variant name - "python:3.12", #image + "python3_13", #variant name + "python:3.13", #image ] # apt-get does not work for debian 6 anymore # - [ @@ -898,8 +898,8 @@ jobs: matrix: image: - [ - "python3_12_alpine3_18", #variant name - "python:3.12-alpine3.18", #image + "python3_13_alpine3_19", #variant name + "python:3.13-alpine3.19", #image ] - [ "alpine_3_20", #variant name @@ -3774,10 +3774,10 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Make folder for artifacts run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0eee03fda..ad4167e6b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -87,10 +87,10 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Python 3.12 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: '3.13' - name: Install Dev dependencies run: | diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 637ae99dd..8adcdb71a 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.8, 3.9, '3.10', 3.11, 3.12] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -54,7 +54,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.8, 3.9, '3.10', 3.11, 3.12] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} @@ -80,7 +80,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: [3.8, 3.9, '3.10', 3.11, 3.12] + python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] steps: - name: Install Locales for Tests run: | @@ -119,7 +119,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.12] + python-version: [3.13] os: - "macos-13" - "macos-14" diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d121c7e..fc89d6aa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- chore: bump max/default python version 3.12->3.13 +- chore: bump min python version 3.8->3.9 - fix: fallback to old raw password auth if srp auth fails [#975](https://github.com/icloud-photos-downloader/icloud_photos_downloader/issues/975) ## 1.25.0 (2024-12-03) diff --git a/Dockerfile.build b/Dockerfile.build index 7ac493033..120b4eaa0 100644 --- a/Dockerfile.build +++ b/Dockerfile.build @@ -6,7 +6,7 @@ # arm7l instead of v6 issue: https://stackoverflow.com/questions/78535054/how-do-you-docker-buildx-build-for-arm-v6-on-qemu-emulated-platforms-that-pres # map source image to base -FROM python:3.12 AS base +FROM python:3.13 AS base ARG TARGETARCH ARG TARGETVARIANT ENV DEBIAN_FRONTEND=noninteractive diff --git a/Dockerfile.build-musl b/Dockerfile.build-musl index f0763ff1e..873a79f2e 100644 --- a/Dockerfile.build-musl +++ b/Dockerfile.build-musl @@ -5,7 +5,7 @@ # rust links from https://forge.rust-lang.org/infra/other-installation-methods.html#standalone-installers # map source image to base -FROM python:3.12-alpine3.19 AS base +FROM python:3.13-alpine3.19 AS base ARG TARGETARCH ARG TARGETVARIANT WORKDIR /app diff --git a/binary_dist/pyproject.toml b/binary_dist/pyproject.toml index 6193e166e..c9f20da90 100644 --- a/binary_dist/pyproject.toml +++ b/binary_dist/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = [ - "setuptools>=68.0.0,<69", - "wheel>=0.40.0,<0.41", + "setuptools>=75.6.0,<76", + "wheel>=0.45.1,<0.46", ] build-backend = "setuptools.build_meta" diff --git a/pyproject.toml b/pyproject.toml index 72c5712fc..6fce2da40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [build-system] requires = [ - "setuptools==69.0.2", - "wheel==0.42.0", + "setuptools==75.6.0", + "wheel==0.45.1", ] build-backend = "setuptools.build_meta" @@ -10,7 +10,7 @@ version="1.25.0" name = "icloudpd" description = "icloudpd is a command-line tool to download photos and videos from iCloud." readme = "README_PYPI.md" -requires-python = ">=3.8,<3.13" +requires-python = ">=3.9,<3.14" keywords = ["icloud", "photo"] license = {file="LICENSE.md"} authors=[ @@ -24,60 +24,60 @@ classifiers = [ ] dependencies = [ "requests==2.31.0", - "schema==0.7.5", - "click==8.1.6", - "tqdm==4.66.4", + "schema==0.7.7", + "click==8.1.8", + "tqdm==4.67.1", "piexif==1.1.3", "python-dateutil==2.9.0.post0", - "urllib3==1.26.16", - "typing_extensions==4.11.0", - "Flask==3.0.3", - "waitress==3.0.0", + "urllib3==1.26.20", + "typing_extensions==4.12.2", + "Flask==3.1.0", + "waitress==3.0.2", # from pyicloud_ipd - "six==1.16.0", - "tzlocal==5.1", - "pytz==2024.1", - "certifi==2022.12.7", - "keyring==25.2.1", - "keyrings-alt==5.0.1", + "six==1.17.0", + "tzlocal==5.2", + "pytz==2024.2", + "certifi==2024.12.14", + "keyring==25.6.0", + "keyrings-alt==5.0.2", "srp==1.0.22", ] [project.optional-dependencies] dev = [ "twine==5.1.1", - "pyinstaller==6.7.0", - "wheel==0.42.0", - "furo==2024.5.6", - "Sphinx==7.3.7", - "sphinx-autobuild==2024.4.16", + "pyinstaller==6.11.1", + "wheel==0.45.1", + "furo==2024.8.6", + "Sphinx==7.4.7", + "sphinx-autobuild==2024.10.3", "myst-parser==3.0.1" ] devlinux = [ - "auditwheel==5.4.0", + "auditwheel==6.1.0", #"staticx==0.14.1", - "scons==4.8.0" + "scons==4.8.1" ] test = [ - "pytest==7.4.3", + "pytest==8.3.4", "mock==5.1.0", "freezegun==1.5.1", - "vcrpy==6.0.1", - "pytest-cov==4.1.0", - "ruff==0.5.0", + "vcrpy==6.0.2", + "pytest-cov==5.0.0", + "ruff==0.8.4", "coveralls==3.3.1", - "pytest-timeout==2.1.0", - "pytest-xdist==3.3.1", - "mypy==1.10.1", - "types-python-dateutil==2.9.0.20241003", - "types-pytz==2024.1.0.20240417", + "pytest-timeout==2.3.1", + "pytest-xdist==3.6.1", + "mypy==1.14.0", + "types-python-dateutil==2.9.0.20241206", + "types-pytz==2024.2.0.20241221", "types-tzlocal==5.1.0.1", "types-requests==2.31.0.2", - "types-six==1.16.0", - "types-urllib3==1.26.16", - "types-tqdm==4.66.0.20240417", - "types-mock==5.1.0.1", - "types-waitress==3.0.0.20240423", + "types-six==1.17.0.20241205", + "types-urllib3==1.26.25.14", + "types-tqdm==4.67.0.20241221", + "types-mock==5.1.0.20240425", + "types-waitress==3.0.1.20241117", ] [project.urls] @@ -133,5 +133,9 @@ select = [ ignore = [ # long lines "E501", + # lower case types + "UP006", + # deprecated typing namespace + "UP035", ] diff --git a/scripts/type_check b/scripts/type_check index 399ea6c38..9a6f3d914 100755 --- a/scripts/type_check +++ b/scripts/type_check @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -euo pipefail echo "Running mypy..." -python3 -m mypy src tests --strict --python-version 3.8 +python3 -m mypy src tests --strict --python-version 3.9 # --strict-equality --warn-return-any --disallow-any-generics --disallow-untyped-defs --disallow-untyped-calls --check-untyped-defs diff --git a/src/icloudpd/authentication.py b/src/icloudpd/authentication.py index da5a37864..fc4e2ea06 100644 --- a/src/icloudpd/authentication.py +++ b/src/icloudpd/authentication.py @@ -6,12 +6,12 @@ from typing import Callable, Dict, Optional, Tuple import click -from pyicloud_ipd.base import PyiCloudService -from pyicloud_ipd.file_match import FileMatchPolicy -from pyicloud_ipd.raw_policy import RawTreatmentPolicy from icloudpd.mfa_provider import MFAProvider from icloudpd.status import Status, StatusExchange +from pyicloud_ipd.base import PyiCloudService +from pyicloud_ipd.file_match import FileMatchPolicy +from pyicloud_ipd.raw_policy import RawTreatmentPolicy class TwoStepAuthRequiredError(Exception): diff --git a/src/icloudpd/autodelete.py b/src/icloudpd/autodelete.py index 0b970787c..936cb8741 100644 --- a/src/icloudpd/autodelete.py +++ b/src/icloudpd/autodelete.py @@ -7,12 +7,12 @@ import os from typing import Sequence, Set -from pyicloud_ipd.services.photos import PhotoLibrary -from pyicloud_ipd.utils import disambiguate_filenames -from pyicloud_ipd.version_size import AssetVersionSize, VersionSize from tzlocal import get_localzone from icloudpd.paths import local_download_path +from pyicloud_ipd.services.photos import PhotoLibrary +from pyicloud_ipd.utils import disambiguate_filenames +from pyicloud_ipd.version_size import AssetVersionSize, VersionSize def delete_file(logger: logging.Logger, path: str) -> bool: diff --git a/src/icloudpd/base.py b/src/icloudpd/base.py index db890a461..3481c5426 100644 --- a/src/icloudpd/base.py +++ b/src/icloudpd/base.py @@ -5,9 +5,8 @@ import foundation from foundation.core import compose, constant, identity -from pyicloud_ipd.item_type import AssetItemType # fmt: skip - from icloudpd.mfa_provider import MFAProvider +from pyicloud_ipd.item_type import AssetItemType # fmt: skip freeze_support() # fmt: skip # fixing tqdm on macos @@ -37,19 +36,6 @@ ) import click -from pyicloud_ipd.base import PyiCloudService -from pyicloud_ipd.exceptions import PyiCloudAPIResponseException -from pyicloud_ipd.file_match import FileMatchPolicy -from pyicloud_ipd.raw_policy import RawTreatmentPolicy -from pyicloud_ipd.services.photos import PhotoAsset, PhotoLibrary, PhotosService -from pyicloud_ipd.utils import ( - add_suffix_to_filename, - disambiguate_filenames, - get_password_from_keyring, - size_to_suffix, - store_password_in_keyring, -) -from pyicloud_ipd.version_size import AssetVersionSize, LivePhotoVersionSize from tqdm import tqdm from tqdm.contrib.logging import logging_redirect_tqdm from tzlocal import get_localzone @@ -65,6 +51,19 @@ from icloudpd.status import Status, StatusExchange from icloudpd.string_helpers import truncate_middle from icloudpd.xmp_sidecar import generate_xmp_file +from pyicloud_ipd.base import PyiCloudService +from pyicloud_ipd.exceptions import PyiCloudAPIResponseException +from pyicloud_ipd.file_match import FileMatchPolicy +from pyicloud_ipd.raw_policy import RawTreatmentPolicy +from pyicloud_ipd.services.photos import PhotoAsset, PhotoLibrary, PhotosService +from pyicloud_ipd.utils import ( + add_suffix_to_filename, + disambiguate_filenames, + get_password_from_keyring, + size_to_suffix, + store_password_in_keyring, +) +from pyicloud_ipd.version_size import AssetVersionSize, LivePhotoVersionSize def build_filename_cleaner( diff --git a/src/icloudpd/config.py b/src/icloudpd/config.py index cbede5d56..80b495d1e 100644 --- a/src/icloudpd/config.py +++ b/src/icloudpd/config.py @@ -1,11 +1,10 @@ from typing import Callable, Dict, Optional, Sequence, Tuple +from icloudpd.mfa_provider import MFAProvider from pyicloud_ipd.file_match import FileMatchPolicy from pyicloud_ipd.raw_policy import RawTreatmentPolicy from pyicloud_ipd.version_size import AssetVersionSize, LivePhotoVersionSize -from icloudpd.mfa_provider import MFAProvider - class Config: def __init__( diff --git a/src/icloudpd/download.py b/src/icloudpd/download.py index 799828f93..f0d13fe8b 100644 --- a/src/icloudpd/download.py +++ b/src/icloudpd/download.py @@ -6,17 +6,17 @@ import socket import time -from pyicloud_ipd.asset_version import AssetVersion -from pyicloud_ipd.base import PyiCloudService -from pyicloud_ipd.exceptions import PyiCloudAPIResponseException -from pyicloud_ipd.services.photos import PhotoAsset -from pyicloud_ipd.version_size import VersionSize from requests import Response from requests.exceptions import ConnectionError from tzlocal import get_localzone # Import the constants object so that we can mock WAIT_SECONDS in tests from icloudpd import constants +from pyicloud_ipd.asset_version import AssetVersion +from pyicloud_ipd.base import PyiCloudService +from pyicloud_ipd.exceptions import PyiCloudAPIResponseException +from pyicloud_ipd.services.photos import PhotoAsset +from pyicloud_ipd.version_size import VersionSize def update_mtime(created: datetime.datetime, download_path: str) -> None: diff --git a/src/icloudpd/xmp_sidecar.py b/src/icloudpd/xmp_sidecar.py index f604be75c..207c3e97b 100644 --- a/src/icloudpd/xmp_sidecar.py +++ b/src/icloudpd/xmp_sidecar.py @@ -13,6 +13,7 @@ from xml.etree import ElementTree import dateutil.tz + from foundation import version_info exif_tool = None diff --git a/src/starters/icloudpd_ex.py b/src/starters/icloudpd_ex.py index 4e84f08b3..d5fea00de 100644 --- a/src/starters/icloudpd_ex.py +++ b/src/starters/icloudpd_ex.py @@ -7,6 +7,7 @@ freeze_support() # fmt: skip # fixing tqdm on macos import click + from icloudpd.base import main as icloudpd_main from pyicloud_ipd.cmdline import main as icloud_main diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py index af1b22771..7ab12eb16 100644 --- a/tests/helpers/__init__.py +++ b/tests/helpers/__init__.py @@ -6,6 +6,7 @@ import vcr from click.testing import CliRunner, Result + from icloudpd.base import main diff --git a/tests/test_authentication.py b/tests/test_authentication.py index 6cdca156a..411355921 100644 --- a/tests/test_authentication.py +++ b/tests/test_authentication.py @@ -4,9 +4,11 @@ from typing import NamedTuple from unittest import TestCase -import pyicloud_ipd import pytest from click.testing import CliRunner +from vcr import VCR + +import pyicloud_ipd from foundation.core import constant, identity from icloudpd.authentication import TwoStepAuthRequiredError, authenticator from icloudpd.base import dummy_password_writter, lp_filename_concatinator, main @@ -16,8 +18,6 @@ from pyicloud_ipd.file_match import FileMatchPolicy from pyicloud_ipd.raw_policy import RawTreatmentPolicy from pyicloud_ipd.sms import parse_trusted_phone_numbers_payload -from vcr import VCR - from tests.helpers import path_from_project_root, recreate_path vcr = VCR(decode_compressed_response=True, record_mode="none") diff --git a/tests/test_autodelete_photos.py b/tests/test_autodelete_photos.py index 1ac9362ee..7080991ed 100644 --- a/tests/test_autodelete_photos.py +++ b/tests/test_autodelete_photos.py @@ -10,14 +10,14 @@ import pytest import pytz from click.testing import CliRunner +from tzlocal import get_localzone +from vcr import VCR + from icloudpd import constants from icloudpd.base import main from pyicloud_ipd.base import PyiCloudService from pyicloud_ipd.exceptions import PyiCloudAPIResponseException from pyicloud_ipd.services.photos import PhotoAsset, PhotoLibrary, PhotosService -from tzlocal import get_localzone -from vcr import VCR - from tests.helpers import path_from_project_root, print_result_exception, recreate_path vcr = VCR(decode_compressed_response=True, record_mode="none") diff --git a/tests/test_cli.py b/tests/test_cli.py index cf53df082..f3e16d705 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -7,9 +7,9 @@ import pytest from click.testing import CliRunner -from icloudpd.base import main from vcr import VCR +from icloudpd.base import main from tests.helpers import ( path_from_project_root, print_result_exception, diff --git a/tests/test_download_live_photos.py b/tests/test_download_live_photos.py index 4ffeac745..9400a5e85 100644 --- a/tests/test_download_live_photos.py +++ b/tests/test_download_live_photos.py @@ -3,9 +3,9 @@ from unittest import TestCase import pytest -from icloudpd.base import lp_filename_concatinator, lp_filename_original from vcr import VCR +from icloudpd.base import lp_filename_concatinator, lp_filename_original from tests.helpers import ( path_from_project_root, run_icloudpd_test, diff --git a/tests/test_download_photos.py b/tests/test_download_photos.py index 2106abce8..e53218825 100644 --- a/tests/test_download_photos.py +++ b/tests/test_download_photos.py @@ -12,18 +12,18 @@ import piexif import pytest from click.testing import CliRunner +from piexif._exceptions import InvalidImageDataError +from requests import Response +from requests.exceptions import ConnectionError +from vcr import VCR + from icloudpd import constants from icloudpd.base import main -from piexif._exceptions import InvalidImageDataError from pyicloud_ipd.asset_version import AssetVersion from pyicloud_ipd.base import PyiCloudService from pyicloud_ipd.exceptions import PyiCloudAPIResponseException from pyicloud_ipd.services.photos import PhotoAlbum, PhotoAsset, PhotoLibrary from pyicloud_ipd.version_size import AssetVersionSize, LivePhotoVersionSize -from requests import Response -from requests.exceptions import ConnectionError -from vcr import VCR - from tests.helpers import ( path_from_project_root, print_result_exception, diff --git a/tests/test_download_photos_id.py b/tests/test_download_photos_id.py index ffccfd19a..abc9ef8d9 100644 --- a/tests/test_download_photos_id.py +++ b/tests/test_download_photos_id.py @@ -12,19 +12,19 @@ import piexif import pytest from click.testing import CliRunner +from piexif._exceptions import InvalidImageDataError +from requests import Response +from requests.exceptions import ConnectionError +from vcr import VCR + from icloudpd import constants from icloudpd.base import main from icloudpd.string_helpers import truncate_middle -from piexif._exceptions import InvalidImageDataError from pyicloud_ipd.asset_version import AssetVersion from pyicloud_ipd.base import PyiCloudService from pyicloud_ipd.exceptions import PyiCloudAPIResponseException from pyicloud_ipd.services.photos import PhotoAlbum, PhotoAsset, PhotoLibrary from pyicloud_ipd.version_size import AssetVersionSize, LivePhotoVersionSize -from requests import Response -from requests.exceptions import ConnectionError -from vcr import VCR - from tests.helpers import ( path_from_project_root, print_result_exception, diff --git a/tests/test_email_notifications.py b/tests/test_email_notifications.py index 1b9d56ca5..268ba371c 100644 --- a/tests/test_email_notifications.py +++ b/tests/test_email_notifications.py @@ -6,9 +6,9 @@ import pytest from click.testing import CliRunner from freezegun import freeze_time -from icloudpd.base import main from vcr import VCR +from icloudpd.base import main from tests.helpers import path_from_project_root, recreate_path vcr = VCR(decode_compressed_response=True, record_mode="none") diff --git a/tests/test_folder_structure.py b/tests/test_folder_structure.py index 91626f862..4d35d8c3b 100644 --- a/tests/test_folder_structure.py +++ b/tests/test_folder_structure.py @@ -8,9 +8,9 @@ import pytest from click.testing import CliRunner -from icloudpd.base import main from vcr import VCR +from icloudpd.base import main from tests.helpers import ( path_from_project_root, print_result_exception, diff --git a/tests/test_listing_albums.py b/tests/test_listing_albums.py index a584c71a8..06632e657 100644 --- a/tests/test_listing_albums.py +++ b/tests/test_listing_albums.py @@ -6,9 +6,9 @@ import pytest from click.testing import CliRunner -from icloudpd.base import main from vcr import VCR +from icloudpd.base import main from tests.helpers import path_from_project_root, print_result_exception, recreate_path vcr = VCR(decode_compressed_response=True, record_mode="none") diff --git a/tests/test_listing_libraries.py b/tests/test_listing_libraries.py index 4c7f69db8..7d8e46da8 100644 --- a/tests/test_listing_libraries.py +++ b/tests/test_listing_libraries.py @@ -5,9 +5,9 @@ import pytest from click.testing import CliRunner -from icloudpd.base import main from vcr import VCR +from icloudpd.base import main from tests.helpers import path_from_project_root, print_result_exception, recreate_path vcr = VCR(decode_compressed_response=True, record_mode="none") diff --git a/tests/test_listing_recent_photos.py b/tests/test_listing_recent_photos.py index 42934f31c..9354e2a7a 100644 --- a/tests/test_listing_recent_photos.py +++ b/tests/test_listing_recent_photos.py @@ -7,9 +7,9 @@ import pytest from click.testing import CliRunner -from icloudpd.base import main from vcr import VCR +from icloudpd.base import main from tests.helpers import path_from_project_root, print_result_exception, recreate_path vcr = VCR(decode_compressed_response=True, record_mode="none") diff --git a/tests/test_logger.py b/tests/test_logger.py index 84bf0d797..c95586f3a 100644 --- a/tests/test_logger.py +++ b/tests/test_logger.py @@ -5,6 +5,7 @@ from unittest.mock import MagicMock from freezegun import freeze_time + from icloudpd.logger import IPDLogger, setup_logger diff --git a/tests/test_two_step_auth.py b/tests/test_two_step_auth.py index d80f3128f..726b5b4ef 100644 --- a/tests/test_two_step_auth.py +++ b/tests/test_two_step_auth.py @@ -4,10 +4,10 @@ import pytest from click.testing import CliRunner -from icloudpd.base import main -from pyicloud_ipd.base import PyiCloudService from vcr import VCR +from icloudpd.base import main +from pyicloud_ipd.base import PyiCloudService from tests.helpers import path_from_project_root, recreate_path vcr = VCR(decode_compressed_response=True, record_mode="none")