Skip to content
This repository has been archived by the owner on Jan 16, 2023. It is now read-only.

Commit

Permalink
switch to pytest and fix #157
Browse files Browse the repository at this point in the history
- Fix #157: catch pydoc.ErrorDuringImport
- Remove runtests.py and use pytest instead
- Add Python 3.8 to test matrix
- Update copyright note in readme
- Add deprecation warning for using BotoStrategy
  • Loading branch information
antonagestam committed Oct 22, 2019
1 parent 54e02ef commit 7608d4f
Show file tree
Hide file tree
Showing 15 changed files with 74 additions and 103 deletions.
7 changes: 6 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ python:
- '3.5'
- '3.6'
- '3.7'
- '3.8'
install:
- pip install --upgrade pip setuptools
- pip install django=="$DJANGO"
Expand All @@ -26,7 +27,7 @@ script:
- 'if [[ $(python --version) == "Python 3.7."* ]]; then black --check .; fi'
- 'if [[ $(python --version) == "Python 3.7."* ]]; then sorti --check .; fi'
- 'if [[ $(python --version) == "Python 3.7."* && "$DJANGO" != "1.11" ]]; then pip install . && mypy .; fi'
- coverage run --source collectfast ./runtests.py
- coverage run --source collectfast -m pytest
after_script:
- coveralls
matrix:
Expand All @@ -35,5 +36,9 @@ matrix:
python: '3.4'
- env: DJANGO=2.2
python: '3.4'
- env: DJANGO=1.11
python: '3.8'
- env: DJANGO=2.1
python: '3.8'
notifications:
email: false
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2013-2017 Anton Agestam
Copyright (c) 2013-2019 Anton Agestam

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
SHELL := /usr/bin/env bash

test:
. storage-credentials && ./runtests.py
. storage-credentials && pytest

test-coverage:
. storage-credentials && coverage run --source collectfast ./runtests.py
. storage-credentials && coverage run --source collectfast -m pytest

distribute:
pip install --upgrade wheel twine setuptools
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ A faster collectstatic command.

**Supported Storage Backends**

- ``storages.backends.s3boto.S3BotoStorage`` (deprecated)
- ``storages.backends.s3boto.S3BotoStorage`` (deprecated, will be removed in 2.0)
- ``storages.backends.s3boto3.S3Boto3Storage``
- ``storages.backends.gcloud.GoogleCloudStorage``
- ``django.core.files.storage.FileSystemStorage``
Expand Down
13 changes: 7 additions & 6 deletions collectfast/strategies/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import hashlib
import logging
import mimetypes
import pydoc
import warnings
from functools import lru_cache
from io import BytesIO
from pydoc import locate
from typing import ClassVar
from typing import Generic
from typing import Optional
Expand Down Expand Up @@ -140,7 +140,7 @@ def get_gzipped_local_file_hash(self, uncompressed_file_hash, path, contents):

def load_strategy(klass: Union[str, type, object]) -> Type[Strategy[Storage]]:
if isinstance(klass, str):
klass = locate(klass)
klass = pydoc.locate(klass)
if not isinstance(klass, type) or not issubclass(klass, Strategy):
raise ImproperlyConfigured(
"Configured strategies must be subclasses of %s.%s"
Expand All @@ -157,11 +157,11 @@ def load_strategy(klass: Union[str, type, object]) -> Type[Strategy[Storage]]:

def _resolves_to_subclass(subclass_ref: str, superclass_ref: str) -> bool:
try:
subclass = locate(subclass_ref)
subclass = pydoc.locate(subclass_ref)
assert isinstance(subclass, type)
superclass = locate(superclass_ref)
superclass = pydoc.locate(superclass_ref)
assert isinstance(superclass, type)
except (ImportError, AssertionError) as e:
except (ImportError, AssertionError, pydoc.ErrorDuringImport) as e:
logger.debug("Failed to import %s: %s" % (superclass_ref, e))
return False
return issubclass(subclass, superclass)
Expand All @@ -171,7 +171,8 @@ def guess_strategy(storage: str) -> str:
warnings.warn(
"Falling back to guessing strategy for backwards compatibility. This "
"is deprecated and will be removed in a future release. Explicitly "
"set COLLECTFAST_STRATEGY to silence this warning."
"set COLLECTFAST_STRATEGY to silence this warning.",
DeprecationWarning,
)
if storage == _BOTO_STORAGE:
return _BOTO_STRATEGY
Expand Down
6 changes: 6 additions & 0 deletions collectfast/strategies/boto.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import warnings
from typing import Optional

import boto.exception
Expand All @@ -14,6 +15,11 @@
class BotoStrategy(CachingHashStrategy[S3BotoStorage]):
def __init__(self, remote_storage):
# type: (S3BotoStorage) -> None
warnings.warn(
"The BotoStrategy class is deprecated and will be removed in Collectfast "
"2.0.",
DeprecationWarning,
)
super().__init__(remote_storage)
self.remote_storage.preload_metadata = True
self.use_gzip = settings.aws_is_gzipped
Expand Down
6 changes: 3 additions & 3 deletions collectfast/tests/strategies/test_caching_hash_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from collectfast import settings
from collectfast.strategies.base import CachingHashStrategy
from collectfast.tests.utils import test
from collectfast.tests.utils import make_test


hash_characters = string.ascii_letters + string.digits
Expand All @@ -22,7 +22,7 @@ def get_remote_file_hash(self, prefixed_path):
pass


@test
@make_test
def test_get_cache_key(case):
# type: (TestCase) -> None
strategy = Strategy()
Expand All @@ -35,7 +35,7 @@ def test_get_cache_key(case):
case.assertIn(c, expected_chars)


@test
@make_test
def test_gets_and_invalidates_hash(case):
# type: (TestCase) -> None
strategy = Strategy()
Expand Down
14 changes: 7 additions & 7 deletions collectfast/tests/strategies/test_guess_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@
from collectfast.strategies.base import _BOTO_STORAGE
from collectfast.strategies.base import _BOTO_STRATEGY
from collectfast.strategies.base import guess_strategy
from collectfast.tests.utils import test
from collectfast.tests.utils import make_test


@test
@make_test
def test_guesses_boto_from_exact(case):
# type: (TestCase) -> None
case.assertEqual(guess_strategy(_BOTO_STORAGE), _BOTO_STRATEGY)


@test
@make_test
def test_guesses_boto3_from_exact(case):
# type: (TestCase) -> None
case.assertEqual(guess_strategy(_BOTO3_STORAGE), _BOTO3_STRATEGY)


@test
@make_test
def test_guesses_boto_from_subclass(case):
# type: (TestCase) -> None
case.assertEqual(
Expand All @@ -31,7 +31,7 @@ def test_guesses_boto_from_subclass(case):
)


@test
@make_test
def test_guesses_boto3_from_subclass(case):
# type: (TestCase) -> None
case.assertEqual(
Expand All @@ -40,14 +40,14 @@ def test_guesses_boto3_from_subclass(case):
)


@test
@make_test
def test_raises_improperly_configured_for_unguessable_class(case):
# type: (TestCase) -> None
with case.assertRaises(ImproperlyConfigured):
guess_strategy("collectfast.tests.test_storages.unguessable.UnguessableStorage")


@test
@make_test
def test_raises_improperly_configured_for_invalid_type(case):
# type: (TestCase) -> None
with case.assertRaises(ImproperlyConfigured):
Expand Down
6 changes: 3 additions & 3 deletions collectfast/tests/strategies/test_hash_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.core.files.storage import FileSystemStorage

from collectfast.strategies.base import HashStrategy
from collectfast.tests.utils import test
from collectfast.tests.utils import make_test


class Strategy(HashStrategy[FileSystemStorage]):
Expand All @@ -20,7 +20,7 @@ def get_remote_file_hash(self, prefixed_path):
pass


@test
@make_test
def test_get_file_hash(case):
# type: (TestCase) -> None
strategy = Strategy()
Expand All @@ -32,7 +32,7 @@ def test_get_file_hash(case):
case.assertTrue(re.fullmatch(r"^[A-z0-9]{32}$", hash_) is not None)


@test
@make_test
def test_should_copy_file(case):
# type: (TestCase) -> None
strategy = Strategy()
Expand Down
24 changes: 12 additions & 12 deletions collectfast/tests/test_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

from .utils import clean_static_dir
from .utils import create_static_file
from .utils import make_test
from .utils import override_setting
from .utils import override_storage_attr
from .utils import test
from .utils import test_many
from collectfast.management.commands.collectstatic import Command

Expand Down Expand Up @@ -39,8 +39,8 @@
}
)

test_aws_backends = test_many(**aws_backend_confs)
test_all_backends = test_many(**all_backend_confs)
make_test_aws_backends = test_many(**aws_backend_confs)
make_test_all_backends = test_many(**all_backend_confs)


def call_collectstatic(*args, **kwargs):
Expand All @@ -52,7 +52,7 @@ def call_collectstatic(*args, **kwargs):
return out.getvalue()


@test_all_backends
@make_test_all_backends
def test_basics(case):
# type: (TestCase) -> None
clean_static_dir()
Expand All @@ -62,7 +62,7 @@ def test_basics(case):
case.assertIn("0 static files copied.", call_collectstatic())


@test_all_backends
@make_test_all_backends
@override_setting("threads", 5)
def test_threads(case):
# type: (TestCase) -> None
Expand All @@ -73,7 +73,7 @@ def test_threads(case):
case.assertIn("0 static files copied.", call_collectstatic())


@test
@make_test
@override_django_settings(
STATICFILES_STORAGE="django.contrib.staticfiles.storage.StaticFilesStorage"
)
Expand All @@ -84,15 +84,15 @@ def test_disable_collectfast_with_default_storage(case):
case.assertIn("1 static file copied.", call_collectstatic(disable_collectfast=True))


@test
@make_test
def test_disable_collectfast(case):
# type: (TestCase) -> None
clean_static_dir()
create_static_file()
case.assertIn("1 static file copied.", call_collectstatic(disable_collectfast=True))


@test
@make_test
def test_dry_run(case):
# type: (TestCase) -> None
clean_static_dir()
Expand All @@ -106,7 +106,7 @@ def test_dry_run(case):
case.assertTrue("Pretending to delete", result)


@test_aws_backends
@make_test_aws_backends
@override_storage_attr("gzip", True)
@override_setting("aws_is_gzipped", True)
def test_aws_is_gzipped(case):
Expand All @@ -118,7 +118,7 @@ def test_aws_is_gzipped(case):
case.assertIn("0 static files copied.", call_collectstatic())


@test
@make_test
@override_django_settings(
STATICFILES_STORAGE="storages.backends.s3boto.S3BotoStorage",
COLLECTFAST_STRATEGY=None,
Expand All @@ -128,7 +128,7 @@ def test_recognizes_boto_storage(case):
case.assertEqual(Command._load_strategy().__name__, "BotoStrategy")


@test
@make_test
@override_django_settings(
STATICFILES_STORAGE="storages.backends.s3boto3.S3Boto3Storage",
COLLECTFAST_STRATEGY=None,
Expand All @@ -138,7 +138,7 @@ def test_recognizes_boto3_storage(case):
case.assertEqual(Command._load_strategy().__name__, "Boto3Strategy")


@test
@make_test
@override_django_settings(STATICFILES_STORAGE=None, COLLECTFAST_STRATEGY=None)
def test_raises_for_unrecognized_storage(case):
# type: (TestCase) -> None
Expand Down
6 changes: 3 additions & 3 deletions collectfast/tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@
static_dir = pathlib.Path(django_settings.STATICFILES_DIRS[0]) # type: Final


def test(func):
def make_test(func):
# type: (F) -> Type[unittest.TestCase]
"""
Creates a class that inherits from `unittest.TestCase` with the decorated
function as a method. Create tests like this:
>>> fn = lambda x: 1337
>>> @test
>>> @make_test
... def test_fn(case):
... case.assertEqual(fn(), 1337)
"""
Expand All @@ -45,7 +45,7 @@ def test(func):
function as a method. Create tests like this:
>>> fn = lambda x: 1337
>>> @test
>>> @make_test
... def test_fn(case):
... case.assertEqual(fn(), 1337)
"""
Expand Down
18 changes: 18 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os
import shutil

import pytest
from django.conf import settings


@pytest.fixture(autouse=True)
def create_test_directories():
paths = (settings.STATICFILES_DIRS[0], settings.STATIC_ROOT, settings.MEDIA_ROOT)
for path in paths:
if not os.path.exists(path):
os.makedirs(path)
try:
yield
finally:
for path in paths:
shutil.rmtree(path)
Loading

0 comments on commit 7608d4f

Please sign in to comment.