Skip to content

Commit

Permalink
Pytest migration (#519)
Browse files Browse the repository at this point in the history
* Add pytest and pytest-asyncio to the requirements

* Update aiohttp ext test

* Update setup.cfg

* Update tox.ini

* Add pytest to the tox requirements

* Update tox.ini

* Move configuration to tox.ini

* Add pytest configs

* Rename pytest-py34-py35.ini -> pytest-py35.ini

* Update config file paths

* Update makefile

* Migrate common tests to pytest

* Migrate FastAPI and Flask wiring tests

* Rename flask and fastapi wiring test files

* Move wiring autoloader tests

* Add pytest-asyncio to the tox.ini

* Migrate wiring async injection tests

* Migrate main wiring tests

* Migrate wiring string module and package names tests

* Migrate wiring config tests

* Migrate misc wiring tests

* Update tests structure

* Migrate misc wiring tests

* Refactor container.from_schema() API tests

* Migrate container.from_schema() integration tests

* Rename schema samples

* Update sample imports

* Migrate container tests

* Refactor container tests

* Migrate container self tests

* Migrate container instance tests

* Migrate container custom string attribute name tests

* Migrate container async resource tests

* Fix py2 container tests

* Migrate container cls tests

* Migrate container class custom string cls as atrribute name tests

* Migrate ext.aiohttp tests

* Migrate ext.flasks tests

* Update ext package tests doc block

* Migrate provider utils tests

* Migrate Factory async mode tests

* Migrate async tests

* Rename common test module

* Refactor asserts in provider tests

* Migrate factory tests

* Migrate selector provider tests

* Migrate object provider tests

* Migrate self provider tests

* Migrate delegate provider tests

* Migrate provider tests

* Migrate dependency provider tests

* Migrate dependencies container provider tests

* Fix warnings

* Migrate list provider tests

* Migrate dict provider tests

* Migrate callable tests

* Migrate injection tests

* Migrate container provider tests

* Migrate coroutine providers

* Migrate traversal tests

* Migrate resource tests

* Migrate configuration tests

* Migrate provided instance provider tests

* Update doc blocks and imports

* Migrate singleton tests

* Update changelog and cosmetic fixes
  • Loading branch information
rmk135 committed Oct 18, 2021
1 parent 4cc4ca9 commit 94aca21
Show file tree
Hide file tree
Showing 197 changed files with 11,464 additions and 11,210 deletions.
11 changes: 2 additions & 9 deletions Makefile
Expand Up @@ -45,17 +45,10 @@ install: uninstall clean cythonize
uninstall:
- pip uninstall -y -q dependency-injector 2> /dev/null

test-py2: build
test:
# Unit tests with coverage report
coverage erase
coverage run --rcfile=./.coveragerc -m unittest discover -s tests/unit/ -p test_*_py2_py3.py
coverage report --rcfile=./.coveragerc
coverage html --rcfile=./.coveragerc

test: build
# Unit tests with coverage report
coverage erase
coverage run --rcfile=./.coveragerc -m unittest discover -s tests/unit/ -p test_*py3*.py
coverage run --rcfile=./.coveragerc -m pytest -c tests/.configs/pytest.ini
coverage report --rcfile=./.coveragerc
coverage html --rcfile=./.coveragerc

Expand Down
2 changes: 2 additions & 0 deletions docs/main/changelog.rst
Expand Up @@ -15,7 +15,9 @@ Develop
- Add support of ``with`` statement for ``container.override_providers()`` method.
- Drop support of Python 3.4. There are no immediate breaking changes, but Dependency Injector
will no longer be tested on Python 3.4 and any bugs will not be fixed.
- Fix ``Dependency.is_defined`` attribute to always return boolean value.
- Update documentation and fix typos.
- Migrate tests to ``pytest``.

4.36.2
------
Expand Down
2 changes: 2 additions & 0 deletions requirements-dev.txt
@@ -1,4 +1,6 @@
cython==0.29.22
pytest
pytest-asyncio
tox
coverage
flake8
Expand Down
10 changes: 9 additions & 1 deletion src/dependency_injector/containers.pyi
Expand Up @@ -49,7 +49,7 @@ class Container:
def __delattr__(self, name: str) -> None: ...
def set_providers(self, **providers: Provider): ...
def set_provider(self, name: str, provider: Provider) -> None: ...
def override(self, overriding: C_Base) -> None: ...
def override(self, overriding: Union[Container, Type[Container]]) -> None: ...
def override_providers(self, **overriding_providers: Union[Provider, Any]) -> ProvidersOverridingContext[C_Base]: ...
def reset_last_overriding(self) -> None: ...
def reset_override(self) -> None: ...
Expand Down Expand Up @@ -88,6 +88,14 @@ class DeclarativeContainer(Container):
cls_providers: ClassVar[Dict[str, Provider]]
inherited_providers: ClassVar[Dict[str, Provider]]
def __init__(self, **overriding_providers: Union[Provider, Any]) -> None: ...
@classmethod
def override(cls, overriding: Union[Container, Type[Container]]) -> None: ...
@classmethod
def override_providers(cls, **overriding_providers: Union[Provider, Any]) -> ProvidersOverridingContext[C_Base]: ...
@classmethod
def reset_last_overriding(cls) -> None: ...
@classmethod
def reset_override(cls) -> None: ...


class ProvidersOverridingContext(Generic[T]):
Expand Down
27 changes: 17 additions & 10 deletions src/dependency_injector/providers.c
Expand Up @@ -17675,7 +17675,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_14set_de
* @property
* def is_defined(self): # <<<<<<<<<<<<<<
* """Return True if dependency is defined."""
* return self.__last_overriding or self.__default
* return self.__last_overriding is not None or self.__default is not None
*/

/* Python wrapper */
Expand All @@ -17696,6 +17696,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
__Pyx_RefNannyDeclarations
PyObject *__pyx_t_1 = NULL;
int __pyx_t_2;
PyObject *__pyx_t_3 = NULL;
int __pyx_lineno = 0;
const char *__pyx_filename = NULL;
int __pyx_clineno = 0;
Expand All @@ -17704,20 +17705,25 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
/* "dependency_injector/providers.pyx":774
* def is_defined(self):
* """Return True if dependency is defined."""
* return self.__last_overriding or self.__default # <<<<<<<<<<<<<<
* return self.__last_overriding is not None or self.__default is not None # <<<<<<<<<<<<<<
*
* def provided_by(self, provider):
*/
__Pyx_XDECREF(__pyx_r);
__pyx_t_2 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(1, 774, __pyx_L1_error)
__pyx_t_2 = (((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding) != Py_None);
if (!__pyx_t_2) {
} else {
__Pyx_INCREF(((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding));
__pyx_t_1 = ((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding);
__pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 774, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_1 = __pyx_t_3;
__pyx_t_3 = 0;
goto __pyx_L3_bool_binop_done;
}
__Pyx_INCREF(__pyx_v_self->__pyx___default);
__pyx_t_1 = __pyx_v_self->__pyx___default;
__pyx_t_2 = (__pyx_v_self->__pyx___default != Py_None);
__pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 774, __pyx_L1_error)
__Pyx_GOTREF(__pyx_t_3);
__pyx_t_1 = __pyx_t_3;
__pyx_t_3 = 0;
__pyx_L3_bool_binop_done:;
__pyx_r = __pyx_t_1;
__pyx_t_1 = 0;
Expand All @@ -17728,12 +17734,13 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
* @property
* def is_defined(self): # <<<<<<<<<<<<<<
* """Return True if dependency is defined."""
* return self.__last_overriding or self.__default
* return self.__last_overriding is not None or self.__default is not None
*/

/* function exit code */
__pyx_L1_error:;
__Pyx_XDECREF(__pyx_t_1);
__Pyx_XDECREF(__pyx_t_3);
__Pyx_AddTraceback("dependency_injector.providers.Dependency.is_defined.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
__pyx_r = NULL;
__pyx_L0:;
Expand All @@ -17743,7 +17750,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
}

/* "dependency_injector/providers.pyx":776
* return self.__last_overriding or self.__default
* return self.__last_overriding is not None or self.__default is not None
*
* def provided_by(self, provider): # <<<<<<<<<<<<<<
* """Set external dependency provider.
Expand Down Expand Up @@ -17805,7 +17812,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_16provid
goto __pyx_L0;

/* "dependency_injector/providers.pyx":776
* return self.__last_overriding or self.__default
* return self.__last_overriding is not None or self.__default is not None
*
* def provided_by(self, provider): # <<<<<<<<<<<<<<
* """Set external dependency provider.
Expand Down
2 changes: 1 addition & 1 deletion src/dependency_injector/providers.pyx
Expand Up @@ -771,7 +771,7 @@ cdef class Dependency(Provider):
@property
def is_defined(self):
"""Return True if dependency is defined."""
return self.__last_overriding or self.__default
return self.__last_overriding is not None or self.__default is not None

def provided_by(self, provider):
"""Set external dependency provider.
Expand Down
6 changes: 6 additions & 0 deletions tests/.configs/pytest-py27.ini
@@ -0,0 +1,6 @@
[pytest]
testpaths = tests/unit
python_files = test_*_py2_py3.py
filterwarnings =
ignore:Module \"dependency_injector.ext.aiohttp\" is deprecated since version 4\.0\.0:DeprecationWarning
ignore:Module \"dependency_injector.ext.flask\" is deprecated since version 4\.0\.0:DeprecationWarning
6 changes: 6 additions & 0 deletions tests/.configs/pytest-py35.ini
@@ -0,0 +1,6 @@
[pytest]
testpaths = tests/unit
python_files = test_*_py3.py
filterwarnings =
ignore:Module \"dependency_injector.ext.aiohttp\" is deprecated since version 4\.0\.0:DeprecationWarning
ignore:Module \"dependency_injector.ext.flask\" is deprecated since version 4\.0\.0:DeprecationWarning
6 changes: 6 additions & 0 deletions tests/.configs/pytest.ini
@@ -0,0 +1,6 @@
[pytest]
testpaths = tests/unit/
python_files = test_*_py3*.py
filterwarnings =
ignore:Module \"dependency_injector.ext.aiohttp\" is deprecated since version 4\.0\.0:DeprecationWarning
ignore:Module \"dependency_injector.ext.flask\" is deprecated since version 4\.0\.0:DeprecationWarning
2 changes: 1 addition & 1 deletion tests/unit/__init__.py
@@ -1 +1 @@
"""Dependency injector unit tests."""
"""Tests package."""
57 changes: 0 additions & 57 deletions tests/unit/asyncutils.py

This file was deleted.

8 changes: 8 additions & 0 deletions tests/unit/conftest.py
@@ -0,0 +1,8 @@
"""Fixtures module."""

import sys
import os.path


# Add current package to import samples/ dir
sys.path.append(os.path.dirname(__file__))
2 changes: 1 addition & 1 deletion tests/unit/containers/__init__.py
@@ -1 +1 @@
"""Dependency injector container unit tests."""
"""Container tests."""
1 change: 1 addition & 0 deletions tests/unit/containers/cls/__init__.py
@@ -0,0 +1 @@
"""Container class tests."""
36 changes: 36 additions & 0 deletions tests/unit/containers/cls/test_custom_strings_py2_py3.py
@@ -0,0 +1,36 @@
"""Tests for container cls with custom string classes as attribute names.
See: https://github.com/ets-labs/python-dependency-injector/issues/479
"""

from dependency_injector import containers, providers
from pytest import fixture, raises


class CustomString(str):
pass


class CustomClass:
thing = None


class Container(containers.DeclarativeContainer):
pass


@fixture
def provider():
return providers.Provider()


def test_setattr(provider):
setattr(Container, CustomString("test_attr"), provider)
assert Container.test_attr is provider


def test_delattr():
setattr(Container, CustomString("test_attr"), provider)
delattr(Container, CustomString("test_attr"))
with raises(AttributeError):
Container.test_attr

0 comments on commit 94aca21

Please sign in to comment.