diff --git a/.cookiecutter.json b/.cookiecutter.json index 8652f8e..7b16041 100644 --- a/.cookiecutter.json +++ b/.cookiecutter.json @@ -12,5 +12,6 @@ "license": "MIT", "package_name": "FunctionalPy", "project_name": "FunctionalPy", + "release_to_pypi": "yes", "version": "0.0.0" } \ No newline at end of file diff --git a/.cruft.json b/.cruft.json index 2a06220..6ea5c9d 100644 --- a/.cruft.json +++ b/.cruft.json @@ -1,6 +1,6 @@ { "template": "https://github.com/MartinBernstorff/nimble-python-cookiecutter", - "commit": "d65d50c7215714a4e6df85be23c5cd9066db9cc0", + "commit": "7b0df632c9b44d28eb60bbfc6fd376c5ba667564", "checkout": null, "context": { "cookiecutter": { @@ -13,6 +13,7 @@ "github_repo": "FunctionalPy", "version": "0.0.0", "copyright_year": "2023", + "release_to_pypi": "no", "license": "MIT", "_copy_without_render": [ "*.github" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2dbf12f..781b3e4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -23,6 +23,9 @@ ] } }, + "mounts": [ + "source=${localEnv:HOME}/.config/gh/hosts.yml,target=/root/.config/gh/hosts.yml,type=bind,consistency=cache", // GitHub CLI authentication login + ], "features": { "ghcr.io/devcontainers/features/github-cli:1": {} }, diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 00a0ed8..f781cc1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -27,6 +27,11 @@ jobs: username: MartinBernstorff password: ${{ secrets.GITHUB_TOKEN }} + - name: Create github hosts file + run: | # If this file is not created, the dev container fails because of non-existant mount + mkdir -p ~/.config/gh + touch ~/.config/gh/hosts.yml + - name: Pre-build dev container image uses: devcontainers/ci@v0.3 with: diff --git a/Makefile b/Makefile index 7d0e127..1631b28 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ SRC_PATH = functionalpy install-dev: - pip install -r dev-requirements.txt + pip install --upgrade -r dev-requirements.txt install-deps: - pip install -r requirements.txt + pip install --upgrade -r requirements.txt install: make install-deps diff --git a/README.md b/README.md index e85b652..e988b14 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ # FunctionalPy - +[![Open in Dev Container](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)][dev container] [![PyPI](https://img.shields.io/pypi/v/functionalpy.svg)][pypi status] [![Python Version](https://img.shields.io/pypi/pyversions/FunctionalPy)][pypi status] [![Tests](https://github.com/MartinBernstorff/FunctionalPy/actions/workflows/tests.yml/badge.svg)][tests] [pypi status]: https://pypi.org/project/FunctionalPy/ [tests]: https://github.com/MartinBernstorff/FunctionalPy/actions?workflow=Tests -[black]: https://github.com/psf/black +[dev container]: https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/MartinBernstorff/FunctionalPy/ @@ -31,11 +31,13 @@ result = (Seq([1, 2]) assert result == [4] ``` -## Dev environment setup +### Setting up a development environment +#### Devcontainer 1. Install [Orbstack](https://orbstack.dev/) or Docker Desktop. Make sure to complete the full install process before continuing. 2. If not installed, install VSCode -3. Press this [link](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/Aarhus-Psychiatry-Research/psycop-common) +3. Press this [link](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/MartinBernstorff/FunctionalPy/) 4. Complete the setup process +5. Done! Easy as that. # 💬 Where to ask questions diff --git a/functionalpy/_sequence.py b/functionalpy/_sequence.py index 92ca6f5..9d38e35 100644 --- a/functionalpy/_sequence.py +++ b/functionalpy/_sequence.py @@ -48,7 +48,9 @@ def filter(self, func: Callable[[_T0], bool]) -> "Seq[_T0]": # noqa: A003 def reduce(self, func: Callable[[_T0, _T0], _T0]) -> _T0: return reduce(func, self._seq) - def group_by(self, func: Callable[[_T0], str]) -> "Seq[Group[_T0]]": + def group_by( + self, func: Callable[[_T0], str] + ) -> "Seq[Group[_T0]]": result = ( Group(key=key, value=Seq(value)) for key, value in itertools.groupby(self._seq, key=func) diff --git a/functionalpy/benchmark/query_1/iterators_q1.py b/functionalpy/benchmark/query_1/iterators_q1.py index 4ddc6ba..4e11e6c 100644 --- a/functionalpy/benchmark/query_1/iterators_q1.py +++ b/functionalpy/benchmark/query_1/iterators_q1.py @@ -53,7 +53,9 @@ def summarise_category(input_data: Group[Item]) -> CategorySummary: category_name=group_id, sum_quantity=sum(r.quantity for r in rows), sum_base_price=sum(r.extended_price for r in rows), - sum_discount_price=sum(calculate_discounted_price(r) for r in rows), + sum_discount_price=sum( + calculate_discounted_price(r) for r in rows + ), sum_charge=sum(calculate_charge(r) for r in rows), avg_quantity=stats.mean(r.quantity for r in rows), avg_price=stats.mean(r.extended_price for r in rows), @@ -70,7 +72,9 @@ def calculate_charge(item: Item) -> float: return item.extended_price * (1 - item.discount) * (1 - item.tax) -def parse_input_data(input_data: Sequence[Mapping[str, Any]]) -> Sequence[Item]: +def parse_input_data( + input_data: Sequence[Mapping[str, Any]] +) -> Sequence[Item]: parsed_data = ( Seq(input_data) .map( @@ -95,7 +99,9 @@ def main_iterator(data: Sequence[Item]) -> Sequence[CategorySummary]: sequence = ( Seq(data) .filter(lambda i: i.ship_date <= dt.datetime(2000, 1, 1)) - .group_by(lambda i: f"status_{i.cancelled}_returned_{i.returned}") + .group_by( + lambda i: f"status_{i.cancelled}_returned_{i.returned}" + ) .map(summarise_category) .to_list() ) diff --git a/functionalpy/benchmark/utils.py b/functionalpy/benchmark/utils.py index daa25cd..8970759 100644 --- a/functionalpy/benchmark/utils.py +++ b/functionalpy/benchmark/utils.py @@ -15,7 +15,9 @@ class BenchmarkResult(Generic[T0]): time_seconds: float -def run_query(query: Callable[..., T0], query_title: str) -> BenchmarkResult[T0]: +def run_query( + query: Callable[..., T0], query_title: str +) -> BenchmarkResult[T0]: with CodeTimer(name=f"{query_title}", unit="s"): t0 = timeit.default_timer() result = query() @@ -47,4 +49,6 @@ def benchmark_method( query_title=f"{method_title}: Computation", ) - return CombinedBenchmark(ingest=data_ingest_result, query_result=result) + return CombinedBenchmark( + ingest=data_ingest_result, query_result=result + ) diff --git a/functionalpy/test_sequence.py b/functionalpy/test_sequence.py index 9b537fb..dad4acf 100644 --- a/functionalpy/test_sequence.py +++ b/functionalpy/test_sequence.py @@ -3,7 +3,11 @@ def test_chaining(): sequence = Seq([1, 2]) - result = sequence.filter(lambda x: x % 2 == 0).map(lambda x: x * 2).to_list() + result = ( + sequence.filter(lambda x: x % 2 == 0) + .map(lambda x: x * 2) + .to_list() + ) assert result == [4] diff --git a/pyproject.toml b/pyproject.toml index 14ff665..8411dcb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,10 +12,9 @@ classifiers = [ "Programming Language :: Python :: 3.11" ] requires-python = ">=3.10" -[project.license] +[project.license] file = "LICENSE" -name = "MIT" [project.readme] file = "README.md" @@ -27,10 +26,12 @@ repository = "https://github.com/MartinBernstorff/FunctionalPy" documentation = "https://MartinBernstorff.github.io/FunctionalPy/" [tool.pyright] -exclude = [".*venv*", ".tox"] +exclude = [".*venv*"] pythonPlatform = "Darwin" +reportMissingTypeStubs = false [tool.ruff] +line-length = 70 # Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default. select = [ "A", @@ -52,7 +53,6 @@ select = [ "PLW", "PT", "UP", - "Q", "PTH", "RSE", "RET", @@ -70,10 +70,6 @@ ignore = [ "RET504", "COM812", "COM819", - "Q000", - "Q001", - "Q002", - "Q003", "W191", ] ignore-init-module-imports = true @@ -107,6 +103,9 @@ exclude = [ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" target-version = "py311" +[tool.ruff.format] +skip-magic-trailing-comma = false + [tool.ruff.flake8-annotations] mypy-init-return = true suppress-none-returning = true @@ -125,3 +124,4 @@ build_command = "python -m pip install build; python -m build" [tool.setuptools] include-package-data = true +