From 2e279081e6e8d62ee743acde83647d53f51dc49a Mon Sep 17 00:00:00 2001 From: Thomas Marwitz Date: Tue, 10 Dec 2024 14:35:21 +0100 Subject: [PATCH] Pre-commit fixes. Whitespace at eof, ruff pyupgrade, typos, formatting. --- .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/workflows/ci.yml | 2 + .github/workflows/codeql-analysis.yml | 34 +++++----- .github/workflows/codeql.yml | 63 +++++++++---------- LICENSE | 2 +- README.rst | 2 +- docker-compose.yml | 10 +-- docs/boto.rst | 2 +- docs/changes.rst | 6 +- docs/development.rst | 2 +- minimalkv/_constants.py | 4 +- minimalkv/_key_value_store.py | 6 +- minimalkv/_mixins.py | 8 +-- minimalkv/_store_creation.py | 12 +--- minimalkv/cache.py | 6 +- minimalkv/crypt.py | 2 +- minimalkv/decorator.py | 2 +- minimalkv/fs.py | 2 +- minimalkv/net/boto3store.py | 7 +-- pixi.toml | 1 - pyproject.toml | 5 ++ terraform/main.tf | 4 +- tests/basic_store.py | 32 +++++----- tests/idgens.py | 6 +- tests/minio-container/files/file1.txt | 2 +- tests/minio-container/files/file2.txt | 2 +- tests/minio-container/scripts/startup.sh | 2 +- .../test_creation_from_params.py | 2 +- tests/test_azure_store.py | 8 +-- tests/test_boto3_store.py | 4 +- tests/test_boto_store.py | 4 +- tests/test_gcloud_store.py | 5 +- tests/test_hmac.py | 14 ++--- tests/test_prefix_decorator.py | 4 +- tests/test_s3fs_aws.py | 2 +- tests/test_s3fs_minio.py | 2 +- 36 files changed, 135 insertions(+), 140 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index f0d3248e..cc5d3154 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,5 +2,7 @@ Thank you for pull request. Below are a few things we ask you kindly to self-check before getting a review. Remove checks that are not relevant. --> + Checklist -* [ ] Added a `docs/changes.rst` entry + +- [ ] Added a `docs/changes.rst` entry diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b60e26a5..a082bcb2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,3 +114,5 @@ jobs: environments: py38 # as in pyproject.toml - name: Install repository run: pixi run -e py38 postinstall + - name: Run mypy + run: pixi run -e py38 mypy minimalkv diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1460ce97..8d19a00e 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -13,12 +13,12 @@ name: "CodeQL" on: push: - branches: [ main ] + branches: [main] pull_request: # The branches below must be a subset of the branches above - branches: [ main ] + branches: [main] schedule: - - cron: '31 21 * * 1' + - cron: "31 21 * * 1" jobs: analyze: @@ -28,21 +28,21 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python' ] + language: ["python"] steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 409727bb..1c1a96c5 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -14,12 +14,12 @@ name: "CodeQL" on: workflow_dispatch: push: - branches: [ "main" ] + branches: ["main"] pull_request: # The branches below must be a subset of the branches above - branches: [ "main" ] + branches: ["main"] schedule: - - cron: '25 17 * * 5' + - cron: "25 17 * * 5" jobs: analyze: @@ -33,43 +33,42 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python' ] + language: ["python"] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v3 - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 + # ℹī¸ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/LICENSE b/LICENSE index b5584059..13081dc5 100644 --- a/LICENSE +++ b/LICENSE @@ -44,7 +44,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER --- +-- The original storefact source had the following license: Copyright (c) 2015-2017, Blue Yonder GmbH diff --git a/README.rst b/README.rst index a1064cb3..b53bc12d 100644 --- a/README.rst +++ b/README.rst @@ -12,7 +12,7 @@ minimalkv is `available on PyPI `_ and can be installed through `pip `_:: pip install minimalkv - + or via ``conda`` on `conda-forge `_:: conda install -c conda-forge minimalkv diff --git a/docker-compose.yml b/docker-compose.yml index 81ef0e86..1a5a6dd7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: image: fsouza/fake-gcs-server container_name: fake-gcs-server ports: - - 4443:4443 + - 4443:4443 command: -scheme http azure: image: mcr.microsoft.com/azure-storage/azurite @@ -18,7 +18,7 @@ services: container_name: minio ports: - 9000:9000 - - 9001:9001 # Debugging over Web GUI if needed + - 9001:9001 # Debugging over Web GUI if needed environment: MINIO_ACCESS_KEY: minio MINIO_SECRET_KEY: miniostorage @@ -26,17 +26,17 @@ services: image: mongo container_name: mongodb ports: - - 27017:27017 + - 27017:27017 redis: image: redis container_name: redis ports: - - 6379:6379 + - 6379:6379 postgres: image: postgres container_name: postgreSQL ports: - - 5432:5432 + - 5432:5432 environment: POSTGRES_USER: minimalkv_test POSTGRES_PASSWORD: minimalkv_test diff --git a/docs/boto.rst b/docs/boto.rst index 28ceb4f8..f0a8d824 100644 --- a/docs/boto.rst +++ b/docs/boto.rst @@ -73,7 +73,7 @@ The unit tests for S3 will be run by travis against a local minio instance, emul Constructs a new boto based backend. :param bucket: An instance of :class:`boto.s3.bucket.Bucket`, - :class:`boto.gs.bucket.Bucket` or similiar. + :class:`boto.gs.bucket.Bucket` or similar. :param prefix: A string that will transparently prefixed to all handled keys. :param url_valid_time=0: When using diff --git a/docs/changes.rst b/docs/changes.rst index 44ec8e2f..825a2d0d 100644 --- a/docs/changes.rst +++ b/docs/changes.rst @@ -6,7 +6,7 @@ Changelog * Add a real AWS integration test for S3FSStore * Add minio test for S3FSStore * `verify` url param that can be passed to url when creating a `[h]s3://` store now really controls SSL verifaction -* Refactor tests to not skip Boto3Store / S3FSStore tests anymore if `boto` is unavailible +* Refactor tests to not skip Boto3Store / S3FSStore tests anymore if `boto` is unavailable 1.9.0 ===== @@ -41,7 +41,7 @@ Changelog 1.8.1 ===== * Drop `pkg_resources` and use `importlib.metadata` to access package version string. -* Add missing `region_name` in `s3fs` store creation to set required location contraint +* Add missing `region_name` in `s3fs` store creation to set required location constraint during bucket creation. 1.8.0 @@ -184,7 +184,7 @@ Changelog * Use ``BlockBlobService.list_blob_names`` in ``minimalkv.net.azurestore.AzureBlockBlobStore.iter_keys``. This will only parse the names from Azure's XML response thus reducing CPU time - siginificantly for this function. + significantly for this function. * They ``.keys()`` method on Python 3 now returns a list. This is in line with the documentation and the behaviour on Python 2. It used to return a generator. diff --git a/docs/development.rst b/docs/development.rst index 7634e58b..c9423df7 100644 --- a/docs/development.rst +++ b/docs/development.rst @@ -18,4 +18,4 @@ To run the tests, setup the Python environment and execute: :: docker-compose up -d - pytest -n auto --dist loadfile \ No newline at end of file + pytest -n auto --dist loadfile diff --git a/minimalkv/_constants.py b/minimalkv/_constants.py index d91bea55..9b9dc264 100644 --- a/minimalkv/_constants.py +++ b/minimalkv/_constants.py @@ -4,7 +4,7 @@ NOT_SET = "not_set" VALID_NON_NUM = r"""\`\!"#$%&'()+,-.<=>?@[]^_{}~""" -VALID_KEY_REGEXP = "^[%s0-9a-zA-Z]+$" % re.escape(VALID_NON_NUM) +VALID_KEY_REGEXP = f"^[{re.escape(VALID_NON_NUM)}0-9a-zA-Z]+$" """This regular expression tests if a key is valid. Allowed are all alphanumeric characters, as well as ``!"`#$%&'()+,-.<=>?@[]^_{}~``.""" @@ -12,7 +12,7 @@ """A compiled version of :data:`~minimalkv._constants.VALID_KEY_REGEXP`.""" VALID_NON_NUM_EXTENDED = VALID_NON_NUM + r"/ " -VALID_KEY_REGEXP_EXTENDED = "^[%s0-9a-zA-Z]+$" % re.escape(VALID_NON_NUM_EXTENDED) +VALID_KEY_REGEXP_EXTENDED = f"^[{re.escape(VALID_NON_NUM_EXTENDED)}0-9a-zA-Z]+$" """This regular expression tests if a key is valid when the extended keyspace mixin is used. Allowed are all alphanumeric characters, as well as ``!"`#$%&'()+,-.<=>?@[]^_{}~/``. and spaces""" VALID_KEY_RE_EXTENDED = re.compile(VALID_KEY_REGEXP_EXTENDED) diff --git a/minimalkv/_key_value_store.py b/minimalkv/_key_value_store.py index 95596fab..62698c5f 100644 --- a/minimalkv/_key_value_store.py +++ b/minimalkv/_key_value_store.py @@ -7,7 +7,7 @@ from minimalkv._constants import VALID_KEY_RE from minimalkv._mixins import UrlMixin -# Only here to keep backwards-compatability +# Only here to keep backwards-compatibility key_type = str @@ -143,7 +143,7 @@ def iter_prefixes(self, delimiter: str, prefix: str = "") -> Iterator[str]: """Iterate over unique prefixes in the store up to delimiter, starting with prefix. If ``prefix`` contains ``delimiter``, return the prefix up to the first - occurence of delimiter after the prefix. + occurrence of delimiter after the prefix. The default uses an naive key iteration. Some backends may implement more efficient methods. @@ -361,7 +361,7 @@ def _has_key(self, key: str) -> bool: Parameters ---------- key : str - Key to check the existance of. + Key to check the existence of. """ return key in self.keys() diff --git a/minimalkv/_mixins.py b/minimalkv/_mixins.py index 71bee5f3..07a153ee 100644 --- a/minimalkv/_mixins.py +++ b/minimalkv/_mixins.py @@ -112,10 +112,10 @@ def _valid_ttl( return ttl_secs if not isinstance(ttl_secs, (int, float)): - raise ValueError("Not a valid ttl_secs value: %r" % ttl_secs) + raise ValueError(f"Not a valid ttl_secs value: {ttl_secs}") if ttl_secs < 0: - raise ValueError("ttl_secs must not be negative: %r" % ttl_secs) + raise ValueError(f"ttl_secs must not be negative: {ttl_secs}") return ttl_secs @@ -411,6 +411,6 @@ def _check_valid_key(self, key: Optional[str]) -> None: """ if key is not None: if not isinstance(key, str): - raise ValueError("%r is not a valid key type" % key) + raise ValueError(f"{key} is not a valid key type") elif not VALID_KEY_RE_EXTENDED.match(key) or key == "/": - raise ValueError("%r contains illegal characters" % key) + raise ValueError(f"{key} contains illegal characters") diff --git a/minimalkv/_store_creation.py b/minimalkv/_store_creation.py index e11fb5e0..11c9f122 100644 --- a/minimalkv/_store_creation.py +++ b/minimalkv/_store_creation.py @@ -171,14 +171,8 @@ def _build_azure_url( protocol = default_endpoints_protocol or "https" if use_sas: return ( - "DefaultEndpointsProtocol={protocol};AccountName={account_name};" - "SharedAccessSignature={shared_access_signature}".format( - protocol=protocol, - account_name=account_name, - shared_access_signature=account_key, - ) + f"DefaultEndpointsProtocol={protocol};AccountName={account_name};" + f"SharedAccessSignature={account_key}" ) else: - return "DefaultEndpointsProtocol={protocol};AccountName={account_name};AccountKey={account_key}".format( - protocol=protocol, account_name=account_name, account_key=account_key - ) + return f"DefaultEndpointsProtocol={protocol};AccountName={account_name};AccountKey={account_key}" diff --git a/minimalkv/cache.py b/minimalkv/cache.py index 84cdc884..23121a87 100644 --- a/minimalkv/cache.py +++ b/minimalkv/cache.py @@ -17,7 +17,7 @@ class CacheDecorator(StoreDecorator): backing store. After their completion, the cache will be updated. No cache maintainenace above this is done by the decorator. The caching - store itselfs decides how large to grow the cache and which data to keep, + store itself decides how large to grow the cache and which data to keep, which data to throw away. Parameters @@ -25,7 +25,7 @@ class CacheDecorator(StoreDecorator): cache : KeyValueStore The caching backend. store : KeyValueStore - The backing store. This is the "authorative" backend. + The backing store. This is the "authoritative" backend. """ def __init__(self, cache: KeyValueStore, store: KeyValueStore): @@ -111,7 +111,7 @@ def get_file(self, key: str, file: Union[str, BinaryIO]) -> str: # return from cache return self.cache.get_file(key, file) - # if an IOError occured, file pointer may be dirty - cannot proceed + # if an IOError occurred, file pointer may be dirty - cannot proceed # safely def open(self, key: str) -> BinaryIO: diff --git a/minimalkv/crypt.py b/minimalkv/crypt.py index 7d564d8e..ccbe8be3 100644 --- a/minimalkv/crypt.py +++ b/minimalkv/crypt.py @@ -119,7 +119,7 @@ def get(self, key): # noqa D hm.update(buf) if not hm.digest() == hash: - raise VerificationException("Invalid hash on key %r" % key) + raise VerificationException(f"Invalid hash on key {key}") return buf diff --git a/minimalkv/decorator.py b/minimalkv/decorator.py index 89152d09..376f0b37 100644 --- a/minimalkv/decorator.py +++ b/minimalkv/decorator.py @@ -177,7 +177,7 @@ class URLEncodeKeysDecorator(KeyTransformingDecorator): def _map_key(self, key: str) -> str: # noqa D if not isinstance(key, str): - raise ValueError("%r is not a unicode string" % key) + raise ValueError(f"{key} is not a unicode string") quoted = quote_plus(key.encode("utf-8")) if isinstance(quoted, bytes): quoted = quoted.decode("utf-8") diff --git a/minimalkv/fs.py b/minimalkv/fs.py index 72bca9ca..deb2f0b9 100644 --- a/minimalkv/fs.py +++ b/minimalkv/fs.py @@ -177,7 +177,7 @@ def iter_prefixes(self, delimiter: str, prefix: str = "") -> Iterator[str]: """Iterate over unique prefixes in the store up to delimiter, starting with prefix. If ``prefix`` contains ``delimiter``, return the prefix up to the first - occurence of delimiter after the prefix. + occurrence of delimiter after the prefix. Parameters ---------- diff --git a/minimalkv/net/boto3store.py b/minimalkv/net/boto3store.py index d5611571..341576af 100644 --- a/minimalkv/net/boto3store.py +++ b/minimalkv/net/boto3store.py @@ -61,8 +61,7 @@ def seek(self, offset: int, whence=io.SEEK_SET) -> int: # noqa D self.position = self.size + offset else: raise ValueError( - "invalid whence (%r, should be %d, %d, %d)" - % (whence, io.SEEK_SET, io.SEEK_CUR, io.SEEK_END) + f"invalid whence ({whence}, should be {io.SEEK_SET}, {io.SEEK_CUR}, {io.SEEK_END})" ) return self.position @@ -73,7 +72,7 @@ def seekable(self) -> bool: # noqa D def read(self, size=-1): # noqa D if size == -1: # Read to the end of the file - range_header = "bytes=%d-" % self.position + range_header = f"bytes={self.position}-" self.seek(offset=0, whence=io.SEEK_END) else: new_position = self.position + size @@ -83,7 +82,7 @@ def read(self, size=-1): # noqa D if new_position >= self.size: return self.read() - range_header = "bytes=%d-%d" % (self.position, new_position - 1) + range_header = f"bytes={self.position}-{new_position - 1}" self.seek(offset=size, whence=io.SEEK_CUR) return self.s3_object.get(Range=range_header)["Body"].read() diff --git a/pixi.toml b/pixi.toml index 0df71a79..aec5235c 100644 --- a/pixi.toml +++ b/pixi.toml @@ -45,7 +45,6 @@ mock = "*" [feature.test.tasks] test = "pytest" test-coverage = "pytest --cov=minimalkv --cov-report=xml --cov-report=term-missing" -mypy = "mypy minimalkv" [feature.build.dependencies] python-build = "*" diff --git a/pyproject.toml b/pyproject.toml index d99f26b0..ac5b421b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,3 +69,8 @@ check_untyped_defs = true [tool.pytest.ini_options] testpaths = ["tests"] + +[tool.typos] +files.extend-exclude = ["tests/storefact"] +[tool.typos.default.extend-words] +ue = "ue" diff --git a/terraform/main.tf b/terraform/main.tf index c8541da9..3be53e5e 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -50,7 +50,7 @@ resource "google_iam_workload_identity_pool_provider" "github_actions_provider" resource "google_service_account" "service_account_gha" { account_id = "sa-github-actions" - display_name = "GHA Service Accont" + display_name = "GHA Service Account" } # Grant the external identities permission to impersonate the service account @@ -76,4 +76,4 @@ resource "google_project_iam_member" "sa-storageaccess" { role = "roles/storage.admin" member = "serviceAccount:${google_service_account.service_account_gha.email}" project = "qc-minimalkv" -} \ No newline at end of file +} diff --git a/tests/basic_store.py b/tests/basic_store.py index 93fc6c56..67cc085f 100644 --- a/tests/basic_store.py +++ b/tests/basic_store.py @@ -52,24 +52,24 @@ def test_store_and_copy(self, store, key, key2, value): pytest.skip( "'test_store_and_copy' can only be tested with stores that use the 'CopyMixin' mixin." ) - store.put(key, value) - assert store.get(key) == value + store.put(key, value) # type: ignore[attr-defined] + assert store.get(key) == value # type: ignore[attr-defined] store.copy(key, key2) - assert store.get(key) == value - assert store.get(key2) == value + assert store.get(key) == value # type: ignore[attr-defined] + assert store.get(key2) == value # type: ignore[attr-defined] def test_store_and_copy_overwrite(self, store, key, key2, value, value2): if not isinstance(store, CopyMixin): pytest.skip( "'test_store_and_copy_overwrite' can only be tested with stores that use the 'CopyMixin' mixin." ) - store.put(key, value) - store.put(key2, value2) - assert store.get(key) == value - assert store.get(key2) == value2 + store.put(key, value) # type: ignore[attr-defined] + store.put(key2, value2) # type: ignore[attr-defined] + assert store.get(key) == value # type: ignore[attr-defined] + assert store.get(key2) == value2 # type: ignore[attr-defined] store.copy(key, key2) - assert store.get(key) == value - assert store.get(key2) == value + assert store.get(key) == value # type: ignore[attr-defined] + assert store.get(key2) == value # type: ignore[attr-defined] def test_open_incremental_read(self, store, key, long_value): store.put_file(key, BytesIO(long_value)) @@ -78,27 +78,27 @@ def test_open_incremental_read(self, store, key, long_value): assert long_value[3:5] == ok.read(2) assert long_value[5:8] == ok.read(3) - def test_key_error_on_nonexistant_get(self, store, key): + def test_key_error_on_nonexistent_get(self, store, key): with pytest.raises(KeyError): store.get(key) - def test_key_error_on_nonexistant_copy(self, store, key, key2): + def test_key_error_on_nonexistent_copy(self, store, key, key2): if not isinstance(store, CopyMixin): pytest.skip( - "'test_key_error_on_nonexistant_copy' can only be tested with stores that use the 'CopyMixin' mixin." + "'test_key_error_on_nonexistent_copy' can only be tested with stores that use the 'CopyMixin' mixin." ) with pytest.raises(KeyError): store.copy(key, key2) - def test_key_error_on_nonexistant_open(self, store, key): + def test_key_error_on_nonexistent_open(self, store, key): with pytest.raises(KeyError): store.open(key) - def test_key_error_on_nonexistant_get_file(self, store, key): + def test_key_error_on_nonexistent_get_file(self, store, key): with pytest.raises(KeyError): store.get_file(key, BytesIO()) - def test_key_error_on_nonexistant_get_filename(self, store, key, tmp_path): + def test_key_error_on_nonexistent_get_filename(self, store, key, tmp_path): with pytest.raises(KeyError): store.get_file(key, "/dev/null") diff --git a/tests/idgens.py b/tests/idgens.py index 0454341e..a71766b5 100644 --- a/tests/idgens.py +++ b/tests/idgens.py @@ -87,11 +87,7 @@ def templated_hashstore(self, store, hashfunc, idgen_template): @pytest.fixture def validate_hash(self, hashfunc): - hash_regexp = re.compile( - r"^[0-9a-f]{{{}}}$".format( - hashfunc().digest_size * 2, - ) - ) + hash_regexp = re.compile(rf"^[0-9a-f]{{{hashfunc().digest_size * 2}}}$") return hash_regexp.match diff --git a/tests/minio-container/files/file1.txt b/tests/minio-container/files/file1.txt index dd954e7a..ac3e272b 100644 --- a/tests/minio-container/files/file1.txt +++ b/tests/minio-container/files/file1.txt @@ -1 +1 @@ -content1 \ No newline at end of file +content1 diff --git a/tests/minio-container/files/file2.txt b/tests/minio-container/files/file2.txt index db00fd65..637f0347 100644 --- a/tests/minio-container/files/file2.txt +++ b/tests/minio-container/files/file2.txt @@ -1 +1 @@ -content2 \ No newline at end of file +content2 diff --git a/tests/minio-container/scripts/startup.sh b/tests/minio-container/scripts/startup.sh index ef4b30fe..223209ab 100755 --- a/tests/minio-container/scripts/startup.sh +++ b/tests/minio-container/scripts/startup.sh @@ -29,4 +29,4 @@ mc cp /files/file2.txt myminio/bucket2 # Keep container running -wait \ No newline at end of file +wait diff --git a/tests/store_creation/test_creation_from_params.py b/tests/store_creation/test_creation_from_params.py index 72729ca7..9d4b8976 100644 --- a/tests/store_creation/test_creation_from_params.py +++ b/tests/store_creation/test_creation_from_params.py @@ -4,7 +4,7 @@ def test_create_store_azure(mocker): - # Mock HAzureBlockBlobStore also here, becase otherwise it will try to inherit from + # Mock HAzureBlockBlobStore also here, because otherwise it will try to inherit from # the mock object `mock_azure` created below, which will fail. mock_hazure = mocker.patch("minimalkv._hstores.HAzureBlockBlobStore") mock_azure = mocker.patch("minimalkv.net.azurestore.AzureBlockBlobStore") diff --git a/tests/test_azure_store.py b/tests/test_azure_store.py index 0dee10f9..d526ae17 100644 --- a/tests/test_azure_store.py +++ b/tests/test_azure_store.py @@ -34,9 +34,7 @@ def get_azure_conn_string(): account_key = parser.get(section, "account_key") protocol = parser.get(section, "protocol") endpoint = parser.get(section, "endpoint") - conn_string = "DefaultEndpointsProtocol={};AccountName={};AccountKey={}".format( - protocol, account_name, account_key - ) + conn_string = f"DefaultEndpointsProtocol={protocol};AccountName={account_name};AccountKey={account_key}" if endpoint: conn_string += f";BlobEndpoint={endpoint}" return conn_string @@ -53,12 +51,12 @@ def _delete_container(conn_string, container): s.delete_container(container) except AzureError as ex: # ignore the ContainerNotFound error: - if ex.error_code != "ContainerNotFound": + if ex.error_code != "ContainerNotFound": # type: ignore[attr-defined] raise s.close() except ImportError: # for azure-storage-blob<12 - from azure.storage.blob import BlockBlobService + from azure.storage.blob import BlockBlobService # type: ignore[attr-defined] s = BlockBlobService(connection_string=conn_string) s.delete_container(container) diff --git a/tests/test_boto3_store.py b/tests/test_boto3_store.py index 832d237d..aef1ec05 100644 --- a/tests/test_boto3_store.py +++ b/tests/test_boto3_store.py @@ -72,11 +72,11 @@ def store(self, request, boto3store, s3fsstore): # Disable max key length test as it leads to problems with minio test_max_key_length = None - def test_get_filename_nonexistant(self, store, key, tmp_path): + def test_get_filename_nonexistent(self, store, key, tmp_path): with pytest.raises(KeyError): store.get_file(key, os.path.join(str(tmp_path), "a")) - def test_key_error_on_nonexistant_get_filename(self, store, key, tmp_path): + def test_key_error_on_nonexistent_get_filename(self, store, key, tmp_path): with pytest.raises(KeyError): store.get_file(key, os.path.join(str(tmp_path), "a")) diff --git a/tests/test_boto_store.py b/tests/test_boto_store.py index 2912bc0a..95a8b937 100644 --- a/tests/test_boto_store.py +++ b/tests/test_boto_store.py @@ -85,14 +85,14 @@ def store(self, bucket, prefix, reduced_redundancy): # Disable max key length test as it leads to problems with minio test_max_key_length = None - def test_get_filename_nonexistant(self, store, key, tmp_path): + def test_get_filename_nonexistent(self, store, key, tmp_path): # NOTE: boto misbehaves here and tries to erase the target file # the parent tests use /dev/null, which you really should not try # to os.remove! with pytest.raises(KeyError): store.get_file(key, os.path.join(str(tmp_path), "a")) - def test_key_error_on_nonexistant_get_filename(self, store, key, tmp_path): + def test_key_error_on_nonexistent_get_filename(self, store, key, tmp_path): with pytest.raises(KeyError): store.get_file(key, os.path.join(str(tmp_path), "a")) diff --git a/tests/test_gcloud_store.py b/tests/test_gcloud_store.py index 20a0bc92..4742f592 100644 --- a/tests/test_gcloud_store.py +++ b/tests/test_gcloud_store.py @@ -8,7 +8,7 @@ import pickle import time from configparser import ConfigParser -from typing import Optional +from typing import Any, Generator, Optional, Union from uuid import uuid4 from basic_store import BasicStore, OpenSeekTellStore @@ -23,7 +23,7 @@ @pytest.fixture(scope="module") -def gc_credentials(): +def gc_credentials() -> Generator[Union[AnonymousCredentials, str, None], Any, None]: # If we have credentials in the environment, we don't need to do anything if "GOOGLE_APPLICATION_CREDENTIALS" in os.environ: yield None @@ -43,6 +43,7 @@ def gc_credentials(): credentials_path or emulator_endpoint ), "Either set endpoint (for gc emulation) or credentials_json_path (for actual gc)" + credentials: Union[AnonymousCredentials, str, None] = None if emulator_endpoint: # google's client library looks for this env var # if we didn't set it it would use the standard endpoint diff --git a/tests/test_hmac.py b/tests/test_hmac.py index 922b14e0..4e988e24 100644 --- a/tests/test_hmac.py +++ b/tests/test_hmac.py @@ -10,7 +10,7 @@ class TestHMACFileReader: @pytest.fixture - def bad_datas(self, value): + def bad_data(self, value): val = value * 3 def _alter_byte(byte_string, pos): @@ -75,19 +75,19 @@ def test_reading_with_limit( assert b"".join(chunks) == value - def test_manipulated_input_full_read(self, secret_key, value, bad_datas, hashfunc): - for bad_data in bad_datas: + def test_manipulated_input_full_read(self, secret_key, value, bad_data, hashfunc): + for bad_data_point in bad_data: reader = _HMACFileReader( - hmac.HMAC(secret_key, None, hashfunc), BytesIO(bad_data) + hmac.HMAC(secret_key, None, hashfunc), BytesIO(bad_data_point) ) with pytest.raises(VerificationException): reader.read() - def test_manipulated_input_incremental_read(self, secret_key, bad_datas, hashfunc): - for bad_data in bad_datas: + def test_manipulated_input_incremental_read(self, secret_key, bad_data, hashfunc): + for bad_data_point in bad_data: reader = _HMACFileReader( - hmac.HMAC(secret_key, None, hashfunc), BytesIO(bad_data) + hmac.HMAC(secret_key, None, hashfunc), BytesIO(bad_data_point) ) with pytest.raises(VerificationException): diff --git a/tests/test_prefix_decorator.py b/tests/test_prefix_decorator.py index 0a1b3dcc..56ec1dea 100644 --- a/tests/test_prefix_decorator.py +++ b/tests/test_prefix_decorator.py @@ -87,5 +87,5 @@ def test_multiple_prefixes_one_store(self, store, prefix, prefix2, key, value): def test_pickle(self, store): import pickle - rountrip = pickle.loads(pickle.dumps(store)) - assert isinstance(rountrip, PrefixDecorator) + roundtrip = pickle.loads(pickle.dumps(store)) + assert isinstance(roundtrip, PrefixDecorator) diff --git a/tests/test_s3fs_aws.py b/tests/test_s3fs_aws.py index 7a5568f6..5c727a81 100644 --- a/tests/test_s3fs_aws.py +++ b/tests/test_s3fs_aws.py @@ -36,7 +36,7 @@ def aws_credentials() -> Tuple[str, str, Union[str, None]]: if "CI_IN_FORK" not in os.environ or os.environ["CI_IN_FORK"].lower() == "true": # We skip if the variable is not set at all (local development) - # or if it is explicitely set to "true". + # or if it is explicitly set to "true". if "CI_IN_FORK" in os.environ: msg += "Skipping, because you (or the CI) set 'CI_IN_FORK=true'." diff --git a/tests/test_s3fs_minio.py b/tests/test_s3fs_minio.py index 640e86b9..977e4c54 100644 --- a/tests/test_s3fs_minio.py +++ b/tests/test_s3fs_minio.py @@ -7,7 +7,7 @@ class User(NamedTuple): access_key: str secret_key: str bucket_name: str - # The mapping between users and accessable buckets can be arbitrary. + # The mapping between users and accessible buckets can be arbitrary. # The config in "tests/minio-container/policies" is very simple, allowing # user1 -> bucket1 # user2 -> bucket2