From 99fc377e620773d24f690a148478fb23a6684e79 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Tue, 16 Jun 2020 22:21:05 +0100 Subject: [PATCH 01/12] domain model for magnum opus --- 021-conical/magnum_opus/.gitignore | 3 + 021-conical/magnum_opus/MANIFEST.in | 1 + 021-conical/magnum_opus/README.md | 5 ++ 021-conical/magnum_opus/RULES.md | 9 +++ .../magnum_opus/magnumopus/__init__.py | 0 021-conical/magnum_opus/magnumopus/alembic.py | 51 ++++++++++++ 021-conical/magnum_opus/magnumopus/pantry.py | 12 +++ .../magnum_opus/magnumopus/substance.py | 23 ++++++ 021-conical/magnum_opus/requirements.txt | 5 ++ 021-conical/magnum_opus/setup.cfg | 19 +++++ 021-conical/magnum_opus/setup.py | 14 ++++ 021-conical/magnum_opus/tests/test_alembic.py | 81 +++++++++++++++++++ 021-conical/magnum_opus/tests/test_pantry.py | 22 +++++ .../magnum_opus/tests/test_substance.py | 49 +++++++++++ 021-conical/magnum_opus/tox.ini | 6 ++ 15 files changed, 300 insertions(+) create mode 100644 021-conical/magnum_opus/.gitignore create mode 100644 021-conical/magnum_opus/MANIFEST.in create mode 100644 021-conical/magnum_opus/README.md create mode 100644 021-conical/magnum_opus/RULES.md create mode 100644 021-conical/magnum_opus/magnumopus/__init__.py create mode 100644 021-conical/magnum_opus/magnumopus/alembic.py create mode 100644 021-conical/magnum_opus/magnumopus/pantry.py create mode 100644 021-conical/magnum_opus/magnumopus/substance.py create mode 100644 021-conical/magnum_opus/requirements.txt create mode 100644 021-conical/magnum_opus/setup.cfg create mode 100644 021-conical/magnum_opus/setup.py create mode 100644 021-conical/magnum_opus/tests/test_alembic.py create mode 100644 021-conical/magnum_opus/tests/test_pantry.py create mode 100644 021-conical/magnum_opus/tests/test_substance.py create mode 100644 021-conical/magnum_opus/tox.ini diff --git a/021-conical/magnum_opus/.gitignore b/021-conical/magnum_opus/.gitignore new file mode 100644 index 0000000..9fb668e --- /dev/null +++ b/021-conical/magnum_opus/.gitignore @@ -0,0 +1,3 @@ +*.egg-info +.tox +Pipfile diff --git a/021-conical/magnum_opus/MANIFEST.in b/021-conical/magnum_opus/MANIFEST.in new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/021-conical/magnum_opus/MANIFEST.in @@ -0,0 +1 @@ + diff --git a/021-conical/magnum_opus/README.md b/021-conical/magnum_opus/README.md new file mode 100644 index 0000000..b87be82 --- /dev/null +++ b/021-conical/magnum_opus/README.md @@ -0,0 +1,5 @@ +Magnum Opus +=========== + +This recipe maker +and averaged over repeated attempts, returning an average round trip time. diff --git a/021-conical/magnum_opus/RULES.md b/021-conical/magnum_opus/RULES.md new file mode 100644 index 0000000..4438311 --- /dev/null +++ b/021-conical/magnum_opus/RULES.md @@ -0,0 +1,9 @@ +* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my "Alembic" (mixing pot), giving one unit of another substance, Gloop +* Any attempt to mix anything other than those three substances, gives Sludge, another substance +* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented +* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills) +[* To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)] + +Final rule: +GROUP 1: When I process a substance, using any process, it becomes a different substance +GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process) diff --git a/021-conical/magnum_opus/magnumopus/__init__.py b/021-conical/magnum_opus/magnumopus/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/021-conical/magnum_opus/magnumopus/alembic.py b/021-conical/magnum_opus/magnumopus/alembic.py new file mode 100644 index 0000000..39f02a4 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/alembic.py @@ -0,0 +1,51 @@ +from .substance import Substance + +class NotEnoughSubstancesToMixException(Exception): + pass + +class UnknownProcessException(Exception): + pass + + +MIXTURES = { + ('Mercury', 'Salt', 'Sulphur'): 'Gloop' +} + + +class Alembic: + _nature_of_unknown_mixture = 'Sludge' + + @staticmethod + def _produce(nature): + return Substance(nature=nature) + + def mix(self, *substances): + if len(substances) < 2: + raise NotEnoughSubstancesToMixException() + + constituents = [substance.nature for substance in substances] + + # This gives us a canonical, ordered way of expressing our + # constituents that we can use as a recipe look-up + ingredient_list = tuple(sorted(constituents)) + + try: + nature = MIXTURES[ingredient_list] + except KeyError: + nature = self._nature_of_unknown_mixture + + return self._produce(nature) + + def process(self, process_name, substance): + if process_name == 'ferment': + result = substance.ferment() + elif process_name == 'cook': + result = substance.cook() + elif process_name == 'wash': + result = substance.wash() + elif process_name == 'pickle': + result = substance.pickle() + else: + raise UnknownProcessException() + + return result diff --git a/021-conical/magnum_opus/magnumopus/pantry.py b/021-conical/magnum_opus/magnumopus/pantry.py new file mode 100644 index 0000000..9e7a1d6 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/pantry.py @@ -0,0 +1,12 @@ +class Pantry: + def __init__(self): + self._cupboard = [] + + def add_substance(self, substance): + self._cupboard.append(substance) + + def find_substance_by_nature(self, nature): + return [substance for substance in self._cupboard if substance.nature == nature][0] + + def count_all_substances(self): + return len(self._cupboard) diff --git a/021-conical/magnum_opus/magnumopus/substance.py b/021-conical/magnum_opus/magnumopus/substance.py new file mode 100644 index 0000000..828b4c5 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/substance.py @@ -0,0 +1,23 @@ +class SubstanceMustBeFreshToProcessException(Exception): + pass + +class Substance: + def __init__(self, nature='Unknown'): + self.nature = nature + self.state = [] + + def _process(self, process_name): + self.state.append(process_name) + return self + + def cook(self): + return self._process('cooked') + + def pickle(self): + return self._process('pickled') + + def ferment(self): + return self._process('fermented') + + def wash(self): + return self._process('washed') diff --git a/021-conical/magnum_opus/requirements.txt b/021-conical/magnum_opus/requirements.txt new file mode 100644 index 0000000..99f65af --- /dev/null +++ b/021-conical/magnum_opus/requirements.txt @@ -0,0 +1,5 @@ +numpy +pylint +pyyaml +Click +appdirs \ No newline at end of file diff --git a/021-conical/magnum_opus/setup.cfg b/021-conical/magnum_opus/setup.cfg new file mode 100644 index 0000000..144266f --- /dev/null +++ b/021-conical/magnum_opus/setup.cfg @@ -0,0 +1,19 @@ +[metadata] +name = magnumopus +version = 0.0.1 +author = Phil Weir +author_email = phil.weir@flaxandteal.co.uk +license = GPL +description = Service for cooking up a philosopher's stone +long-description = file:README.md + +[options] +include_package_data = True +packages = find: +python_requires = >=3.6 +install_requires = + appdirs + +[options.packages.find] +exclude = + tests diff --git a/021-conical/magnum_opus/setup.py b/021-conical/magnum_opus/setup.py new file mode 100644 index 0000000..1767837 --- /dev/null +++ b/021-conical/magnum_opus/setup.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Magnum Opus + +This tool performs alchemical reactions to create +the Philosopher's Stone. + +@author: Phil Weir +""" + +from setuptools import setup + +if __name__ == '__main__': + setup() diff --git a/021-conical/magnum_opus/tests/test_alembic.py b/021-conical/magnum_opus/tests/test_alembic.py new file mode 100644 index 0000000..01fd341 --- /dev/null +++ b/021-conical/magnum_opus/tests/test_alembic.py @@ -0,0 +1,81 @@ +import pytest + +from magnumopus.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException +from magnumopus.substance import Substance + +def test_can_set_up_my_alembic(): + Alembic() + +def test_can_mix_multiple_substances_in_my_alembic(): + alembic = Alembic() + substance = [Substance() for _ in range(3)] + alembic.mix(*substance) + + substance = [Substance() for _ in range(6)] + alembic.mix(*substance) + +def test_cannot_mix_one_substance_in_my_alembic(): + alembic = Alembic() + substance = Substance() + + with pytest.raises(NotEnoughSubstancesToMixException): + alembic.mix(substance) + +def test_mixing_sulphur_salt_and_mercury_gives_gloop(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + + result = alembic.mix(sulphur, salt, mercury) + + assert result.nature == 'Gloop' + + result = alembic.mix(mercury, sulphur, salt) + + assert result.nature == 'Gloop' + +def test_mixing_other_recipes_gives_sludge(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + gloop = Substance(nature='Gloop') + + result = alembic.mix(sulphur, salt, mercury, sulphur) + + assert result.nature == 'Sludge' + + result = alembic.mix(salt, mercury) + + assert result.nature == 'Sludge' + + result = alembic.mix(gloop, salt, mercury) + + assert result.nature == 'Sludge' + +def test_can_process_substance(): + alembic = Alembic() + + substance = Substance() + result = alembic.process('cook', substance) + + substance = Substance() + cooked_substance = substance.cook() + + assert result.state == cooked_substance.state + + result = alembic.process('ferment', substance) + cooked_fermented_substance = cooked_substance.ferment() + + assert result.state == cooked_fermented_substance.state + +def test_cannot_perform_unknown_process(): + alembic = Alembic() + + substance = Substance() + + with pytest.raises(UnknownProcessException): + alembic.process('boil', substance) diff --git a/021-conical/magnum_opus/tests/test_pantry.py b/021-conical/magnum_opus/tests/test_pantry.py new file mode 100644 index 0000000..84dbd7e --- /dev/null +++ b/021-conical/magnum_opus/tests/test_pantry.py @@ -0,0 +1,22 @@ +from magnumopus.pantry import Pantry +from magnumopus.substance import Substance + +def test_can_add_to_pantry(): + pantry = Pantry() + + substance = Substance() + + pantry.add_substance(substance) + + assert pantry.count_all_substances() == 1 + +def test_can_retrieve_substance_from_pantry_by_nature(): + pantry = Pantry() + + substance = Substance(nature='Mercury') + + pantry.add_substance(substance) + + mercury = pantry.find_substance_by_nature('Mercury') + + assert mercury.nature == 'Mercury' diff --git a/021-conical/magnum_opus/tests/test_substance.py b/021-conical/magnum_opus/tests/test_substance.py new file mode 100644 index 0000000..342cf50 --- /dev/null +++ b/021-conical/magnum_opus/tests/test_substance.py @@ -0,0 +1,49 @@ +from magnumopus.substance import Substance + +def test_can_cook_substance(): + substance = Substance() + + result = substance.cook() + + assert substance.state == ['cooked'] + +def test_can_wash_substance(): + substance = Substance() + + result = substance.wash() + + assert result.state == ['washed'] + +def test_can_pickle_substance(): + substance = Substance() + + result = substance.pickle() + + assert result.state == ['pickled'] + +def test_can_ferment_substance(): + substance = Substance() + + result = substance.ferment() + + assert substance.state == ['fermented'] + +def test_can_cook_and_ferment_substance(): + substance = Substance() + + result = substance.cook() + result = result.ferment() + + assert substance.state == ['cooked', 'fermented'] + +def test_the_order_of_processes_applied_to_a_substance_matters(): + substance1 = Substance() + result1 = substance1.cook() + result1 = result1.ferment() + + substance2 = Substance() + result2 = substance2.ferment() + result2 = result2.cook() + + assert result1.state != result2.state + assert result1.state == result2.state[::-1] diff --git a/021-conical/magnum_opus/tox.ini b/021-conical/magnum_opus/tox.ini new file mode 100644 index 0000000..d815853 --- /dev/null +++ b/021-conical/magnum_opus/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py38 + +[testenv] +deps = pytest +commands = pytest From fa61f0cc394299697c4a82da3f4e60977828d4b8 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Wed, 17 Jun 2020 00:50:30 +0100 Subject: [PATCH 02/12] basic flask app (with work needed, as exercise) --- 021-conical/magnum_opus/Dockerfile | 23 +++++++++ 021-conical/magnum_opus/docker-compose.yml | 6 +++ 021-conical/magnum_opus/gunicorn_config.py | 5 ++ .../magnum_opus/magnumopus/__init__.py | 14 ++++++ 021-conical/magnum_opus/magnumopus/index.py | 3 ++ 021-conical/magnum_opus/magnumopus/logger.py | 5 ++ .../magnum_opus/magnumopus/models/__init__.py | 5 ++ .../magnum_opus/magnumopus/models/base.py | 3 ++ .../magnumopus/{ => models}/substance.py | 0 .../magnumopus/repositories/__init__.py | 0 .../magnumopus/{ => repositories}/pantry.py | 8 +-- .../magnumopus/resources/__init__.py | 8 +++ .../resources/alembic_instruction.py | 49 +++++++++++++++++++ .../magnumopus/resources/substance.py | 37 ++++++++++++++ .../magnumopus/schemas/__init__.py | 6 +++ .../magnumopus/schemas/substance_schema.py | 13 +++++ .../magnumopus/services/__init__.py | 0 .../magnumopus/{ => services}/alembic.py | 2 +- .../services/alembic_instruction_handler.py | 31 ++++++++++++ .../magnumopus/services/assessor.py | 2 + 021-conical/magnum_opus/requirements.txt | 10 ++-- 021-conical/magnum_opus/setup.cfg | 4 ++ 021-conical/magnum_opus/tests/test_alembic.py | 4 +- 021-conical/magnum_opus/tests/test_pantry.py | 6 +-- .../magnum_opus/tests/test_substance.py | 2 +- 25 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 021-conical/magnum_opus/Dockerfile create mode 100644 021-conical/magnum_opus/docker-compose.yml create mode 100644 021-conical/magnum_opus/gunicorn_config.py create mode 100644 021-conical/magnum_opus/magnumopus/index.py create mode 100644 021-conical/magnum_opus/magnumopus/logger.py create mode 100644 021-conical/magnum_opus/magnumopus/models/__init__.py create mode 100644 021-conical/magnum_opus/magnumopus/models/base.py rename 021-conical/magnum_opus/magnumopus/{ => models}/substance.py (100%) create mode 100644 021-conical/magnum_opus/magnumopus/repositories/__init__.py rename 021-conical/magnum_opus/magnumopus/{ => repositories}/pantry.py (70%) create mode 100644 021-conical/magnum_opus/magnumopus/resources/__init__.py create mode 100644 021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py create mode 100644 021-conical/magnum_opus/magnumopus/resources/substance.py create mode 100644 021-conical/magnum_opus/magnumopus/schemas/__init__.py create mode 100644 021-conical/magnum_opus/magnumopus/schemas/substance_schema.py create mode 100644 021-conical/magnum_opus/magnumopus/services/__init__.py rename 021-conical/magnum_opus/magnumopus/{ => services}/alembic.py (96%) create mode 100644 021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py create mode 100644 021-conical/magnum_opus/magnumopus/services/assessor.py diff --git a/021-conical/magnum_opus/Dockerfile b/021-conical/magnum_opus/Dockerfile new file mode 100644 index 0000000..e8b07e3 --- /dev/null +++ b/021-conical/magnum_opus/Dockerfile @@ -0,0 +1,23 @@ +FROM python:3-alpine + +RUN addgroup -S user && adduser user -S -G user + +WORKDIR /home/user/ + +COPY requirements.txt . +COPY gunicorn_config.py . +COPY setup.py . +COPY setup.cfg . + +RUN pip install gunicorn +RUN pip install -r requirements.txt + +USER user + +EXPOSE 5000 + +ENTRYPOINT [] + +CMD gunicorn --config ./gunicorn_config.py magnumopus.index:app + +COPY magnumopus magnumopus diff --git a/021-conical/magnum_opus/docker-compose.yml b/021-conical/magnum_opus/docker-compose.yml new file mode 100644 index 0000000..a234fe9 --- /dev/null +++ b/021-conical/magnum_opus/docker-compose.yml @@ -0,0 +1,6 @@ +version: "3" +services: + web: + build: . + ports: + - 5000:5000 diff --git a/021-conical/magnum_opus/gunicorn_config.py b/021-conical/magnum_opus/gunicorn_config.py new file mode 100644 index 0000000..29db9d9 --- /dev/null +++ b/021-conical/magnum_opus/gunicorn_config.py @@ -0,0 +1,5 @@ +port = '5000' +bind = "0.0.0.0:%s" % port +workers = 1 +timeout = 600 +reload = False diff --git a/021-conical/magnum_opus/magnumopus/__init__.py b/021-conical/magnum_opus/magnumopus/__init__.py index e69de29..2a3a1fb 100644 --- a/021-conical/magnum_opus/magnumopus/__init__.py +++ b/021-conical/magnum_opus/magnumopus/__init__.py @@ -0,0 +1,14 @@ +from flask import Flask + +def create_app(): + from . import models, resources, schemas, logger + + app = Flask(__name__) + + # This helps avoid cyclic dependencies + logger.init_app(app) + models.init_app(app) + resources.init_app(app) + schemas.init_app(app) + + return app diff --git a/021-conical/magnum_opus/magnumopus/index.py b/021-conical/magnum_opus/magnumopus/index.py new file mode 100644 index 0000000..183c186 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/index.py @@ -0,0 +1,3 @@ +from . import create_app + +app = create_app() diff --git a/021-conical/magnum_opus/magnumopus/logger.py b/021-conical/magnum_opus/magnumopus/logger.py new file mode 100644 index 0000000..9b7f97a --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/logger.py @@ -0,0 +1,5 @@ +import logging + +def init_app(app): + app.logger.addHandler(logging.StreamHandler()) + app.logger.setLevel(logging.INFO) diff --git a/021-conical/magnum_opus/magnumopus/models/__init__.py b/021-conical/magnum_opus/magnumopus/models/__init__.py new file mode 100644 index 0000000..2e94a1e --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/models/__init__.py @@ -0,0 +1,5 @@ +from .base import db + +def init_app(app): + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' + db.init_app(app) diff --git a/021-conical/magnum_opus/magnumopus/models/base.py b/021-conical/magnum_opus/magnumopus/models/base.py new file mode 100644 index 0000000..f0b13d6 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/models/base.py @@ -0,0 +1,3 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() diff --git a/021-conical/magnum_opus/magnumopus/substance.py b/021-conical/magnum_opus/magnumopus/models/substance.py similarity index 100% rename from 021-conical/magnum_opus/magnumopus/substance.py rename to 021-conical/magnum_opus/magnumopus/models/substance.py diff --git a/021-conical/magnum_opus/magnumopus/repositories/__init__.py b/021-conical/magnum_opus/magnumopus/repositories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/021-conical/magnum_opus/magnumopus/pantry.py b/021-conical/magnum_opus/magnumopus/repositories/pantry.py similarity index 70% rename from 021-conical/magnum_opus/magnumopus/pantry.py rename to 021-conical/magnum_opus/magnumopus/repositories/pantry.py index 9e7a1d6..90ac0d9 100644 --- a/021-conical/magnum_opus/magnumopus/pantry.py +++ b/021-conical/magnum_opus/magnumopus/repositories/pantry.py @@ -1,12 +1,14 @@ class Pantry: + _cupboard = [] + def __init__(self): - self._cupboard = [] + pass def add_substance(self, substance): self._cupboard.append(substance) - def find_substance_by_nature(self, nature): - return [substance for substance in self._cupboard if substance.nature == nature][0] + def find_substances_by_nature(self, nature): + return [substance for substance in self._cupboard if substance.nature == nature] def count_all_substances(self): return len(self._cupboard) diff --git a/021-conical/magnum_opus/magnumopus/resources/__init__.py b/021-conical/magnum_opus/magnumopus/resources/__init__.py new file mode 100644 index 0000000..85683b9 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/resources/__init__.py @@ -0,0 +1,8 @@ +from flask_restful import Api +from . import substance +from . import alembic_instruction + +def init_app(app): + api = Api(app) + substance.init_app(app, api) + alembic_instruction.init_app(app, api) diff --git a/021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py b/021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py new file mode 100644 index 0000000..1843acf --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py @@ -0,0 +1,49 @@ +from flask_restful import Resource, reqparse +from ..repositories.pantry import Pantry +from ..models.substance import Substance +from ..schemas.substance_schema import SubstanceSchema +from ..services.alembic_instruction_handler import AlembicInstructionHandler, AlembicInstruction + +parser = reqparse.RequestParser() +parser.add_argument('instruction_type') +parser.add_argument('action') +parser.add_argument('natures') + +substance_schema = SubstanceSchema() + +class AlembicInstructionResource(Resource): + def get(self): + """This should return past requests/commands.""" + pass + + def post(self): + """ + Add an instruction for the alembic. + + Note that POST is _not_ assumed to be idempotent, unlike PUT + """ + + args = parser.parse_args() + instruction_type = args['instruction_type'] + + pantry = Pantry() + + instruction_handler = AlembicInstructionHandler() + + # This could do with deserialization... + instruction = AlembicInstruction( + instruction_type=args.instruction_type, + natures=args.natures.split(','), + action=args.action + ) + + # Crude start at DI... see flask-injector + result = instruction_handler.handle(instruction, pantry) + + pantry.add_substance(result) + + return substance_schema.dump(result) + + +def init_app(app, api): + api.add_resource(AlembicInstructionResource, '/alembic_instruction') diff --git a/021-conical/magnum_opus/magnumopus/resources/substance.py b/021-conical/magnum_opus/magnumopus/resources/substance.py new file mode 100644 index 0000000..770dcac --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/resources/substance.py @@ -0,0 +1,37 @@ +from flask_restful import Resource, reqparse +from ..repositories.pantry import Pantry +from ..models.substance import Substance +from ..schemas.substance_schema import SubstanceSchema + +parser = reqparse.RequestParser() +parser.add_argument('nature') + +substance_schema = SubstanceSchema() +substances_schema = SubstanceSchema(many=True) + + +class SubstanceResource(Resource): + def get(self): + args = parser.parse_args() + nature = args['nature'] + pantry = Pantry() + + substances = pantry.find_substances_by_nature(nature) + + return substances_schema.dump(substances) + + def post(self): + args = parser.parse_args() + nature = args['nature'] + + pantry = Pantry() + + substance = Substance(nature=nature) + + pantry.add_substance(substance) + + return substance_schema.dump(substance) + + +def init_app(app, api): + api.add_resource(SubstanceResource, '/substance') diff --git a/021-conical/magnum_opus/magnumopus/schemas/__init__.py b/021-conical/magnum_opus/magnumopus/schemas/__init__.py new file mode 100644 index 0000000..34395e3 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/schemas/__init__.py @@ -0,0 +1,6 @@ +from flask_marshmallow import Marshmallow + +ma = Marshmallow() + +def init_app(app): + ma.init_app(app) diff --git a/021-conical/magnum_opus/magnumopus/schemas/substance_schema.py b/021-conical/magnum_opus/magnumopus/schemas/substance_schema.py new file mode 100644 index 0000000..430e96c --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/schemas/substance_schema.py @@ -0,0 +1,13 @@ +from marshmallow import fields + +from . import ma + +from ..services.assessor import assess_whether_substance_is_philosophers_stone + +class SubstanceSchema(ma.Schema): + is_philosophers_stone = fields.Function( + assess_whether_substance_is_philosophers_stone + ) + + class Meta: + fields = ("nature", "is_philosophers_stone") diff --git a/021-conical/magnum_opus/magnumopus/services/__init__.py b/021-conical/magnum_opus/magnumopus/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/021-conical/magnum_opus/magnumopus/alembic.py b/021-conical/magnum_opus/magnumopus/services/alembic.py similarity index 96% rename from 021-conical/magnum_opus/magnumopus/alembic.py rename to 021-conical/magnum_opus/magnumopus/services/alembic.py index 39f02a4..5fc05b2 100644 --- a/021-conical/magnum_opus/magnumopus/alembic.py +++ b/021-conical/magnum_opus/magnumopus/services/alembic.py @@ -1,4 +1,4 @@ -from .substance import Substance +from ..models.substance import Substance class NotEnoughSubstancesToMixException(Exception): pass diff --git a/021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py b/021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py new file mode 100644 index 0000000..556bbe2 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass + +from .alembic import Alembic +from ..repositories.pantry import Pantry + +@dataclass +class AlembicInstruction: + instruction_type: str + natures: list + action: str = '' + +class AlembicInstructionHandler: + def handle(self, instruction: AlembicInstruction, pantry: Pantry): + natures = instruction.natures + action = instruction.action + instruction_type = instruction.instruction_type + + # Clearly need some validation here! + substances = [pantry.find_substances_by_nature(nature)[0] for nature in natures] + + alembic = Alembic() + + if instruction_type == 'mix': + result = alembic.mix(*substances) + elif instruction_type == 'process': + result = alembic.process(action, substances[0]) + else: + pass + # a sensible error + + return result diff --git a/021-conical/magnum_opus/magnumopus/services/assessor.py b/021-conical/magnum_opus/magnumopus/services/assessor.py new file mode 100644 index 0000000..94d564d --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/services/assessor.py @@ -0,0 +1,2 @@ +def assess_whether_substance_is_philosophers_stone(substance): + return substance.nature == 'Gloop' and substance.state == ['cooked', 'washed', 'pickled', 'fermented'] diff --git a/021-conical/magnum_opus/requirements.txt b/021-conical/magnum_opus/requirements.txt index 99f65af..10bd0c2 100644 --- a/021-conical/magnum_opus/requirements.txt +++ b/021-conical/magnum_opus/requirements.txt @@ -1,5 +1,5 @@ -numpy -pylint -pyyaml -Click -appdirs \ No newline at end of file +appdirs +flask +flask-restful +flask-marshmallow +flask-sqlalchemy diff --git a/021-conical/magnum_opus/setup.cfg b/021-conical/magnum_opus/setup.cfg index 144266f..262547a 100644 --- a/021-conical/magnum_opus/setup.cfg +++ b/021-conical/magnum_opus/setup.cfg @@ -13,6 +13,10 @@ packages = find: python_requires = >=3.6 install_requires = appdirs + flask-restful + flask-marshmallow + flask-sqlalchemy + flask [options.packages.find] exclude = diff --git a/021-conical/magnum_opus/tests/test_alembic.py b/021-conical/magnum_opus/tests/test_alembic.py index 01fd341..cd67657 100644 --- a/021-conical/magnum_opus/tests/test_alembic.py +++ b/021-conical/magnum_opus/tests/test_alembic.py @@ -1,7 +1,7 @@ import pytest -from magnumopus.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException -from magnumopus.substance import Substance +from magnumopus.services.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException +from magnumopus.models.substance import Substance def test_can_set_up_my_alembic(): Alembic() diff --git a/021-conical/magnum_opus/tests/test_pantry.py b/021-conical/magnum_opus/tests/test_pantry.py index 84dbd7e..c968129 100644 --- a/021-conical/magnum_opus/tests/test_pantry.py +++ b/021-conical/magnum_opus/tests/test_pantry.py @@ -1,5 +1,5 @@ -from magnumopus.pantry import Pantry -from magnumopus.substance import Substance +from magnumopus.repositories.pantry import Pantry +from magnumopus.models.substance import Substance def test_can_add_to_pantry(): pantry = Pantry() @@ -17,6 +17,6 @@ def test_can_retrieve_substance_from_pantry_by_nature(): pantry.add_substance(substance) - mercury = pantry.find_substance_by_nature('Mercury') + mercury = pantry.find_substances_by_nature('Mercury')[0] assert mercury.nature == 'Mercury' diff --git a/021-conical/magnum_opus/tests/test_substance.py b/021-conical/magnum_opus/tests/test_substance.py index 342cf50..d00a6f7 100644 --- a/021-conical/magnum_opus/tests/test_substance.py +++ b/021-conical/magnum_opus/tests/test_substance.py @@ -1,4 +1,4 @@ -from magnumopus.substance import Substance +from magnumopus.models.substance import Substance def test_can_cook_substance(): substance = Substance() From bf5a2213c34d83c1860a064f14cd868a067689e8 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Wed, 17 Jun 2020 00:52:27 +0100 Subject: [PATCH 03/12] two version of conical exercise at different points --- 021-conical-continued/magnum_opus/.gitignore | 3 + 021-conical-continued/magnum_opus/Dockerfile | 23 ++++++ 021-conical-continued/magnum_opus/MANIFEST.in | 1 + 021-conical-continued/magnum_opus/README.md | 5 ++ 021-conical-continued/magnum_opus/RULES.md | 9 +++ .../magnum_opus/docker-compose.yml | 6 ++ .../magnum_opus/gunicorn_config.py | 5 ++ .../magnum_opus/magnumopus/__init__.py | 14 ++++ .../magnum_opus/magnumopus/index.py | 3 + .../magnum_opus/magnumopus/logger.py | 5 ++ .../magnum_opus/magnumopus/models/__init__.py | 5 ++ .../magnum_opus/magnumopus/models/base.py | 3 + .../magnumopus/models/substance.py | 23 ++++++ .../magnumopus/repositories/__init__.py | 0 .../magnumopus/repositories/pantry.py | 14 ++++ .../magnumopus/resources/__init__.py | 8 ++ .../resources/alembic_instruction.py | 49 +++++++++++ .../magnumopus/resources/substance.py | 37 +++++++++ .../magnumopus/schemas/__init__.py | 6 ++ .../magnumopus/schemas/substance_schema.py | 13 +++ .../magnumopus/services/__init__.py | 0 .../magnumopus/services/alembic.py | 51 ++++++++++++ .../services/alembic_instruction_handler.py | 31 +++++++ .../magnumopus/services/assessor.py | 2 + .../magnum_opus/requirements.txt | 5 ++ 021-conical-continued/magnum_opus/setup.cfg | 23 ++++++ 021-conical-continued/magnum_opus/setup.py | 14 ++++ .../magnum_opus/tests/test_alembic.py | 81 +++++++++++++++++++ .../magnum_opus/tests/test_pantry.py | 22 +++++ .../magnum_opus/tests/test_substance.py | 49 +++++++++++ 021-conical-continued/magnum_opus/tox.ini | 6 ++ .../magnum_opus/magnumopus/__init__.py | 14 ---- 021-conical/magnum_opus/magnumopus/alembic.py | 51 ++++++++++++ 021-conical/magnum_opus/magnumopus/pantry.py | 12 +++ .../magnum_opus/magnumopus/substance.py | 23 ++++++ 021-conical/magnum_opus/requirements.txt | 10 +-- 021-conical/magnum_opus/setup.cfg | 4 - 021-conical/magnum_opus/tests/test_alembic.py | 4 +- 021-conical/magnum_opus/tests/test_pantry.py | 6 +- .../magnum_opus/tests/test_substance.py | 2 +- 40 files changed, 613 insertions(+), 29 deletions(-) create mode 100644 021-conical-continued/magnum_opus/.gitignore create mode 100644 021-conical-continued/magnum_opus/Dockerfile create mode 100644 021-conical-continued/magnum_opus/MANIFEST.in create mode 100644 021-conical-continued/magnum_opus/README.md create mode 100644 021-conical-continued/magnum_opus/RULES.md create mode 100644 021-conical-continued/magnum_opus/docker-compose.yml create mode 100644 021-conical-continued/magnum_opus/gunicorn_config.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/__init__.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/index.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/logger.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/models/__init__.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/models/base.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/models/substance.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/repositories/__init__.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/repositories/pantry.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/resources/__init__.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/resources/alembic_instruction.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/resources/substance.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/schemas/__init__.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/schemas/substance_schema.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/services/__init__.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/services/alembic.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/services/alembic_instruction_handler.py create mode 100644 021-conical-continued/magnum_opus/magnumopus/services/assessor.py create mode 100644 021-conical-continued/magnum_opus/requirements.txt create mode 100644 021-conical-continued/magnum_opus/setup.cfg create mode 100644 021-conical-continued/magnum_opus/setup.py create mode 100644 021-conical-continued/magnum_opus/tests/test_alembic.py create mode 100644 021-conical-continued/magnum_opus/tests/test_pantry.py create mode 100644 021-conical-continued/magnum_opus/tests/test_substance.py create mode 100644 021-conical-continued/magnum_opus/tox.ini create mode 100644 021-conical/magnum_opus/magnumopus/alembic.py create mode 100644 021-conical/magnum_opus/magnumopus/pantry.py create mode 100644 021-conical/magnum_opus/magnumopus/substance.py diff --git a/021-conical-continued/magnum_opus/.gitignore b/021-conical-continued/magnum_opus/.gitignore new file mode 100644 index 0000000..9fb668e --- /dev/null +++ b/021-conical-continued/magnum_opus/.gitignore @@ -0,0 +1,3 @@ +*.egg-info +.tox +Pipfile diff --git a/021-conical-continued/magnum_opus/Dockerfile b/021-conical-continued/magnum_opus/Dockerfile new file mode 100644 index 0000000..e8b07e3 --- /dev/null +++ b/021-conical-continued/magnum_opus/Dockerfile @@ -0,0 +1,23 @@ +FROM python:3-alpine + +RUN addgroup -S user && adduser user -S -G user + +WORKDIR /home/user/ + +COPY requirements.txt . +COPY gunicorn_config.py . +COPY setup.py . +COPY setup.cfg . + +RUN pip install gunicorn +RUN pip install -r requirements.txt + +USER user + +EXPOSE 5000 + +ENTRYPOINT [] + +CMD gunicorn --config ./gunicorn_config.py magnumopus.index:app + +COPY magnumopus magnumopus diff --git a/021-conical-continued/magnum_opus/MANIFEST.in b/021-conical-continued/magnum_opus/MANIFEST.in new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/021-conical-continued/magnum_opus/MANIFEST.in @@ -0,0 +1 @@ + diff --git a/021-conical-continued/magnum_opus/README.md b/021-conical-continued/magnum_opus/README.md new file mode 100644 index 0000000..b87be82 --- /dev/null +++ b/021-conical-continued/magnum_opus/README.md @@ -0,0 +1,5 @@ +Magnum Opus +=========== + +This recipe maker +and averaged over repeated attempts, returning an average round trip time. diff --git a/021-conical-continued/magnum_opus/RULES.md b/021-conical-continued/magnum_opus/RULES.md new file mode 100644 index 0000000..4438311 --- /dev/null +++ b/021-conical-continued/magnum_opus/RULES.md @@ -0,0 +1,9 @@ +* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my "Alembic" (mixing pot), giving one unit of another substance, Gloop +* Any attempt to mix anything other than those three substances, gives Sludge, another substance +* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented +* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills) +[* To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)] + +Final rule: +GROUP 1: When I process a substance, using any process, it becomes a different substance +GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process) diff --git a/021-conical-continued/magnum_opus/docker-compose.yml b/021-conical-continued/magnum_opus/docker-compose.yml new file mode 100644 index 0000000..a234fe9 --- /dev/null +++ b/021-conical-continued/magnum_opus/docker-compose.yml @@ -0,0 +1,6 @@ +version: "3" +services: + web: + build: . + ports: + - 5000:5000 diff --git a/021-conical-continued/magnum_opus/gunicorn_config.py b/021-conical-continued/magnum_opus/gunicorn_config.py new file mode 100644 index 0000000..29db9d9 --- /dev/null +++ b/021-conical-continued/magnum_opus/gunicorn_config.py @@ -0,0 +1,5 @@ +port = '5000' +bind = "0.0.0.0:%s" % port +workers = 1 +timeout = 600 +reload = False diff --git a/021-conical-continued/magnum_opus/magnumopus/__init__.py b/021-conical-continued/magnum_opus/magnumopus/__init__.py new file mode 100644 index 0000000..2a3a1fb --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/__init__.py @@ -0,0 +1,14 @@ +from flask import Flask + +def create_app(): + from . import models, resources, schemas, logger + + app = Flask(__name__) + + # This helps avoid cyclic dependencies + logger.init_app(app) + models.init_app(app) + resources.init_app(app) + schemas.init_app(app) + + return app diff --git a/021-conical-continued/magnum_opus/magnumopus/index.py b/021-conical-continued/magnum_opus/magnumopus/index.py new file mode 100644 index 0000000..183c186 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/index.py @@ -0,0 +1,3 @@ +from . import create_app + +app = create_app() diff --git a/021-conical-continued/magnum_opus/magnumopus/logger.py b/021-conical-continued/magnum_opus/magnumopus/logger.py new file mode 100644 index 0000000..9b7f97a --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/logger.py @@ -0,0 +1,5 @@ +import logging + +def init_app(app): + app.logger.addHandler(logging.StreamHandler()) + app.logger.setLevel(logging.INFO) diff --git a/021-conical-continued/magnum_opus/magnumopus/models/__init__.py b/021-conical-continued/magnum_opus/magnumopus/models/__init__.py new file mode 100644 index 0000000..2e94a1e --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/models/__init__.py @@ -0,0 +1,5 @@ +from .base import db + +def init_app(app): + app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' + db.init_app(app) diff --git a/021-conical-continued/magnum_opus/magnumopus/models/base.py b/021-conical-continued/magnum_opus/magnumopus/models/base.py new file mode 100644 index 0000000..f0b13d6 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/models/base.py @@ -0,0 +1,3 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() diff --git a/021-conical-continued/magnum_opus/magnumopus/models/substance.py b/021-conical-continued/magnum_opus/magnumopus/models/substance.py new file mode 100644 index 0000000..828b4c5 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/models/substance.py @@ -0,0 +1,23 @@ +class SubstanceMustBeFreshToProcessException(Exception): + pass + +class Substance: + def __init__(self, nature='Unknown'): + self.nature = nature + self.state = [] + + def _process(self, process_name): + self.state.append(process_name) + return self + + def cook(self): + return self._process('cooked') + + def pickle(self): + return self._process('pickled') + + def ferment(self): + return self._process('fermented') + + def wash(self): + return self._process('washed') diff --git a/021-conical-continued/magnum_opus/magnumopus/repositories/__init__.py b/021-conical-continued/magnum_opus/magnumopus/repositories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/021-conical-continued/magnum_opus/magnumopus/repositories/pantry.py b/021-conical-continued/magnum_opus/magnumopus/repositories/pantry.py new file mode 100644 index 0000000..90ac0d9 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/repositories/pantry.py @@ -0,0 +1,14 @@ +class Pantry: + _cupboard = [] + + def __init__(self): + pass + + def add_substance(self, substance): + self._cupboard.append(substance) + + def find_substances_by_nature(self, nature): + return [substance for substance in self._cupboard if substance.nature == nature] + + def count_all_substances(self): + return len(self._cupboard) diff --git a/021-conical-continued/magnum_opus/magnumopus/resources/__init__.py b/021-conical-continued/magnum_opus/magnumopus/resources/__init__.py new file mode 100644 index 0000000..85683b9 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/resources/__init__.py @@ -0,0 +1,8 @@ +from flask_restful import Api +from . import substance +from . import alembic_instruction + +def init_app(app): + api = Api(app) + substance.init_app(app, api) + alembic_instruction.init_app(app, api) diff --git a/021-conical-continued/magnum_opus/magnumopus/resources/alembic_instruction.py b/021-conical-continued/magnum_opus/magnumopus/resources/alembic_instruction.py new file mode 100644 index 0000000..1843acf --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/resources/alembic_instruction.py @@ -0,0 +1,49 @@ +from flask_restful import Resource, reqparse +from ..repositories.pantry import Pantry +from ..models.substance import Substance +from ..schemas.substance_schema import SubstanceSchema +from ..services.alembic_instruction_handler import AlembicInstructionHandler, AlembicInstruction + +parser = reqparse.RequestParser() +parser.add_argument('instruction_type') +parser.add_argument('action') +parser.add_argument('natures') + +substance_schema = SubstanceSchema() + +class AlembicInstructionResource(Resource): + def get(self): + """This should return past requests/commands.""" + pass + + def post(self): + """ + Add an instruction for the alembic. + + Note that POST is _not_ assumed to be idempotent, unlike PUT + """ + + args = parser.parse_args() + instruction_type = args['instruction_type'] + + pantry = Pantry() + + instruction_handler = AlembicInstructionHandler() + + # This could do with deserialization... + instruction = AlembicInstruction( + instruction_type=args.instruction_type, + natures=args.natures.split(','), + action=args.action + ) + + # Crude start at DI... see flask-injector + result = instruction_handler.handle(instruction, pantry) + + pantry.add_substance(result) + + return substance_schema.dump(result) + + +def init_app(app, api): + api.add_resource(AlembicInstructionResource, '/alembic_instruction') diff --git a/021-conical-continued/magnum_opus/magnumopus/resources/substance.py b/021-conical-continued/magnum_opus/magnumopus/resources/substance.py new file mode 100644 index 0000000..770dcac --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/resources/substance.py @@ -0,0 +1,37 @@ +from flask_restful import Resource, reqparse +from ..repositories.pantry import Pantry +from ..models.substance import Substance +from ..schemas.substance_schema import SubstanceSchema + +parser = reqparse.RequestParser() +parser.add_argument('nature') + +substance_schema = SubstanceSchema() +substances_schema = SubstanceSchema(many=True) + + +class SubstanceResource(Resource): + def get(self): + args = parser.parse_args() + nature = args['nature'] + pantry = Pantry() + + substances = pantry.find_substances_by_nature(nature) + + return substances_schema.dump(substances) + + def post(self): + args = parser.parse_args() + nature = args['nature'] + + pantry = Pantry() + + substance = Substance(nature=nature) + + pantry.add_substance(substance) + + return substance_schema.dump(substance) + + +def init_app(app, api): + api.add_resource(SubstanceResource, '/substance') diff --git a/021-conical-continued/magnum_opus/magnumopus/schemas/__init__.py b/021-conical-continued/magnum_opus/magnumopus/schemas/__init__.py new file mode 100644 index 0000000..34395e3 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/schemas/__init__.py @@ -0,0 +1,6 @@ +from flask_marshmallow import Marshmallow + +ma = Marshmallow() + +def init_app(app): + ma.init_app(app) diff --git a/021-conical-continued/magnum_opus/magnumopus/schemas/substance_schema.py b/021-conical-continued/magnum_opus/magnumopus/schemas/substance_schema.py new file mode 100644 index 0000000..430e96c --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/schemas/substance_schema.py @@ -0,0 +1,13 @@ +from marshmallow import fields + +from . import ma + +from ..services.assessor import assess_whether_substance_is_philosophers_stone + +class SubstanceSchema(ma.Schema): + is_philosophers_stone = fields.Function( + assess_whether_substance_is_philosophers_stone + ) + + class Meta: + fields = ("nature", "is_philosophers_stone") diff --git a/021-conical-continued/magnum_opus/magnumopus/services/__init__.py b/021-conical-continued/magnum_opus/magnumopus/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/021-conical-continued/magnum_opus/magnumopus/services/alembic.py b/021-conical-continued/magnum_opus/magnumopus/services/alembic.py new file mode 100644 index 0000000..5fc05b2 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/services/alembic.py @@ -0,0 +1,51 @@ +from ..models.substance import Substance + +class NotEnoughSubstancesToMixException(Exception): + pass + +class UnknownProcessException(Exception): + pass + + +MIXTURES = { + ('Mercury', 'Salt', 'Sulphur'): 'Gloop' +} + + +class Alembic: + _nature_of_unknown_mixture = 'Sludge' + + @staticmethod + def _produce(nature): + return Substance(nature=nature) + + def mix(self, *substances): + if len(substances) < 2: + raise NotEnoughSubstancesToMixException() + + constituents = [substance.nature for substance in substances] + + # This gives us a canonical, ordered way of expressing our + # constituents that we can use as a recipe look-up + ingredient_list = tuple(sorted(constituents)) + + try: + nature = MIXTURES[ingredient_list] + except KeyError: + nature = self._nature_of_unknown_mixture + + return self._produce(nature) + + def process(self, process_name, substance): + if process_name == 'ferment': + result = substance.ferment() + elif process_name == 'cook': + result = substance.cook() + elif process_name == 'wash': + result = substance.wash() + elif process_name == 'pickle': + result = substance.pickle() + else: + raise UnknownProcessException() + + return result diff --git a/021-conical-continued/magnum_opus/magnumopus/services/alembic_instruction_handler.py b/021-conical-continued/magnum_opus/magnumopus/services/alembic_instruction_handler.py new file mode 100644 index 0000000..556bbe2 --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/services/alembic_instruction_handler.py @@ -0,0 +1,31 @@ +from dataclasses import dataclass + +from .alembic import Alembic +from ..repositories.pantry import Pantry + +@dataclass +class AlembicInstruction: + instruction_type: str + natures: list + action: str = '' + +class AlembicInstructionHandler: + def handle(self, instruction: AlembicInstruction, pantry: Pantry): + natures = instruction.natures + action = instruction.action + instruction_type = instruction.instruction_type + + # Clearly need some validation here! + substances = [pantry.find_substances_by_nature(nature)[0] for nature in natures] + + alembic = Alembic() + + if instruction_type == 'mix': + result = alembic.mix(*substances) + elif instruction_type == 'process': + result = alembic.process(action, substances[0]) + else: + pass + # a sensible error + + return result diff --git a/021-conical-continued/magnum_opus/magnumopus/services/assessor.py b/021-conical-continued/magnum_opus/magnumopus/services/assessor.py new file mode 100644 index 0000000..94d564d --- /dev/null +++ b/021-conical-continued/magnum_opus/magnumopus/services/assessor.py @@ -0,0 +1,2 @@ +def assess_whether_substance_is_philosophers_stone(substance): + return substance.nature == 'Gloop' and substance.state == ['cooked', 'washed', 'pickled', 'fermented'] diff --git a/021-conical-continued/magnum_opus/requirements.txt b/021-conical-continued/magnum_opus/requirements.txt new file mode 100644 index 0000000..10bd0c2 --- /dev/null +++ b/021-conical-continued/magnum_opus/requirements.txt @@ -0,0 +1,5 @@ +appdirs +flask +flask-restful +flask-marshmallow +flask-sqlalchemy diff --git a/021-conical-continued/magnum_opus/setup.cfg b/021-conical-continued/magnum_opus/setup.cfg new file mode 100644 index 0000000..262547a --- /dev/null +++ b/021-conical-continued/magnum_opus/setup.cfg @@ -0,0 +1,23 @@ +[metadata] +name = magnumopus +version = 0.0.1 +author = Phil Weir +author_email = phil.weir@flaxandteal.co.uk +license = GPL +description = Service for cooking up a philosopher's stone +long-description = file:README.md + +[options] +include_package_data = True +packages = find: +python_requires = >=3.6 +install_requires = + appdirs + flask-restful + flask-marshmallow + flask-sqlalchemy + flask + +[options.packages.find] +exclude = + tests diff --git a/021-conical-continued/magnum_opus/setup.py b/021-conical-continued/magnum_opus/setup.py new file mode 100644 index 0000000..1767837 --- /dev/null +++ b/021-conical-continued/magnum_opus/setup.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Magnum Opus + +This tool performs alchemical reactions to create +the Philosopher's Stone. + +@author: Phil Weir +""" + +from setuptools import setup + +if __name__ == '__main__': + setup() diff --git a/021-conical-continued/magnum_opus/tests/test_alembic.py b/021-conical-continued/magnum_opus/tests/test_alembic.py new file mode 100644 index 0000000..cd67657 --- /dev/null +++ b/021-conical-continued/magnum_opus/tests/test_alembic.py @@ -0,0 +1,81 @@ +import pytest + +from magnumopus.services.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException +from magnumopus.models.substance import Substance + +def test_can_set_up_my_alembic(): + Alembic() + +def test_can_mix_multiple_substances_in_my_alembic(): + alembic = Alembic() + substance = [Substance() for _ in range(3)] + alembic.mix(*substance) + + substance = [Substance() for _ in range(6)] + alembic.mix(*substance) + +def test_cannot_mix_one_substance_in_my_alembic(): + alembic = Alembic() + substance = Substance() + + with pytest.raises(NotEnoughSubstancesToMixException): + alembic.mix(substance) + +def test_mixing_sulphur_salt_and_mercury_gives_gloop(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + + result = alembic.mix(sulphur, salt, mercury) + + assert result.nature == 'Gloop' + + result = alembic.mix(mercury, sulphur, salt) + + assert result.nature == 'Gloop' + +def test_mixing_other_recipes_gives_sludge(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + gloop = Substance(nature='Gloop') + + result = alembic.mix(sulphur, salt, mercury, sulphur) + + assert result.nature == 'Sludge' + + result = alembic.mix(salt, mercury) + + assert result.nature == 'Sludge' + + result = alembic.mix(gloop, salt, mercury) + + assert result.nature == 'Sludge' + +def test_can_process_substance(): + alembic = Alembic() + + substance = Substance() + result = alembic.process('cook', substance) + + substance = Substance() + cooked_substance = substance.cook() + + assert result.state == cooked_substance.state + + result = alembic.process('ferment', substance) + cooked_fermented_substance = cooked_substance.ferment() + + assert result.state == cooked_fermented_substance.state + +def test_cannot_perform_unknown_process(): + alembic = Alembic() + + substance = Substance() + + with pytest.raises(UnknownProcessException): + alembic.process('boil', substance) diff --git a/021-conical-continued/magnum_opus/tests/test_pantry.py b/021-conical-continued/magnum_opus/tests/test_pantry.py new file mode 100644 index 0000000..c968129 --- /dev/null +++ b/021-conical-continued/magnum_opus/tests/test_pantry.py @@ -0,0 +1,22 @@ +from magnumopus.repositories.pantry import Pantry +from magnumopus.models.substance import Substance + +def test_can_add_to_pantry(): + pantry = Pantry() + + substance = Substance() + + pantry.add_substance(substance) + + assert pantry.count_all_substances() == 1 + +def test_can_retrieve_substance_from_pantry_by_nature(): + pantry = Pantry() + + substance = Substance(nature='Mercury') + + pantry.add_substance(substance) + + mercury = pantry.find_substances_by_nature('Mercury')[0] + + assert mercury.nature == 'Mercury' diff --git a/021-conical-continued/magnum_opus/tests/test_substance.py b/021-conical-continued/magnum_opus/tests/test_substance.py new file mode 100644 index 0000000..d00a6f7 --- /dev/null +++ b/021-conical-continued/magnum_opus/tests/test_substance.py @@ -0,0 +1,49 @@ +from magnumopus.models.substance import Substance + +def test_can_cook_substance(): + substance = Substance() + + result = substance.cook() + + assert substance.state == ['cooked'] + +def test_can_wash_substance(): + substance = Substance() + + result = substance.wash() + + assert result.state == ['washed'] + +def test_can_pickle_substance(): + substance = Substance() + + result = substance.pickle() + + assert result.state == ['pickled'] + +def test_can_ferment_substance(): + substance = Substance() + + result = substance.ferment() + + assert substance.state == ['fermented'] + +def test_can_cook_and_ferment_substance(): + substance = Substance() + + result = substance.cook() + result = result.ferment() + + assert substance.state == ['cooked', 'fermented'] + +def test_the_order_of_processes_applied_to_a_substance_matters(): + substance1 = Substance() + result1 = substance1.cook() + result1 = result1.ferment() + + substance2 = Substance() + result2 = substance2.ferment() + result2 = result2.cook() + + assert result1.state != result2.state + assert result1.state == result2.state[::-1] diff --git a/021-conical-continued/magnum_opus/tox.ini b/021-conical-continued/magnum_opus/tox.ini new file mode 100644 index 0000000..d815853 --- /dev/null +++ b/021-conical-continued/magnum_opus/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py38 + +[testenv] +deps = pytest +commands = pytest diff --git a/021-conical/magnum_opus/magnumopus/__init__.py b/021-conical/magnum_opus/magnumopus/__init__.py index 2a3a1fb..e69de29 100644 --- a/021-conical/magnum_opus/magnumopus/__init__.py +++ b/021-conical/magnum_opus/magnumopus/__init__.py @@ -1,14 +0,0 @@ -from flask import Flask - -def create_app(): - from . import models, resources, schemas, logger - - app = Flask(__name__) - - # This helps avoid cyclic dependencies - logger.init_app(app) - models.init_app(app) - resources.init_app(app) - schemas.init_app(app) - - return app diff --git a/021-conical/magnum_opus/magnumopus/alembic.py b/021-conical/magnum_opus/magnumopus/alembic.py new file mode 100644 index 0000000..39f02a4 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/alembic.py @@ -0,0 +1,51 @@ +from .substance import Substance + +class NotEnoughSubstancesToMixException(Exception): + pass + +class UnknownProcessException(Exception): + pass + + +MIXTURES = { + ('Mercury', 'Salt', 'Sulphur'): 'Gloop' +} + + +class Alembic: + _nature_of_unknown_mixture = 'Sludge' + + @staticmethod + def _produce(nature): + return Substance(nature=nature) + + def mix(self, *substances): + if len(substances) < 2: + raise NotEnoughSubstancesToMixException() + + constituents = [substance.nature for substance in substances] + + # This gives us a canonical, ordered way of expressing our + # constituents that we can use as a recipe look-up + ingredient_list = tuple(sorted(constituents)) + + try: + nature = MIXTURES[ingredient_list] + except KeyError: + nature = self._nature_of_unknown_mixture + + return self._produce(nature) + + def process(self, process_name, substance): + if process_name == 'ferment': + result = substance.ferment() + elif process_name == 'cook': + result = substance.cook() + elif process_name == 'wash': + result = substance.wash() + elif process_name == 'pickle': + result = substance.pickle() + else: + raise UnknownProcessException() + + return result diff --git a/021-conical/magnum_opus/magnumopus/pantry.py b/021-conical/magnum_opus/magnumopus/pantry.py new file mode 100644 index 0000000..9e7a1d6 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/pantry.py @@ -0,0 +1,12 @@ +class Pantry: + def __init__(self): + self._cupboard = [] + + def add_substance(self, substance): + self._cupboard.append(substance) + + def find_substance_by_nature(self, nature): + return [substance for substance in self._cupboard if substance.nature == nature][0] + + def count_all_substances(self): + return len(self._cupboard) diff --git a/021-conical/magnum_opus/magnumopus/substance.py b/021-conical/magnum_opus/magnumopus/substance.py new file mode 100644 index 0000000..828b4c5 --- /dev/null +++ b/021-conical/magnum_opus/magnumopus/substance.py @@ -0,0 +1,23 @@ +class SubstanceMustBeFreshToProcessException(Exception): + pass + +class Substance: + def __init__(self, nature='Unknown'): + self.nature = nature + self.state = [] + + def _process(self, process_name): + self.state.append(process_name) + return self + + def cook(self): + return self._process('cooked') + + def pickle(self): + return self._process('pickled') + + def ferment(self): + return self._process('fermented') + + def wash(self): + return self._process('washed') diff --git a/021-conical/magnum_opus/requirements.txt b/021-conical/magnum_opus/requirements.txt index 10bd0c2..99f65af 100644 --- a/021-conical/magnum_opus/requirements.txt +++ b/021-conical/magnum_opus/requirements.txt @@ -1,5 +1,5 @@ -appdirs -flask -flask-restful -flask-marshmallow -flask-sqlalchemy +numpy +pylint +pyyaml +Click +appdirs \ No newline at end of file diff --git a/021-conical/magnum_opus/setup.cfg b/021-conical/magnum_opus/setup.cfg index 262547a..144266f 100644 --- a/021-conical/magnum_opus/setup.cfg +++ b/021-conical/magnum_opus/setup.cfg @@ -13,10 +13,6 @@ packages = find: python_requires = >=3.6 install_requires = appdirs - flask-restful - flask-marshmallow - flask-sqlalchemy - flask [options.packages.find] exclude = diff --git a/021-conical/magnum_opus/tests/test_alembic.py b/021-conical/magnum_opus/tests/test_alembic.py index cd67657..01fd341 100644 --- a/021-conical/magnum_opus/tests/test_alembic.py +++ b/021-conical/magnum_opus/tests/test_alembic.py @@ -1,7 +1,7 @@ import pytest -from magnumopus.services.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException -from magnumopus.models.substance import Substance +from magnumopus.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException +from magnumopus.substance import Substance def test_can_set_up_my_alembic(): Alembic() diff --git a/021-conical/magnum_opus/tests/test_pantry.py b/021-conical/magnum_opus/tests/test_pantry.py index c968129..84dbd7e 100644 --- a/021-conical/magnum_opus/tests/test_pantry.py +++ b/021-conical/magnum_opus/tests/test_pantry.py @@ -1,5 +1,5 @@ -from magnumopus.repositories.pantry import Pantry -from magnumopus.models.substance import Substance +from magnumopus.pantry import Pantry +from magnumopus.substance import Substance def test_can_add_to_pantry(): pantry = Pantry() @@ -17,6 +17,6 @@ def test_can_retrieve_substance_from_pantry_by_nature(): pantry.add_substance(substance) - mercury = pantry.find_substances_by_nature('Mercury')[0] + mercury = pantry.find_substance_by_nature('Mercury') assert mercury.nature == 'Mercury' diff --git a/021-conical/magnum_opus/tests/test_substance.py b/021-conical/magnum_opus/tests/test_substance.py index d00a6f7..342cf50 100644 --- a/021-conical/magnum_opus/tests/test_substance.py +++ b/021-conical/magnum_opus/tests/test_substance.py @@ -1,4 +1,4 @@ -from magnumopus.models.substance import Substance +from magnumopus.substance import Substance def test_can_cook_substance(): substance = Substance() From 69a071398a9fbf48a0e19a9b5d0c1fc1ce16cb67 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Wed, 17 Jun 2020 08:39:24 +0100 Subject: [PATCH 04/12] basic sqlalchemy and containers attached for magnumopus --- .../magnum_opus/.gitignore | 3 + .../magnum_opus/Dockerfile | 24 ++++++ .../magnum_opus/MANIFEST.in | 1 + .../magnum_opus/README.md | 5 ++ .../magnum_opus/RULES.md | 9 ++ .../magnum_opus/docker-compose.yml | 10 +++ .../magnum_opus/docker/storage/storage.db | Bin 0 -> 8192 bytes .../magnum_opus/gunicorn_config.py | 5 ++ .../magnum_opus/init_containers.sh | 6 ++ .../magnum_opus/init_entrypoint.sh | 3 + .../magnum_opus/magnumopus/__init__.py | 17 ++++ .../magnum_opus/magnumopus/config.py | 5 ++ .../magnum_opus/magnumopus/index.py | 3 + .../magnum_opus/magnumopus/initialize.py | 9 ++ .../magnum_opus/magnumopus/logger.py | 5 ++ .../magnum_opus/magnumopus/models/__init__.py | 4 + .../magnum_opus/magnumopus/models/base.py | 3 + .../magnumopus/models/substance.py | 34 ++++++++ .../magnumopus/repositories/__init__.py | 0 .../magnumopus/repositories/pantry.py | 17 ++++ .../repositories/sqlalchemy_pantry.py | 24 ++++++ .../magnumopus/resources/__init__.py | 8 ++ .../resources/alembic_instruction.py | 52 +++++++++++ .../magnumopus/resources/substance.py | 44 ++++++++++ .../magnumopus/schemas/__init__.py | 6 ++ .../magnumopus/schemas/substance_schema.py | 18 ++++ .../magnumopus/services/__init__.py | 0 .../magnumopus/services/alembic.py | 51 +++++++++++ .../services/alembic_instruction_handler.py | 31 +++++++ .../magnumopus/services/assessor.py | 2 + .../magnum_opus/requirements.txt | 7 ++ .../magnum_opus/setup.cfg | 25 ++++++ .../magnum_opus/setup.py | 14 +++ .../magnum_opus/tests/test_alembic.py | 81 ++++++++++++++++++ .../magnum_opus/tests/test_pantry.py | 22 +++++ .../magnum_opus/tests/test_substance.py | 49 +++++++++++ .../magnum_opus/tox.ini | 6 ++ 37 files changed, 603 insertions(+) create mode 100644 021-conical-continued-again/magnum_opus/.gitignore create mode 100644 021-conical-continued-again/magnum_opus/Dockerfile create mode 100644 021-conical-continued-again/magnum_opus/MANIFEST.in create mode 100644 021-conical-continued-again/magnum_opus/README.md create mode 100644 021-conical-continued-again/magnum_opus/RULES.md create mode 100644 021-conical-continued-again/magnum_opus/docker-compose.yml create mode 100644 021-conical-continued-again/magnum_opus/docker/storage/storage.db create mode 100644 021-conical-continued-again/magnum_opus/gunicorn_config.py create mode 100755 021-conical-continued-again/magnum_opus/init_containers.sh create mode 100755 021-conical-continued-again/magnum_opus/init_entrypoint.sh create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/__init__.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/config.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/index.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/initialize.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/logger.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/models/__init__.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/models/base.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/models/substance.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/repositories/__init__.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/repositories/pantry.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/repositories/sqlalchemy_pantry.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/resources/__init__.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/resources/alembic_instruction.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/resources/substance.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/schemas/__init__.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/schemas/substance_schema.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/services/__init__.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/services/alembic.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/services/alembic_instruction_handler.py create mode 100644 021-conical-continued-again/magnum_opus/magnumopus/services/assessor.py create mode 100644 021-conical-continued-again/magnum_opus/requirements.txt create mode 100644 021-conical-continued-again/magnum_opus/setup.cfg create mode 100644 021-conical-continued-again/magnum_opus/setup.py create mode 100644 021-conical-continued-again/magnum_opus/tests/test_alembic.py create mode 100644 021-conical-continued-again/magnum_opus/tests/test_pantry.py create mode 100644 021-conical-continued-again/magnum_opus/tests/test_substance.py create mode 100644 021-conical-continued-again/magnum_opus/tox.ini diff --git a/021-conical-continued-again/magnum_opus/.gitignore b/021-conical-continued-again/magnum_opus/.gitignore new file mode 100644 index 0000000..9fb668e --- /dev/null +++ b/021-conical-continued-again/magnum_opus/.gitignore @@ -0,0 +1,3 @@ +*.egg-info +.tox +Pipfile diff --git a/021-conical-continued-again/magnum_opus/Dockerfile b/021-conical-continued-again/magnum_opus/Dockerfile new file mode 100644 index 0000000..03a8d6e --- /dev/null +++ b/021-conical-continued-again/magnum_opus/Dockerfile @@ -0,0 +1,24 @@ +FROM python:3-alpine + +RUN addgroup -S user && adduser user -S -G user + +WORKDIR /home/user/ + +COPY requirements.txt . +COPY gunicorn_config.py . +COPY setup.py . +COPY setup.cfg . +COPY init_entrypoint.sh / + +RUN pip install gunicorn +RUN pip install -r requirements.txt + +USER user + +EXPOSE 5000 + +ENTRYPOINT [] + +CMD gunicorn --config ./gunicorn_config.py magnumopus.index:app + +COPY magnumopus magnumopus diff --git a/021-conical-continued-again/magnum_opus/MANIFEST.in b/021-conical-continued-again/magnum_opus/MANIFEST.in new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/MANIFEST.in @@ -0,0 +1 @@ + diff --git a/021-conical-continued-again/magnum_opus/README.md b/021-conical-continued-again/magnum_opus/README.md new file mode 100644 index 0000000..b87be82 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/README.md @@ -0,0 +1,5 @@ +Magnum Opus +=========== + +This recipe maker +and averaged over repeated attempts, returning an average round trip time. diff --git a/021-conical-continued-again/magnum_opus/RULES.md b/021-conical-continued-again/magnum_opus/RULES.md new file mode 100644 index 0000000..4438311 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/RULES.md @@ -0,0 +1,9 @@ +* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my "Alembic" (mixing pot), giving one unit of another substance, Gloop +* Any attempt to mix anything other than those three substances, gives Sludge, another substance +* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented +* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills) +[* To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)] + +Final rule: +GROUP 1: When I process a substance, using any process, it becomes a different substance +GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process) diff --git a/021-conical-continued-again/magnum_opus/docker-compose.yml b/021-conical-continued-again/magnum_opus/docker-compose.yml new file mode 100644 index 0000000..b5b9962 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/docker-compose.yml @@ -0,0 +1,10 @@ +version: "3" +services: + web: + build: . + environment: + DATABASE_URI: 'sqlite:////docker/storage/storage.db' + volumes: + - ./docker:/docker + ports: + - 5000:5000 diff --git a/021-conical-continued-again/magnum_opus/docker/storage/storage.db b/021-conical-continued-again/magnum_opus/docker/storage/storage.db new file mode 100644 index 0000000000000000000000000000000000000000..1ca583a44b1c65b9c5aee6b06168dcfc0b816ca9 GIT binary patch literal 8192 zcmeI#F;2oz9LMojtU_DM-^DPvJT^#-gN!a#(jc*bmSV)jp+Jqq+G1&ATuhj~fEVxr zUcd`@0WaWgynwF*;cXtk-#=~ozOPM(&-VIf&NL19b)4M!DQ~bXrYP)?bH*5nyCCl6 zC}N>5Lp<~TYl!U~e4FAcg;FLi3@*6W;E6cFT5ox99Qhz;SlDu0?*DB>_LT z+~%?6)*Acud{_Kg9Pd5*!prN_ZFekp$WQDcuT3X)y`G=V%hY4^LtpesAM{Rd^hz)E zOiy%A6S@>HF%W=3.6 +install_requires = + appdirs + flask-restful + flask-marshmallow + flask-sqlalchemy + sqlalchemy-utils + marshmallow-sqlalchemy + flask + +[options.packages.find] +exclude = + tests diff --git a/021-conical-continued-again/magnum_opus/setup.py b/021-conical-continued-again/magnum_opus/setup.py new file mode 100644 index 0000000..1767837 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/setup.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Magnum Opus + +This tool performs alchemical reactions to create +the Philosopher's Stone. + +@author: Phil Weir +""" + +from setuptools import setup + +if __name__ == '__main__': + setup() diff --git a/021-conical-continued-again/magnum_opus/tests/test_alembic.py b/021-conical-continued-again/magnum_opus/tests/test_alembic.py new file mode 100644 index 0000000..cd67657 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/tests/test_alembic.py @@ -0,0 +1,81 @@ +import pytest + +from magnumopus.services.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException +from magnumopus.models.substance import Substance + +def test_can_set_up_my_alembic(): + Alembic() + +def test_can_mix_multiple_substances_in_my_alembic(): + alembic = Alembic() + substance = [Substance() for _ in range(3)] + alembic.mix(*substance) + + substance = [Substance() for _ in range(6)] + alembic.mix(*substance) + +def test_cannot_mix_one_substance_in_my_alembic(): + alembic = Alembic() + substance = Substance() + + with pytest.raises(NotEnoughSubstancesToMixException): + alembic.mix(substance) + +def test_mixing_sulphur_salt_and_mercury_gives_gloop(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + + result = alembic.mix(sulphur, salt, mercury) + + assert result.nature == 'Gloop' + + result = alembic.mix(mercury, sulphur, salt) + + assert result.nature == 'Gloop' + +def test_mixing_other_recipes_gives_sludge(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + gloop = Substance(nature='Gloop') + + result = alembic.mix(sulphur, salt, mercury, sulphur) + + assert result.nature == 'Sludge' + + result = alembic.mix(salt, mercury) + + assert result.nature == 'Sludge' + + result = alembic.mix(gloop, salt, mercury) + + assert result.nature == 'Sludge' + +def test_can_process_substance(): + alembic = Alembic() + + substance = Substance() + result = alembic.process('cook', substance) + + substance = Substance() + cooked_substance = substance.cook() + + assert result.state == cooked_substance.state + + result = alembic.process('ferment', substance) + cooked_fermented_substance = cooked_substance.ferment() + + assert result.state == cooked_fermented_substance.state + +def test_cannot_perform_unknown_process(): + alembic = Alembic() + + substance = Substance() + + with pytest.raises(UnknownProcessException): + alembic.process('boil', substance) diff --git a/021-conical-continued-again/magnum_opus/tests/test_pantry.py b/021-conical-continued-again/magnum_opus/tests/test_pantry.py new file mode 100644 index 0000000..c968129 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/tests/test_pantry.py @@ -0,0 +1,22 @@ +from magnumopus.repositories.pantry import Pantry +from magnumopus.models.substance import Substance + +def test_can_add_to_pantry(): + pantry = Pantry() + + substance = Substance() + + pantry.add_substance(substance) + + assert pantry.count_all_substances() == 1 + +def test_can_retrieve_substance_from_pantry_by_nature(): + pantry = Pantry() + + substance = Substance(nature='Mercury') + + pantry.add_substance(substance) + + mercury = pantry.find_substances_by_nature('Mercury')[0] + + assert mercury.nature == 'Mercury' diff --git a/021-conical-continued-again/magnum_opus/tests/test_substance.py b/021-conical-continued-again/magnum_opus/tests/test_substance.py new file mode 100644 index 0000000..d00a6f7 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/tests/test_substance.py @@ -0,0 +1,49 @@ +from magnumopus.models.substance import Substance + +def test_can_cook_substance(): + substance = Substance() + + result = substance.cook() + + assert substance.state == ['cooked'] + +def test_can_wash_substance(): + substance = Substance() + + result = substance.wash() + + assert result.state == ['washed'] + +def test_can_pickle_substance(): + substance = Substance() + + result = substance.pickle() + + assert result.state == ['pickled'] + +def test_can_ferment_substance(): + substance = Substance() + + result = substance.ferment() + + assert substance.state == ['fermented'] + +def test_can_cook_and_ferment_substance(): + substance = Substance() + + result = substance.cook() + result = result.ferment() + + assert substance.state == ['cooked', 'fermented'] + +def test_the_order_of_processes_applied_to_a_substance_matters(): + substance1 = Substance() + result1 = substance1.cook() + result1 = result1.ferment() + + substance2 = Substance() + result2 = substance2.ferment() + result2 = result2.cook() + + assert result1.state != result2.state + assert result1.state == result2.state[::-1] diff --git a/021-conical-continued-again/magnum_opus/tox.ini b/021-conical-continued-again/magnum_opus/tox.ini new file mode 100644 index 0000000..d815853 --- /dev/null +++ b/021-conical-continued-again/magnum_opus/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py38 + +[testenv] +deps = pytest +commands = pytest From ebc6fdbd4ec327a6904338695c2f16858b3eb2d6 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Wed, 17 Jun 2020 09:09:11 +0000 Subject: [PATCH 05/12] add basic directions for alchemy exercise --- 021-conical/Alchemy - A Sequel.ipynb | 376 +++++++++++++++++++++++++++ 1 file changed, 376 insertions(+) create mode 100644 021-conical/Alchemy - A Sequel.ipynb diff --git a/021-conical/Alchemy - A Sequel.ipynb b/021-conical/Alchemy - A Sequel.ipynb new file mode 100644 index 0000000..933372e --- /dev/null +++ b/021-conical/Alchemy - A Sequel.ipynb @@ -0,0 +1,376 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Brewing up a Stone" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Alchemy with Flask and SQLAlchemy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Before chemistry, there was alchemy, and the learned elite used to search for the secret of the true cure for all afflictions, the Philosopher's Stone. Using modern technology, we are able to implement it as a web service." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While a plethora of abstruse, esoteric jingo concealed the complex, ever-changing rite, the basic recipe boils down to:\n", + "\n", + "* Cooking - charring\n", + "* Washing - brightening\n", + "* Pickling - yellowing\n", + "* Fermentation - reddening" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This recipe also works for gherkins." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### SQLAlchemy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For those who haven't come across it, SQLAlchemy is a database toolkit and ORM - Object Relational Mapper. That is (amongst other things), it facilitates turning a set of living objects to and from frozen database records. Very alchemical." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "During its construction, its creator used [Martin Fowler's work](https://martinfowler.com/eaaCatalog/) in enterprise architecture (who we talked about before) to incorporate a number of patterns. A few to highlight:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* [Association Table Mapping](https://martinfowler.com/eaaCatalog/associationTableMapping.html)\n", + "* [Inheritance Mapping](https://martinfowler.com/eaaCatalog/inheritanceMappers.html)\n", + "* [Unit of Work](https://martinfowler.com/eaaCatalog/unitOfWork.html)\n", + "* [Embedded Value](https://martinfowler.com/eaaCatalog/embeddedValue.html)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Implementing Alchemy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my \"Alembic\" (mixing pot), giving one unit of another substance, Gloop\n", + "* Any attempt to mix anything other than those three substances, gives Sludge, another substance\n", + "* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented\n", + "* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills)\n", + "\n", + "Final rule:\n", + "\n", + "GROUP 1: When I process a substance, using any process, it becomes a different substance\n", + "\n", + "GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process)\n", + "\n", + "* Extension Rule: To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "----" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "hidePrompt": true + }, + "source": [ + "Each group has 10 minutes to discuss how they plan to approach it - no code, just words and pictures (if you want to screenshare).\n", + "Write down all your names in alphabetical order in Etherpad, and pick a rule for ech person to begin implementing (if you don't have a rule, focus on any models or shared classes)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At this point, you begin coding, but zero talking or code comments (this time!). Only active code. Use Etherpad to share your code. Every 5 minutes, the next person in the alphabetical list swaps between groups. We'll take a break and, if necessary, do another round." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Test with tox !" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Tips" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Try and avoid \"create\", \"update\", \"delete\" or obvious equivalents as verbs - think about the word in the domain." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 12 Factor App" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "From https://12factor.net/\n", + "([license](https://github.com/heroku/12factor/blob/master/LICENSE))\n", + "\n", + "1. **Codebase**: One codebase tracked in revision control, many deploys\n", + "2. **Dependencies**: Explicitly declare and isolate dependencies\n", + "3. **Config**: Store config in the environment\n", + "4. **Backing services**: Treat backing services as attached resources\n", + "5. **Build, release, run**: Strictly separate build and run stages\n", + "6. **Processes**: Execute the app as one or more stateless processes\n", + "7. **Port binding**: Export services via port binding\n", + "8. **Concurrency**: Scale out via the process model\n", + "9. **Disposability**: Maximize robustness with fast startup and graceful shutdown\n", + "10. **Dev/prod parity**: Keep development, staging, and production as similar as possible\n", + "11. **Logs**: Treat logs as event streams\n", + "12. **Admin processes**: Run admin/management tasks as one-off processes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Exercise" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the name order in the Etherpad, take your corresponding \"factor\" and add a section to Etherpad to explain why Flask+Docker+SQLAlchemy (or any one of them) can help to achieving it. Focus on why this is different from a big monolithic Python/Java/.NET application. Does the testing approach used by tox help any of these?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Extension Exercise" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Looking at https://github.com/docker-library/docs/blob/master/postgres/README.md#-via-docker-stack-deploy-or-docker-compose can you work out how to add a `db:` section to the existing `docker-compose.yml` ?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you did, can you configure `magnumopus` to use that instead?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How about an nginx proxy, so that you can port-forward to your `web` container from port 8080?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "----" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Further reading..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Patterns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "http://io.made.com/blog/2017-09-07-introducing-command-handler.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://www.infoworld.com/article/3117713/design-patterns-that-i-often-avoid-repository-pattern.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://github.com/faif/python-patterns" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://medium.com/@ssola/building-microservices-with-python-part-i-5240a8dcc2fb" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Persistence" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://softwareengineering.stackexchange.com/questions/374047/sqlalchemy-and-ddd-its-own-pattern" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://www.sqlalchemy.org/features.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "http://dev.nando.audio/2014/04/01/large_apps_with_sqlalchemy__architecture.html" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://proofit404.github.io/mappers/usage/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://stackoverflow.com/questions/2276523/how-do-i-effectively-use-sqlalchemy-with-multiple-ddd-repositories" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Web" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://bobwaycott.com/blog/how-i-use-flask/flask-app-organization/#a-sample-app-layout" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://flask.palletsprojects.com/en/1.1.x/patterns/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://pypi.org/project/Flask-Injector/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://testdriven.io/blog/dockerizing-django-with-postgres-gunicorn-and-nginx/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "https://github.com/pytest-dev/pytest-flask" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "PythonCourse", + "language": "python", + "name": "pythoncourse" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 923905db1de2e651ed6479c24b9cad3187d03daf Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Wed, 17 Jun 2020 11:26:00 +0100 Subject: [PATCH 06/12] basic sqlalchemy and containers attached for magnumopus --- 021-conical/magnum_opus/Dockerfile | 23 --------- 021-conical/magnum_opus/docker-compose.yml | 6 --- 021-conical/magnum_opus/gunicorn_config.py | 5 -- 021-conical/magnum_opus/magnumopus/index.py | 3 -- 021-conical/magnum_opus/magnumopus/logger.py | 5 -- .../magnum_opus/magnumopus/models/__init__.py | 5 -- .../magnum_opus/magnumopus/models/base.py | 3 -- .../magnumopus/models/substance.py | 23 --------- .../magnumopus/repositories/__init__.py | 0 .../magnumopus/repositories/pantry.py | 14 ----- .../magnumopus/resources/__init__.py | 8 --- .../resources/alembic_instruction.py | 49 ------------------ .../magnumopus/resources/substance.py | 37 -------------- .../magnumopus/schemas/__init__.py | 6 --- .../magnumopus/schemas/substance_schema.py | 13 ----- .../magnumopus/services/__init__.py | 0 .../magnumopus/services/alembic.py | 51 ------------------- .../services/alembic_instruction_handler.py | 31 ----------- .../magnumopus/services/assessor.py | 2 - 19 files changed, 284 deletions(-) delete mode 100644 021-conical/magnum_opus/Dockerfile delete mode 100644 021-conical/magnum_opus/docker-compose.yml delete mode 100644 021-conical/magnum_opus/gunicorn_config.py delete mode 100644 021-conical/magnum_opus/magnumopus/index.py delete mode 100644 021-conical/magnum_opus/magnumopus/logger.py delete mode 100644 021-conical/magnum_opus/magnumopus/models/__init__.py delete mode 100644 021-conical/magnum_opus/magnumopus/models/base.py delete mode 100644 021-conical/magnum_opus/magnumopus/models/substance.py delete mode 100644 021-conical/magnum_opus/magnumopus/repositories/__init__.py delete mode 100644 021-conical/magnum_opus/magnumopus/repositories/pantry.py delete mode 100644 021-conical/magnum_opus/magnumopus/resources/__init__.py delete mode 100644 021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py delete mode 100644 021-conical/magnum_opus/magnumopus/resources/substance.py delete mode 100644 021-conical/magnum_opus/magnumopus/schemas/__init__.py delete mode 100644 021-conical/magnum_opus/magnumopus/schemas/substance_schema.py delete mode 100644 021-conical/magnum_opus/magnumopus/services/__init__.py delete mode 100644 021-conical/magnum_opus/magnumopus/services/alembic.py delete mode 100644 021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py delete mode 100644 021-conical/magnum_opus/magnumopus/services/assessor.py diff --git a/021-conical/magnum_opus/Dockerfile b/021-conical/magnum_opus/Dockerfile deleted file mode 100644 index e8b07e3..0000000 --- a/021-conical/magnum_opus/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM python:3-alpine - -RUN addgroup -S user && adduser user -S -G user - -WORKDIR /home/user/ - -COPY requirements.txt . -COPY gunicorn_config.py . -COPY setup.py . -COPY setup.cfg . - -RUN pip install gunicorn -RUN pip install -r requirements.txt - -USER user - -EXPOSE 5000 - -ENTRYPOINT [] - -CMD gunicorn --config ./gunicorn_config.py magnumopus.index:app - -COPY magnumopus magnumopus diff --git a/021-conical/magnum_opus/docker-compose.yml b/021-conical/magnum_opus/docker-compose.yml deleted file mode 100644 index a234fe9..0000000 --- a/021-conical/magnum_opus/docker-compose.yml +++ /dev/null @@ -1,6 +0,0 @@ -version: "3" -services: - web: - build: . - ports: - - 5000:5000 diff --git a/021-conical/magnum_opus/gunicorn_config.py b/021-conical/magnum_opus/gunicorn_config.py deleted file mode 100644 index 29db9d9..0000000 --- a/021-conical/magnum_opus/gunicorn_config.py +++ /dev/null @@ -1,5 +0,0 @@ -port = '5000' -bind = "0.0.0.0:%s" % port -workers = 1 -timeout = 600 -reload = False diff --git a/021-conical/magnum_opus/magnumopus/index.py b/021-conical/magnum_opus/magnumopus/index.py deleted file mode 100644 index 183c186..0000000 --- a/021-conical/magnum_opus/magnumopus/index.py +++ /dev/null @@ -1,3 +0,0 @@ -from . import create_app - -app = create_app() diff --git a/021-conical/magnum_opus/magnumopus/logger.py b/021-conical/magnum_opus/magnumopus/logger.py deleted file mode 100644 index 9b7f97a..0000000 --- a/021-conical/magnum_opus/magnumopus/logger.py +++ /dev/null @@ -1,5 +0,0 @@ -import logging - -def init_app(app): - app.logger.addHandler(logging.StreamHandler()) - app.logger.setLevel(logging.INFO) diff --git a/021-conical/magnum_opus/magnumopus/models/__init__.py b/021-conical/magnum_opus/magnumopus/models/__init__.py deleted file mode 100644 index 2e94a1e..0000000 --- a/021-conical/magnum_opus/magnumopus/models/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .base import db - -def init_app(app): - app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' - db.init_app(app) diff --git a/021-conical/magnum_opus/magnumopus/models/base.py b/021-conical/magnum_opus/magnumopus/models/base.py deleted file mode 100644 index f0b13d6..0000000 --- a/021-conical/magnum_opus/magnumopus/models/base.py +++ /dev/null @@ -1,3 +0,0 @@ -from flask_sqlalchemy import SQLAlchemy - -db = SQLAlchemy() diff --git a/021-conical/magnum_opus/magnumopus/models/substance.py b/021-conical/magnum_opus/magnumopus/models/substance.py deleted file mode 100644 index 828b4c5..0000000 --- a/021-conical/magnum_opus/magnumopus/models/substance.py +++ /dev/null @@ -1,23 +0,0 @@ -class SubstanceMustBeFreshToProcessException(Exception): - pass - -class Substance: - def __init__(self, nature='Unknown'): - self.nature = nature - self.state = [] - - def _process(self, process_name): - self.state.append(process_name) - return self - - def cook(self): - return self._process('cooked') - - def pickle(self): - return self._process('pickled') - - def ferment(self): - return self._process('fermented') - - def wash(self): - return self._process('washed') diff --git a/021-conical/magnum_opus/magnumopus/repositories/__init__.py b/021-conical/magnum_opus/magnumopus/repositories/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/021-conical/magnum_opus/magnumopus/repositories/pantry.py b/021-conical/magnum_opus/magnumopus/repositories/pantry.py deleted file mode 100644 index 90ac0d9..0000000 --- a/021-conical/magnum_opus/magnumopus/repositories/pantry.py +++ /dev/null @@ -1,14 +0,0 @@ -class Pantry: - _cupboard = [] - - def __init__(self): - pass - - def add_substance(self, substance): - self._cupboard.append(substance) - - def find_substances_by_nature(self, nature): - return [substance for substance in self._cupboard if substance.nature == nature] - - def count_all_substances(self): - return len(self._cupboard) diff --git a/021-conical/magnum_opus/magnumopus/resources/__init__.py b/021-conical/magnum_opus/magnumopus/resources/__init__.py deleted file mode 100644 index 85683b9..0000000 --- a/021-conical/magnum_opus/magnumopus/resources/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from flask_restful import Api -from . import substance -from . import alembic_instruction - -def init_app(app): - api = Api(app) - substance.init_app(app, api) - alembic_instruction.init_app(app, api) diff --git a/021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py b/021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py deleted file mode 100644 index 1843acf..0000000 --- a/021-conical/magnum_opus/magnumopus/resources/alembic_instruction.py +++ /dev/null @@ -1,49 +0,0 @@ -from flask_restful import Resource, reqparse -from ..repositories.pantry import Pantry -from ..models.substance import Substance -from ..schemas.substance_schema import SubstanceSchema -from ..services.alembic_instruction_handler import AlembicInstructionHandler, AlembicInstruction - -parser = reqparse.RequestParser() -parser.add_argument('instruction_type') -parser.add_argument('action') -parser.add_argument('natures') - -substance_schema = SubstanceSchema() - -class AlembicInstructionResource(Resource): - def get(self): - """This should return past requests/commands.""" - pass - - def post(self): - """ - Add an instruction for the alembic. - - Note that POST is _not_ assumed to be idempotent, unlike PUT - """ - - args = parser.parse_args() - instruction_type = args['instruction_type'] - - pantry = Pantry() - - instruction_handler = AlembicInstructionHandler() - - # This could do with deserialization... - instruction = AlembicInstruction( - instruction_type=args.instruction_type, - natures=args.natures.split(','), - action=args.action - ) - - # Crude start at DI... see flask-injector - result = instruction_handler.handle(instruction, pantry) - - pantry.add_substance(result) - - return substance_schema.dump(result) - - -def init_app(app, api): - api.add_resource(AlembicInstructionResource, '/alembic_instruction') diff --git a/021-conical/magnum_opus/magnumopus/resources/substance.py b/021-conical/magnum_opus/magnumopus/resources/substance.py deleted file mode 100644 index 770dcac..0000000 --- a/021-conical/magnum_opus/magnumopus/resources/substance.py +++ /dev/null @@ -1,37 +0,0 @@ -from flask_restful import Resource, reqparse -from ..repositories.pantry import Pantry -from ..models.substance import Substance -from ..schemas.substance_schema import SubstanceSchema - -parser = reqparse.RequestParser() -parser.add_argument('nature') - -substance_schema = SubstanceSchema() -substances_schema = SubstanceSchema(many=True) - - -class SubstanceResource(Resource): - def get(self): - args = parser.parse_args() - nature = args['nature'] - pantry = Pantry() - - substances = pantry.find_substances_by_nature(nature) - - return substances_schema.dump(substances) - - def post(self): - args = parser.parse_args() - nature = args['nature'] - - pantry = Pantry() - - substance = Substance(nature=nature) - - pantry.add_substance(substance) - - return substance_schema.dump(substance) - - -def init_app(app, api): - api.add_resource(SubstanceResource, '/substance') diff --git a/021-conical/magnum_opus/magnumopus/schemas/__init__.py b/021-conical/magnum_opus/magnumopus/schemas/__init__.py deleted file mode 100644 index 34395e3..0000000 --- a/021-conical/magnum_opus/magnumopus/schemas/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from flask_marshmallow import Marshmallow - -ma = Marshmallow() - -def init_app(app): - ma.init_app(app) diff --git a/021-conical/magnum_opus/magnumopus/schemas/substance_schema.py b/021-conical/magnum_opus/magnumopus/schemas/substance_schema.py deleted file mode 100644 index 430e96c..0000000 --- a/021-conical/magnum_opus/magnumopus/schemas/substance_schema.py +++ /dev/null @@ -1,13 +0,0 @@ -from marshmallow import fields - -from . import ma - -from ..services.assessor import assess_whether_substance_is_philosophers_stone - -class SubstanceSchema(ma.Schema): - is_philosophers_stone = fields.Function( - assess_whether_substance_is_philosophers_stone - ) - - class Meta: - fields = ("nature", "is_philosophers_stone") diff --git a/021-conical/magnum_opus/magnumopus/services/__init__.py b/021-conical/magnum_opus/magnumopus/services/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/021-conical/magnum_opus/magnumopus/services/alembic.py b/021-conical/magnum_opus/magnumopus/services/alembic.py deleted file mode 100644 index 5fc05b2..0000000 --- a/021-conical/magnum_opus/magnumopus/services/alembic.py +++ /dev/null @@ -1,51 +0,0 @@ -from ..models.substance import Substance - -class NotEnoughSubstancesToMixException(Exception): - pass - -class UnknownProcessException(Exception): - pass - - -MIXTURES = { - ('Mercury', 'Salt', 'Sulphur'): 'Gloop' -} - - -class Alembic: - _nature_of_unknown_mixture = 'Sludge' - - @staticmethod - def _produce(nature): - return Substance(nature=nature) - - def mix(self, *substances): - if len(substances) < 2: - raise NotEnoughSubstancesToMixException() - - constituents = [substance.nature for substance in substances] - - # This gives us a canonical, ordered way of expressing our - # constituents that we can use as a recipe look-up - ingredient_list = tuple(sorted(constituents)) - - try: - nature = MIXTURES[ingredient_list] - except KeyError: - nature = self._nature_of_unknown_mixture - - return self._produce(nature) - - def process(self, process_name, substance): - if process_name == 'ferment': - result = substance.ferment() - elif process_name == 'cook': - result = substance.cook() - elif process_name == 'wash': - result = substance.wash() - elif process_name == 'pickle': - result = substance.pickle() - else: - raise UnknownProcessException() - - return result diff --git a/021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py b/021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py deleted file mode 100644 index 556bbe2..0000000 --- a/021-conical/magnum_opus/magnumopus/services/alembic_instruction_handler.py +++ /dev/null @@ -1,31 +0,0 @@ -from dataclasses import dataclass - -from .alembic import Alembic -from ..repositories.pantry import Pantry - -@dataclass -class AlembicInstruction: - instruction_type: str - natures: list - action: str = '' - -class AlembicInstructionHandler: - def handle(self, instruction: AlembicInstruction, pantry: Pantry): - natures = instruction.natures - action = instruction.action - instruction_type = instruction.instruction_type - - # Clearly need some validation here! - substances = [pantry.find_substances_by_nature(nature)[0] for nature in natures] - - alembic = Alembic() - - if instruction_type == 'mix': - result = alembic.mix(*substances) - elif instruction_type == 'process': - result = alembic.process(action, substances[0]) - else: - pass - # a sensible error - - return result diff --git a/021-conical/magnum_opus/magnumopus/services/assessor.py b/021-conical/magnum_opus/magnumopus/services/assessor.py deleted file mode 100644 index 94d564d..0000000 --- a/021-conical/magnum_opus/magnumopus/services/assessor.py +++ /dev/null @@ -1,2 +0,0 @@ -def assess_whether_substance_is_philosophers_stone(substance): - return substance.nature == 'Gloop' and substance.state == ['cooked', 'washed', 'pickled', 'fermented'] From cb0b410f29d48d013dc69665b3ba6bfb0e344598 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Sat, 27 Jun 2020 18:30:11 +0100 Subject: [PATCH 07/12] add dependency injection to improve separation of concerns and modularity --- 022-burette/magnum_opus/.coverage | Bin 0 -> 53248 bytes 022-burette/magnum_opus/.gitignore | 4 + 022-burette/magnum_opus/Dockerfile | 24 ++++++ 022-burette/magnum_opus/MANIFEST.in | 1 + 022-burette/magnum_opus/README.md | 46 ++++++++++ 022-burette/magnum_opus/RULES.md | 9 ++ 022-burette/magnum_opus/docker-compose.yml | 11 +++ .../magnum_opus/docker/storage/storage.db | Bin 0 -> 8192 bytes 022-burette/magnum_opus/gunicorn_config.py | 5 ++ 022-burette/magnum_opus/init_containers.sh | 6 ++ 022-burette/magnum_opus/init_entrypoint.sh | 3 + .../magnum_opus/magnumopus/__init__.py | 22 +++++ 022-burette/magnum_opus/magnumopus/config.py | 7 ++ 022-burette/magnum_opus/magnumopus/index.py | 3 + .../magnum_opus/magnumopus/initialize.py | 9 ++ .../magnum_opus/magnumopus/injection.py | 11 +++ 022-burette/magnum_opus/magnumopus/logger.py | 6 ++ .../magnum_opus/magnumopus/models/__init__.py | 11 +++ .../magnum_opus/magnumopus/models/base.py | 3 + .../magnumopus/models/substance.py | 34 ++++++++ .../magnumopus/repositories/__init__.py | 18 ++++ .../magnumopus/repositories/list_pantry.py | 15 ++++ .../magnumopus/repositories/pantry.py | 21 +++++ .../repositories/sqlalchemy_pantry.py | 28 ++++++ .../magnumopus/resources/__init__.py | 9 ++ .../resources/alembic_instruction.py | 58 +++++++++++++ .../magnumopus/resources/substance.py | 62 ++++++++++++++ .../magnumopus/schemas/__init__.py | 22 +++++ .../magnumopus/schemas/substance_schema.py | 18 ++++ .../magnumopus/services/__init__.py | 9 ++ .../magnumopus/services/alembic.py | 51 +++++++++++ .../services/alembic_instruction_handler.py | 35 ++++++++ .../magnumopus/services/assessor.py | 2 + 022-burette/magnum_opus/requirements.txt | 8 ++ 022-burette/magnum_opus/setup.cfg | 34 ++++++++ 022-burette/magnum_opus/setup.py | 14 +++ 022-burette/magnum_opus/tests/__init__.py | 0 .../magnum_opus/tests/application/test_app.py | 7 ++ 022-burette/magnum_opus/tests/conftest.py | 15 ++++ .../magnum_opus/tests/domain/__init__.py | 0 .../magnum_opus/tests/domain/test_alembic.py | 81 ++++++++++++++++++ .../test_alembic_instruction_handler.py | 37 ++++++++ .../magnum_opus/tests/domain/test_pantry.py | 43 ++++++++++ .../tests/domain/test_substance.py | 49 +++++++++++ 022-burette/magnum_opus/tox.ini | 6 ++ 45 files changed, 857 insertions(+) create mode 100644 022-burette/magnum_opus/.coverage create mode 100644 022-burette/magnum_opus/.gitignore create mode 100644 022-burette/magnum_opus/Dockerfile create mode 100644 022-burette/magnum_opus/MANIFEST.in create mode 100644 022-burette/magnum_opus/README.md create mode 100644 022-burette/magnum_opus/RULES.md create mode 100644 022-burette/magnum_opus/docker-compose.yml create mode 100644 022-burette/magnum_opus/docker/storage/storage.db create mode 100644 022-burette/magnum_opus/gunicorn_config.py create mode 100755 022-burette/magnum_opus/init_containers.sh create mode 100755 022-burette/magnum_opus/init_entrypoint.sh create mode 100644 022-burette/magnum_opus/magnumopus/__init__.py create mode 100644 022-burette/magnum_opus/magnumopus/config.py create mode 100644 022-burette/magnum_opus/magnumopus/index.py create mode 100644 022-burette/magnum_opus/magnumopus/initialize.py create mode 100644 022-burette/magnum_opus/magnumopus/injection.py create mode 100644 022-burette/magnum_opus/magnumopus/logger.py create mode 100644 022-burette/magnum_opus/magnumopus/models/__init__.py create mode 100644 022-burette/magnum_opus/magnumopus/models/base.py create mode 100644 022-burette/magnum_opus/magnumopus/models/substance.py create mode 100644 022-burette/magnum_opus/magnumopus/repositories/__init__.py create mode 100644 022-burette/magnum_opus/magnumopus/repositories/list_pantry.py create mode 100644 022-burette/magnum_opus/magnumopus/repositories/pantry.py create mode 100644 022-burette/magnum_opus/magnumopus/repositories/sqlalchemy_pantry.py create mode 100644 022-burette/magnum_opus/magnumopus/resources/__init__.py create mode 100644 022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py create mode 100644 022-burette/magnum_opus/magnumopus/resources/substance.py create mode 100644 022-burette/magnum_opus/magnumopus/schemas/__init__.py create mode 100644 022-burette/magnum_opus/magnumopus/schemas/substance_schema.py create mode 100644 022-burette/magnum_opus/magnumopus/services/__init__.py create mode 100644 022-burette/magnum_opus/magnumopus/services/alembic.py create mode 100644 022-burette/magnum_opus/magnumopus/services/alembic_instruction_handler.py create mode 100644 022-burette/magnum_opus/magnumopus/services/assessor.py create mode 100644 022-burette/magnum_opus/requirements.txt create mode 100644 022-burette/magnum_opus/setup.cfg create mode 100644 022-burette/magnum_opus/setup.py create mode 100644 022-burette/magnum_opus/tests/__init__.py create mode 100644 022-burette/magnum_opus/tests/application/test_app.py create mode 100644 022-burette/magnum_opus/tests/conftest.py create mode 100644 022-burette/magnum_opus/tests/domain/__init__.py create mode 100644 022-burette/magnum_opus/tests/domain/test_alembic.py create mode 100644 022-burette/magnum_opus/tests/domain/test_alembic_instruction_handler.py create mode 100644 022-burette/magnum_opus/tests/domain/test_pantry.py create mode 100644 022-burette/magnum_opus/tests/domain/test_substance.py create mode 100644 022-burette/magnum_opus/tox.ini diff --git a/022-burette/magnum_opus/.coverage b/022-burette/magnum_opus/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..acffb036006a2fd0428756bfafc1028b3539f7f7 GIT binary patch literal 53248 zcmeI4TWlOx8GvVYW@mQxcGg~Bl%~NWB;;7Jy|Kfk4M-sbKeP#I8`1`mhRy8y*q(TI z#+jL2+f4%+w^AOs2(<`Q-~l9{4@k5RG(r&)541?|fFJ<`Z9^qMln01Zgt({(@&9x2 zjuShI1miZzKiWO#%*;9GKmYgt=ggeBee|ItrpNU;+i4q~zE7wKq9}Y&*9Ae);9r7& zyr__n;}wX-M0%^FCQKgqO^H1s6qPRu>=UJrv5De0OSQtw#jf^r;aT;x)`A_h5CI}U z1c(3;2nhHO71iM#JH)kfp3!J=&oP?Z3B%H%qcaDO&FIGte(1=I9&Xcj=XF>nCiH{4 zV=wDV+|lRE7S~N{)@&M{Y0c~20*`ZdTt16OJlF=uJj^&5l*d%voP|;zpNA@z9J6gW ztNJ2e9S<@@(mcN6g&Uv}Zq8enL*E@0AJZK^#~p4pxf`}(w>dkOAA90cd3Cs270>fP zC&OvNudqQI*w9nuzB#C&Ci}Ro1g3WpCOxo7l3a?*?F{;qkL$gX z&>JngvC-E8k8wG45Eu*MY;zr}iCx7-9h!ERJH|YpjP{1Z!dvY~;5t*9 zGCVV~mFuj#Kz(XGnfG@n>hR8;;+ht?QDm(sQa89zY{^ZA(Rf#z8*aym2a+2Nl5vUN zC>i&WXb-3}p(?`%cW$Lll&?M&C33zhtHXnXq967M9GCE)-Jk?+>2-l?4g@#f{3XL% z(64VhZia@BW|iUh4{p_PY(jksL*5h%#M05Pki@=s>RycNOcH?~VpdiH|8bx*vnS7I!O1wA+R? z8y%+b=o{7wLq7INloO5}P*5L*zUV^Fyr#~$(r7OZRB`>2OMn7vZ5y*;FGpJ>YFu96 z*HsrDgg$I|+%wx;$1Fi(0)JXIT)pXV*a?Twu~F$p)<+}Nr!d4>at=>q{1H(d-m^#a zJ5e7DhnKnw$MUujH#=I*Z19b1cJ|!l0T^fDBq!+}$S#2cS3?OnriB)4gcRaj(J4-T z3@7*^dsBcPEku9_5CI}U1c(3;AOb{y2oM1xKm>@u?MFZoGop&~f0^wN*im+fjY5JJ zB0vO)01+SpM1Tko0U|&IhyW2F0(TODqAcxV@uLxY?~Yn}6)9@>0q@C61#`=3Er~Eylyld@n{6xfw(b|ID=C!2-v*j&w)2SV|oyFQQ$1p8; zvaj~ws<&WUhwP5yLZ)D4q8YC3ot~a(z(Y5l$7^k49-c|6+e;m{Hp#7Stz|Z%?E5C~ zslnrZd}7IHF2ci0E^grCnlt-9pYugCbtGkP6aHF}g;P zDM-7t`0@na{~yY}BCw~~Ncp+)y`>jR4-{W29xhxiJd(eZKcW3zvvP0b&Z_@ZKdX)? z-&O91%(M^zB0vO)z}uNXdq@`i`v3jvbMNYL4X$8&rqMDV<8X<2VGzVUoUS-{ZyF?- z10d;mnv&qf(>ZeSUUtOzSicUO-00`qNgdWzWNx4M3DH^vS|nHcibO?!tWx z_zFVJXmNNayID6a*K<0twq6CaZKv4+mpffEXn^Z-*R@gcvkau3O;u{}a;IB!I}O)^ z&o=Pr{Z0_>mO=R9b_lNnY|{(w{d7wp^h}yUdzN0;8I=euH2G?M$*??U6`d@fwv#zL(S(-idOhJ?Eq!|@gs&^Tk^{M&ZR4Ia zxvGN6t7(ev4JFr)W%UJkr@a*ntF8hJQtjYvdzQBngA0x-*|ddTt33$yWDvSNqj$p6 zmIP9bGz}f`Z5S?|)HoTCXKsVMgpP|M$UKpz%!Dw!|38#{RbXFGUQiBaUsZMWb4)Kk zUwW{3q;S0Oi~QyMqw2r3KWKLDujT!vmx@2iJ^pq+>7}+20U|&Ih=3qivR@a|JdSLb z{|}k6|8UCU!ukK;Y1u!Xs-*S#|3F*zPo^p=IsdPwuGsqgzuy<-wQQ=I^=5^e&;R>6 zvfoa%1-;YO-u%Dvxa^-zSL)XDf9A>l;dCt$tYt>Xm_lA-i&i~ca zJNPE^e01+SpM1Tko0U|&I zhyW2F0z`la+=c`ssifik{{i-Hf&GJBWq)M9Wj|vtvhT6)uy3%hu+OveY=v2DmOaWo z!e-b9AR{eAfCvx)B0vO)01+SpM1Tko0U|&I?hpdXfGld|fs1Mt;!5>mPU*)D{g0LU zAilfrlj=K>grZb%b0w2w5cjjwuPeDSrpmu+zoS&btfl`5cUOdra7r!0YNdEp(h86m zC|ppN3u+#><*gGr4HEs@m!H{@%V8>awI$_MNDZkM&K>w=F0Wu(xp1ZPic-u%`mXHD zpSd#gTpf16T3NndkuZir8Hg*HuBwW%ruBdP(s8{1Kft;IdlSC@{};Fd@EZFy`#Jjw z`yu;2djYNkJj=euo?%b1PqQc4Imk#05g-CYfCvx)B0vO)01+SpM1Tko0U~gd1aQJG z4h#fQwHieI{Xx{%7etjx5HS`+<#G^}N>Y5g-CYfCvzQTap0Y|EKx? zEonMxG!Y;IM1Tko0U|&IhyW2F0z`la5P_Q}fbahgv8V9)|G%?0*q_g!( zq#^h$zch%!00vbI`Z4Ikpn?Izpo~EYgCYh64DuLg800WeF;FnbVjyE6VUWQ9zyJSV D&<%nw literal 0 HcmV?d00001 diff --git a/022-burette/magnum_opus/.gitignore b/022-burette/magnum_opus/.gitignore new file mode 100644 index 0000000..8a3f0fc --- /dev/null +++ b/022-burette/magnum_opus/.gitignore @@ -0,0 +1,4 @@ +*.egg-info +.tox +Pipfile +.env diff --git a/022-burette/magnum_opus/Dockerfile b/022-burette/magnum_opus/Dockerfile new file mode 100644 index 0000000..03a8d6e --- /dev/null +++ b/022-burette/magnum_opus/Dockerfile @@ -0,0 +1,24 @@ +FROM python:3-alpine + +RUN addgroup -S user && adduser user -S -G user + +WORKDIR /home/user/ + +COPY requirements.txt . +COPY gunicorn_config.py . +COPY setup.py . +COPY setup.cfg . +COPY init_entrypoint.sh / + +RUN pip install gunicorn +RUN pip install -r requirements.txt + +USER user + +EXPOSE 5000 + +ENTRYPOINT [] + +CMD gunicorn --config ./gunicorn_config.py magnumopus.index:app + +COPY magnumopus magnumopus diff --git a/022-burette/magnum_opus/MANIFEST.in b/022-burette/magnum_opus/MANIFEST.in new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/022-burette/magnum_opus/MANIFEST.in @@ -0,0 +1 @@ + diff --git a/022-burette/magnum_opus/README.md b/022-burette/magnum_opus/README.md new file mode 100644 index 0000000..94ce180 --- /dev/null +++ b/022-burette/magnum_opus/README.md @@ -0,0 +1,46 @@ +Magnum Opus +=========== + +Recipe maker for the philosopher's stone. + + + python3 -m pytest --cov magnumopus >> README.md + + ============================= test session starts ============================== + platform linux -- Python 3.8.2, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 + rootdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus + plugins: pep8-1.0.6, cov-2.10.0 + collected 15 items + + tests/domain/test_alembic.py ....... [ 46%] + tests/domain/test_pantry.py .. [ 60%] + tests/domain/test_substance.py ...... [100%] + + ----------- coverage: platform linux, python 3.8.2-final-0 ----------- + Name Stmts Miss Cover + ------------------------------------------------------------------------ + magnumopus/__init__.py 10 8 20% + magnumopus/config.py 4 4 0% + magnumopus/index.py 2 2 0% + magnumopus/initialize.py 6 6 0% + magnumopus/logger.py 4 4 0% + magnumopus/models/__init__.py 3 1 67% + magnumopus/models/base.py 2 0 100% + magnumopus/models/substance.py 24 0 100% + magnumopus/repositories/__init__.py 0 0 100% + magnumopus/repositories/pantry.py 12 1 92% + magnumopus/repositories/sqlalchemy_pantry.py 15 15 0% + magnumopus/resources/__init__.py 7 7 0% + magnumopus/resources/alembic_instruction.py 26 26 0% + magnumopus/resources/substance.py 28 28 0% + magnumopus/schemas/__init__.py 4 4 0% + magnumopus/schemas/substance_schema.py 11 11 0% + magnumopus/services/__init__.py 0 0 100% + magnumopus/services/alembic.py 32 2 94% + magnumopus/services/alembic_instruction_handler.py 20 20 0% + magnumopus/services/assessor.py 2 2 0% + ------------------------------------------------------------------------ + TOTAL 212 141 33% + + + ============================== 15 passed in 0.38s ============================== diff --git a/022-burette/magnum_opus/RULES.md b/022-burette/magnum_opus/RULES.md new file mode 100644 index 0000000..4438311 --- /dev/null +++ b/022-burette/magnum_opus/RULES.md @@ -0,0 +1,9 @@ +* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my "Alembic" (mixing pot), giving one unit of another substance, Gloop +* Any attempt to mix anything other than those three substances, gives Sludge, another substance +* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented +* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills) +[* To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)] + +Final rule: +GROUP 1: When I process a substance, using any process, it becomes a different substance +GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process) diff --git a/022-burette/magnum_opus/docker-compose.yml b/022-burette/magnum_opus/docker-compose.yml new file mode 100644 index 0000000..9e5f302 --- /dev/null +++ b/022-burette/magnum_opus/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3" +services: + web: + build: . + environment: + DATABASE_URI: 'sqlite:////docker/storage/storage.db' + volumes: + - ./docker:/docker + - ./magnumopus:/home/user/magnumopus + ports: + - 5000:5000 diff --git a/022-burette/magnum_opus/docker/storage/storage.db b/022-burette/magnum_opus/docker/storage/storage.db new file mode 100644 index 0000000000000000000000000000000000000000..59ffca1581efa0de8441c324bba89044ca4e200d GIT binary patch literal 8192 zcmeI#y-ve06a`>Ajf9da3L8Q!w_74120F43Dhn#o0FFU)U`QJSkwQWF85sMTJODf5 z1+a&zBQxS0*|P7I<>A|Iev?+6rpMRjrRZqPb{XgFl!!6rn(dgq2{#wp+r-wt#brk) zUx9hW!;YDSKmY;|fB*y_009U<00Izz00jPxz}n+Gd!rFwKXk>S)@{FNyJEG}?e^wO zq)3z?m7Jx5wtb3xuPSMpDRC|&Wmk%_+cZ5S-&+-3-)Oo^OI{DI5% dgS_s`Cp~mrb`a!!{r229LvD+iZkB!X{sXgdJx%}s literal 0 HcmV?d00001 diff --git a/022-burette/magnum_opus/gunicorn_config.py b/022-burette/magnum_opus/gunicorn_config.py new file mode 100644 index 0000000..29db9d9 --- /dev/null +++ b/022-burette/magnum_opus/gunicorn_config.py @@ -0,0 +1,5 @@ +port = '5000' +bind = "0.0.0.0:%s" % port +workers = 1 +timeout = 600 +reload = False diff --git a/022-burette/magnum_opus/init_containers.sh b/022-burette/magnum_opus/init_containers.sh new file mode 100755 index 0000000..0a64c94 --- /dev/null +++ b/022-burette/magnum_opus/init_containers.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +mkdir -p docker/storage + +docker-compose run --user root web /init_entrypoint.sh +docker-compose run web python3 -m magnumopus.initialize diff --git a/022-burette/magnum_opus/init_entrypoint.sh b/022-burette/magnum_opus/init_entrypoint.sh new file mode 100755 index 0000000..8366386 --- /dev/null +++ b/022-burette/magnum_opus/init_entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +chown -R user:user /docker/storage diff --git a/022-burette/magnum_opus/magnumopus/__init__.py b/022-burette/magnum_opus/magnumopus/__init__.py new file mode 100644 index 0000000..e410774 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/__init__.py @@ -0,0 +1,22 @@ +from flask import Flask + +def create_app(): + from . import models, resources, schemas, logger, repositories, injection + + app = Flask(__name__) + + # This could be used to separate by environment + app.config.from_object('magnumopus.config.Config') + + # This helps avoid cyclic dependencies + modules = [] + + modules += logger.init_app(app) + modules += models.init_app(app) + modules += resources.init_app(app) + modules += repositories.init_app(app) + modules += schemas.init_app(app) + + injection.init_app(app, modules) + + return app diff --git a/022-burette/magnum_opus/magnumopus/config.py b/022-burette/magnum_opus/magnumopus/config.py new file mode 100644 index 0000000..637a5ef --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/config.py @@ -0,0 +1,7 @@ +import os + +class Config: + SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URI', 'sqlite:///:memory:') + SQLALCHEMY_TRACK_MODIFICATIONS = False + + PANTRY_STORE = os.environ.get('MAGNUMOPUS_PANTRY_STORE', 'sqlalchemy') diff --git a/022-burette/magnum_opus/magnumopus/index.py b/022-burette/magnum_opus/magnumopus/index.py new file mode 100644 index 0000000..183c186 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/index.py @@ -0,0 +1,3 @@ +from . import create_app + +app = create_app() diff --git a/022-burette/magnum_opus/magnumopus/initialize.py b/022-burette/magnum_opus/magnumopus/initialize.py new file mode 100644 index 0000000..b251d32 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/initialize.py @@ -0,0 +1,9 @@ +from . import create_app +from .models import db + +if __name__ == "__main__": + # There are nicer ways around this, but this keeps it clear for an example + app = create_app() + + with app.app_context(): + db.create_all() diff --git a/022-burette/magnum_opus/magnumopus/injection.py b/022-burette/magnum_opus/magnumopus/injection.py new file mode 100644 index 0000000..8d74458 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/injection.py @@ -0,0 +1,11 @@ +from flask_injector import FlaskInjector + +def init_app(app, modules): + modules.append(configure_injector) + FlaskInjector(app=app, modules=modules) + +def configure_injector(binder): + """ + Add any general purpose injectables, not included in a submodule + """ + pass diff --git a/022-burette/magnum_opus/magnumopus/logger.py b/022-burette/magnum_opus/magnumopus/logger.py new file mode 100644 index 0000000..b5c4b4f --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/logger.py @@ -0,0 +1,6 @@ +import logging + +def init_app(app): + app.logger.addHandler(logging.StreamHandler()) + app.logger.setLevel(logging.INFO) + return [] diff --git a/022-burette/magnum_opus/magnumopus/models/__init__.py b/022-burette/magnum_opus/magnumopus/models/__init__.py new file mode 100644 index 0000000..63b0a0e --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/models/__init__.py @@ -0,0 +1,11 @@ +from .base import db +from flask_sqlalchemy import SQLAlchemy + +def init_app(app): + db.init_app(app) + return [configure_injector] + +def configure_injector(binding): + binding.bind( + SQLAlchemy, to=db + ) diff --git a/022-burette/magnum_opus/magnumopus/models/base.py b/022-burette/magnum_opus/magnumopus/models/base.py new file mode 100644 index 0000000..f0b13d6 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/models/base.py @@ -0,0 +1,3 @@ +from flask_sqlalchemy import SQLAlchemy + +db = SQLAlchemy() diff --git a/022-burette/magnum_opus/magnumopus/models/substance.py b/022-burette/magnum_opus/magnumopus/models/substance.py new file mode 100644 index 0000000..58e821e --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/models/substance.py @@ -0,0 +1,34 @@ +from . import db +from sqlalchemy_utils.types.scalar_list import ScalarListType + +class SubstanceMustBeFreshToProcessException(Exception): + pass + +class Substance(db.Model): + __tablename__ = 'substances' + + id = db.Column(db.Integer, primary_key=True) + nature = db.Column(db.String(32), default='Unknown') + state = db.Column(ScalarListType()) + + def __init__(self, nature='Unknown'): + self.state = [] + self.nature = nature + + super(Substance, self).__init__() + + def _process(self, process_name): + self.state.append(process_name) + return self + + def cook(self): + return self._process('cooked') + + def pickle(self): + return self._process('pickled') + + def ferment(self): + return self._process('fermented') + + def wash(self): + return self._process('washed') diff --git a/022-burette/magnum_opus/magnumopus/repositories/__init__.py b/022-burette/magnum_opus/magnumopus/repositories/__init__.py new file mode 100644 index 0000000..6135fe4 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/repositories/__init__.py @@ -0,0 +1,18 @@ +from .pantry import Pantry +from .list_pantry import ListPantry +from .sqlalchemy_pantry import SQLAlchemyPantry + +PANTRY_STORES = { + 'sqlalchemy': SQLAlchemyPantry, + 'list': ListPantry() # we instantiate this, as we want a singleton cupboard +} + +def init_app(app): + return [lambda binder: configure_injector(binder, app)] + +def configure_injector(binder, app): + pantry_cls = PANTRY_STORES[app.config['PANTRY_STORE']] + + binder.bind( + Pantry, to=pantry_cls + ) diff --git a/022-burette/magnum_opus/magnumopus/repositories/list_pantry.py b/022-burette/magnum_opus/magnumopus/repositories/list_pantry.py new file mode 100644 index 0000000..e14711a --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/repositories/list_pantry.py @@ -0,0 +1,15 @@ +class ListPantry: + def __init__(self): + self._cupboard = [] + + def add_substance(self, substance): + self._cupboard.append(substance) + + def find_substances_by_nature(self, nature): + return [substance for substance in self._cupboard if substance.nature == nature] + + def count_all_substances(self): + return len(self._cupboard) + + def commit(self): + pass diff --git a/022-burette/magnum_opus/magnumopus/repositories/pantry.py b/022-burette/magnum_opus/magnumopus/repositories/pantry.py new file mode 100644 index 0000000..a2cb730 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/repositories/pantry.py @@ -0,0 +1,21 @@ +from abc import ABC, abstractmethod + +class Pantry(ABC): + def __init__(self): + pass + + @abstractmethod + def add_substance(self, substance): + pass + + @abstractmethod + def find_substances_by_nature(self, nature): + pass + + @abstractmethod + def count_all_substances(self): + pass + + @abstractmethod + def commit(self): + pass diff --git a/022-burette/magnum_opus/magnumopus/repositories/sqlalchemy_pantry.py b/022-burette/magnum_opus/magnumopus/repositories/sqlalchemy_pantry.py new file mode 100644 index 0000000..996fe76 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/repositories/sqlalchemy_pantry.py @@ -0,0 +1,28 @@ +from flask_sqlalchemy import SQLAlchemy +from injector import inject + +from ..models.substance import Substance +from ..models import db + +class SQLAlchemyPantry: + @inject + def __init__(self, db: SQLAlchemy): + self._db = db + + # A more involved solution would open and close the pantry... like + # a cupboard door, or a Unit of Work + + # Note how we're committing too frequently? + def add_substance(self, substance): + self._db.session.add(substance) + return substance + + def find_substances_by_nature(self, nature): + substances = Substance.query.filter_by(nature=nature).all() + return substances + + def count_all_substances(self): + return Substance.query.count() + + def commit(self): + self._db.session.commit() diff --git a/022-burette/magnum_opus/magnumopus/resources/__init__.py b/022-burette/magnum_opus/magnumopus/resources/__init__.py new file mode 100644 index 0000000..11345e8 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/resources/__init__.py @@ -0,0 +1,9 @@ +from flask_restful import Api +from . import substance +from . import alembic_instruction + +def init_app(app): + api = Api(app) + substance.init_app(app, api) + alembic_instruction.init_app(app, api) + return [] diff --git a/022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py b/022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py new file mode 100644 index 0000000..7afa085 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py @@ -0,0 +1,58 @@ +from flask_restful import Resource, reqparse +from injector import inject +from ..repositories.pantry import Pantry +from ..models.substance import Substance +from ..schemas.substance_schema import SubstanceSchema +from ..services.alembic_instruction_handler import AlembicInstructionHandler, AlembicInstruction + +class AlembicInstructionResource(Resource): + @inject + def __init__(self, pantry: Pantry, substance_schema: SubstanceSchema, parser_fcty=reqparse.RequestParser): + super(AlembicInstructionResource, self).__init__() + + self._pantry = pantry + self._substance_schema = substance_schema + self._parser_fcty = parser_fcty + + def get(self): + """This should return past requests/commands.""" + pass + + def post(self): + """ + Add an instruction for the alembic. + + Note that POST is _not_ assumed to be idempotent, unlike PUT + """ + + parser = self._parser_fcty() + parser.add_argument('instruction_type') + parser.add_argument('action') + parser.add_argument('natures') + + args = parser.parse_args() + instruction_type = args['instruction_type'] + + pantry = self._pantry + + instruction_handler = AlembicInstructionHandler() + + # This could do with deserialization... + instruction = AlembicInstruction( + instruction_type=args.instruction_type, + natures=args.natures.split(','), + action=args.action + ) + + # Crude start at DI... see flask-injector + result = instruction_handler.handle(instruction, pantry) + + pantry.add_substance(result) + + pantry.commit() + + return self._substance_schema.dump(result) + + +def init_app(app, api): + api.add_resource(AlembicInstructionResource, '/alembic_instruction') diff --git a/022-burette/magnum_opus/magnumopus/resources/substance.py b/022-burette/magnum_opus/magnumopus/resources/substance.py new file mode 100644 index 0000000..95840f3 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/resources/substance.py @@ -0,0 +1,62 @@ +from flask_restful import Resource, reqparse +from injector import inject +from typing import Dict +from ..repositories.pantry import Pantry +from ..models import db +from ..models.substance import Substance +from ..schemas.substance_schema import SubstanceSchema + +# parser = reqparse.RequestParser() +# parser.add_argument('nature') + +# substance_schema = SubstanceSchema() +# substances_schema = SubstanceSchema(many=True) + +# pantry_cls = SQLAlchemyPantry + + +class SubstanceResource(Resource): + @inject + def __init__(self, pantry: Pantry, substance_schemas: Dict[str, SubstanceSchema], parser_fcty=reqparse.RequestParser): + super(SubstanceResource, self).__init__() + + self._pantry = pantry + self._substance_schema = substance_schemas['one'] + self._substances_schema = substance_schemas['many'] + self._parser_fcty = parser_fcty + + def get(self): + parser = self._parser_fcty() + + parser.add_argument('nature') + + args = parser.parse_args() + + nature = args['nature'] + + substances = self._pantry.find_substances_by_nature(nature) + + return self._substances_schema.dump(substances) + + def post(self): + parser = self._parser_fcty() + + parser.add_argument('nature') + + args = parser.parse_args() + + nature = args['nature'] + + pantry = self._pantry + + substance = Substance(nature=nature) + + pantry.add_substance(substance) + + pantry.commit() + + return self._substance_schema.dump(substance) + + +def init_app(app, api): + api.add_resource(SubstanceResource, '/substance') diff --git a/022-burette/magnum_opus/magnumopus/schemas/__init__.py b/022-burette/magnum_opus/magnumopus/schemas/__init__.py new file mode 100644 index 0000000..7b27dd7 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/schemas/__init__.py @@ -0,0 +1,22 @@ +from typing import Dict +from flask_marshmallow import Marshmallow + +ma = Marshmallow() + +def init_app(app): + ma.init_app(app) + return [configure_injector] + +def configure_injector(binder): + from .substance_schema import SubstanceSchema + + binder.bind( + SubstanceSchema, to=SubstanceSchema() + ) + + binder.multibind( + Dict[str, SubstanceSchema], to={ + 'one': SubstanceSchema(), + 'many': SubstanceSchema(many=True) + } + ) diff --git a/022-burette/magnum_opus/magnumopus/schemas/substance_schema.py b/022-burette/magnum_opus/magnumopus/schemas/substance_schema.py new file mode 100644 index 0000000..6484e98 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/schemas/substance_schema.py @@ -0,0 +1,18 @@ +from marshmallow import fields + +from . import ma + +from ..models.substance import Substance +from ..services.assessor import assess_whether_substance_is_philosophers_stone + +class SubstanceSchema(ma.SQLAlchemySchema): + is_philosophers_stone = fields.Function( + assess_whether_substance_is_philosophers_stone + ) + + class Meta: + model = Substance + fields = ('id', 'nature', 'is_philosophers_stone', 'state') + + id = ma.auto_field() + nature = ma.auto_field() diff --git a/022-burette/magnum_opus/magnumopus/services/__init__.py b/022-burette/magnum_opus/magnumopus/services/__init__.py new file mode 100644 index 0000000..561fd25 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/services/__init__.py @@ -0,0 +1,9 @@ +from .alembic import Alembic + +def init_app(app): + return [configure_injector] + +def configure_injector(binder): + binder.bind( + Alembic, to=Alembic + ) diff --git a/022-burette/magnum_opus/magnumopus/services/alembic.py b/022-burette/magnum_opus/magnumopus/services/alembic.py new file mode 100644 index 0000000..5fc05b2 --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/services/alembic.py @@ -0,0 +1,51 @@ +from ..models.substance import Substance + +class NotEnoughSubstancesToMixException(Exception): + pass + +class UnknownProcessException(Exception): + pass + + +MIXTURES = { + ('Mercury', 'Salt', 'Sulphur'): 'Gloop' +} + + +class Alembic: + _nature_of_unknown_mixture = 'Sludge' + + @staticmethod + def _produce(nature): + return Substance(nature=nature) + + def mix(self, *substances): + if len(substances) < 2: + raise NotEnoughSubstancesToMixException() + + constituents = [substance.nature for substance in substances] + + # This gives us a canonical, ordered way of expressing our + # constituents that we can use as a recipe look-up + ingredient_list = tuple(sorted(constituents)) + + try: + nature = MIXTURES[ingredient_list] + except KeyError: + nature = self._nature_of_unknown_mixture + + return self._produce(nature) + + def process(self, process_name, substance): + if process_name == 'ferment': + result = substance.ferment() + elif process_name == 'cook': + result = substance.cook() + elif process_name == 'wash': + result = substance.wash() + elif process_name == 'pickle': + result = substance.pickle() + else: + raise UnknownProcessException() + + return result diff --git a/022-burette/magnum_opus/magnumopus/services/alembic_instruction_handler.py b/022-burette/magnum_opus/magnumopus/services/alembic_instruction_handler.py new file mode 100644 index 0000000..571dbfc --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/services/alembic_instruction_handler.py @@ -0,0 +1,35 @@ +from dataclasses import dataclass +from injector import inject + +from .alembic import Alembic +from ..repositories.pantry import Pantry + +class UnknownAlembicInstructionException(Exception): + pass + +@dataclass +class AlembicInstruction: + instruction_type: str + natures: list + action: str = '' + +class AlembicInstructionHandler: + @inject + def handle(self, instruction: AlembicInstruction, pantry: Pantry): + natures = instruction.natures + action = instruction.action + instruction_type = instruction.instruction_type + + # Clearly need some validation here! + substances = [pantry.find_substances_by_nature(nature)[0] for nature in natures] + + alembic = Alembic() + + if instruction_type == 'mix': + result = alembic.mix(*substances) + elif instruction_type == 'process': + result = alembic.process(action, substances[0]) + else: + raise UnknownAlembicInstructionException(f'Unknown instruction: {action}') + + return result diff --git a/022-burette/magnum_opus/magnumopus/services/assessor.py b/022-burette/magnum_opus/magnumopus/services/assessor.py new file mode 100644 index 0000000..94d564d --- /dev/null +++ b/022-burette/magnum_opus/magnumopus/services/assessor.py @@ -0,0 +1,2 @@ +def assess_whether_substance_is_philosophers_stone(substance): + return substance.nature == 'Gloop' and substance.state == ['cooked', 'washed', 'pickled', 'fermented'] diff --git a/022-burette/magnum_opus/requirements.txt b/022-burette/magnum_opus/requirements.txt new file mode 100644 index 0000000..4c1dc81 --- /dev/null +++ b/022-burette/magnum_opus/requirements.txt @@ -0,0 +1,8 @@ +appdirs +flask +flask-restful +flask-marshmallow +flask-sqlalchemy +flask-injector +marshmallow-sqlalchemy +sqlalchemy-utils diff --git a/022-burette/magnum_opus/setup.cfg b/022-burette/magnum_opus/setup.cfg new file mode 100644 index 0000000..bfffc70 --- /dev/null +++ b/022-burette/magnum_opus/setup.cfg @@ -0,0 +1,34 @@ +[metadata] +name = magnumopus +version = 0.0.1 +author = Phil Weir +author_email = phil.weir@flaxandteal.co.uk +license = GPL +description = Service for cooking up a philosopher's stone +long-description = file:README.md + +[options] +include_package_data = True +packages = find: +python_requires = >=3.6 +install_requires = + appdirs + flask-restful + flask-marshmallow + flask-sqlalchemy + flask-injector + sqlalchemy-utils + marshmallow-sqlalchemy + flask + +[options.extras_require] +dev = + pytest + pytest-pep8 + pytest-cov + pytest-flask + pytest-flask-sqlalchemy + +[options.packages.find] +exclude = + tests diff --git a/022-burette/magnum_opus/setup.py b/022-burette/magnum_opus/setup.py new file mode 100644 index 0000000..1767837 --- /dev/null +++ b/022-burette/magnum_opus/setup.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Magnum Opus + +This tool performs alchemical reactions to create +the Philosopher's Stone. + +@author: Phil Weir +""" + +from setuptools import setup + +if __name__ == '__main__': + setup() diff --git a/022-burette/magnum_opus/tests/__init__.py b/022-burette/magnum_opus/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/022-burette/magnum_opus/tests/application/test_app.py b/022-burette/magnum_opus/tests/application/test_app.py new file mode 100644 index 0000000..81169bc --- /dev/null +++ b/022-burette/magnum_opus/tests/application/test_app.py @@ -0,0 +1,7 @@ +import pytest +from magnumopus import create_app + +@pytest.fixture +def app(): + app = create_app() + return app diff --git a/022-burette/magnum_opus/tests/conftest.py b/022-burette/magnum_opus/tests/conftest.py new file mode 100644 index 0000000..bee0b40 --- /dev/null +++ b/022-burette/magnum_opus/tests/conftest.py @@ -0,0 +1,15 @@ +import pytest +from magnumopus import create_app +from magnumopus.models import db + +@pytest.fixture(scope='session') +def app(): + app = create_app() + return app + + +@pytest.fixture(scope='session') +def _db(app): + with app.app_context(): + db.create_all() + return db diff --git a/022-burette/magnum_opus/tests/domain/__init__.py b/022-burette/magnum_opus/tests/domain/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/022-burette/magnum_opus/tests/domain/test_alembic.py b/022-burette/magnum_opus/tests/domain/test_alembic.py new file mode 100644 index 0000000..cd67657 --- /dev/null +++ b/022-burette/magnum_opus/tests/domain/test_alembic.py @@ -0,0 +1,81 @@ +import pytest + +from magnumopus.services.alembic import Alembic, NotEnoughSubstancesToMixException, UnknownProcessException +from magnumopus.models.substance import Substance + +def test_can_set_up_my_alembic(): + Alembic() + +def test_can_mix_multiple_substances_in_my_alembic(): + alembic = Alembic() + substance = [Substance() for _ in range(3)] + alembic.mix(*substance) + + substance = [Substance() for _ in range(6)] + alembic.mix(*substance) + +def test_cannot_mix_one_substance_in_my_alembic(): + alembic = Alembic() + substance = Substance() + + with pytest.raises(NotEnoughSubstancesToMixException): + alembic.mix(substance) + +def test_mixing_sulphur_salt_and_mercury_gives_gloop(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + + result = alembic.mix(sulphur, salt, mercury) + + assert result.nature == 'Gloop' + + result = alembic.mix(mercury, sulphur, salt) + + assert result.nature == 'Gloop' + +def test_mixing_other_recipes_gives_sludge(): + alembic = Alembic() + + sulphur = Substance(nature='Sulphur') + salt = Substance(nature='Salt') + mercury = Substance(nature='Mercury') + gloop = Substance(nature='Gloop') + + result = alembic.mix(sulphur, salt, mercury, sulphur) + + assert result.nature == 'Sludge' + + result = alembic.mix(salt, mercury) + + assert result.nature == 'Sludge' + + result = alembic.mix(gloop, salt, mercury) + + assert result.nature == 'Sludge' + +def test_can_process_substance(): + alembic = Alembic() + + substance = Substance() + result = alembic.process('cook', substance) + + substance = Substance() + cooked_substance = substance.cook() + + assert result.state == cooked_substance.state + + result = alembic.process('ferment', substance) + cooked_fermented_substance = cooked_substance.ferment() + + assert result.state == cooked_fermented_substance.state + +def test_cannot_perform_unknown_process(): + alembic = Alembic() + + substance = Substance() + + with pytest.raises(UnknownProcessException): + alembic.process('boil', substance) diff --git a/022-burette/magnum_opus/tests/domain/test_alembic_instruction_handler.py b/022-burette/magnum_opus/tests/domain/test_alembic_instruction_handler.py new file mode 100644 index 0000000..ccb2f96 --- /dev/null +++ b/022-burette/magnum_opus/tests/domain/test_alembic_instruction_handler.py @@ -0,0 +1,37 @@ +import pytest + +from magnumopus.services.alembic_instruction_handler import AlembicInstruction, AlembicInstructionHandler +from magnumopus.repositories.list_pantry import ListPantry +from magnumopus.models.substance import Substance + +@pytest.fixture +def instruction_unknown(): + return AlembicInstruction( + 'saute', + ['Sulphur'], + 'cook' + ) + +@pytest.fixture +def instruction(): + return AlembicInstruction( + 'process', + ['Sludge'], + 'cook' + ) + +@pytest.fixture +def pantry(): + pantry = ListPantry() + + substance = Substance(nature='Sludge') + pantry.add_substance(substance) + + substance = Substance(nature='Sulphur') + pantry.add_substance(substance) + + return pantry + +def test_can_set_up_my_alembic_instruction_handler(instruction, pantry): + handler = AlembicInstructionHandler() + handler.handle(instruction, pantry) diff --git a/022-burette/magnum_opus/tests/domain/test_pantry.py b/022-burette/magnum_opus/tests/domain/test_pantry.py new file mode 100644 index 0000000..464ed15 --- /dev/null +++ b/022-burette/magnum_opus/tests/domain/test_pantry.py @@ -0,0 +1,43 @@ +import pytest + +from magnumopus.repositories.list_pantry import ListPantry +from magnumopus.repositories.sqlalchemy_pantry import SQLAlchemyPantry +from magnumopus.models.substance import Substance + +@pytest.fixture +def list_pantry(): + return ListPantry() + +@pytest.fixture +def sqlalchemy_pantry(_db): + return SQLAlchemyPantry(_db) + +@pytest.fixture +def pantries(list_pantry, sqlalchemy_pantry): + return { + 'list': list_pantry, + 'sqlalchemy': sqlalchemy_pantry + } + +# We may want other pantry-specific tests, but bear in mind LSP +@pytest.mark.parametrize('pantry_type', ['list', 'sqlalchemy']) +def test_can_add_to_pantry(pantry_type, pantries): + pantry = pantries[pantry_type] + + substance = Substance() + + pantry.add_substance(substance) + + assert pantry.count_all_substances() == 1 + +@pytest.mark.parametrize('pantry_type', ['list', 'sqlalchemy']) +def test_can_retrieve_substance_from_pantry_by_nature(pantry_type, pantries): + pantry = pantries[pantry_type] + + substance = Substance(nature='Mercury') + + pantry.add_substance(substance) + + mercury = pantry.find_substances_by_nature('Mercury')[0] + + assert mercury.nature == 'Mercury' diff --git a/022-burette/magnum_opus/tests/domain/test_substance.py b/022-burette/magnum_opus/tests/domain/test_substance.py new file mode 100644 index 0000000..d00a6f7 --- /dev/null +++ b/022-burette/magnum_opus/tests/domain/test_substance.py @@ -0,0 +1,49 @@ +from magnumopus.models.substance import Substance + +def test_can_cook_substance(): + substance = Substance() + + result = substance.cook() + + assert substance.state == ['cooked'] + +def test_can_wash_substance(): + substance = Substance() + + result = substance.wash() + + assert result.state == ['washed'] + +def test_can_pickle_substance(): + substance = Substance() + + result = substance.pickle() + + assert result.state == ['pickled'] + +def test_can_ferment_substance(): + substance = Substance() + + result = substance.ferment() + + assert substance.state == ['fermented'] + +def test_can_cook_and_ferment_substance(): + substance = Substance() + + result = substance.cook() + result = result.ferment() + + assert substance.state == ['cooked', 'fermented'] + +def test_the_order_of_processes_applied_to_a_substance_matters(): + substance1 = Substance() + result1 = substance1.cook() + result1 = result1.ferment() + + substance2 = Substance() + result2 = substance2.ferment() + result2 = result2.cook() + + assert result1.state != result2.state + assert result1.state == result2.state[::-1] diff --git a/022-burette/magnum_opus/tox.ini b/022-burette/magnum_opus/tox.ini new file mode 100644 index 0000000..d815853 --- /dev/null +++ b/022-burette/magnum_opus/tox.ini @@ -0,0 +1,6 @@ +[tox] +envlist = py38 + +[testenv] +deps = pytest +commands = pytest From 28f08801da3bbc75e89af409a76e7ebc25d5c178 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Sat, 27 Jun 2020 19:42:36 +0100 Subject: [PATCH 08/12] expand tests to include some flask/integration testing --- .../magnum_opus/docker/storage/storage.db | Bin 8192 -> 8192 bytes .../magnumopus/models/substance.py | 10 +++- .../resources/alembic_instruction.py | 6 ++- .../magnumopus/resources/substance.py | 2 +- .../magnumopus/schemas/substance_schema.py | 1 + .../services/alembic_instruction_handler.py | 1 + 022-burette/magnum_opus/tests/__init__.py | 4 ++ .../magnum_opus/tests/application/.coverage | Bin 0 -> 53248 bytes .../magnum_opus/tests/application/__init__.py | 0 .../test_alembic_instruction_resource.py | 47 ++++++++++++++++ .../magnum_opus/tests/application/test_app.py | 7 --- .../application/test_philosophers_stone.py | 7 +++ .../application/test_substance_resource.py | 50 ++++++++++++++++++ 022-burette/magnum_opus/tests/conftest.py | 8 +++ 14 files changed, 132 insertions(+), 11 deletions(-) create mode 100644 022-burette/magnum_opus/tests/application/.coverage create mode 100644 022-burette/magnum_opus/tests/application/__init__.py create mode 100644 022-burette/magnum_opus/tests/application/test_alembic_instruction_resource.py delete mode 100644 022-burette/magnum_opus/tests/application/test_app.py create mode 100644 022-burette/magnum_opus/tests/application/test_philosophers_stone.py create mode 100644 022-burette/magnum_opus/tests/application/test_substance_resource.py diff --git a/022-burette/magnum_opus/docker/storage/storage.db b/022-burette/magnum_opus/docker/storage/storage.db index 59ffca1581efa0de8441c324bba89044ca4e200d..41e4173e74b7ef47d0eaff4eba95ac3eb2ab418f 100644 GIT binary patch delta 93 zcmZp0XmFSy&B!rP#+i|0W5N=CA$I=N4E&$@pYh+~Kg)lZe;fbm&4L0``Sm&3Ss285 w-E;Eu3%J=>7^Hc9Q;U*Iiz+!-Sr|llgA;Q~xLH8L!KFC`8Kp&&Z^^3x0LdH~eEJ5_bF@g&h4&X=}$R(F>fJnJ;2@oWHgOIq81Cc;NNGKe5uYYEG>|GNH zdJ=D5Yo?}us_NDI-m9v4{rAOZt{Og9Hyzi~ef7LBEr_D<8C4Yop#==1-p%55Df}EtC7M-sWzU)-GM!xOja-y?*htS2xsXpL({e!qRA{7gg8UReRi3 zHw}}khTSpRx^LK9s^8^F?!L!6IOD-SnDa2>N?0D(G@}Ehe7*%$^jyQz-FDknGx^uP$%7O!>2N) z4eS`H^7JND)OOqsw!Y=+cDu{HWmO+)*mj_udw!&?>sU?SQBA`R)wDgsHym5#d%WHE zdFN0Cml0aB0KBv|P}lRQ(DPBrSXPS8sPG{rE%j&4)a;S#wEUTyl zc)&+1h51j-hyr*e-}81%_~WJNecuVUH88%m21)gsCyL7anKRHF$!*jQ+T z+A^KixUYpC<8kO9Fcu`)Hv4uPyNZW8w4DKW^)0>D7I7*#3pSBjS6az(8=4WTcAnFk~F5x#nrUdR8b%6&ag7@D1p6++mhue<3q2cv> zVgA#zM>QOqpsitAc;Q+uZ1P^z39o|0Hu{EfNO-bey9Nn)&UrV|btXP(Acj9RZXWyt+81k`C zqMT^#fP!ir`l1It^MN{(O5>wAP$l)R^Z*6cYU!P*m!mCGHSTu#L)Ar-&}H4{zF~0{ zvxJQa{b^VC)V9mvAWWf4b?H&oMwC==ZV#HK(TcO5UwN_#xBKx%Pj7F-%}XBc z=bqoxGz)}i8r&99Usmf4sCR%XQC(P7{Z<)lDzi5Q_9puWdz<~~!(?L8l?V_4B0vO) z01+SpM1Tko0U|&Ih`{4Zpeikj$$1O8D9ws^+Cr*G3u1hZB3F?XOUda8y#7Cz|AWBp zu`^RYnz~&3b#1#QR$r_xR_<38%lFIcrB_Rria#x0QQlBKSNKKYImk>45g-CYfCzk$ z3EY{Jh2YNr{p|DT>~YiOJqOM_JFWpIolV2@wVrPK?mnDw9?XL9orwt_%H2B!a{CjL zt7&i+-w#i*2jYw@94HeL4G)m(CO${FKcar;WY#8+o-6d4Uccq}@J<3AKfDMg_fCND z?JV_Agr}(s(?C6+rBs)Da6Jaz=Frql4$qdi!RDUt_QS`VjuP`tqaden;cu> zmnWuw%Ei1=)~2?c4mVSy38-onL8z7`a~!e_-88<+L0ne>anEKe4qo>Gl8gdKx{;+M zcwfS%u?3>cJczoLr6|L`&65Gpkh50IbhhAyJfN5@fhavo#bS?a=^lEAn*({q1mvZ9 z-L?oaZ)PboB@D0s&*k3|*tcqCEmyr)`_0q_Q>R|8K2i8({;k57l`Eyo#n(zdE?!lB zUU{i}zVbx*r4RC-UTPZ=AOb{y2nfR0H@F?#n@ca&l8M z>8T(mA1IR(eOUZIlex*05PTRBj^h85z8q|4s(&IpMg2q|$_M#OrT(}0e|jJX&V*W! z(wt48haDFGPi1fBVJIHO#PC17)|Ue-Q^tqI|J9%?7m<%H;GXdwbbfCvx)B0vO)01+SpM1Tko0U|&Ijv)a_s+I8izr@}a*uU7{;D;6> zKm>>Y5g-CYfCvx)B0vO)01+SpMBp(dP>^J?G$oal9Q;n_=ES@xmr7G*y#6n-cLeq> zy#N25$5=sXIuRfOM1Tko0U|&IhyW2F0z`la5CI|(5hy_HFG^DQlgr6)0wBEpFH934 zB0vO)01+SpM1Tko0U|&IhyW2F0z}|A6Ts{L6#pM*3zKd{fCvx)B0vO)01+SpM1Tko z0U|&I1OcD_pJOlL{r~@De`kMXe_?-Se`LR9zhZB&pRw23PuQ#M74|awA^QRQ9{Vo) z4rHc<2oM1xKm>>Y5g-CYfCvx)B0vO)01@~f2}pDBT7GF3lT( Date: Sat, 27 Jun 2020 21:17:38 +0100 Subject: [PATCH 09/12] remove stray debug --- .../magnum_opus/magnumopus/resources/alembic_instruction.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py b/022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py index 526b67e..2d39fc4 100644 --- a/022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py +++ b/022-burette/magnum_opus/magnumopus/resources/alembic_instruction.py @@ -46,14 +46,10 @@ def post(self): # Crude start at DI... see flask-injector result = instruction_handler.handle(instruction, pantry) - print('y', result.state, result.id, self._substance_schema.dump(result)) pantry.add_substance(result) - print('z', result.state, result.id, self._substance_schema.dump(result)) pantry.commit() - print('a', result.state, result.id, self._substance_schema.dump(result)) - print(result.state, result.id, self._substance_schema.dump(result)) return self._substance_schema.dump(result), 201 From 12df01149fccf1ffe17b1c43e0ce0806e07cdf58 Mon Sep 17 00:00:00 2001 From: Phil Weir Date: Sun, 28 Jun 2020 01:12:48 +0100 Subject: [PATCH 10/12] asynchronous quart server --- 022-burette/magnum_opus_ii/.coverage | Bin 0 -> 53248 bytes 022-burette/magnum_opus_ii/.gitignore | 4 + 022-burette/magnum_opus_ii/Dockerfile | 24 + 022-burette/magnum_opus_ii/MANIFEST.in | 1 + 022-burette/magnum_opus_ii/README.md | 46 + 022-burette/magnum_opus_ii/RULES.md | 9 + 022-burette/magnum_opus_ii/docker-compose.yml | 11 + .../magnum_opus_ii/docker/storage/storage.db | Bin 0 -> 8192 bytes 022-burette/magnum_opus_ii/gunicorn_config.py | 5 + 022-burette/magnum_opus_ii/init_containers.sh | 6 + 022-burette/magnum_opus_ii/init_entrypoint.sh | 3 + .../magnum_opus_ii/magnumopus/__init__.py | 22 + .../magnum_opus_ii/magnumopus/config.py | 7 + .../magnum_opus_ii/magnumopus/index.py | 3 + .../magnum_opus_ii/magnumopus/initialize.py | 9 + .../magnum_opus_ii/magnumopus/injection.py | 26 + .../magnum_opus_ii/magnumopus/logger.py | 6 + .../magnumopus/models/__init__.py | 11 + .../magnum_opus_ii/magnumopus/models/base.py | 3 + .../magnumopus/models/substance.py | 40 + .../magnumopus/repositories/__init__.py | 18 + .../magnumopus/repositories/list_pantry.py | 26 + .../magnumopus/repositories/pantry.py | 25 + .../repositories/sqlalchemy_pantry.py | 31 + .../magnumopus/resources/__init__.py | 7 + .../resources/alembic_instruction.py | 57 + .../magnumopus/resources/substance.py | 49 + .../magnumopus/schemas/__init__.py | 22 + .../magnumopus/schemas/substance_schema.py | 19 + .../magnumopus/services/__init__.py | 9 + .../magnumopus/services/alembic.py | 51 + .../services/alembic_instruction_handler.py | 36 + .../magnumopus/services/assessor.py | 2 + 022-burette/magnum_opus_ii/pytestdebug.log | 4688 +++++++++++++++++ 022-burette/magnum_opus_ii/requirements.txt | 9 + 022-burette/magnum_opus_ii/setup.cfg | 34 + 022-burette/magnum_opus_ii/setup.py | 14 + 022-burette/magnum_opus_ii/tests/__init__.py | 4 + .../tests/application/.coverage | Bin 0 -> 53248 bytes .../tests/application/__init__.py | 0 .../test_alembic_instruction_resource.py | 49 + .../application/test_philosophers_stone.py | 7 + .../application/test_substance_resource.py | 52 + 022-burette/magnum_opus_ii/tests/conftest.py | 19 + .../magnum_opus_ii/tests/domain/__init__.py | 0 .../tests/domain/test_alembic.py | 81 + .../test_alembic_instruction_handler.py | 37 + .../tests/domain/test_pantry.py | 38 + .../tests/domain/test_substance.py | 49 + 022-burette/magnum_opus_ii/tox.ini | 6 + 50 files changed, 5675 insertions(+) create mode 100644 022-burette/magnum_opus_ii/.coverage create mode 100644 022-burette/magnum_opus_ii/.gitignore create mode 100644 022-burette/magnum_opus_ii/Dockerfile create mode 100644 022-burette/magnum_opus_ii/MANIFEST.in create mode 100644 022-burette/magnum_opus_ii/README.md create mode 100644 022-burette/magnum_opus_ii/RULES.md create mode 100644 022-burette/magnum_opus_ii/docker-compose.yml create mode 100644 022-burette/magnum_opus_ii/docker/storage/storage.db create mode 100644 022-burette/magnum_opus_ii/gunicorn_config.py create mode 100755 022-burette/magnum_opus_ii/init_containers.sh create mode 100755 022-burette/magnum_opus_ii/init_entrypoint.sh create mode 100644 022-burette/magnum_opus_ii/magnumopus/__init__.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/config.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/index.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/initialize.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/injection.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/logger.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/models/__init__.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/models/base.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/models/substance.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/repositories/list_pantry.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/repositories/pantry.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/repositories/sqlalchemy_pantry.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/resources/__init__.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/resources/alembic_instruction.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/resources/substance.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/schemas/substance_schema.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/services/__init__.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/services/alembic.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/services/alembic_instruction_handler.py create mode 100644 022-burette/magnum_opus_ii/magnumopus/services/assessor.py create mode 100644 022-burette/magnum_opus_ii/pytestdebug.log create mode 100644 022-burette/magnum_opus_ii/requirements.txt create mode 100644 022-burette/magnum_opus_ii/setup.cfg create mode 100644 022-burette/magnum_opus_ii/setup.py create mode 100644 022-burette/magnum_opus_ii/tests/__init__.py create mode 100644 022-burette/magnum_opus_ii/tests/application/.coverage create mode 100644 022-burette/magnum_opus_ii/tests/application/__init__.py create mode 100644 022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py create mode 100644 022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py create mode 100644 022-burette/magnum_opus_ii/tests/application/test_substance_resource.py create mode 100644 022-burette/magnum_opus_ii/tests/conftest.py create mode 100644 022-burette/magnum_opus_ii/tests/domain/__init__.py create mode 100644 022-burette/magnum_opus_ii/tests/domain/test_alembic.py create mode 100644 022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py create mode 100644 022-burette/magnum_opus_ii/tests/domain/test_pantry.py create mode 100644 022-burette/magnum_opus_ii/tests/domain/test_substance.py create mode 100644 022-burette/magnum_opus_ii/tox.ini diff --git a/022-burette/magnum_opus_ii/.coverage b/022-burette/magnum_opus_ii/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..acffb036006a2fd0428756bfafc1028b3539f7f7 GIT binary patch literal 53248 zcmeI4TWlOx8GvVYW@mQxcGg~Bl%~NWB;;7Jy|Kfk4M-sbKeP#I8`1`mhRy8y*q(TI z#+jL2+f4%+w^AOs2(<`Q-~l9{4@k5RG(r&)541?|fFJ<`Z9^qMln01Zgt({(@&9x2 zjuShI1miZzKiWO#%*;9GKmYgt=ggeBee|ItrpNU;+i4q~zE7wKq9}Y&*9Ae);9r7& zyr__n;}wX-M0%^FCQKgqO^H1s6qPRu>=UJrv5De0OSQtw#jf^r;aT;x)`A_h5CI}U z1c(3;2nhHO71iM#JH)kfp3!J=&oP?Z3B%H%qcaDO&FIGte(1=I9&Xcj=XF>nCiH{4 zV=wDV+|lRE7S~N{)@&M{Y0c~20*`ZdTt16OJlF=uJj^&5l*d%voP|;zpNA@z9J6gW ztNJ2e9S<@@(mcN6g&Uv}Zq8enL*E@0AJZK^#~p4pxf`}(w>dkOAA90cd3Cs270>fP zC&OvNudqQI*w9nuzB#C&Ci}Ro1g3WpCOxo7l3a?*?F{;qkL$gX z&>JngvC-E8k8wG45Eu*MY;zr}iCx7-9h!ERJH|YpjP{1Z!dvY~;5t*9 zGCVV~mFuj#Kz(XGnfG@n>hR8;;+ht?QDm(sQa89zY{^ZA(Rf#z8*aym2a+2Nl5vUN zC>i&WXb-3}p(?`%cW$Lll&?M&C33zhtHXnXq967M9GCE)-Jk?+>2-l?4g@#f{3XL% z(64VhZia@BW|iUh4{p_PY(jksL*5h%#M05Pki@=s>RycNOcH?~VpdiH|8bx*vnS7I!O1wA+R? z8y%+b=o{7wLq7INloO5}P*5L*zUV^Fyr#~$(r7OZRB`>2OMn7vZ5y*;FGpJ>YFu96 z*HsrDgg$I|+%wx;$1Fi(0)JXIT)pXV*a?Twu~F$p)<+}Nr!d4>at=>q{1H(d-m^#a zJ5e7DhnKnw$MUujH#=I*Z19b1cJ|!l0T^fDBq!+}$S#2cS3?OnriB)4gcRaj(J4-T z3@7*^dsBcPEku9_5CI}U1c(3;AOb{y2oM1xKm>@u?MFZoGop&~f0^wN*im+fjY5JJ zB0vO)01+SpM1Tko0U|&IhyW2F0(TODqAcxV@uLxY?~Yn}6)9@>0q@C61#`=3Er~Eylyld@n{6xfw(b|ID=C!2-v*j&w)2SV|oyFQQ$1p8; zvaj~ws<&WUhwP5yLZ)D4q8YC3ot~a(z(Y5l$7^k49-c|6+e;m{Hp#7Stz|Z%?E5C~ zslnrZd}7IHF2ci0E^grCnlt-9pYugCbtGkP6aHF}g;P zDM-7t`0@na{~yY}BCw~~Ncp+)y`>jR4-{W29xhxiJd(eZKcW3zvvP0b&Z_@ZKdX)? z-&O91%(M^zB0vO)z}uNXdq@`i`v3jvbMNYL4X$8&rqMDV<8X<2VGzVUoUS-{ZyF?- z10d;mnv&qf(>ZeSUUtOzSicUO-00`qNgdWzWNx4M3DH^vS|nHcibO?!tWx z_zFVJXmNNayID6a*K<0twq6CaZKv4+mpffEXn^Z-*R@gcvkau3O;u{}a;IB!I}O)^ z&o=Pr{Z0_>mO=R9b_lNnY|{(w{d7wp^h}yUdzN0;8I=euH2G?M$*??U6`d@fwv#zL(S(-idOhJ?Eq!|@gs&^Tk^{M&ZR4Ia zxvGN6t7(ev4JFr)W%UJkr@a*ntF8hJQtjYvdzQBngA0x-*|ddTt33$yWDvSNqj$p6 zmIP9bGz}f`Z5S?|)HoTCXKsVMgpP|M$UKpz%!Dw!|38#{RbXFGUQiBaUsZMWb4)Kk zUwW{3q;S0Oi~QyMqw2r3KWKLDujT!vmx@2iJ^pq+>7}+20U|&Ih=3qivR@a|JdSLb z{|}k6|8UCU!ukK;Y1u!Xs-*S#|3F*zPo^p=IsdPwuGsqgzuy<-wQQ=I^=5^e&;R>6 zvfoa%1-;YO-u%Dvxa^-zSL)XDf9A>l;dCt$tYt>Xm_lA-i&i~ca zJNPE^e01+SpM1Tko0U|&I zhyW2F0z`la+=c`ssifik{{i-Hf&GJBWq)M9Wj|vtvhT6)uy3%hu+OveY=v2DmOaWo z!e-b9AR{eAfCvx)B0vO)01+SpM1Tko0U|&I?hpdXfGld|fs1Mt;!5>mPU*)D{g0LU zAilfrlj=K>grZb%b0w2w5cjjwuPeDSrpmu+zoS&btfl`5cUOdra7r!0YNdEp(h86m zC|ppN3u+#><*gGr4HEs@m!H{@%V8>awI$_MNDZkM&K>w=F0Wu(xp1ZPic-u%`mXHD zpSd#gTpf16T3NndkuZir8Hg*HuBwW%ruBdP(s8{1Kft;IdlSC@{};Fd@EZFy`#Jjw z`yu;2djYNkJj=euo?%b1PqQc4Imk#05g-CYfCvx)B0vO)01+SpM1Tko0U~gd1aQJG z4h#fQwHieI{Xx{%7etjx5HS`+<#G^}N>Y5g-CYfCvzQTap0Y|EKx? zEonMxG!Y;IM1Tko0U|&IhyW2F0z`la5P_Q}fbahgv8V9)|G%?0*q_g!( zq#^h$zch%!00vbI`Z4Ikpn?Izpo~EYgCYh64DuLg800WeF;FnbVjyE6VUWQ9zyJSV D&<%nw literal 0 HcmV?d00001 diff --git a/022-burette/magnum_opus_ii/.gitignore b/022-burette/magnum_opus_ii/.gitignore new file mode 100644 index 0000000..8a3f0fc --- /dev/null +++ b/022-burette/magnum_opus_ii/.gitignore @@ -0,0 +1,4 @@ +*.egg-info +.tox +Pipfile +.env diff --git a/022-burette/magnum_opus_ii/Dockerfile b/022-burette/magnum_opus_ii/Dockerfile new file mode 100644 index 0000000..0c7c8cf --- /dev/null +++ b/022-burette/magnum_opus_ii/Dockerfile @@ -0,0 +1,24 @@ +FROM python:3-alpine + +RUN addgroup -S user && adduser user -S -G user + +WORKDIR /home/user/ + +COPY requirements.txt . +COPY gunicorn_config.py . +COPY setup.py . +COPY setup.cfg . +COPY init_entrypoint.sh / + +RUN pip install hypercorn +RUN pip install -r requirements.txt + +USER user + +EXPOSE 5000 + +ENTRYPOINT [] + +CMD hypercorn --config python:./gunicorn_config.py magnumopus.index:app + +COPY magnumopus magnumopus diff --git a/022-burette/magnum_opus_ii/MANIFEST.in b/022-burette/magnum_opus_ii/MANIFEST.in new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/022-burette/magnum_opus_ii/MANIFEST.in @@ -0,0 +1 @@ + diff --git a/022-burette/magnum_opus_ii/README.md b/022-burette/magnum_opus_ii/README.md new file mode 100644 index 0000000..94ce180 --- /dev/null +++ b/022-burette/magnum_opus_ii/README.md @@ -0,0 +1,46 @@ +Magnum Opus +=========== + +Recipe maker for the philosopher's stone. + + + python3 -m pytest --cov magnumopus >> README.md + + ============================= test session starts ============================== + platform linux -- Python 3.8.2, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 + rootdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus + plugins: pep8-1.0.6, cov-2.10.0 + collected 15 items + + tests/domain/test_alembic.py ....... [ 46%] + tests/domain/test_pantry.py .. [ 60%] + tests/domain/test_substance.py ...... [100%] + + ----------- coverage: platform linux, python 3.8.2-final-0 ----------- + Name Stmts Miss Cover + ------------------------------------------------------------------------ + magnumopus/__init__.py 10 8 20% + magnumopus/config.py 4 4 0% + magnumopus/index.py 2 2 0% + magnumopus/initialize.py 6 6 0% + magnumopus/logger.py 4 4 0% + magnumopus/models/__init__.py 3 1 67% + magnumopus/models/base.py 2 0 100% + magnumopus/models/substance.py 24 0 100% + magnumopus/repositories/__init__.py 0 0 100% + magnumopus/repositories/pantry.py 12 1 92% + magnumopus/repositories/sqlalchemy_pantry.py 15 15 0% + magnumopus/resources/__init__.py 7 7 0% + magnumopus/resources/alembic_instruction.py 26 26 0% + magnumopus/resources/substance.py 28 28 0% + magnumopus/schemas/__init__.py 4 4 0% + magnumopus/schemas/substance_schema.py 11 11 0% + magnumopus/services/__init__.py 0 0 100% + magnumopus/services/alembic.py 32 2 94% + magnumopus/services/alembic_instruction_handler.py 20 20 0% + magnumopus/services/assessor.py 2 2 0% + ------------------------------------------------------------------------ + TOTAL 212 141 33% + + + ============================== 15 passed in 0.38s ============================== diff --git a/022-burette/magnum_opus_ii/RULES.md b/022-burette/magnum_opus_ii/RULES.md new file mode 100644 index 0000000..4438311 --- /dev/null +++ b/022-burette/magnum_opus_ii/RULES.md @@ -0,0 +1,9 @@ +* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my "Alembic" (mixing pot), giving one unit of another substance, Gloop +* Any attempt to mix anything other than those three substances, gives Sludge, another substance +* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented +* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills) +[* To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)] + +Final rule: +GROUP 1: When I process a substance, using any process, it becomes a different substance +GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process) diff --git a/022-burette/magnum_opus_ii/docker-compose.yml b/022-burette/magnum_opus_ii/docker-compose.yml new file mode 100644 index 0000000..34d2be6 --- /dev/null +++ b/022-burette/magnum_opus_ii/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3" +services: + web_async: + build: . + environment: + DATABASE_URI: 'sqlite:////docker/storage/storage.db' + volumes: + - ./docker:/docker + - ./magnumopus:/home/user/magnumopus + ports: + - 5000:5000 diff --git a/022-burette/magnum_opus_ii/docker/storage/storage.db b/022-burette/magnum_opus_ii/docker/storage/storage.db new file mode 100644 index 0000000000000000000000000000000000000000..41e4173e74b7ef47d0eaff4eba95ac3eb2ab418f GIT binary patch literal 8192 zcmeI#zfZzI6bJA-tU}u~=R$~ad2A&y4l=q}$pwj}YFmvA4h5=`R3PO#IP&+n`wuw# z5BLYT8~*{X1A)!a!SBmm?!9+EhR=4 + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_configure [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.LFPlugin object at 0x7f780666a820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.NFPlugin object at 0x7f780666a9a0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + early skip of rewriting module: faulthandler [assertion] + pytest_configure [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_configure --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.faulthandler.FaultHandlerHooks object at 0x7f780666aa60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.stepwise.StepwisePlugin object at 0x7f780666ab80> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + early skip of rewriting module: pdb [assertion] + early skip of rewriting module: cmd [assertion] + pytest_plugin_registered [hook] + plugin: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.config.Config object at 0x7f78089fd5b0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: > err=> in_=> _state='suspended' _in_suspended=False> _capture_fixture=None> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: testsfailed=0 testscollected=0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.LFPlugin object at 0x7f780666a820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.NFPlugin object at 0x7f780666a9a0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.faulthandler.FaultHandlerHooks object at 0x7f780666aa60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.stepwise.StepwisePlugin object at 0x7f780666ab80> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.terminal.TerminalReporter object at 0x7f780666aee0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.logging.LoggingPlugin object at 0x7f7806694820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + finish pytest_configure --> [] [hook] + pytest_sessionstart [hook] + session: testsfailed=0 testscollected=0> + pytest_plugin_registered [hook] + plugin: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.config.Config object at 0x7f78089fd5b0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: > err=> in_=> _state='suspended' _in_suspended=False> _capture_fixture=None> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: testsfailed=0 testscollected=0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.LFPlugin object at 0x7f780666a820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.NFPlugin object at 0x7f780666a9a0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.faulthandler.FaultHandlerHooks object at 0x7f780666aa60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.stepwise.StepwisePlugin object at 0x7f780666ab80> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.terminal.TerminalReporter object at 0x7f780666aee0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.logging.LoggingPlugin object at 0x7f7806694820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.fixtures.FixtureManager object at 0x7f7806694a60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_report_header [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + startdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii + finish pytest_report_header --> [['rootdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii', 'plugins: pep8-1.0.6, asyncio-0.14.0, cov-2.10.0'], ['using: pytest-5.4.3 pylib-1.9.0', 'setuptools registered plugins:', ' pytest-pep8-1.0.6 at /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env/lib/python3.8/site-packages/pytest_pep8.py', ' pytest-asyncio-0.14.0 at /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env/lib/python3.8/site-packages/pytest_asyncio/plugin.py', ' pytest-cov-2.10.0 at /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env/lib/python3.8/site-packages/pytest_cov/plugin.py']] [hook] + finish pytest_sessionstart --> [] [hook] + pytest_collection [hook] + session: testsfailed=0 testscollected=0> + perform_collect testsfailed=0 testscollected=0> ['/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii'] [collection] + pytest_collectstart [hook] + collector: testsfailed=0 testscollected=0> + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: testsfailed=0 testscollected=0> + processing argument (local('/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii'), []) [collection] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + early skip of rewriting module: py._code [assertion] + early skip of rewriting module: py._code.code [assertion] + early skip of rewriting module: repr [assertion] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.pytest_cache + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> True [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.tox + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.coverage + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.coverage + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.gitignore + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.gitignore + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/Dockerfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/Dockerfile + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/MANIFEST.in + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/MANIFEST.in + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/README.md + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/README.md + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/RULES.md + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/RULES.md + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker-compose.yml + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker-compose.yml + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/gunicorn_config.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/gunicorn_config.py + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_containers.sh + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_containers.sh + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_entrypoint.sh + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_entrypoint.sh + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/pytestdebug.log + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/pytestdebug.log + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/requirements.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/requirements.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.cfg + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.cfg + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.py + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tox.ini + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tox.ini + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/PKG-INFO + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/PKG-INFO + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/SOURCES.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/SOURCES.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/dependency_links.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/dependency_links.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/requires.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/requires.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/top_level.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/top_level.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage/storage.db + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage/storage.db + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/Pipfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/Pipfile + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/config.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/config.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/index.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/index.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/initialize.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/initialize.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/injection.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/injection.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/logger.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/logger.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/base.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/base.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/substance.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/substance.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/list_pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/list_pantry.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/pantry.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/sqlalchemy_pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/sqlalchemy_pantry.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/alembic_instruction.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/alembic_instruction.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/substance.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/substance.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/substance_schema.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/substance_schema.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic_instruction_handler.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic_instruction_handler.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/assessor.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/assessor.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/Pipfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/Pipfile + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/conftest.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/conftest.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/.coverage + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/.coverage + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/Pipfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/Pipfile + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + early skip of rewriting module: tests.application [assertion] + find_module called for: tests.application.test_alembic_instruction_resource [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py [assertion] + find_module called for: tests.application.test_substance_resource [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.application.test_alembic_instruction_resource + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.application + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.application.test_alembic_instruction_resource', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__pycache__/test_alembic_instruction_resource.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_app + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: is_dictionary_inside + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_substance_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_alembic_instruction_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_alembic_mix_instruction + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e04c0> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_alembic_process_instruction + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806649640> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.application.test_philosophers_stone [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.application.test_philosophers_stone + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.application + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.application.test_philosophers_stone', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__pycache__/test_philosophers_stone.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_app + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: is_dictionary_inside + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_philosophers_stone + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e0fa0> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.application.test_substance_resource + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.application + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.application.test_substance_resource', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__pycache__/test_substance_resource.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_app + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: is_dictionary_inside + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_substance_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: index_substances_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e04c0> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_get_substances + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e0550> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + early skip of rewriting module: tests.domain [assertion] + find_module called for: tests.domain.test_alembic [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py [assertion] + early skip of rewriting module: magnumopus.services [assertion] + early skip of rewriting module: magnumopus.services.alembic [assertion] + early skip of rewriting module: magnumopus.models.substance [assertion] + early skip of rewriting module: sqlalchemy_utils [assertion] + early skip of rewriting module: sqlalchemy_utils.aggregates [assertion] + early skip of rewriting module: sqlalchemy_utils.functions [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.database [assertion] + early skip of rewriting module: sqlalchemy_utils.utils [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.orm [assertion] + early skip of rewriting module: sqlalchemy.ext.hybrid [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.foreign_keys [assertion] + early skip of rewriting module: sqlalchemy_utils.query_chain [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.mock [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.render [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.sort_query [assertion] + early skip of rewriting module: sqlalchemy_utils.relationships [assertion] + early skip of rewriting module: sqlalchemy_utils.relationships.chained_join [assertion] + early skip of rewriting module: sqlalchemy_utils.asserts [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.array [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.hstore [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.json [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.ranges [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.pg8000 [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.psycopg2 [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.psycopg2cffi [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.pygresql [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.pypostgresql [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy.connectors [assertion] + early skip of rewriting module: sqlalchemy.connectors.zxJDBC [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.dml [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.ext [assertion] + early skip of rewriting module: sqlalchemy_utils.exceptions [assertion] + early skip of rewriting module: sqlalchemy_utils.expressions [assertion] + early skip of rewriting module: sqlalchemy.ext.compiler [assertion] + early skip of rewriting module: sqlalchemy_utils.generic [assertion] + early skip of rewriting module: sqlalchemy_utils.i18n [assertion] + early skip of rewriting module: babel [assertion] + early skip of rewriting module: sqlalchemy_utils.listeners [assertion] + early skip of rewriting module: sqlalchemy_utils.models [assertion] + early skip of rewriting module: sqlalchemy_utils.observer [assertion] + early skip of rewriting module: sqlalchemy_utils.path [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.country [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.currency [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.ltree [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.weekday [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.weekdays [assertion] + early skip of rewriting module: sqlalchemy_utils.proxy_dict [assertion] + early skip of rewriting module: sqlalchemy_utils.types [assertion] + early skip of rewriting module: sqlalchemy_utils.types.arrow [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.arrow_datetime [assertion] + early skip of rewriting module: arrow [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.pendulum_date [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.pendulum_datetime [assertion] + early skip of rewriting module: pendulum [assertion] + early skip of rewriting module: pendulum [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.enriched_datetime_type [assertion] + early skip of rewriting module: sqlalchemy_utils.types.scalar_coercible [assertion] + early skip of rewriting module: arrow [assertion] + early skip of rewriting module: sqlalchemy_utils.types.choice [assertion] + early skip of rewriting module: sqlalchemy_utils.types.color [assertion] + early skip of rewriting module: colour [assertion] + early skip of rewriting module: sqlalchemy_utils.types.country [assertion] + early skip of rewriting module: sqlalchemy_utils.types.currency [assertion] + early skip of rewriting module: sqlalchemy_utils.types.email [assertion] + early skip of rewriting module: sqlalchemy_utils.operators [assertion] + early skip of rewriting module: sqlalchemy_utils.types.encrypted [assertion] + early skip of rewriting module: sqlalchemy_utils.types.encrypted.encrypted_type [assertion] + early skip of rewriting module: sqlalchemy_utils.types.encrypted.padding [assertion] + early skip of rewriting module: sqlalchemy_utils.types.json [assertion] + early skip of rewriting module: anyjson [assertion] + early skip of rewriting module: cryptography [assertion] + early skip of rewriting module: dateutil [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.enriched_date_type [assertion] + early skip of rewriting module: sqlalchemy_utils.types.ip_address [assertion] + early skip of rewriting module: ipaddress [assertion] + early skip of rewriting module: sqlalchemy_utils.types.locale [assertion] + early skip of rewriting module: babel [assertion] + early skip of rewriting module: sqlalchemy_utils.types.ltree [assertion] + early skip of rewriting module: sqlalchemy_utils.types.password [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle.cx_oracle [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.json [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.pysqlcipher [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.pysqlite [assertion] + early skip of rewriting module: sqlalchemy.ext.mutable [assertion] + early skip of rewriting module: passlib [assertion] + early skip of rewriting module: sqlalchemy_utils.types.pg_composite [assertion] + early skip of rewriting module: psycopg2 [assertion] + early skip of rewriting module: sqlalchemy_utils.types.phone_number [assertion] + early skip of rewriting module: phonenumbers [assertion] + early skip of rewriting module: sqlalchemy_utils.types.range [assertion] + early skip of rewriting module: intervals [assertion] + early skip of rewriting module: sqlalchemy_utils.types.scalar_list [assertion] + early skip of rewriting module: sqlalchemy_utils.types.timezone [assertion] + early skip of rewriting module: sqlalchemy_utils.types.ts_vector [assertion] + early skip of rewriting module: sqlalchemy_utils.types.url [assertion] + early skip of rewriting module: furl [assertion] + early skip of rewriting module: sqlalchemy_utils.types.uuid [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.adodbapi [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.information_schema [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.mxodbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.pyodbc [assertion] + early skip of rewriting module: sqlalchemy.connectors.pyodbc [assertion] + early skip of rewriting module: sqlalchemy.connectors.mxodbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.pymssql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy_utils.types.weekdays [assertion] + early skip of rewriting module: sqlalchemy_utils.types.bit [assertion] + early skip of rewriting module: sqlalchemy_utils.view [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_alembic + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_alembic', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_alembic.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Alembic + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: NotEnoughSubstancesToMixException + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: UnknownProcessException + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_set_up_my_alembic + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_mix_multiple_substances_in_my_alembic + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_cannot_mix_one_substance_in_my_alembic + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_mixing_sulphur_salt_and_mercury_gives_gloop + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_mixing_other_recipes_gives_sludge + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_process_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_cannot_perform_unknown_process + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.domain.test_alembic_instruction_handler [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py [assertion] + early skip of rewriting module: magnumopus.services.alembic_instruction_handler [assertion] + early skip of rewriting module: injector [assertion] + early skip of rewriting module: magnumopus.repositories [assertion] + early skip of rewriting module: magnumopus.repositories.pantry [assertion] + early skip of rewriting module: magnumopus.repositories.list_pantry [assertion] + early skip of rewriting module: magnumopus.repositories.sqlalchemy_pantry [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_alembic_instruction_handler + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_alembic_instruction_handler', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_alembic_instruction_handler.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: AlembicInstruction + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: AlembicInstructionHandler + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: ListPantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: instruction_unknown + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: instruction + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_set_up_my_alembic_instruction_handler + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325040> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.domain.test_pantry [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_pantry + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_pantry', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_pantry.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: ListPantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: list_pantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pantries + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_add_to_pantry + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78063257f0> + pytest_make_parametrize_id [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + val: list + argname: pantry_type + finish pytest_make_parametrize_id --> None [hook] + early skip of rewriting module: encodings.unicode_escape [assertion] + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_retrieve_substance_from_pantry_by_nature + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325670> + pytest_make_parametrize_id [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + val: list + argname: pantry_type + finish pytest_make_parametrize_id --> None [hook] + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.domain.test_substance [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_substance + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_substance', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_substance.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_cook_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_wash_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_pickle_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_ferment_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_cook_and_ferment_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_the_order_of_processes_applied_to_a_substance_matters + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + pytest_collection_modifyitems [hook] + session: testsfailed=0 testscollected=0> + config: <_pytest.config.Config object at 0x7f78089fd5b0> + items: [, , , , , , , , , , , , , , , , , , , , ] + finish pytest_collection_modifyitems --> [] [hook] + pytest_collection_finish [hook] + session: testsfailed=0 testscollected=0> + pytest_report_collectionfinish [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + startdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii + items: [, , , , , , , , , , , , , , , , , , , , ] + finish pytest_report_collectionfinish --> [] [hook] + finish pytest_collection_finish --> [] [hook] + finish pytest_collection --> [, , , , , , , , , , , , , , , , , , , , ] [hook] + pytest_runtestloop [hook] + session: testsfailed=0 testscollected=21> + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_mix_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 16, 'test_create_alembic_mix_instruction') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + early skip of rewriting module: magnumopus.resources [assertion] + early skip of rewriting module: magnumopus.resources.substance [assertion] + early skip of rewriting module: magnumopus.injection [assertion] + early skip of rewriting module: magnumopus.schemas [assertion] + early skip of rewriting module: flask_marshmallow [assertion] + early skip of rewriting module: distutils [assertion] + early skip of rewriting module: distutils.version [assertion] + early skip of rewriting module: marshmallow [assertion] + early skip of rewriting module: marshmallow.schema [assertion] + early skip of rewriting module: marshmallow.base [assertion] + early skip of rewriting module: marshmallow.fields [assertion] + early skip of rewriting module: marshmallow.validate [assertion] + early skip of rewriting module: marshmallow.types [assertion] + early skip of rewriting module: marshmallow.exceptions [assertion] + early skip of rewriting module: marshmallow.utils [assertion] + early skip of rewriting module: marshmallow.class_registry [assertion] + early skip of rewriting module: marshmallow.error_store [assertion] + early skip of rewriting module: marshmallow.orderedset [assertion] + early skip of rewriting module: marshmallow.decorators [assertion] + early skip of rewriting module: flask_marshmallow.fields [assertion] + early skip of rewriting module: flask_marshmallow.schema [assertion] + early skip of rewriting module: flask_marshmallow.compat [assertion] + early skip of rewriting module: flask_marshmallow.sqla [assertion] + early skip of rewriting module: six.moves.urllib [assertion] + early skip of rewriting module: marshmallow_sqlalchemy [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.model_schema [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.convert [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.reflection [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.enumerated [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.types [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.json [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.cymysql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.mysqldb [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.gaerdbms [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.mysqlconnector [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.oursql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.pymysql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.pyodbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.dml [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.exceptions [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.fields [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.schema_meta [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.load_instance_mixin [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.table_schema [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.sqlalchemy_schema [assertion] + early skip of rewriting module: magnumopus.schemas.substance_schema [assertion] + early skip of rewriting module: magnumopus.services.assessor [assertion] + early skip of rewriting module: magnumopus.resources.alembic_instruction [assertion] + early skip of rewriting module: magnumopus.logger [assertion] + early skip of rewriting module: magnumopus.config [assertion] + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + pytest_assertrepr_compare [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + op: == + left: 500 + right: 201 + finish pytest_assertrepr_compare --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: > + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_exception_interact [hook] + node: + call: > + report: + finish pytest_exception_interact --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_mix_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 16, 'test_create_alembic_mix_instruction') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_process_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 34, 'test_create_alembic_process_instruction') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + pytest_assertrepr_compare [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + op: == + left: 500 + right: 201 + finish pytest_assertrepr_compare --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: > + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_exception_interact [hook] + node: + call: > + report: + finish pytest_exception_interact --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_process_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 34, 'test_create_alembic_process_instruction') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_philosophers_stone.py::test_create_philosophers_stone + location: ('tests/application/test_philosophers_stone.py', 5, 'test_create_philosophers_stone') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_philosophers_stone.py::test_create_philosophers_stone + location: ('tests/application/test_philosophers_stone.py', 5, 'test_create_philosophers_stone') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_substance_resource.py::test_create_substance + location: ('tests/application/test_substance_resource.py', 12, 'test_create_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_substance_resource.py::test_create_substance + location: ('tests/application/test_substance_resource.py', 12, 'test_create_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_substance_resource.py::test_get_substances + location: ('tests/application/test_substance_resource.py', 29, 'test_get_substances') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + pytest_assertrepr_compare [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + op: is + left: + right: + finish pytest_assertrepr_compare --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: is list\n + where = type(None)") tblen=31>> + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_exception_interact [hook] + node: + call: is list\n + where = type(None)") tblen=1>> + report: + finish pytest_exception_interact --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_substance_resource.py::test_get_substances + location: ('tests/application/test_substance_resource.py', 29, 'test_get_substances') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_can_set_up_my_alembic + location: ('tests/domain/test_alembic.py', 5, 'test_can_set_up_my_alembic') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_can_set_up_my_alembic + location: ('tests/domain/test_alembic.py', 5, 'test_can_set_up_my_alembic') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_can_mix_multiple_substances_in_my_alembic + location: ('tests/domain/test_alembic.py', 8, 'test_can_mix_multiple_substances_in_my_alembic') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_can_mix_multiple_substances_in_my_alembic + location: ('tests/domain/test_alembic.py', 8, 'test_can_mix_multiple_substances_in_my_alembic') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_mix_one_substance_in_my_alembic + location: ('tests/domain/test_alembic.py', 16, 'test_cannot_mix_one_substance_in_my_alembic') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_mix_one_substance_in_my_alembic + location: ('tests/domain/test_alembic.py', 16, 'test_cannot_mix_one_substance_in_my_alembic') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_sulphur_salt_and_mercury_gives_gloop + location: ('tests/domain/test_alembic.py', 23, 'test_mixing_sulphur_salt_and_mercury_gives_gloop') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_sulphur_salt_and_mercury_gives_gloop + location: ('tests/domain/test_alembic.py', 23, 'test_mixing_sulphur_salt_and_mercury_gives_gloop') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_other_recipes_gives_sludge + location: ('tests/domain/test_alembic.py', 38, 'test_mixing_other_recipes_gives_sludge') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_other_recipes_gives_sludge + location: ('tests/domain/test_alembic.py', 38, 'test_mixing_other_recipes_gives_sludge') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_can_process_substance + location: ('tests/domain/test_alembic.py', 58, 'test_can_process_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_can_process_substance + location: ('tests/domain/test_alembic.py', 58, 'test_can_process_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_perform_unknown_process + location: ('tests/domain/test_alembic.py', 74, 'test_cannot_perform_unknown_process') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_perform_unknown_process + location: ('tests/domain/test_alembic.py', 74, 'test_cannot_perform_unknown_process') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic_instruction_handler.py::test_can_set_up_my_alembic_instruction_handler + location: ('tests/domain/test_alembic_instruction_handler.py', 34, 'test_can_set_up_my_alembic_instruction_handler') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> AlembicInstruction(instruction_type='process', natures=['Sludge'], action='cook') [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic_instruction_handler.py::test_can_set_up_my_alembic_instruction_handler + location: ('tests/domain/test_alembic_instruction_handler.py', 34, 'test_can_set_up_my_alembic_instruction_handler') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_pantry.py::test_can_add_to_pantry[list] + location: ('tests/domain/test_pantry.py', 17, 'test_can_add_to_pantry[list]') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> list [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + list: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_pantry.py::test_can_add_to_pantry[list] + location: ('tests/domain/test_pantry.py', 17, 'test_can_add_to_pantry[list]') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_pantry.py::test_can_retrieve_substance_from_pantry_by_nature[list] + location: ('tests/domain/test_pantry.py', 27, 'test_can_retrieve_substance_from_pantry_by_nature[list]') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> list [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + list: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_pantry.py::test_can_retrieve_substance_from_pantry_by_nature[list] + location: ('tests/domain/test_pantry.py', 27, 'test_can_retrieve_substance_from_pantry_by_nature[list]') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_substance + location: ('tests/domain/test_substance.py', 2, 'test_can_cook_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_substance + location: ('tests/domain/test_substance.py', 2, 'test_can_cook_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_wash_substance + location: ('tests/domain/test_substance.py', 9, 'test_can_wash_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_wash_substance + location: ('tests/domain/test_substance.py', 9, 'test_can_wash_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_pickle_substance + location: ('tests/domain/test_substance.py', 16, 'test_can_pickle_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_pickle_substance + location: ('tests/domain/test_substance.py', 16, 'test_can_pickle_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_ferment_substance + location: ('tests/domain/test_substance.py', 23, 'test_can_ferment_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_ferment_substance + location: ('tests/domain/test_substance.py', 23, 'test_can_ferment_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_and_ferment_substance + location: ('tests/domain/test_substance.py', 30, 'test_can_cook_and_ferment_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_and_ferment_substance + location: ('tests/domain/test_substance.py', 30, 'test_can_cook_and_ferment_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: None + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_the_order_of_processes_applied_to_a_substance_matters + location: ('tests/domain/test_substance.py', 38, 'test_the_order_of_processes_applied_to_a_substance_matters') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: None + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_the_order_of_processes_applied_to_a_substance_matters + location: ('tests/domain/test_substance.py', 38, 'test_the_order_of_processes_applied_to_a_substance_matters') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + finish pytest_runtestloop --> True [hook] + pytest_sessionfinish [hook] + session: testsfailed=3 testscollected=21> + exitstatus: ExitCode.TESTS_FAILED + pytest_terminal_summary [hook] + terminalreporter: <_pytest.terminal.TerminalReporter object at 0x7f780666aee0> + exitstatus: ExitCode.TESTS_FAILED + config: <_pytest.config.Config object at 0x7f78089fd5b0> + early skip of rewriting module: pygments [assertion] + early skip of rewriting module: pygments [assertion] + early skip of rewriting module: pygments [assertion] + early skip of rewriting module: wcwidth [assertion] + early skip of rewriting module: wcwidth.wcwidth [assertion] + early skip of rewriting module: wcwidth.table_wide [assertion] + early skip of rewriting module: wcwidth.table_zero [assertion] + early skip of rewriting module: wcwidth.unicode_versions [assertion] + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_terminal_summary --> [] [hook] + finish pytest_sessionfinish --> [] [hook] + pytest_unconfigure [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_unconfigure --> [] [hook] diff --git a/022-burette/magnum_opus_ii/requirements.txt b/022-burette/magnum_opus_ii/requirements.txt new file mode 100644 index 0000000..0104ae5 --- /dev/null +++ b/022-burette/magnum_opus_ii/requirements.txt @@ -0,0 +1,9 @@ +appdirs +quart +wheel +quart-openapi +flask-marshmallow +flask-sqlalchemy +flask-injector +marshmallow-sqlalchemy +sqlalchemy-utils diff --git a/022-burette/magnum_opus_ii/setup.cfg b/022-burette/magnum_opus_ii/setup.cfg new file mode 100644 index 0000000..74b608f --- /dev/null +++ b/022-burette/magnum_opus_ii/setup.cfg @@ -0,0 +1,34 @@ +[metadata] +name = aiomagnumopus +version = 0.0.1 +author = Phil Weir +author_email = phil.weir@flaxandteal.co.uk +license = GPL +description = Service for cooking up a philosopher's stone +long-description = file:README.md + +[options] +include_package_data = True +packages = find: +python_requires = >=3.6 +install_requires = + appdirs + quart-openapi + flask-marshmallow + flask-sqlalchemy + flask-injector + sqlalchemy-utils + marshmallow-sqlalchemy + quart-openapi + wheel + +[options.extras_require] +dev = + pytest + pytest-pep8 + pytest-cov + pytest-asyncio + +[options.packages.find] +exclude = + tests diff --git a/022-burette/magnum_opus_ii/setup.py b/022-burette/magnum_opus_ii/setup.py new file mode 100644 index 0000000..1767837 --- /dev/null +++ b/022-burette/magnum_opus_ii/setup.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Magnum Opus + +This tool performs alchemical reactions to create +the Philosopher's Stone. + +@author: Phil Weir +""" + +from setuptools import setup + +if __name__ == '__main__': + setup() diff --git a/022-burette/magnum_opus_ii/tests/__init__.py b/022-burette/magnum_opus_ii/tests/__init__.py new file mode 100644 index 0000000..c09f99d --- /dev/null +++ b/022-burette/magnum_opus_ii/tests/__init__.py @@ -0,0 +1,4 @@ + +def is_dictionary_inside(d1, d2): + return d1.items() <= d2.items() + diff --git a/022-burette/magnum_opus_ii/tests/application/.coverage b/022-burette/magnum_opus_ii/tests/application/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..0e5750b04d16c86d92dbe9e012e32b8f135b4fbd GIT binary patch literal 53248 zcmeI4O^h5z6@a^^d#2}iYwh*!%B(i-3mUJyv$MPACzwMp_8x*QL5zcgEYsJ5_bF@g&h4&X=}$R(F>fJnJ;2@oWHgOIq81Cc;NNGKe5uYYEG>|GNH zdJ=D5Yo?}us_NDI-m9v4{rAOZt{Og9Hyzi~ef7LBEr_D<8C4Yop#==1-p%55Df}EtC7M-sWzU)-GM!xOja-y?*htS2xsXpL({e!qRA{7gg8UReRi3 zHw}}khTSpRx^LK9s^8^F?!L!6IOD-SnDa2>N?0D(G@}Ehe7*%$^jyQz-FDknGx^uP$%7O!>2N) z4eS`H^7JND)OOqsw!Y=+cDu{HWmO+)*mj_udw!&?>sU?SQBA`R)wDgsHym5#d%WHE zdFN0Cml0aB0KBv|P}lRQ(DPBrSXPS8sPG{rE%j&4)a;S#wEUTyl zc)&+1h51j-hyr*e-}81%_~WJNecuVUH88%m21)gsCyL7anKRHF$!*jQ+T z+A^KixUYpC<8kO9Fcu`)Hv4uPyNZW8w4DKW^)0>D7I7*#3pSBjS6az(8=4WTcAnFk~F5x#nrUdR8b%6&ag7@D1p6++mhue<3q2cv> zVgA#zM>QOqpsitAc;Q+uZ1P^z39o|0Hu{EfNO-bey9Nn)&UrV|btXP(Acj9RZXWyt+81k`C zqMT^#fP!ir`l1It^MN{(O5>wAP$l)R^Z*6cYU!P*m!mCGHSTu#L)Ar-&}H4{zF~0{ zvxJQa{b^VC)V9mvAWWf4b?H&oMwC==ZV#HK(TcO5UwN_#xBKx%Pj7F-%}XBc z=bqoxGz)}i8r&99Usmf4sCR%XQC(P7{Z<)lDzi5Q_9puWdz<~~!(?L8l?V_4B0vO) z01+SpM1Tko0U|&Ih`{4Zpeikj$$1O8D9ws^+Cr*G3u1hZB3F?XOUda8y#7Cz|AWBp zu`^RYnz~&3b#1#QR$r_xR_<38%lFIcrB_Rria#x0QQlBKSNKKYImk>45g-CYfCzk$ z3EY{Jh2YNr{p|DT>~YiOJqOM_JFWpIolV2@wVrPK?mnDw9?XL9orwt_%H2B!a{CjL zt7&i+-w#i*2jYw@94HeL4G)m(CO${FKcar;WY#8+o-6d4Uccq}@J<3AKfDMg_fCND z?JV_Agr}(s(?C6+rBs)Da6Jaz=Frql4$qdi!RDUt_QS`VjuP`tqaden;cu> zmnWuw%Ei1=)~2?c4mVSy38-onL8z7`a~!e_-88<+L0ne>anEKe4qo>Gl8gdKx{;+M zcwfS%u?3>cJczoLr6|L`&65Gpkh50IbhhAyJfN5@fhavo#bS?a=^lEAn*({q1mvZ9 z-L?oaZ)PboB@D0s&*k3|*tcqCEmyr)`_0q_Q>R|8K2i8({;k57l`Eyo#n(zdE?!lB zUU{i}zVbx*r4RC-UTPZ=AOb{y2nfR0H@F?#n@ca&l8M z>8T(mA1IR(eOUZIlex*05PTRBj^h85z8q|4s(&IpMg2q|$_M#OrT(}0e|jJX&V*W! z(wt48haDFGPi1fBVJIHO#PC17)|Ue-Q^tqI|J9%?7m<%H;GXdwbbfCvx)B0vO)01+SpM1Tko0U|&Ijv)a_s+I8izr@}a*uU7{;D;6> zKm>>Y5g-CYfCvx)B0vO)01+SpMBp(dP>^J?G$oal9Q;n_=ES@xmr7G*y#6n-cLeq> zy#N25$5=sXIuRfOM1Tko0U|&IhyW2F0z`la5CI|(5hy_HFG^DQlgr6)0wBEpFH934 zB0vO)01+SpM1Tko0U|&IhyW2F0z}|A6Ts{L6#pM*3zKd{fCvx)B0vO)01+SpM1Tko z0U|&I1OcD_pJOlL{r~@De`kMXe_?-Se`LR9zhZB&pRw23PuQ#M74|awA^QRQ9{Vo) z4rHc<2oM1xKm>>Y5g-CYfCvx)B0vO)01@~f2}pDBT7GF3lT( Date: Sun, 28 Jun 2020 02:22:39 +0100 Subject: [PATCH 11/12] add graphql intro --- 022-burette/magnum_opus_iii/.coverage | Bin 0 -> 53248 bytes 022-burette/magnum_opus_iii/.gitignore | 5 + 022-burette/magnum_opus_iii/Dockerfile | 24 + 022-burette/magnum_opus_iii/MANIFEST.in | 1 + 022-burette/magnum_opus_iii/README.md | 46 + 022-burette/magnum_opus_iii/RULES.md | 9 + .../magnum_opus_iii/docker-compose.yml | 11 + .../magnum_opus_iii/docker/storage/storage.db | Bin 0 -> 8192 bytes .../magnum_opus_iii/gunicorn_config.py | 5 + .../magnum_opus_iii/init_containers.sh | 6 + .../magnum_opus_iii/init_entrypoint.sh | 3 + .../magnum_opus_iii/magnumopus/__init__.py | 23 + .../magnum_opus_iii/magnumopus/config.py | 7 + .../magnum_opus_iii/magnumopus/graph.py | 57 + .../magnum_opus_iii/magnumopus/index.py | 3 + .../magnum_opus_iii/magnumopus/initialize.py | 9 + .../magnum_opus_iii/magnumopus/injection.py | 26 + .../magnum_opus_iii/magnumopus/logger.py | 6 + .../magnumopus/models/__init__.py | 11 + .../magnum_opus_iii/magnumopus/models/base.py | 3 + .../magnumopus/models/substance.py | 40 + .../magnumopus/repositories/__init__.py | 18 + .../magnumopus/repositories/list_pantry.py | 26 + .../magnumopus/repositories/pantry.py | 25 + .../repositories/sqlalchemy_pantry.py | 31 + .../magnumopus/resources/__init__.py | 7 + .../resources/alembic_instruction.py | 57 + .../magnumopus/resources/substance.py | 49 + .../magnumopus/schemas/__init__.py | 22 + .../magnumopus/schemas/substance_schema.py | 19 + .../magnumopus/services/__init__.py | 9 + .../magnumopus/services/alembic.py | 51 + .../services/alembic_instruction_handler.py | 36 + .../magnumopus/services/assessor.py | 2 + 022-burette/magnum_opus_iii/pytestdebug.log | 4688 +++++++++++++++++ 022-burette/magnum_opus_iii/requirements.txt | 10 + 022-burette/magnum_opus_iii/setup.cfg | 35 + 022-burette/magnum_opus_iii/setup.py | 14 + 022-burette/magnum_opus_iii/tests/__init__.py | 4 + .../tests/application/.coverage | Bin 0 -> 53248 bytes .../tests/application/__init__.py | 0 .../test_alembic_instruction_resource.py | 49 + .../application/test_philosophers_stone.py | 7 + .../application/test_substance_resource.py | 52 + 022-burette/magnum_opus_iii/tests/conftest.py | 19 + .../magnum_opus_iii/tests/domain/__init__.py | 0 .../tests/domain/test_alembic.py | 81 + .../test_alembic_instruction_handler.py | 37 + .../tests/domain/test_pantry.py | 38 + .../tests/domain/test_substance.py | 49 + 022-burette/magnum_opus_iii/tox.ini | 6 + 51 files changed, 5736 insertions(+) create mode 100644 022-burette/magnum_opus_iii/.coverage create mode 100644 022-burette/magnum_opus_iii/.gitignore create mode 100644 022-burette/magnum_opus_iii/Dockerfile create mode 100644 022-burette/magnum_opus_iii/MANIFEST.in create mode 100644 022-burette/magnum_opus_iii/README.md create mode 100644 022-burette/magnum_opus_iii/RULES.md create mode 100644 022-burette/magnum_opus_iii/docker-compose.yml create mode 100644 022-burette/magnum_opus_iii/docker/storage/storage.db create mode 100644 022-burette/magnum_opus_iii/gunicorn_config.py create mode 100755 022-burette/magnum_opus_iii/init_containers.sh create mode 100755 022-burette/magnum_opus_iii/init_entrypoint.sh create mode 100644 022-burette/magnum_opus_iii/magnumopus/__init__.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/config.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/graph.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/index.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/initialize.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/injection.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/logger.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/models/__init__.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/models/base.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/models/substance.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/repositories/__init__.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/repositories/list_pantry.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/repositories/pantry.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/repositories/sqlalchemy_pantry.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/resources/__init__.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/resources/alembic_instruction.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/resources/substance.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/schemas/__init__.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/schemas/substance_schema.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/services/__init__.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/services/alembic.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/services/alembic_instruction_handler.py create mode 100644 022-burette/magnum_opus_iii/magnumopus/services/assessor.py create mode 100644 022-burette/magnum_opus_iii/pytestdebug.log create mode 100644 022-burette/magnum_opus_iii/requirements.txt create mode 100644 022-burette/magnum_opus_iii/setup.cfg create mode 100644 022-burette/magnum_opus_iii/setup.py create mode 100644 022-burette/magnum_opus_iii/tests/__init__.py create mode 100644 022-burette/magnum_opus_iii/tests/application/.coverage create mode 100644 022-burette/magnum_opus_iii/tests/application/__init__.py create mode 100644 022-burette/magnum_opus_iii/tests/application/test_alembic_instruction_resource.py create mode 100644 022-burette/magnum_opus_iii/tests/application/test_philosophers_stone.py create mode 100644 022-burette/magnum_opus_iii/tests/application/test_substance_resource.py create mode 100644 022-burette/magnum_opus_iii/tests/conftest.py create mode 100644 022-burette/magnum_opus_iii/tests/domain/__init__.py create mode 100644 022-burette/magnum_opus_iii/tests/domain/test_alembic.py create mode 100644 022-burette/magnum_opus_iii/tests/domain/test_alembic_instruction_handler.py create mode 100644 022-burette/magnum_opus_iii/tests/domain/test_pantry.py create mode 100644 022-burette/magnum_opus_iii/tests/domain/test_substance.py create mode 100644 022-burette/magnum_opus_iii/tox.ini diff --git a/022-burette/magnum_opus_iii/.coverage b/022-burette/magnum_opus_iii/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..acffb036006a2fd0428756bfafc1028b3539f7f7 GIT binary patch literal 53248 zcmeI4TWlOx8GvVYW@mQxcGg~Bl%~NWB;;7Jy|Kfk4M-sbKeP#I8`1`mhRy8y*q(TI z#+jL2+f4%+w^AOs2(<`Q-~l9{4@k5RG(r&)541?|fFJ<`Z9^qMln01Zgt({(@&9x2 zjuShI1miZzKiWO#%*;9GKmYgt=ggeBee|ItrpNU;+i4q~zE7wKq9}Y&*9Ae);9r7& zyr__n;}wX-M0%^FCQKgqO^H1s6qPRu>=UJrv5De0OSQtw#jf^r;aT;x)`A_h5CI}U z1c(3;2nhHO71iM#JH)kfp3!J=&oP?Z3B%H%qcaDO&FIGte(1=I9&Xcj=XF>nCiH{4 zV=wDV+|lRE7S~N{)@&M{Y0c~20*`ZdTt16OJlF=uJj^&5l*d%voP|;zpNA@z9J6gW ztNJ2e9S<@@(mcN6g&Uv}Zq8enL*E@0AJZK^#~p4pxf`}(w>dkOAA90cd3Cs270>fP zC&OvNudqQI*w9nuzB#C&Ci}Ro1g3WpCOxo7l3a?*?F{;qkL$gX z&>JngvC-E8k8wG45Eu*MY;zr}iCx7-9h!ERJH|YpjP{1Z!dvY~;5t*9 zGCVV~mFuj#Kz(XGnfG@n>hR8;;+ht?QDm(sQa89zY{^ZA(Rf#z8*aym2a+2Nl5vUN zC>i&WXb-3}p(?`%cW$Lll&?M&C33zhtHXnXq967M9GCE)-Jk?+>2-l?4g@#f{3XL% z(64VhZia@BW|iUh4{p_PY(jksL*5h%#M05Pki@=s>RycNOcH?~VpdiH|8bx*vnS7I!O1wA+R? z8y%+b=o{7wLq7INloO5}P*5L*zUV^Fyr#~$(r7OZRB`>2OMn7vZ5y*;FGpJ>YFu96 z*HsrDgg$I|+%wx;$1Fi(0)JXIT)pXV*a?Twu~F$p)<+}Nr!d4>at=>q{1H(d-m^#a zJ5e7DhnKnw$MUujH#=I*Z19b1cJ|!l0T^fDBq!+}$S#2cS3?OnriB)4gcRaj(J4-T z3@7*^dsBcPEku9_5CI}U1c(3;AOb{y2oM1xKm>@u?MFZoGop&~f0^wN*im+fjY5JJ zB0vO)01+SpM1Tko0U|&IhyW2F0(TODqAcxV@uLxY?~Yn}6)9@>0q@C61#`=3Er~Eylyld@n{6xfw(b|ID=C!2-v*j&w)2SV|oyFQQ$1p8; zvaj~ws<&WUhwP5yLZ)D4q8YC3ot~a(z(Y5l$7^k49-c|6+e;m{Hp#7Stz|Z%?E5C~ zslnrZd}7IHF2ci0E^grCnlt-9pYugCbtGkP6aHF}g;P zDM-7t`0@na{~yY}BCw~~Ncp+)y`>jR4-{W29xhxiJd(eZKcW3zvvP0b&Z_@ZKdX)? z-&O91%(M^zB0vO)z}uNXdq@`i`v3jvbMNYL4X$8&rqMDV<8X<2VGzVUoUS-{ZyF?- z10d;mnv&qf(>ZeSUUtOzSicUO-00`qNgdWzWNx4M3DH^vS|nHcibO?!tWx z_zFVJXmNNayID6a*K<0twq6CaZKv4+mpffEXn^Z-*R@gcvkau3O;u{}a;IB!I}O)^ z&o=Pr{Z0_>mO=R9b_lNnY|{(w{d7wp^h}yUdzN0;8I=euH2G?M$*??U6`d@fwv#zL(S(-idOhJ?Eq!|@gs&^Tk^{M&ZR4Ia zxvGN6t7(ev4JFr)W%UJkr@a*ntF8hJQtjYvdzQBngA0x-*|ddTt33$yWDvSNqj$p6 zmIP9bGz}f`Z5S?|)HoTCXKsVMgpP|M$UKpz%!Dw!|38#{RbXFGUQiBaUsZMWb4)Kk zUwW{3q;S0Oi~QyMqw2r3KWKLDujT!vmx@2iJ^pq+>7}+20U|&Ih=3qivR@a|JdSLb z{|}k6|8UCU!ukK;Y1u!Xs-*S#|3F*zPo^p=IsdPwuGsqgzuy<-wQQ=I^=5^e&;R>6 zvfoa%1-;YO-u%Dvxa^-zSL)XDf9A>l;dCt$tYt>Xm_lA-i&i~ca zJNPE^e01+SpM1Tko0U|&I zhyW2F0z`la+=c`ssifik{{i-Hf&GJBWq)M9Wj|vtvhT6)uy3%hu+OveY=v2DmOaWo z!e-b9AR{eAfCvx)B0vO)01+SpM1Tko0U|&I?hpdXfGld|fs1Mt;!5>mPU*)D{g0LU zAilfrlj=K>grZb%b0w2w5cjjwuPeDSrpmu+zoS&btfl`5cUOdra7r!0YNdEp(h86m zC|ppN3u+#><*gGr4HEs@m!H{@%V8>awI$_MNDZkM&K>w=F0Wu(xp1ZPic-u%`mXHD zpSd#gTpf16T3NndkuZir8Hg*HuBwW%ruBdP(s8{1Kft;IdlSC@{};Fd@EZFy`#Jjw z`yu;2djYNkJj=euo?%b1PqQc4Imk#05g-CYfCvx)B0vO)01+SpM1Tko0U~gd1aQJG z4h#fQwHieI{Xx{%7etjx5HS`+<#G^}N>Y5g-CYfCvzQTap0Y|EKx? zEonMxG!Y;IM1Tko0U|&IhyW2F0z`la5P_Q}fbahgv8V9)|G%?0*q_g!( zq#^h$zch%!00vbI`Z4Ikpn?Izpo~EYgCYh64DuLg800WeF;FnbVjyE6VUWQ9zyJSV D&<%nw literal 0 HcmV?d00001 diff --git a/022-burette/magnum_opus_iii/.gitignore b/022-burette/magnum_opus_iii/.gitignore new file mode 100644 index 0000000..1069b36 --- /dev/null +++ b/022-burette/magnum_opus_iii/.gitignore @@ -0,0 +1,5 @@ +*.egg-info +.tox +Pipfile +.env +.nenv diff --git a/022-burette/magnum_opus_iii/Dockerfile b/022-burette/magnum_opus_iii/Dockerfile new file mode 100644 index 0000000..0c7c8cf --- /dev/null +++ b/022-burette/magnum_opus_iii/Dockerfile @@ -0,0 +1,24 @@ +FROM python:3-alpine + +RUN addgroup -S user && adduser user -S -G user + +WORKDIR /home/user/ + +COPY requirements.txt . +COPY gunicorn_config.py . +COPY setup.py . +COPY setup.cfg . +COPY init_entrypoint.sh / + +RUN pip install hypercorn +RUN pip install -r requirements.txt + +USER user + +EXPOSE 5000 + +ENTRYPOINT [] + +CMD hypercorn --config python:./gunicorn_config.py magnumopus.index:app + +COPY magnumopus magnumopus diff --git a/022-burette/magnum_opus_iii/MANIFEST.in b/022-burette/magnum_opus_iii/MANIFEST.in new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/022-burette/magnum_opus_iii/MANIFEST.in @@ -0,0 +1 @@ + diff --git a/022-burette/magnum_opus_iii/README.md b/022-burette/magnum_opus_iii/README.md new file mode 100644 index 0000000..94ce180 --- /dev/null +++ b/022-burette/magnum_opus_iii/README.md @@ -0,0 +1,46 @@ +Magnum Opus +=========== + +Recipe maker for the philosopher's stone. + + + python3 -m pytest --cov magnumopus >> README.md + + ============================= test session starts ============================== + platform linux -- Python 3.8.2, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 + rootdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus + plugins: pep8-1.0.6, cov-2.10.0 + collected 15 items + + tests/domain/test_alembic.py ....... [ 46%] + tests/domain/test_pantry.py .. [ 60%] + tests/domain/test_substance.py ...... [100%] + + ----------- coverage: platform linux, python 3.8.2-final-0 ----------- + Name Stmts Miss Cover + ------------------------------------------------------------------------ + magnumopus/__init__.py 10 8 20% + magnumopus/config.py 4 4 0% + magnumopus/index.py 2 2 0% + magnumopus/initialize.py 6 6 0% + magnumopus/logger.py 4 4 0% + magnumopus/models/__init__.py 3 1 67% + magnumopus/models/base.py 2 0 100% + magnumopus/models/substance.py 24 0 100% + magnumopus/repositories/__init__.py 0 0 100% + magnumopus/repositories/pantry.py 12 1 92% + magnumopus/repositories/sqlalchemy_pantry.py 15 15 0% + magnumopus/resources/__init__.py 7 7 0% + magnumopus/resources/alembic_instruction.py 26 26 0% + magnumopus/resources/substance.py 28 28 0% + magnumopus/schemas/__init__.py 4 4 0% + magnumopus/schemas/substance_schema.py 11 11 0% + magnumopus/services/__init__.py 0 0 100% + magnumopus/services/alembic.py 32 2 94% + magnumopus/services/alembic_instruction_handler.py 20 20 0% + magnumopus/services/assessor.py 2 2 0% + ------------------------------------------------------------------------ + TOTAL 212 141 33% + + + ============================== 15 passed in 0.38s ============================== diff --git a/022-burette/magnum_opus_iii/RULES.md b/022-burette/magnum_opus_iii/RULES.md new file mode 100644 index 0000000..4438311 --- /dev/null +++ b/022-burette/magnum_opus_iii/RULES.md @@ -0,0 +1,9 @@ +* One unit of each of the substances Mercury, Salt and Sulphur are mixed, using my "Alembic" (mixing pot), giving one unit of another substance, Gloop +* Any attempt to mix anything other than those three substances, gives Sludge, another substance +* Substances can undergo several Processes in my Alembic - they can be Cooked, Washed, Pickled or Fermented +* If Gloop is Cooked, Washed, Pickled and Fermented, in that order, it is the Philosopher's Stone (panacea and cure of all ills) +[* To process a Substance, at least one unit must be in my Pantry, including Gloop - even when freshly processed/created, it must be stored there before re-use (to cool)] + +Final rule: +GROUP 1: When I process a substance, using any process, it becomes a different substance +GROUP 2: When I process a substance, its state changes but is essentially the same substance (NB: mixing is not a process) diff --git a/022-burette/magnum_opus_iii/docker-compose.yml b/022-burette/magnum_opus_iii/docker-compose.yml new file mode 100644 index 0000000..8dd5ffa --- /dev/null +++ b/022-burette/magnum_opus_iii/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3" +services: + web_async_gql: + build: . + environment: + DATABASE_URI: 'sqlite:////docker/storage/storage.db' + volumes: + - ./docker:/docker + - ./magnumopus:/home/user/magnumopus + ports: + - 5000:5000 diff --git a/022-burette/magnum_opus_iii/docker/storage/storage.db b/022-burette/magnum_opus_iii/docker/storage/storage.db new file mode 100644 index 0000000000000000000000000000000000000000..41e4173e74b7ef47d0eaff4eba95ac3eb2ab418f GIT binary patch literal 8192 zcmeI#zfZzI6bJA-tU}u~=R$~ad2A&y4l=q}$pwj}YFmvA4h5=`R3PO#IP&+n`wuw# z5BLYT8~*{X1A)!a!SBmm?!9+EhR=4 + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_configure [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.LFPlugin object at 0x7f780666a820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.NFPlugin object at 0x7f780666a9a0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + early skip of rewriting module: faulthandler [assertion] + pytest_configure [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_configure --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.faulthandler.FaultHandlerHooks object at 0x7f780666aa60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.stepwise.StepwisePlugin object at 0x7f780666ab80> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + early skip of rewriting module: pdb [assertion] + early skip of rewriting module: cmd [assertion] + pytest_plugin_registered [hook] + plugin: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.config.Config object at 0x7f78089fd5b0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: > err=> in_=> _state='suspended' _in_suspended=False> _capture_fixture=None> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: testsfailed=0 testscollected=0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.LFPlugin object at 0x7f780666a820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.NFPlugin object at 0x7f780666a9a0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.faulthandler.FaultHandlerHooks object at 0x7f780666aa60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.stepwise.StepwisePlugin object at 0x7f780666ab80> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.terminal.TerminalReporter object at 0x7f780666aee0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.logging.LoggingPlugin object at 0x7f7806694820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + finish pytest_configure --> [] [hook] + pytest_sessionstart [hook] + session: testsfailed=0 testscollected=0> + pytest_plugin_registered [hook] + plugin: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.config.Config object at 0x7f78089fd5b0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: > err=> in_=> _state='suspended' _in_suspended=False> _capture_fixture=None> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: testsfailed=0 testscollected=0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.LFPlugin object at 0x7f780666a820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.cacheprovider.NFPlugin object at 0x7f780666a9a0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.faulthandler.FaultHandlerHooks object at 0x7f780666aa60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.stepwise.StepwisePlugin object at 0x7f780666ab80> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.terminal.TerminalReporter object at 0x7f780666aee0> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.logging.LoggingPlugin object at 0x7f7806694820> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_plugin_registered [hook] + plugin: <_pytest.fixtures.FixtureManager object at 0x7f7806694a60> + manager: <_pytest.config.PytestPluginManager object at 0x7f78091f69d0> + finish pytest_plugin_registered --> [] [hook] + pytest_report_header [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + startdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii + finish pytest_report_header --> [['rootdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii', 'plugins: pep8-1.0.6, asyncio-0.14.0, cov-2.10.0'], ['using: pytest-5.4.3 pylib-1.9.0', 'setuptools registered plugins:', ' pytest-pep8-1.0.6 at /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env/lib/python3.8/site-packages/pytest_pep8.py', ' pytest-asyncio-0.14.0 at /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env/lib/python3.8/site-packages/pytest_asyncio/plugin.py', ' pytest-cov-2.10.0 at /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env/lib/python3.8/site-packages/pytest_cov/plugin.py']] [hook] + finish pytest_sessionstart --> [] [hook] + pytest_collection [hook] + session: testsfailed=0 testscollected=0> + perform_collect testsfailed=0 testscollected=0> ['/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii'] [collection] + pytest_collectstart [hook] + collector: testsfailed=0 testscollected=0> + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: testsfailed=0 testscollected=0> + processing argument (local('/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii'), []) [collection] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + early skip of rewriting module: py._code [assertion] + early skip of rewriting module: py._code.code [assertion] + early skip of rewriting module: repr [assertion] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.pytest_cache + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.env + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> True [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.tox + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.coverage + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.coverage + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.gitignore + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/.gitignore + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/Dockerfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/Dockerfile + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/MANIFEST.in + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/MANIFEST.in + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/README.md + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/README.md + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/RULES.md + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/RULES.md + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker-compose.yml + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker-compose.yml + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/gunicorn_config.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/gunicorn_config.py + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_containers.sh + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_containers.sh + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_entrypoint.sh + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/init_entrypoint.sh + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/pytestdebug.log + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/pytestdebug.log + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/requirements.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/requirements.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.cfg + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.cfg + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/setup.py + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tox.ini + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tox.ini + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/PKG-INFO + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/PKG-INFO + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/SOURCES.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/SOURCES.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/dependency_links.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/dependency_links.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/requires.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/requires.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/top_level.txt + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/aiomagnumopus.egg-info/top_level.txt + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage/storage.db + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/docker/storage/storage.db + parent: testsfailed=0 testscollected=0> + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + parent: testsfailed=0 testscollected=0> + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + parent: testsfailed=0 testscollected=0> + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + parent: testsfailed=0 testscollected=0> + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/Pipfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/Pipfile + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/config.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/config.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/index.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/index.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/initialize.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/initialize.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/injection.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/injection.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/logger.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/logger.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/base.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/base.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/substance.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/models/substance.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/list_pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/list_pantry.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/pantry.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/sqlalchemy_pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/repositories/sqlalchemy_pantry.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/alembic_instruction.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/alembic_instruction.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/substance.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/resources/substance.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/substance_schema.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/schemas/substance_schema.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic_instruction_handler.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/alembic_instruction_handler.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/assessor.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/magnumopus/services/assessor.py + parent: + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_directory [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain + parent: + finish pytest_collect_directory --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/Pipfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/Pipfile + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/conftest.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/conftest.py + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__init__.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + finish pytest_make_collect_report --> [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/.coverage + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/.coverage + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/Pipfile + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/Pipfile + parent: + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + early skip of rewriting module: tests.application [assertion] + find_module called for: tests.application.test_alembic_instruction_resource [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py [assertion] + find_module called for: tests.application.test_substance_resource [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.application.test_alembic_instruction_resource + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.application + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.application.test_alembic_instruction_resource', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_alembic_instruction_resource.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__pycache__/test_alembic_instruction_resource.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_app + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: is_dictionary_inside + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_substance_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_alembic_instruction_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_alembic_mix_instruction + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e04c0> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_alembic_process_instruction + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806649640> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.application.test_philosophers_stone [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.application.test_philosophers_stone + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.application + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.application.test_philosophers_stone', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_philosophers_stone.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__pycache__/test_philosophers_stone.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_app + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: is_dictionary_inside + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_philosophers_stone + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e0fa0> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.application.test_substance_resource + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.application + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.application.test_substance_resource', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/test_substance_resource.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/application/__pycache__/test_substance_resource.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_app + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: is_dictionary_inside + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: create_substance_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: index_substances_request + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_create_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e04c0> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_get_substances + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78065e0550> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + pytest_ignore_collect [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_ignore_collect --> None [hook] + pytest_collect_file [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + parent: + pytest_pycollect_makemodule [hook] + path: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + parent: + finish pytest_pycollect_makemodule --> [hook] + finish pytest_collect_file --> [] [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + early skip of rewriting module: tests.domain [assertion] + find_module called for: tests.domain.test_alembic [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py [assertion] + early skip of rewriting module: magnumopus.services [assertion] + early skip of rewriting module: magnumopus.services.alembic [assertion] + early skip of rewriting module: magnumopus.models.substance [assertion] + early skip of rewriting module: sqlalchemy_utils [assertion] + early skip of rewriting module: sqlalchemy_utils.aggregates [assertion] + early skip of rewriting module: sqlalchemy_utils.functions [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.database [assertion] + early skip of rewriting module: sqlalchemy_utils.utils [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.orm [assertion] + early skip of rewriting module: sqlalchemy.ext.hybrid [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.foreign_keys [assertion] + early skip of rewriting module: sqlalchemy_utils.query_chain [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.mock [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.render [assertion] + early skip of rewriting module: sqlalchemy_utils.functions.sort_query [assertion] + early skip of rewriting module: sqlalchemy_utils.relationships [assertion] + early skip of rewriting module: sqlalchemy_utils.relationships.chained_join [assertion] + early skip of rewriting module: sqlalchemy_utils.asserts [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.array [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.hstore [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.json [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.ranges [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.pg8000 [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.psycopg2 [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.psycopg2cffi [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.pygresql [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.pypostgresql [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy.connectors [assertion] + early skip of rewriting module: sqlalchemy.connectors.zxJDBC [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.dml [assertion] + early skip of rewriting module: sqlalchemy.dialects.postgresql.ext [assertion] + early skip of rewriting module: sqlalchemy_utils.exceptions [assertion] + early skip of rewriting module: sqlalchemy_utils.expressions [assertion] + early skip of rewriting module: sqlalchemy.ext.compiler [assertion] + early skip of rewriting module: sqlalchemy_utils.generic [assertion] + early skip of rewriting module: sqlalchemy_utils.i18n [assertion] + early skip of rewriting module: babel [assertion] + early skip of rewriting module: sqlalchemy_utils.listeners [assertion] + early skip of rewriting module: sqlalchemy_utils.models [assertion] + early skip of rewriting module: sqlalchemy_utils.observer [assertion] + early skip of rewriting module: sqlalchemy_utils.path [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.country [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.currency [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.ltree [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.weekday [assertion] + early skip of rewriting module: sqlalchemy_utils.primitives.weekdays [assertion] + early skip of rewriting module: sqlalchemy_utils.proxy_dict [assertion] + early skip of rewriting module: sqlalchemy_utils.types [assertion] + early skip of rewriting module: sqlalchemy_utils.types.arrow [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.arrow_datetime [assertion] + early skip of rewriting module: arrow [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.pendulum_date [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.pendulum_datetime [assertion] + early skip of rewriting module: pendulum [assertion] + early skip of rewriting module: pendulum [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.enriched_datetime_type [assertion] + early skip of rewriting module: sqlalchemy_utils.types.scalar_coercible [assertion] + early skip of rewriting module: arrow [assertion] + early skip of rewriting module: sqlalchemy_utils.types.choice [assertion] + early skip of rewriting module: sqlalchemy_utils.types.color [assertion] + early skip of rewriting module: colour [assertion] + early skip of rewriting module: sqlalchemy_utils.types.country [assertion] + early skip of rewriting module: sqlalchemy_utils.types.currency [assertion] + early skip of rewriting module: sqlalchemy_utils.types.email [assertion] + early skip of rewriting module: sqlalchemy_utils.operators [assertion] + early skip of rewriting module: sqlalchemy_utils.types.encrypted [assertion] + early skip of rewriting module: sqlalchemy_utils.types.encrypted.encrypted_type [assertion] + early skip of rewriting module: sqlalchemy_utils.types.encrypted.padding [assertion] + early skip of rewriting module: sqlalchemy_utils.types.json [assertion] + early skip of rewriting module: anyjson [assertion] + early skip of rewriting module: cryptography [assertion] + early skip of rewriting module: dateutil [assertion] + early skip of rewriting module: sqlalchemy_utils.types.enriched_datetime.enriched_date_type [assertion] + early skip of rewriting module: sqlalchemy_utils.types.ip_address [assertion] + early skip of rewriting module: ipaddress [assertion] + early skip of rewriting module: sqlalchemy_utils.types.locale [assertion] + early skip of rewriting module: babel [assertion] + early skip of rewriting module: sqlalchemy_utils.types.ltree [assertion] + early skip of rewriting module: sqlalchemy_utils.types.password [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle.cx_oracle [assertion] + early skip of rewriting module: sqlalchemy.dialects.oracle.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.json [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.pysqlcipher [assertion] + early skip of rewriting module: sqlalchemy.dialects.sqlite.pysqlite [assertion] + early skip of rewriting module: sqlalchemy.ext.mutable [assertion] + early skip of rewriting module: passlib [assertion] + early skip of rewriting module: sqlalchemy_utils.types.pg_composite [assertion] + early skip of rewriting module: psycopg2 [assertion] + early skip of rewriting module: sqlalchemy_utils.types.phone_number [assertion] + early skip of rewriting module: phonenumbers [assertion] + early skip of rewriting module: sqlalchemy_utils.types.range [assertion] + early skip of rewriting module: intervals [assertion] + early skip of rewriting module: sqlalchemy_utils.types.scalar_list [assertion] + early skip of rewriting module: sqlalchemy_utils.types.timezone [assertion] + early skip of rewriting module: sqlalchemy_utils.types.ts_vector [assertion] + early skip of rewriting module: sqlalchemy_utils.types.url [assertion] + early skip of rewriting module: furl [assertion] + early skip of rewriting module: sqlalchemy_utils.types.uuid [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.adodbapi [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.information_schema [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.mxodbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.pyodbc [assertion] + early skip of rewriting module: sqlalchemy.connectors.pyodbc [assertion] + early skip of rewriting module: sqlalchemy.connectors.mxodbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.pymssql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mssql.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy_utils.types.weekdays [assertion] + early skip of rewriting module: sqlalchemy_utils.types.bit [assertion] + early skip of rewriting module: sqlalchemy_utils.view [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_alembic + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_alembic', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_alembic.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Alembic + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: NotEnoughSubstancesToMixException + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: UnknownProcessException + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_set_up_my_alembic + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_mix_multiple_substances_in_my_alembic + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_cannot_mix_one_substance_in_my_alembic + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_mixing_sulphur_salt_and_mercury_gives_gloop + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_mixing_other_recipes_gives_sludge + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_process_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_cannot_perform_unknown_process + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806623d30> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.domain.test_alembic_instruction_handler [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py [assertion] + early skip of rewriting module: magnumopus.services.alembic_instruction_handler [assertion] + early skip of rewriting module: injector [assertion] + early skip of rewriting module: magnumopus.repositories [assertion] + early skip of rewriting module: magnumopus.repositories.pantry [assertion] + early skip of rewriting module: magnumopus.repositories.list_pantry [assertion] + early skip of rewriting module: magnumopus.repositories.sqlalchemy_pantry [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_alembic_instruction_handler + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_alembic_instruction_handler', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_alembic_instruction_handler.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_alembic_instruction_handler.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: AlembicInstruction + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: AlembicInstructionHandler + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: ListPantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: instruction_unknown + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: instruction + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_set_up_my_alembic_instruction_handler + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325040> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.domain.test_pantry [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_pantry + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_pantry', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_pantry.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_pantry.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pytest + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: ListPantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: list_pantry + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: pantries + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_add_to_pantry + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f78063257f0> + pytest_make_parametrize_id [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + val: list + argname: pantry_type + finish pytest_make_parametrize_id --> None [hook] + early skip of rewriting module: encodings.unicode_escape [assertion] + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_retrieve_substance_from_pantry_by_nature + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325670> + pytest_make_parametrize_id [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + val: list + argname: pantry_type + finish pytest_make_parametrize_id --> None [hook] + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + genitems [collection] + pytest_collectstart [hook] + collector: + finish pytest_collectstart --> [] [hook] + pytest_make_collect_report [hook] + collector: + find_module called for: tests.domain.test_substance [assertion] + matched test file '/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py' [assertion] + found cached rewritten pyc for /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py [assertion] + pytest_pycollect_makeitem [hook] + collector: + name: __name__ + obj: tests.domain.test_substance + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __doc__ + obj: None + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __package__ + obj: tests.domain + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __loader__ + obj: <_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370> + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __spec__ + obj: ModuleSpec(name='tests.domain.test_substance', loader=<_pytest.assertion.rewrite.AssertionRewritingHook object at 0x7f7808885370>, origin='/home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py') + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __file__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/test_substance.py + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __cached__ + obj: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii/tests/domain/__pycache__/test_substance.cpython-38.pyc + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __builtins__ + obj: {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': , '__spec__': ModuleSpec(name='builtins', loader=), '__build_class__': , '__import__': , 'abs': , 'all': , 'any': , 'ascii': , 'bin': , 'breakpoint': , 'callable': , 'chr': , 'compile': , 'delattr': , 'dir': , 'divmod': , 'eval': , 'exec': , 'format': , 'getattr': , 'globals': , 'hasattr': , 'hash': , 'hex': , 'id': , 'input': , 'isinstance': , 'issubclass': , 'iter': , 'len': , 'locals': , 'max': , 'min': , 'next': , 'oct': , 'ord': , 'pow': , 'print': , 'repr': , 'round': , 'setattr': , 'sorted': , 'sum': , 'vars': , 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': , 'memoryview': , 'bytearray': , 'bytes': , 'classmethod': , 'complex': , 'dict': , 'enumerate': , 'filter': , 'float': , 'frozenset': , 'property': , 'int': , 'list': , 'map': , 'object': , 'range': , 'reversed': , 'set': , 'slice': , 'staticmethod': , 'str': , 'super': , 'tuple': , 'type': , 'zip': , '__debug__': True, 'BaseException': , 'Exception': , 'TypeError': , 'StopAsyncIteration': , 'StopIteration': , 'GeneratorExit': , 'SystemExit': , 'KeyboardInterrupt': , 'ImportError': , 'ModuleNotFoundError': , 'OSError': , 'EnvironmentError': , 'IOError': , 'EOFError': , 'RuntimeError': , 'RecursionError': , 'NotImplementedError': , 'NameError': , 'UnboundLocalError': , 'AttributeError': , 'SyntaxError': , 'IndentationError': , 'TabError': , 'LookupError': , 'IndexError': , 'KeyError': , 'ValueError': , 'UnicodeError': , 'UnicodeEncodeError': , 'UnicodeDecodeError': , 'UnicodeTranslateError': , 'AssertionError': , 'ArithmeticError': , 'FloatingPointError': , 'OverflowError': , 'ZeroDivisionError': , 'SystemError': , 'ReferenceError': , 'MemoryError': , 'BufferError': , 'Warning': , 'UserWarning': , 'DeprecationWarning': , 'PendingDeprecationWarning': , 'SyntaxWarning': , 'RuntimeWarning': , 'FutureWarning': , 'ImportWarning': , 'UnicodeWarning': , 'BytesWarning': , 'ResourceWarning': , 'ConnectionError': , 'BlockingIOError': , 'BrokenPipeError': , 'ChildProcessError': , 'ConnectionAbortedError': , 'ConnectionRefusedError': , 'ConnectionResetError': , 'FileExistsError': , 'FileNotFoundError': , 'IsADirectoryError': , 'NotADirectoryError': , 'InterruptedError': , 'PermissionError': , 'ProcessLookupError': , 'TimeoutError': , 'open': , 'quit': Use quit() or Ctrl-D (i.e. EOF) to exit, 'exit': Use exit() or Ctrl-D (i.e. EOF) to exit, 'copyright': Copyright (c) 2001-2020 Python Software Foundation. +All Rights Reserved. + +Copyright (c) 2000 BeOpen.com. +All Rights Reserved. + +Copyright (c) 1995-2001 Corporation for National Research Initiatives. +All Rights Reserved. + +Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. +All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.} + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @py_builtins + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: @pytest_ar + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: Substance + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_cook_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_wash_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_pickle_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_ferment_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_can_cook_and_ferment_substance + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: test_the_order_of_processes_applied_to_a_substance_matters + obj: + pytest_generate_tests [hook] + metafunc: <_pytest.python.Metafunc object at 0x7f7806325e20> + finish pytest_generate_tests --> [] [hook] + finish pytest_pycollect_makeitem --> [] [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __repr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __getattribute__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __setattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __delattr__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __new__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dir__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __dict__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __hash__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __str__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __lt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __le__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __eq__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ne__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __gt__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __ge__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce_ex__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __reduce__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __subclasshook__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __init_subclass__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __format__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __sizeof__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + pytest_pycollect_makeitem [hook] + collector: + name: __class__ + obj: + finish pytest_pycollect_makeitem --> None [hook] + finish pytest_make_collect_report --> [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + genitems [collection] + pytest_itemcollected [hook] + item: + finish pytest_itemcollected --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + pytest_collectreport [hook] + report: + finish pytest_collectreport --> [] [hook] + pytest_collection_modifyitems [hook] + session: testsfailed=0 testscollected=0> + config: <_pytest.config.Config object at 0x7f78089fd5b0> + items: [, , , , , , , , , , , , , , , , , , , , ] + finish pytest_collection_modifyitems --> [] [hook] + pytest_collection_finish [hook] + session: testsfailed=0 testscollected=0> + pytest_report_collectionfinish [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + startdir: /home/philtweir/Work/Training/PythonCourse/python-course/022-burette/magnum_opus_ii + items: [, , , , , , , , , , , , , , , , , , , , ] + finish pytest_report_collectionfinish --> [] [hook] + finish pytest_collection_finish --> [] [hook] + finish pytest_collection --> [, , , , , , , , , , , , , , , , , , , , ] [hook] + pytest_runtestloop [hook] + session: testsfailed=0 testscollected=21> + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_mix_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 16, 'test_create_alembic_mix_instruction') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + early skip of rewriting module: magnumopus.resources [assertion] + early skip of rewriting module: magnumopus.resources.substance [assertion] + early skip of rewriting module: magnumopus.injection [assertion] + early skip of rewriting module: magnumopus.schemas [assertion] + early skip of rewriting module: flask_marshmallow [assertion] + early skip of rewriting module: distutils [assertion] + early skip of rewriting module: distutils.version [assertion] + early skip of rewriting module: marshmallow [assertion] + early skip of rewriting module: marshmallow.schema [assertion] + early skip of rewriting module: marshmallow.base [assertion] + early skip of rewriting module: marshmallow.fields [assertion] + early skip of rewriting module: marshmallow.validate [assertion] + early skip of rewriting module: marshmallow.types [assertion] + early skip of rewriting module: marshmallow.exceptions [assertion] + early skip of rewriting module: marshmallow.utils [assertion] + early skip of rewriting module: marshmallow.class_registry [assertion] + early skip of rewriting module: marshmallow.error_store [assertion] + early skip of rewriting module: marshmallow.orderedset [assertion] + early skip of rewriting module: marshmallow.decorators [assertion] + early skip of rewriting module: flask_marshmallow.fields [assertion] + early skip of rewriting module: flask_marshmallow.schema [assertion] + early skip of rewriting module: flask_marshmallow.compat [assertion] + early skip of rewriting module: flask_marshmallow.sqla [assertion] + early skip of rewriting module: six.moves.urllib [assertion] + early skip of rewriting module: marshmallow_sqlalchemy [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.model_schema [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.convert [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.base [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.reflection [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.enumerated [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.types [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.json [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.cymysql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.mysqldb [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.gaerdbms [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.mysqlconnector [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.oursql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.pymysql [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.pyodbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.zxjdbc [assertion] + early skip of rewriting module: sqlalchemy.dialects.mysql.dml [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.exceptions [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.fields [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.schema_meta [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.load_instance_mixin [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.table_schema [assertion] + early skip of rewriting module: marshmallow_sqlalchemy.schema.sqlalchemy_schema [assertion] + early skip of rewriting module: magnumopus.schemas.substance_schema [assertion] + early skip of rewriting module: magnumopus.services.assessor [assertion] + early skip of rewriting module: magnumopus.resources.alembic_instruction [assertion] + early skip of rewriting module: magnumopus.logger [assertion] + early skip of rewriting module: magnumopus.config [assertion] + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + pytest_assertrepr_compare [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + op: == + left: 500 + right: 201 + finish pytest_assertrepr_compare --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: > + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_exception_interact [hook] + node: + call: > + report: + finish pytest_exception_interact --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_mix_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 16, 'test_create_alembic_mix_instruction') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_process_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 34, 'test_create_alembic_process_instruction') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + pytest_assertrepr_compare [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + op: == + left: 500 + right: 201 + finish pytest_assertrepr_compare --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: > + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_exception_interact [hook] + node: + call: > + report: + finish pytest_exception_interact --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_alembic_instruction_resource.py::test_create_alembic_process_instruction + location: ('tests/application/test_alembic_instruction_resource.py', 34, 'test_create_alembic_process_instruction') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_philosophers_stone.py::test_create_philosophers_stone + location: ('tests/application/test_philosophers_stone.py', 5, 'test_create_philosophers_stone') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_philosophers_stone.py::test_create_philosophers_stone + location: ('tests/application/test_philosophers_stone.py', 5, 'test_create_philosophers_stone') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_substance_resource.py::test_create_substance + location: ('tests/application/test_substance_resource.py', 12, 'test_create_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_substance_resource.py::test_create_substance + location: ('tests/application/test_substance_resource.py', 12, 'test_create_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/application/test_substance_resource.py::test_get_substances + location: ('tests/application/test_substance_resource.py', 29, 'test_get_substances') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> <_UnixSelectorEventLoop running=False closed=False debug=False> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + pytest_assertrepr_compare [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + op: is + left: + right: + finish pytest_assertrepr_compare --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: is list\n + where = type(None)") tblen=31>> + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_exception_interact [hook] + node: + call: is list\n + where = type(None)") tblen=1>> + report: + finish pytest_exception_interact --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/application/test_substance_resource.py::test_get_substances + location: ('tests/application/test_substance_resource.py', 29, 'test_get_substances') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_can_set_up_my_alembic + location: ('tests/domain/test_alembic.py', 5, 'test_can_set_up_my_alembic') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_can_set_up_my_alembic + location: ('tests/domain/test_alembic.py', 5, 'test_can_set_up_my_alembic') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_can_mix_multiple_substances_in_my_alembic + location: ('tests/domain/test_alembic.py', 8, 'test_can_mix_multiple_substances_in_my_alembic') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_can_mix_multiple_substances_in_my_alembic + location: ('tests/domain/test_alembic.py', 8, 'test_can_mix_multiple_substances_in_my_alembic') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_mix_one_substance_in_my_alembic + location: ('tests/domain/test_alembic.py', 16, 'test_cannot_mix_one_substance_in_my_alembic') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_mix_one_substance_in_my_alembic + location: ('tests/domain/test_alembic.py', 16, 'test_cannot_mix_one_substance_in_my_alembic') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_sulphur_salt_and_mercury_gives_gloop + location: ('tests/domain/test_alembic.py', 23, 'test_mixing_sulphur_salt_and_mercury_gives_gloop') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_sulphur_salt_and_mercury_gives_gloop + location: ('tests/domain/test_alembic.py', 23, 'test_mixing_sulphur_salt_and_mercury_gives_gloop') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_other_recipes_gives_sludge + location: ('tests/domain/test_alembic.py', 38, 'test_mixing_other_recipes_gives_sludge') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_mixing_other_recipes_gives_sludge + location: ('tests/domain/test_alembic.py', 38, 'test_mixing_other_recipes_gives_sludge') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_can_process_substance + location: ('tests/domain/test_alembic.py', 58, 'test_can_process_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_can_process_substance + location: ('tests/domain/test_alembic.py', 58, 'test_can_process_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_perform_unknown_process + location: ('tests/domain/test_alembic.py', 74, 'test_cannot_perform_unknown_process') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic.py::test_cannot_perform_unknown_process + location: ('tests/domain/test_alembic.py', 74, 'test_cannot_perform_unknown_process') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_alembic_instruction_handler.py::test_can_set_up_my_alembic_instruction_handler + location: ('tests/domain/test_alembic_instruction_handler.py', 34, 'test_can_set_up_my_alembic_instruction_handler') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> AlembicInstruction(instruction_type='process', natures=['Sludge'], action='cook') [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_alembic_instruction_handler.py::test_can_set_up_my_alembic_instruction_handler + location: ('tests/domain/test_alembic_instruction_handler.py', 34, 'test_can_set_up_my_alembic_instruction_handler') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_pantry.py::test_can_add_to_pantry[list] + location: ('tests/domain/test_pantry.py', 17, 'test_can_add_to_pantry[list]') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> list [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + list: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_pantry.py::test_can_add_to_pantry[list] + location: ('tests/domain/test_pantry.py', 17, 'test_can_add_to_pantry[list]') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_pantry.py::test_can_retrieve_substance_from_pantry_by_nature[list] + location: ('tests/domain/test_pantry.py', 27, 'test_can_retrieve_substance_from_pantry_by_nature[list]') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> list [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + pytest_fixture_setup [hook] + fixturedef: + request: > + finish pytest_fixture_setup --> [hook] + list: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + pytest_fixture_post_finalizer [hook] + fixturedef: + request: > + finish pytest_fixture_post_finalizer --> [] [hook] + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_pantry.py::test_can_retrieve_substance_from_pantry_by_nature[list] + location: ('tests/domain/test_pantry.py', 27, 'test_can_retrieve_substance_from_pantry_by_nature[list]') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_substance + location: ('tests/domain/test_substance.py', 2, 'test_can_cook_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_substance + location: ('tests/domain/test_substance.py', 2, 'test_can_cook_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_wash_substance + location: ('tests/domain/test_substance.py', 9, 'test_can_wash_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_wash_substance + location: ('tests/domain/test_substance.py', 9, 'test_can_wash_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_pickle_substance + location: ('tests/domain/test_substance.py', 16, 'test_can_pickle_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_pickle_substance + location: ('tests/domain/test_substance.py', 16, 'test_can_pickle_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_ferment_substance + location: ('tests/domain/test_substance.py', 23, 'test_can_ferment_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_ferment_substance + location: ('tests/domain/test_substance.py', 23, 'test_can_ferment_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_and_ferment_substance + location: ('tests/domain/test_substance.py', 30, 'test_can_cook_and_ferment_substance') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_can_cook_and_ferment_substance + location: ('tests/domain/test_substance.py', 30, 'test_can_cook_and_ferment_substance') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + pytest_runtest_protocol [hook] + item: + nextitem: None + pytest_runtest_logstart [hook] + nodeid: tests/domain/test_substance.py::test_the_order_of_processes_applied_to_a_substance_matters + location: ('tests/domain/test_substance.py', 38, 'test_the_order_of_processes_applied_to_a_substance_matters') + finish pytest_runtest_logstart --> [] [hook] + pytest_runtest_setup [hook] + item: + finish pytest_runtest_setup --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_call [hook] + item: + pytest_pyfunc_call [hook] + pyfuncitem: + finish pytest_pyfunc_call --> True [hook] + finish pytest_runtest_call --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('passed', '.', 'PASSED') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_teardown [hook] + item: + nextitem: None + finish pytest_runtest_teardown --> [] [hook] + pytest_runtest_makereport [hook] + item: + call: + finish pytest_runtest_makereport --> [hook] + pytest_runtest_logreport [hook] + report: + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('', '', '') [hook] + finish pytest_runtest_logreport --> [] [hook] + pytest_runtest_logfinish [hook] + nodeid: tests/domain/test_substance.py::test_the_order_of_processes_applied_to_a_substance_matters + location: ('tests/domain/test_substance.py', 38, 'test_the_order_of_processes_applied_to_a_substance_matters') + finish pytest_runtest_logfinish --> [] [hook] + finish pytest_runtest_protocol --> True [hook] + finish pytest_runtestloop --> True [hook] + pytest_sessionfinish [hook] + session: testsfailed=3 testscollected=21> + exitstatus: ExitCode.TESTS_FAILED + pytest_terminal_summary [hook] + terminalreporter: <_pytest.terminal.TerminalReporter object at 0x7f780666aee0> + exitstatus: ExitCode.TESTS_FAILED + config: <_pytest.config.Config object at 0x7f78089fd5b0> + early skip of rewriting module: pygments [assertion] + early skip of rewriting module: pygments [assertion] + early skip of rewriting module: pygments [assertion] + early skip of rewriting module: wcwidth [assertion] + early skip of rewriting module: wcwidth.wcwidth [assertion] + early skip of rewriting module: wcwidth.table_wide [assertion] + early skip of rewriting module: wcwidth.table_zero [assertion] + early skip of rewriting module: wcwidth.unicode_versions [assertion] + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + pytest_report_teststatus [hook] + report: + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_report_teststatus --> ('failed', 'F', 'FAILED') [hook] + finish pytest_terminal_summary --> [] [hook] + finish pytest_sessionfinish --> [] [hook] + pytest_unconfigure [hook] + config: <_pytest.config.Config object at 0x7f78089fd5b0> + finish pytest_unconfigure --> [] [hook] diff --git a/022-burette/magnum_opus_iii/requirements.txt b/022-burette/magnum_opus_iii/requirements.txt new file mode 100644 index 0000000..3400e03 --- /dev/null +++ b/022-burette/magnum_opus_iii/requirements.txt @@ -0,0 +1,10 @@ +appdirs +quart +wheel +quart-openapi +flask-marshmallow +flask-sqlalchemy +flask-injector +marshmallow-sqlalchemy +sqlalchemy-utils +ariadne diff --git a/022-burette/magnum_opus_iii/setup.cfg b/022-burette/magnum_opus_iii/setup.cfg new file mode 100644 index 0000000..163e9af --- /dev/null +++ b/022-burette/magnum_opus_iii/setup.cfg @@ -0,0 +1,35 @@ +[metadata] +name = aiomagnumopus +version = 0.0.1 +author = Phil Weir +author_email = phil.weir@flaxandteal.co.uk +license = GPL +description = Service for cooking up a philosopher's stone +long-description = file:README.md + +[options] +include_package_data = True +packages = find: +python_requires = >=3.6 +install_requires = + appdirs + quart-openapi + flask-marshmallow + flask-sqlalchemy + flask-injector + sqlalchemy-utils + marshmallow-sqlalchemy + quart-openapi + wheel + ariadne + +[options.extras_require] +dev = + pytest + pytest-pep8 + pytest-cov + pytest-asyncio + +[options.packages.find] +exclude = + tests diff --git a/022-burette/magnum_opus_iii/setup.py b/022-burette/magnum_opus_iii/setup.py new file mode 100644 index 0000000..1767837 --- /dev/null +++ b/022-burette/magnum_opus_iii/setup.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +""" +Magnum Opus + +This tool performs alchemical reactions to create +the Philosopher's Stone. + +@author: Phil Weir +""" + +from setuptools import setup + +if __name__ == '__main__': + setup() diff --git a/022-burette/magnum_opus_iii/tests/__init__.py b/022-burette/magnum_opus_iii/tests/__init__.py new file mode 100644 index 0000000..c09f99d --- /dev/null +++ b/022-burette/magnum_opus_iii/tests/__init__.py @@ -0,0 +1,4 @@ + +def is_dictionary_inside(d1, d2): + return d1.items() <= d2.items() + diff --git a/022-burette/magnum_opus_iii/tests/application/.coverage b/022-burette/magnum_opus_iii/tests/application/.coverage new file mode 100644 index 0000000000000000000000000000000000000000..0e5750b04d16c86d92dbe9e012e32b8f135b4fbd GIT binary patch literal 53248 zcmeI4O^h5z6@a^^d#2}iYwh*!%B(i-3mUJyv$MPACzwMp_8x*QL5zcgEYsJ5_bF@g&h4&X=}$R(F>fJnJ;2@oWHgOIq81Cc;NNGKe5uYYEG>|GNH zdJ=D5Yo?}us_NDI-m9v4{rAOZt{Og9Hyzi~ef7LBEr_D<8C4Yop#==1-p%55Df}EtC7M-sWzU)-GM!xOja-y?*htS2xsXpL({e!qRA{7gg8UReRi3 zHw}}khTSpRx^LK9s^8^F?!L!6IOD-SnDa2>N?0D(G@}Ehe7*%$^jyQz-FDknGx^uP$%7O!>2N) z4eS`H^7JND)OOqsw!Y=+cDu{HWmO+)*mj_udw!&?>sU?SQBA`R)wDgsHym5#d%WHE zdFN0Cml0aB0KBv|P}lRQ(DPBrSXPS8sPG{rE%j&4)a;S#wEUTyl zc)&+1h51j-hyr*e-}81%_~WJNecuVUH88%m21)gsCyL7anKRHF$!*jQ+T z+A^KixUYpC<8kO9Fcu`)Hv4uPyNZW8w4DKW^)0>D7I7*#3pSBjS6az(8=4WTcAnFk~F5x#nrUdR8b%6&ag7@D1p6++mhue<3q2cv> zVgA#zM>QOqpsitAc;Q+uZ1P^z39o|0Hu{EfNO-bey9Nn)&UrV|btXP(Acj9RZXWyt+81k`C zqMT^#fP!ir`l1It^MN{(O5>wAP$l)R^Z*6cYU!P*m!mCGHSTu#L)Ar-&}H4{zF~0{ zvxJQa{b^VC)V9mvAWWf4b?H&oMwC==ZV#HK(TcO5UwN_#xBKx%Pj7F-%}XBc z=bqoxGz)}i8r&99Usmf4sCR%XQC(P7{Z<)lDzi5Q_9puWdz<~~!(?L8l?V_4B0vO) z01+SpM1Tko0U|&Ih`{4Zpeikj$$1O8D9ws^+Cr*G3u1hZB3F?XOUda8y#7Cz|AWBp zu`^RYnz~&3b#1#QR$r_xR_<38%lFIcrB_Rria#x0QQlBKSNKKYImk>45g-CYfCzk$ z3EY{Jh2YNr{p|DT>~YiOJqOM_JFWpIolV2@wVrPK?mnDw9?XL9orwt_%H2B!a{CjL zt7&i+-w#i*2jYw@94HeL4G)m(CO${FKcar;WY#8+o-6d4Uccq}@J<3AKfDMg_fCND z?JV_Agr}(s(?C6+rBs)Da6Jaz=Frql4$qdi!RDUt_QS`VjuP`tqaden;cu> zmnWuw%Ei1=)~2?c4mVSy38-onL8z7`a~!e_-88<+L0ne>anEKe4qo>Gl8gdKx{;+M zcwfS%u?3>cJczoLr6|L`&65Gpkh50IbhhAyJfN5@fhavo#bS?a=^lEAn*({q1mvZ9 z-L?oaZ)PboB@D0s&*k3|*tcqCEmyr)`_0q_Q>R|8K2i8({;k57l`Eyo#n(zdE?!lB zUU{i}zVbx*r4RC-UTPZ=AOb{y2nfR0H@F?#n@ca&l8M z>8T(mA1IR(eOUZIlex*05PTRBj^h85z8q|4s(&IpMg2q|$_M#OrT(}0e|jJX&V*W! z(wt48haDFGPi1fBVJIHO#PC17)|Ue-Q^tqI|J9%?7m<%H;GXdwbbfCvx)B0vO)01+SpM1Tko0U|&Ijv)a_s+I8izr@}a*uU7{;D;6> zKm>>Y5g-CYfCvx)B0vO)01+SpMBp(dP>^J?G$oal9Q;n_=ES@xmr7G*y#6n-cLeq> zy#N25$5=sXIuRfOM1Tko0U|&IhyW2F0z`la5CI|(5hy_HFG^DQlgr6)0wBEpFH934 zB0vO)01+SpM1Tko0U|&IhyW2F0z}|A6Ts{L6#pM*3zKd{fCvx)B0vO)01+SpM1Tko z0U|&I1OcD_pJOlL{r~@De`kMXe_?-Se`LR9zhZB&pRw23PuQ#M74|awA^QRQ9{Vo) z4rHc<2oM1xKm>>Y5g-CYfCvx)B0vO)01@~f2}pDBT7GF3lT( Date: Tue, 30 Jun 2020 08:43:36 +0100 Subject: [PATCH 12/12] integrate ariadne, modularity and injection --- .../magnum_opus_iii/magnumopus/graph.py | 79 ++++++++----------- .../magnumopus/resources/__init__.py | 7 ++ .../magnumopus/resources/graph.py | 39 +++++++++ .../magnumopus/resources/substance.py | 20 +++++ .../magnumopus/schemas/__init__.py | 7 ++ .../magnumopus/schemas/substance_schema.py | 10 +++ 6 files changed, 117 insertions(+), 45 deletions(-) create mode 100644 022-burette/magnum_opus_iii/magnumopus/resources/graph.py diff --git a/022-burette/magnum_opus_iii/magnumopus/graph.py b/022-burette/magnum_opus_iii/magnumopus/graph.py index c14b74c..e4d0f90 100644 --- a/022-burette/magnum_opus_iii/magnumopus/graph.py +++ b/022-burette/magnum_opus_iii/magnumopus/graph.py @@ -1,57 +1,46 @@ from quart import request, jsonify +from graphql import GraphQLSchema from ariadne import ObjectType, make_executable_schema, graphql -from ariadne.constants import PLAYGROUND_HTML +from .schemas import init_graph as init_graph_schemas +from .resources import init_graph as init_graph_resources -from .repositories import PANTRY_STORES - -PANTRY = PANTRY_STORES['list'] - -type_defs = """ +TYPE_DEFS = """ type Query { substances(nature: String!): [Substance] } - - type Substance { - nature: String!, - state: [String]! - } """ -query = ObjectType('Query') -substance = ObjectType('Substance') - -@query.field('substances') -def resolve_substances(obj, *_, nature='Unknown'): - return PANTRY.find_substances_by_nature(nature) - - -@substance.field('nature') -def resolve_nature(obj, *_): - return obj.nature - -@substance.field('state') -def resolve_state(obj, *_): - return obj.state - -schema = make_executable_schema(type_defs, query, substance) - -async def graphql_server(): - data = await request.get_json() - success, result = await graphql( - schema, - data, - context_value=request - ) - - return jsonify(result), (200 if success else 400) +class InjectorObjectType(ObjectType): + def __init__(self, *args, app=None, **kwargs): + super(InjectorObjectType, self).__init__(*args, **kwargs) + self._app = app + + def get_injector(self): + return self._app.extensions['injector'] + + def field(self, name: str): + g = super(InjectorObjectType, self).field(name) + def injected_resolver(f): + def _inject_resolver(*args, **kwargs): + self._app.logger.error(name) + inj = self.get_injector() + return inj.call_with_injection( + f, args=args, kwargs=kwargs + ) + return g(_inject_resolver) + return injected_resolver def init_app(app): - app.route('/graphql', methods=['GET'], endpoint='graphql_playground')( - lambda: (PLAYGROUND_HTML, 200) - ) + query = InjectorObjectType('Query', app=app) + + type_defs = [TYPE_DEFS] + init_graph_schemas(query) + resolvers = [query] + init_graph_resources(query) - app.route('/graphql', methods=['POST'], endpoint='graphql_server')( - graphql_server - ) + schema = make_executable_schema(type_defs, resolvers) - return [] + return [ + lambda binder: binder.bind( + GraphQLSchema, + to=schema + ) + ] diff --git a/022-burette/magnum_opus_iii/magnumopus/resources/__init__.py b/022-burette/magnum_opus_iii/magnumopus/resources/__init__.py index 7088c1e..cbe6bf9 100644 --- a/022-burette/magnum_opus_iii/magnumopus/resources/__init__.py +++ b/022-burette/magnum_opus_iii/magnumopus/resources/__init__.py @@ -1,7 +1,14 @@ from . import substance from . import alembic_instruction +from . import graph def init_app(app): substance.init_app(app) alembic_instruction.init_app(app) + graph.init_app(app) return [] + +def init_graph(graph): + resolvers = [] + resolvers += substance.init_graph(graph) + return resolvers diff --git a/022-burette/magnum_opus_iii/magnumopus/resources/graph.py b/022-burette/magnum_opus_iii/magnumopus/resources/graph.py new file mode 100644 index 0000000..7a44b5c --- /dev/null +++ b/022-burette/magnum_opus_iii/magnumopus/resources/graph.py @@ -0,0 +1,39 @@ +from quart import request, jsonify +from quart_openapi import Resource +from injector import inject +from typing import Dict +from ariadne import graphql +from ariadne.constants import PLAYGROUND_HTML +from graphql.type import GraphQLSchema +from ..injection import ViewInjectorMeta +from ..repositories.pantry import Pantry +from ..models import db + +class GraphResource(Resource): + @inject + def __init__(self, schema: GraphQLSchema): + super(GraphResource, self).__init__() + + self._schema = schema + + async def get(self): + return (PLAYGROUND_HTML, 200) + + async def post(self): + data = await request.get_json() + success, result = await graphql( + self._schema, + data, + context_value=request + ) + + return jsonify(result), (200 if success else 400) + + +def init_app(app): + class AppGraphResource(GraphResource, metaclass=ViewInjectorMeta): + get_app = lambda: app + + app.route('/graphql', endpoint='graphql')(AppGraphResource) + + return [] diff --git a/022-burette/magnum_opus_iii/magnumopus/resources/substance.py b/022-burette/magnum_opus_iii/magnumopus/resources/substance.py index 7c5ad88..2052a7b 100644 --- a/022-burette/magnum_opus_iii/magnumopus/resources/substance.py +++ b/022-burette/magnum_opus_iii/magnumopus/resources/substance.py @@ -2,6 +2,7 @@ from quart_openapi import Resource from injector import inject from typing import Dict +from ariadne import ObjectType from ..injection import ViewInjectorMeta from ..repositories.pantry import Pantry from ..models import db @@ -47,3 +48,22 @@ class AppSubstanceResource(SubstanceResource, metaclass=ViewInjectorMeta): get_app = lambda: app app.route('/substance', endpoint='SubstanceResource')(AppSubstanceResource) + +def init_graph(query): + substance = ObjectType('Substance') + + @query.field('substances') + @inject + def resolve_substances(obj, info, pantry: Pantry, *_, nature='Unknown'): + substances = pantry.find_substances_by_nature(nature) + return substances + + @substance.field('nature') + def resolve_nature(obj, *_): + return obj.nature + + @substance.field('state') + def resolve_state(obj, *_): + return obj.state + + return [substance] diff --git a/022-burette/magnum_opus_iii/magnumopus/schemas/__init__.py b/022-burette/magnum_opus_iii/magnumopus/schemas/__init__.py index 7b27dd7..58b0ef1 100644 --- a/022-burette/magnum_opus_iii/magnumopus/schemas/__init__.py +++ b/022-burette/magnum_opus_iii/magnumopus/schemas/__init__.py @@ -20,3 +20,10 @@ def configure_injector(binder): 'many': SubstanceSchema(many=True) } ) + +def init_graph(query): + from .substance_schema import init_graph as init_graph_substance + + return [ + init_graph_substance(query) + ] diff --git a/022-burette/magnum_opus_iii/magnumopus/schemas/substance_schema.py b/022-burette/magnum_opus_iii/magnumopus/schemas/substance_schema.py index 3f86c70..7c99105 100644 --- a/022-burette/magnum_opus_iii/magnumopus/schemas/substance_schema.py +++ b/022-burette/magnum_opus_iii/magnumopus/schemas/substance_schema.py @@ -5,6 +5,13 @@ from ..models.substance import Substance from ..services.assessor import assess_whether_substance_is_philosophers_stone +SUBSTANCE_GRAPH_SCHEMA = """ + type Substance { + nature: String!, + state: [String]! + } +""" + class SubstanceSchema(ma.SQLAlchemySchema): is_philosophers_stone = fields.Function( assess_whether_substance_is_philosophers_stone @@ -17,3 +24,6 @@ class Meta: id = fields.Integer() nature = fields.String() state = fields.Function(lambda model: model.state or []) + +def init_graph(query): + return SUBSTANCE_GRAPH_SCHEMA