diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml index 2fd12494..4b654cff 100644 --- a/.github/workflows/lint_python.yml +++ b/.github/workflows/lint_python.yml @@ -8,15 +8,6 @@ jobs: - uses: actions/setup-python@v4 with: python-version: 3.x - - run: pip install --upgrade pip - - run: pip install black codespell flake8 isort mypy pytest pyupgrade tox - - run: black --check . - - run: codespell --quiet-level=2 # --ignore-words-list="" --skip="" - - run: flake8 . --count --show-source --statistics - - run: isort --profile black . - - run: tox - - run: pip install -e . - - run: mypy --ignore-missing-imports . || true - - run: pytest . - - run: pytest --doctest-modules . || true - - run: shopt -s globstar && pyupgrade --py37-plus **/*.py + - shell: bash + name: Lint and test + run: ./lint.sh diff --git a/.gitignore b/.gitignore index aaf2ded3..d272a2e1 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,5 @@ venv/ .vscode/ .python-version .coverage +build/ +dist/ \ No newline at end of file diff --git a/README.md b/README.md index 74b689da..d49f7fb7 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,12 @@ To see Python 2 compatible versions of some patterns please check-out the [legac When everything else is done - update corresponding part of README. ##### Travis CI -Please run `tox` or `tox -e ci37` before submitting a patch to be sure your changes will pass CI. +Please run the following before submitting a patch +- `black .` This lints your code. + +Then either: +- `tox` or `tox -e ci37` This runs unit tests. see tox.ini for further details. +- If you have a bash compatible shell use `./lint.sh` This script will lint and test your code. This script mirrors the CI pipeline actions. You can also run `flake8` or `pytest` commands manually. Examples can be found in `tox.ini`. diff --git a/lint.sh b/lint.sh new file mode 100755 index 00000000..a3ce9719 --- /dev/null +++ b/lint.sh @@ -0,0 +1,14 @@ +#! /bin/bash + +pip install --upgrade pip +pip install black codespell flake8 isort mypy pytest pyupgrade tox +black --check . +codespell --quiet-level=2 # --ignore-words-list="" --skip="" +flake8 . --count --show-source --statistics +isort --profile black . +tox +pip install -e . +mypy --ignore-missing-imports . || true +pytest . +pytest --doctest-modules . || true +shopt -s globstar && pyupgrade --py37-plus **/*.py \ No newline at end of file diff --git a/patterns/behavioral/catalog.py b/patterns/behavioral/catalog.py index 7c91aa7d..ba85f500 100644 --- a/patterns/behavioral/catalog.py +++ b/patterns/behavioral/catalog.py @@ -46,7 +46,6 @@ def main_method(self) -> None: # Alternative implementation for different levels of methods class CatalogInstance: - """catalog of multiple methods that are executed depending on an init parameter @@ -82,7 +81,6 @@ def main_method(self) -> None: class CatalogClass: - """catalog of multiple class methods that are executed depending on an init parameter @@ -121,7 +119,6 @@ def main_method(self): class CatalogStatic: - """catalog of multiple static methods that are executed depending on an init parameter diff --git a/patterns/behavioral/iterator_alt.py b/patterns/behavioral/iterator_alt.py index d6fb0df9..a2a71d82 100644 --- a/patterns/behavioral/iterator_alt.py +++ b/patterns/behavioral/iterator_alt.py @@ -4,6 +4,7 @@ *TL;DR Traverses a container and accesses the container's elements. """ + from __future__ import annotations diff --git a/patterns/behavioral/memento.py b/patterns/behavioral/memento.py index e1d42fc2..545975d3 100644 --- a/patterns/behavioral/memento.py +++ b/patterns/behavioral/memento.py @@ -5,8 +5,8 @@ Provides the ability to restore an object to its previous state. """ -from typing import Callable, List from copy import copy, deepcopy +from typing import Callable, List def memento(obj, deep=False): diff --git a/patterns/behavioral/publish_subscribe.py b/patterns/behavioral/publish_subscribe.py index 40aefd2e..7e76955c 100644 --- a/patterns/behavioral/publish_subscribe.py +++ b/patterns/behavioral/publish_subscribe.py @@ -4,7 +4,6 @@ Author: https://github.com/HanWenfang """ - from __future__ import annotations diff --git a/patterns/behavioral/strategy.py b/patterns/behavioral/strategy.py index 88862fa4..000ff2ad 100644 --- a/patterns/behavioral/strategy.py +++ b/patterns/behavioral/strategy.py @@ -7,7 +7,6 @@ Enables selecting an algorithm at runtime. """ - from __future__ import annotations from typing import Callable @@ -56,7 +55,8 @@ def apply_discount(self) -> float: return self.price - discount def __repr__(self) -> str: - return f"" + strategy = getattr(self.discount_strategy, "__name__", None) + return f"" def ten_percent_discount(order: Order) -> float: diff --git a/patterns/creational/abstract_factory.py b/patterns/creational/abstract_factory.py index d092a6b4..0ec49bbf 100644 --- a/patterns/creational/abstract_factory.py +++ b/patterns/creational/abstract_factory.py @@ -62,7 +62,6 @@ def __str__(self) -> str: class PetShop: - """A pet shop""" def __init__(self, animal_factory: Type[Pet]) -> None: @@ -78,14 +77,6 @@ def buy_pet(self, name: str) -> Pet: return pet -# Additional factories: - -# Create a random animal -def random_animal(name: str) -> Pet: - """Let's be dynamic!""" - return random.choice([Dog, Cat])(name) - - # Show pets with various factories def main() -> None: """ @@ -95,27 +86,10 @@ def main() -> None: Here is your lovely Cat >>> pet.speak() meow - - # A shop that sells random animals - >>> shop = PetShop(random_animal) - >>> for name in ["Max", "Jack", "Buddy"]: - ... pet = shop.buy_pet(name) - ... pet.speak() - ... print("=" * 20) - Here is your lovely Cat - meow - ==================== - Here is your lovely Dog - woof - ==================== - Here is your lovely Dog - woof - ==================== """ if __name__ == "__main__": - random.seed(1234) # for deterministic doctest outputs shop = PetShop(random_animal) import doctest diff --git a/patterns/creational/borg.py b/patterns/creational/borg.py index de36a23f..edd0589d 100644 --- a/patterns/creational/borg.py +++ b/patterns/creational/borg.py @@ -32,6 +32,7 @@ *TL;DR Provides singleton-like behavior sharing state between instances. """ + from typing import Dict diff --git a/patterns/creational/factory.py b/patterns/creational/factory.py index a1beffa8..3ef2d2a8 100644 --- a/patterns/creational/factory.py +++ b/patterns/creational/factory.py @@ -21,9 +21,8 @@ *TL;DR Creates objects without having to specify the exact class. """ -from typing import Dict -from typing import Protocol -from typing import Type + +from typing import Dict, Protocol, Type class Localizer(Protocol): @@ -50,7 +49,6 @@ def localize(self, msg: str) -> str: def get_localizer(language: str = "English") -> Localizer: - """Factory""" localizers: Dict[str, Type[Localizer]] = { "English": EnglishLocalizer, diff --git a/patterns/creational/prototype.py b/patterns/creational/prototype.py index 4151ffbf..4c2dd7ed 100644 --- a/patterns/creational/prototype.py +++ b/patterns/creational/prototype.py @@ -20,6 +20,7 @@ *TL;DR Creates new object instances by cloning prototype. """ + from __future__ import annotations from typing import Any diff --git a/patterns/other/blackboard.py b/patterns/other/blackboard.py index ef48f501..cd2eb7ab 100644 --- a/patterns/other/blackboard.py +++ b/patterns/other/blackboard.py @@ -8,6 +8,7 @@ https://en.wikipedia.org/wiki/Blackboard_system """ + from __future__ import annotations import abc diff --git a/patterns/other/graph_search.py b/patterns/other/graph_search.py index ad224db3..262a6f08 100644 --- a/patterns/other/graph_search.py +++ b/patterns/other/graph_search.py @@ -1,5 +1,4 @@ class GraphSearch: - """Graph search emulation in python, from source http://www.python.org/doc/essays/graphs/ diff --git a/tests/behavioral/test_strategy.py b/tests/behavioral/test_strategy.py index 86018a44..53976f38 100644 --- a/tests/behavioral/test_strategy.py +++ b/tests/behavioral/test_strategy.py @@ -1,6 +1,6 @@ import pytest -from patterns.behavioral.strategy import Order, ten_percent_discount, on_sale_discount +from patterns.behavioral.strategy import Order, on_sale_discount, ten_percent_discount @pytest.fixture diff --git a/tests/creational/test_pool.py b/tests/creational/test_pool.py index 38476eb7..cd501db3 100644 --- a/tests/creational/test_pool.py +++ b/tests/creational/test_pool.py @@ -29,7 +29,6 @@ def test_frozen_pool(self): class TestNaitivePool(unittest.TestCase): - """def test_object(queue): queue_object = QueueObject(queue, True) print('Inside func: {}'.format(queue_object.object))"""