diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml index dd9c7ec..e808ef2 100644 --- a/.github/workflows/pull_request.yaml +++ b/.github/workflows/pull_request.yaml @@ -11,9 +11,51 @@ concurrency: cancel-in-progress: true jobs: + flake8: + name: flake8 + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + - run: python -m pip install flake8 + - name: flake8 + uses: liskin/gh-problem-matcher-wrap@e7b7beaaafa52524748b31a381160759d68d61fb + with: + linters: flake8 + run: flake8 + + isort: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13' + - run: python -m pip install "isort<6" + - name: isort + # Pinned to v3.0.0. + uses: liskin/gh-problem-matcher-wrap@e7b7beaaafa52524748b31a381160759d68d61fb + with: + linters: isort + run: isort --check --diff diskcollections tests + black: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: black + uses: psf/black@stable + tests: name: Python ${{ matrix.python-version }} runs-on: ubuntu-22.04 + needs: ["flake8", "isort", "black"] strategy: matrix: python-version: @@ -50,7 +92,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.11" + python-version: "3.12" - name: Install dependencies run: python -m pip install --upgrade coverage[toml] diff --git a/README.rst b/README.rst index ec6367d..96f6f5d 100644 --- a/README.rst +++ b/README.rst @@ -205,7 +205,6 @@ Contribute $ pyenv install 3.7 3.8 3.9 3.10 3.11 3.12 3.13 - #. Check your code and tests with **tox** .. code-block:: bash @@ -234,6 +233,11 @@ Contribute py313: OK (0.75=setup[0.01]+cmd[0.74] seconds) evaluation failed :( (4.12 seconds) +#. Lint your code + +.. code-block:: bash + + $ tox -e lint #. Send a pull request! diff --git a/diskcollections/iterables/__init__.py b/diskcollections/iterables/__init__.py index cbe434c..33744d4 100644 --- a/diskcollections/iterables/__init__.py +++ b/diskcollections/iterables/__init__.py @@ -1,32 +1,26 @@ from functools import partial -from ..serializers import ( - PickleZLibSerializer -) -from .clients import ( - PersistentDirectoryClient, - TemporaryDirectoryClient -) -from .iterables import ( - Deque, - List -) - +from ..serializers import PickleZLibSerializer +from .clients import PersistentDirectoryClient, TemporaryDirectoryClient +from .iterables import Deque, List FileList = partial( List, client_class=TemporaryDirectoryClient, - serializer_class=PickleZLibSerializer + serializer_class=PickleZLibSerializer, ) FileDeque = partial( Deque, client_class=TemporaryDirectoryClient, - serializer_class=PickleZLibSerializer + serializer_class=PickleZLibSerializer, ) __all__ = ( - 'List', 'Deque', - 'FileDeque', 'FileList', - 'PersistentDirectoryClient', 'TemporaryDirectoryClient', + "List", + "Deque", + "FileDeque", + "FileList", + "PersistentDirectoryClient", + "TemporaryDirectoryClient", ) diff --git a/diskcollections/iterables/clients.py b/diskcollections/iterables/clients.py index 4773d7e..5adfd77 100644 --- a/diskcollections/iterables/clients.py +++ b/diskcollections/iterables/clients.py @@ -15,7 +15,7 @@ class TemporaryDirectoryClient(IClientSequence): new content. """ - def __init__(self, iterable=(), mode='w+b'): + def __init__(self, iterable=(), mode="w+b"): super(TemporaryDirectoryClient, self).__init__() self.__mode = mode self.__files = [] @@ -23,11 +23,11 @@ def __init__(self, iterable=(), mode='w+b'): self.extend(iterable) def __repr__(self): - return 'TemporaryDirectoryClient(%s)' % self.__str__() + return "TemporaryDirectoryClient(%s)" % self.__str__() def __str__(self): - s = ', '.join(map(repr, self)) - return '[%s]' % s + s = ", ".join(map(repr, self)) + return "[%s]" % s def __del__(self): for f in self.__files: @@ -41,10 +41,7 @@ def __getitem__(self, index): if isinstance(index, slice): indices = index.indices(len(self)) start, stop, step = indices - items = ( - self[i] - for i in range(start, stop, step) - ) + items = (self[i] for i in range(start, stop, step)) return self.__class__(iterable=items, mode=self.__mode) file = self.__files[index] @@ -53,8 +50,7 @@ def __getitem__(self, index): def __setitem__(self, index, value): file = tempfile.TemporaryFile( - mode=self.__mode, - dir=self.__directory.name + mode=self.__mode, dir=self.__directory.name ) file.write(bytes(value)) self.__files[index] = file @@ -64,8 +60,7 @@ def __len__(self): def insert(self, index, value): file = tempfile.TemporaryFile( - mode=self.__mode, - dir=self.__directory.name + mode=self.__mode, dir=self.__directory.name ) file.write(value) self.__files.insert(index, file) @@ -83,7 +78,7 @@ class PersistentDirectoryClient(IClientSequence): def __init__(self, directory, iterable=()): super(PersistentDirectoryClient, self).__init__() - self.__mode = 'w+' + self.__mode = "w+" self.__files = [] if not os.path.exists(directory): @@ -93,11 +88,11 @@ def __init__(self, directory, iterable=()): self.extend(iterable) def __repr__(self): - return 'PersistentDirectoryClient(%s)' % self.__str__() + return "PersistentDirectoryClient(%s)" % self.__str__() def __str__(self): - s = ', '.join(map(repr, self)) - return '[%s]' % s + s = ", ".join(map(repr, self)) + return "[%s]" % s def __del__(self): for f in self.__files: @@ -137,10 +132,7 @@ def __getitem__(self, index): if isinstance(index, slice): indices = index.indices(len(self)) start, stop, step = indices - items = ( - self[i] - for i in range(start, stop, step) - ) + items = (self[i] for i in range(start, stop, step)) return self.__class__( self.__directory, iterable=items, diff --git a/diskcollections/iterables/iterables.py b/diskcollections/iterables/iterables.py index 960bfaf..b06df96 100644 --- a/diskcollections/iterables/iterables.py +++ b/diskcollections/iterables/iterables.py @@ -1,14 +1,12 @@ import collections + from diskcollections.py2to3 import izip class List(collections.abc.MutableSequence): def __init__( - self, - iterable=None, - client_class=None, - serializer_class=None + self, iterable=None, client_class=None, serializer_class=None ): super(List, self).__init__() self.__client = client_class() @@ -18,11 +16,11 @@ def __init__( self.extend(iterable) def __repr__(self): - return '%s%s' % (self.__class__, self.__str__()) + return "%s%s" % (self.__class__, self.__str__()) def __str__(self): - s = ', '.join(map(repr, self)) - return '[%s]' % s + s = ", ".join(map(repr, self)) + return "[%s]" % s def __copy__(self): return self.__class__( @@ -96,11 +94,11 @@ def __len__(self): return len(self.__client) def __repr__(self): - return '%s(%s)' % (self.__class__, self.__str__()) + return "%s(%s)" % (self.__class__, self.__str__()) def __str__(self): - s = ', '.join(map(repr, self)) - return '[%s]' % s + s = ", ".join(map(repr, self)) + return "[%s]" % s def __copy__(self): return self.__class__( diff --git a/diskcollections/py2to3.py b/diskcollections/py2to3.py index f28baee..21812bd 100644 --- a/diskcollections/py2to3.py +++ b/diskcollections/py2to3.py @@ -13,6 +13,7 @@ if sys.version_info >= (3, 4): TemporaryDirectory = tempfile.TemporaryDirectory else: + class TemporaryDirectory: def __init__(self): self._directory_path = tempfile.mkdtemp() diff --git a/diskcollections/serializers.py b/diskcollections/serializers.py index a8e1a46..bf301b1 100644 --- a/diskcollections/serializers.py +++ b/diskcollections/serializers.py @@ -14,9 +14,7 @@ class PickleZLibSerializer(ISerializer): @staticmethod def dumps( - obj, - protocol=pickle.HIGHEST_PROTOCOL, - level=zlib.Z_DEFAULT_COMPRESSION + obj, protocol=pickle.HIGHEST_PROTOCOL, level=zlib.Z_DEFAULT_COMPRESSION ): pickled = pickle.dumps(obj, protocol=protocol) compressed = zlib.compress(pickled, level) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9216134 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,2 @@ +[tool.black] +line-length = 79 \ No newline at end of file diff --git a/setup.py b/setup.py index 2fa11a2..2694a1d 100644 --- a/setup.py +++ b/setup.py @@ -1,45 +1,51 @@ import os -from setuptools import ( - find_packages, - setup, -) + +from setuptools import find_packages, setup def url(*args): - return '/'.join(args) + return "/".join(args) here = os.path.abspath(os.path.dirname(__file__)) -with open('README.rst', 'r') as f: +with open("README.rst", "r") as f: readme = f.read() -package_name = 'python-disk-collections' -url_profile = 'https://github.com/thegrymek' -version = '0.0.5' +package_name = "python-disk-collections" +url_profile = "https://github.com/thegrymek" +version = "0.0.5" setup( name=package_name, version=version, - author='thegrymek', - author_email='andrzej.grymkowski@gmail.com', - description='Package provides classes: FileList, FileDeque that behaves ' - 'like bulltins but keeps items at disk.', + author="thegrymek", + author_email="andrzej.grymkowski@gmail.com", + description="Package provides classes: FileList, FileDeque that behaves " + "like bulltins but keeps items at disk.", long_description=readme, packages=find_packages(), url=url(url_profile, package_name), - download_url=url(url_profile, package_name, 'archive/%s.tar.gz' % version), - license='MIT', + download_url=url(url_profile, package_name, "archive/%s.tar.gz" % version), + license="MIT", zip_safe=False, - keywords=['pickle', 'cache', 'collections', 'list', 'deque', 'json', - 'zlib', 'disk'], + keywords=[ + "pickle", + "cache", + "collections", + "list", + "deque", + "json", + "zlib", + "disk", + ], classifiers=[ - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Programming Language :: Python :: 3.13', - 'Topic :: Software Development :: Libraries :: Python Modules', + "Operating System :: OS Independent", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Libraries :: Python Modules", ], ) diff --git a/tests/sequences/test_clients.py b/tests/sequences/test_clients.py index 685da60..3eee7b5 100644 --- a/tests/sequences/test_clients.py +++ b/tests/sequences/test_clients.py @@ -5,24 +5,24 @@ class TestTemporaryDirectoryClient: - def create_client(self, mode='w+'): + def create_client(self, mode="w+"): return clients.TemporaryDirectoryClient(mode=mode) def test_append(self): client = self.create_client() - client.append('abc') - assert client[0] == 'abc' + client.append("abc") + assert client[0] == "abc" def test_insert(self): client = self.create_client() - client.extend(['a', 'b', 'c']) - client.insert(1, 'z') - assert list(client) == ['a', 'z', 'b', 'c'] + client.extend(["a", "b", "c"]) + client.insert(1, "z") + assert list(client) == ["a", "z", "b", "c"] def test_slice(self): client = self.create_client() - client.extend(['a', 'b', 'c']) - assert list(client[0:2]) == ['a', 'b'] + client.extend(["a", "b", "c"]) + assert list(client[0:2]) == ["a", "b"] class TestPersistentDirectoryClient: @@ -32,29 +32,29 @@ def create_client(self): def test_append(self): client = self.create_client() - client.append('abc') - assert client[0] == 'abc' + client.append("abc") + assert client[0] == "abc" def test_insert(self): client = self.create_client() - client.extend(['a', 'b', 'c', 'd']) - client.insert(1, 'z') - assert list(client) == ['a', 'z', 'b', 'c', 'd'] + client.extend(["a", "b", "c", "d"]) + client.insert(1, "z") + assert list(client) == ["a", "z", "b", "c", "d"] client[2] = "x" - assert list(client) == ['a', 'z', 'x', 'c', 'd'] + assert list(client) == ["a", "z", "x", "c", "d"] del client[3] - assert list(client) == ['a', 'z', 'x', 'd'] + assert list(client) == ["a", "z", "x", "d"] client.append("y") - assert list(client) == ['a', 'z', 'x', 'd', 'y'] + assert list(client) == ["a", "z", "x", "d", "y"] def test_slice(self): client = self.create_client() - client.extend(['a', 'b', 'c']) - assert list(client[0:2]) == ['a', 'b'] + client.extend(["a", "b", "c"]) + assert list(client[0:2]) == ["a", "b"] def test_dir_exists(self): client = self.create_client() diff --git a/tests/sequences/test_iterables.py b/tests/sequences/test_iterables.py index 01c6fcc..6b0ff92 100644 --- a/tests/sequences/test_iterables.py +++ b/tests/sequences/test_iterables.py @@ -1,21 +1,19 @@ import collections -import pytest from copy import copy -from diskcollections.iterables import ( - Deque, List, - FileList, FileDeque, -) +import pytest + +from diskcollections.iterables import Deque, FileDeque, FileList, List class TestFileList: def test_init(self): - l1 = FileList([1, 'a', [5, 'b']]) + l1 = FileList([1, "a", [5, "b"]]) assert len(l1) == 3 assert l1[0] == 1 - assert l1[1] == 'a' - assert l1[2] == [5, 'b'] + assert l1[1] == "a" + assert l1[2] == [5, "b"] def test_init_exceptions(self): with pytest.raises(TypeError): @@ -103,7 +101,7 @@ def test_convert(self): assert l1[2:3] == l1[2:3] def test_str(self): - l1 = [1, 'b', ['abc', 3], {1, 2, 3}] + l1 = [1, "b", ["abc", 3], {1, 2, 3}] f1 = FileList(l1) assert str(l1) == str(f1) @@ -134,9 +132,9 @@ def test_overlaps_insert(self): class TestFileDeque: def test_init(self): - d1 = FileDeque([1, 'a', [5, 'b']]) + d1 = FileDeque([1, "a", [5, "b"]]) assert len(d1) == 3 - assert d1 == [1, 'a', [5, 'b']] + assert d1 == [1, "a", [5, "b"]] def test_maxlen(self): d1 = FileDeque([1, 2], maxlen=3) @@ -255,13 +253,13 @@ def test_getitem(self): def test_insert(self): d1 = FileDeque() - d1.insert(5, 'c') - assert d1[0] == 'c' + d1.insert(5, "c") + assert d1[0] == "c" - d1.insert(0, 'a') - d1.insert(1, 'b') - assert d1[0] == 'a' - assert d1[1] == 'b' + d1.insert(0, "a") + d1.insert(1, "b") + assert d1[0] == "a" + assert d1[1] == "b" def test_count(self): d1 = FileDeque([1, 2, 2, 3, 3, 3]) @@ -270,7 +268,7 @@ def test_count(self): assert d1.count(3) == 3 def test_str(self): - l1 = [1, 'b', ['abc', 3], {1, 2, 3}] + l1 = [1, "b", ["abc", 3], {1, 2, 3}] d1 = FileDeque(l1) assert str(l1) == str(d1) diff --git a/tests/test_serializers.py b/tests/test_serializers.py index 6b260ba..a900c95 100644 --- a/tests/test_serializers.py +++ b/tests/test_serializers.py @@ -1,12 +1,8 @@ import pytest + from diskcollections import serializers -primitive_values = [ - 'a', - 1, - [1, 2, 3], - {'a': 1, 'b': 2, 'c': [1, 2, 3]} -] +primitive_values = ["a", 1, [1, 2, 3], {"a": 1, "b": 2, "c": [1, 2, 3]}] serializers_classes = [ serializers.JsonSerializer, @@ -16,17 +12,13 @@ ] -@pytest.fixture( - params=primitive_values, - ids=list(map(str, primitive_values)) -) +@pytest.fixture(params=primitive_values, ids=list(map(str, primitive_values))) def primitive_value(request): return request.param @pytest.fixture( - params=serializers_classes, - ids=list(map(str, serializers_classes)) + params=serializers_classes, ids=list(map(str, serializers_classes)) ) def serializer_class(request): return request.param diff --git a/tox.ini b/tox.ini index 5a1877d..3a9cc82 100644 --- a/tox.ini +++ b/tox.ini @@ -29,9 +29,13 @@ skips_dist = True skip_install = True deps = flake8 + black + isort readme_renderer commands = - flake8 + black diskcollections tests + isort diskcollections tests + flake8 diskcollections tests python setup.py check -r -s -m