Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor #97

Merged
merged 13 commits into from
Nov 6, 2023
Merged
11 changes: 0 additions & 11 deletions .flake8

This file was deleted.

14 changes: 7 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ jobs:
name: Unit tests - ${{ matrix.PYTHON_VERSION }}
runs-on: ubuntu-latest
permissions:
contents: 'read'
id-token: 'write'
contents: "read"
id-token: "write"
strategy:
fail-fast: false
matrix:
PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11"]
PYTHON_VERSION: ["3.8", "3.9", "3.10", "3.11", "3.12"]
services:
postgres:
image: postgres:11
Expand Down Expand Up @@ -45,12 +45,12 @@ jobs:
continue-on-error: true
- id: google_auth
if: steps.check-id-token.outcome == 'success'
name: 'Authenticate to Google Cloud'
name: "Authenticate to Google Cloud"
uses: google-github-actions/auth@v1
with:
workload_identity_provider: 'projects/498651197656/locations/global/workloadIdentityPools/qc-minimalkv-gh-actions-pool/providers/github-actions-provider'
service_account: 'sa-github-actions@qc-minimalkv.iam.gserviceaccount.com'
token_format: 'access_token'
workload_identity_provider: "projects/498651197656/locations/global/workloadIdentityPools/qc-minimalkv-gh-actions-pool/providers/github-actions-provider"
service_account: "sa-github-actions@qc-minimalkv.iam.gserviceaccount.com"
token_format: "access_token"
- name: Run the unittests
shell: bash -x -l {0}
run: |
Expand Down
45 changes: 45 additions & 0 deletions .github/workflows/pre-commit-autoupdate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: pre-commit autoupdate
on:
workflow_dispatch:
schedule:
- cron: "0 6 4 * *"

defaults:
run:
shell: bash -el {0}

jobs:
check_update:
name: Check if newer version exists
runs-on: ubuntu-latest
steps:
- name: Checkout branch
uses: actions/checkout@v4
# We need to checkout with SSH here to have actions run on the PR.
with:
ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Set up Conda env
uses: mamba-org/setup-micromamba@db1df3ba9e07ea86f759e98b575c002747e9e757
with:
environment-name: pre-commit
create-args: >-
-c
conda-forge
pre-commit
mamba
- name: Update pre-commit hooks and run
id: versions
env:
PRE_COMMIT_USE_MAMBA: 1
run: |
pre-commit autoupdate
pre-commit run -a || true
- uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38
with:
commit-message: "Auto-update pre-commit hooks"
title: "Auto-update pre-commit hooks"
body: |
New versions of the used pre-commit hooks were detected.
This PR updates them to the latest and already ran `pre-commit run -a` for you to fix any changes in formatting.
branch: pre-commit-autoupdate
delete-branch: true
22 changes: 7 additions & 15 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
repos:
- repo: https://github.com/Quantco/pre-commit-mirrors-black
rev: 23.7.0
# Run ruff first because autofix behaviour is enabled
- repo: https://github.com/Quantco/pre-commit-mirrors-ruff
rev: "0.1.3"
hooks:
- id: black-conda
args:
- --safe
- --target-version=py38
- repo: https://github.com/Quantco/pre-commit-mirrors-flake8
rev: 6.1.0
- id: ruff-conda
- repo: https://github.com/Quantco/pre-commit-mirrors-ruff
rev: "0.1.3"
hooks:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a single ruff section?

Suggested change
- repo: https://github.com/Quantco/pre-commit-mirrors-ruff
rev: "0.1.3"
hooks:

- id: flake8-conda
additional_dependencies: [-c, conda-forge, flake8-docstrings=1.5.0, flake8-rst-docstrings=0.0.14]
- repo: https://github.com/Quantco/pre-commit-mirrors-isort
rev: 5.12.0
hooks:
- id: isort-conda
additional_dependencies: [-c, conda-forge, toml=0.10.2]
- id: ruff-format-conda
- repo: https://github.com/Quantco/pre-commit-mirrors-mypy
rev: "1.5.1"
hooks:
Expand Down
2 changes: 1 addition & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ conda:

python:
install:
- method: setuptools
- method: pip
path: .
8 changes: 8 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Changelog
*********

1.8.2
=====
* Include Python 3.12 in CI
* Migrate setup.cfg and setup.py into pyproject.toml
* Port to ruff
* Include pre-commit autoupdate workflow
* Determine version in ``docs/conf.py`` automatically

1.8.1
=====
* Drop `pkg_resources` and use `importlib.metadata` to access package version string.
Expand Down
16 changes: 7 additions & 9 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@

from sphinx.ext import apidoc

from minimalkv import __version__ as version

release = version

sys.path.append("../")

package = "minimalkv"
html_theme = "alabaster"

__location__ = os.path.join(
os.getcwd(), os.path.dirname(inspect.getfile(inspect.currentframe())) # type: ignore
os.getcwd(),
os.path.dirname(inspect.getfile(inspect.currentframe())), # type: ignore
)


# Generate module references
output_dir = os.path.abspath(os.path.join(__location__, "../docs/_rst"))
module_dir = os.path.abspath(os.path.join(__location__, "..", package))
Expand All @@ -37,14 +43,6 @@
project = "minimalkv"
copyright = "2011-2021, The minimalkv contributors"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = "0.14.1"
# The full version, including alpha/beta/rc tags.
release = "0.14.1"

exclude_trees = ["_build"]

Expand Down
9 changes: 6 additions & 3 deletions minimalkv/_boto.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
create_if_missing=True,
):
# TODO: Write docstring.
from boto.s3.connection import S3ResponseError # type: ignore
from boto.s3.connection import OrdinaryCallingFormat, S3Connection
from boto.s3.connection import ( # type: ignore

Check warning on line 10 in minimalkv/_boto.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/_boto.py#L10

Added line #L10 was not covered by tests
OrdinaryCallingFormat,
S3Connection,
S3ResponseError,
)

s3_connection_params = {
"aws_access_key_id": access_key,
Expand All @@ -35,5 +38,5 @@
if create_if_missing:
return s3con.create_bucket(bucket)
else:
raise OSError(f"Bucket {bucket} does not exist")
raise OSError(f"Bucket {bucket} does not exist") from ex

Check warning on line 41 in minimalkv/_boto.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/_boto.py#L41

Added line #L41 was not covered by tests
raise
6 changes: 2 additions & 4 deletions minimalkv/_get_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
def get_store_from_url(
url: str, store_cls: Optional[Type[KeyValueStore]] = None
) -> KeyValueStore:
"""
Take a URL and return a minimalkv store according to the parameters in the URL.
"""Take a URL and return a minimalkv store according to the parameters in the URL.

Parameters
----------
Expand Down Expand Up @@ -97,8 +96,7 @@ def get_store_from_url(


def _extract_wrappers(parsed_url: SplitResult) -> List[str]:
"""
Extract wrappers from a parsed URL.
"""Extract wrappers from a parsed URL.

Wrappers allow you to add additional functionality to a store, e.g. encryption.
They can be specified in two ways:
Expand Down
9 changes: 3 additions & 6 deletions minimalkv/_key_value_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@


class KeyValueStore:
"""
Class to access a key-value store.
"""Class to access a key-value store.

Supported keys are ascii-strings containing alphanumeric characters or symbols out
of ``minimalkv._constants.VALID_NON_NUM`` of length not greater than 250. Values
Expand Down Expand Up @@ -141,8 +140,7 @@ def iter_keys(self, prefix: str = "") -> Iterator[str]:
raise NotImplementedError

def iter_prefixes(self, delimiter: str, prefix: str = "") -> Iterator[str]:
"""
Iterate over unique prefixes in the store up to delimiter, starting with prefix.
"""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.
Expand Down Expand Up @@ -468,8 +466,7 @@ def __exit__(
def _from_parsed_url(
cls, parsed_url: SplitResult, query: Dict[str, str]
) -> "KeyValueStore":
"""
Build a ``KeyValueStore`` from a parsed URL.
"""Build a ``KeyValueStore`` from a parsed URL.

To build a ``KeyValueStore`` from a URL, use :func:`get_store_from_url`.

Expand Down
2 changes: 1 addition & 1 deletion minimalkv/_store_creation.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
from minimalkv._hstores import HGoogleCloudStore
from minimalkv.net.gcstore import GoogleCloudStore

if type(params["credentials"]) is bytes:
if isinstance(params["credentials"], bytes):

Check warning on line 53 in minimalkv/_store_creation.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/_store_creation.py#L53

Added line #L53 was not covered by tests
account_info = json.loads(params["credentials"].decode())
params["credentials"] = Credentials.from_service_account_info(
account_info,
Expand Down
16 changes: 8 additions & 8 deletions minimalkv/_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@
)

u = urisplit(url)
parsed = dict(
scheme=u.getscheme(),
host=u.gethost(),
port=u.getport(),
path=u.getpath(),
query=u.getquerydict(),
userinfo=u.getuserinfo(),
)
parsed = {

Check warning on line 47 in minimalkv/_urls.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/_urls.py#L47

Added line #L47 was not covered by tests
"scheme": u.getscheme(),
"host": u.gethost(),
"port": u.getport(),
"path": u.getpath(),
"query": u.getquerydict(),
"userinfo": u.getuserinfo(),
}
fragment = u.getfragment()

params = {"type": parsed["scheme"]}
Expand Down
2 changes: 1 addition & 1 deletion minimalkv/crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
try:
f = open(file, "wb")
except OSError as e:
raise OSError(f"Error opening {file} for writing: {e!r}")
raise OSError(f"Error opening {file} for writing: {e!r}") from e

Check warning on line 131 in minimalkv/crypt.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/crypt.py#L131

Added line #L131 was not covered by tests

# file is open, now we call ourself again with a proper file
try:
Expand Down
4 changes: 2 additions & 2 deletions minimalkv/db/mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
try:
item = next(self.db[self.collection].find({"_id": key}))
return pickle.loads(item["v"])
except StopIteration:
raise KeyError(key)
except StopIteration as e:
raise KeyError(key) from e

Check warning on line 38 in minimalkv/db/mongo.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/db/mongo.py#L37-L38

Added lines #L37 - L38 were not covered by tests

def _open(self, key: str) -> IO:
return BytesIO(self._get(key))
Expand Down
2 changes: 1 addition & 1 deletion minimalkv/db/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,4 @@
query = select(self.table.c.key)
if prefix != "":
query = query.where(self.table.c.key.like(prefix + "%"))
return map(lambda v: str(v[0]), session.execute(query))
return (str(v[0]) for v in session.execute(query))

Check warning on line 90 in minimalkv/db/sql.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/db/sql.py#L90

Added line #L90 was not covered by tests
3 changes: 1 addition & 2 deletions minimalkv/decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,7 @@ def copy(self, source: str, dest: str): # noqa D


class PrefixDecorator(KeyTransformingDecorator):
"""
Prefixes any key with a string before passing it on the decorated store.
"""Prefixes any key with a string before passing it on the decorated store.

Automatically strips the prefix upon key retrieval.

Expand Down
12 changes: 5 additions & 7 deletions minimalkv/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
return f
except OSError as e:
if 2 == e.errno:
raise KeyError(key)
raise KeyError(key) from e

Check warning on line 85 in minimalkv/fs.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/fs.py#L85

Added line #L85 was not covered by tests
else:
raise

Expand All @@ -97,7 +97,7 @@
return dest
except OSError as e:
if 2 == e.errno:
raise KeyError(source)
raise KeyError(source) from e

Check warning on line 100 in minimalkv/fs.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/fs.py#L100

Added line #L100 was not covered by tests
else:
raise

Expand Down Expand Up @@ -155,7 +155,7 @@
"""
root = os.path.abspath(self.root)
result = []
for dp, dn, fn in os.walk(root):
for dp, _, fn in os.walk(root):

Check warning on line 158 in minimalkv/fs.py

View check run for this annotation

Codecov / codecov/patch

minimalkv/fs.py#L158

Added line #L158 was not covered by tests
for f in fn:
key = os.path.join(dp, f)[len(root) + 1 :]
if key.startswith(prefix):
Expand All @@ -174,8 +174,7 @@
return iter(self.keys(prefix))

def iter_prefixes(self, delimiter: str, prefix: str = "") -> Iterator[str]:
"""
Iterate over unique prefixes in the store up to delimiter, starting with prefix.
"""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.
Expand Down Expand Up @@ -224,8 +223,7 @@


class WebFilesystemStore(FilesystemStore):
"""
FilesystemStore supporting generating URLS for web applications.
"""FilesystemStore supporting generating URLS for web applications.

The most common use is to make the ``root`` directory of the filesystem store
available through a webserver.
Expand Down
Loading
Loading