diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index b64ef34..e21acff 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -1,5 +1,5 @@
[bumpversion]
-current_version = 3.4.6
+current_version = 3.4.7
[bumpversion:file:Makefile]
search = CURRENT_VERSION = {current_version}
diff --git a/CAVEATS.rst b/CAVEATS.rst
new file mode 100644
index 0000000..17c3a7a
--- /dev/null
+++ b/CAVEATS.rst
@@ -0,0 +1,39 @@
+=======
+Caveats
+=======
+
+This is a non-exhaustive list of known caveats to the usage of this library.
+
+Automatic dependency discovery
+------------------------------
+
+Injectable automatic dependency discovery system is inspired from Airflow's DAG automatic
+discovery. So first all files in the search path are recursively read looking for any
+occurrence of the following four strings: ``@injectable``, ``injectable(``,
+``@injectable_factory``, and ``injectable_factory(``. Then those files are executed as
+python modules so the decorators can register the injectable to the container.
+
+This implementation leads to some issues:
+
+* If, for any reason, the code aliases the decorators to other incompatible names or
+ do not use the decorator functions directly automatic dependency will fail and those
+ injectables will never be registered to the container.
+* Any file containing these strings will be executed causing potential unintended
+ side-effects such as file-level code outside classes and functions being executed.
+* The module of each injectable class may be loaded twice: one for in this automatic
+ discovery step and another by the regular application operation. This will render
+ impossible to run type checks for injected objects through the use of ``type`` or
+ ``isinstance`` builtin functions. If one must type check using the type's
+ ``__qualname__`` attribute is a possible workaround.
+
+Pytest and relative imports
+---------------------------
+
+As described in this issue: https://github.com/pytest-dev/pytest/issues/9007 , pytest
+won't work with injectable's automatic dependency discovery system if one declares
+injectables in the same file of the test itself, load the injection container during the
+test and use relative imports in this file. This corner-case combination will lead to an
+``AttributeError: 'AssertionRewritingHook' object has no attribute 'get_code'``.
+
+Currently the workaround for this is either to use absolute imports in these files or to
+move the declaration of injectables to any other file other than the test's file.
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 864adc6..b6b0940 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,11 +1,16 @@
Changelog
=========
+3.4.7 (2021-08-15)
+------------------
+
+* Fix injectable crashing when relative imports are used in files containing injectables.
+
3.4.6 (2021-03-20)
------------------
* Fix ``testing.register_injectables`` not creating the namespace when it doesn't exist
- yet
+ yet
3.4.5 (2021-03-11)
------------------
@@ -50,7 +55,7 @@ Changelog
------------------
* ``InjectionContainer::load`` is more resilient against duplicated injectables
- registering
+ registering
3.2.0 (2020-04-15)
------------------
@@ -76,7 +81,7 @@ Changelog
------------------
* Fix bug of scanning the same module more than once when ``InjectionContainer.load()``
- is called multiple times with different relative search paths.
+ is called multiple times with different relative search paths.
3.1.0 (2020-04-13)
------------------
@@ -121,11 +126,11 @@ Changelog
------------------
* Statically infer dependency's constructor suitability for injection instead of using
- trial instantiation
+ trial instantiation
* Fix bug of raising ``TypeError`` when injectable fails on the trial dependency
- instantiation which can happen when the dependency does provide a default
- constructor with no arguments but the running environment (possibly a test suite
- environment) will make the instantiation fail
+ instantiation which can happen when the dependency does provide a default
+ constructor with no arguments but the running environment (possibly a test suite
+ environment) will make the instantiation fail
1.1.0 (2018-02-10)
------------------
@@ -136,7 +141,7 @@ Changelog
------------------
* Fixes required dependency ``lazy_object_proxy`` not being installed when installing
- injectable through pip
+ injectable through pip
1.0.0 (2018-02-06)
------------------
diff --git a/Makefile b/Makefile
index 1a1794e..919f122 100644
--- a/Makefile
+++ b/Makefile
@@ -72,7 +72,7 @@ docs:
make html -B
cp -a build/html/. docs
-CURRENT_VERSION = 3.4.6
+CURRENT_VERSION = 3.4.7
.PHONY: bump-patch-version
bump-patch-version:
diff --git a/docs/.buildinfo b/docs/.buildinfo
index 231193b..ce63eb4 100644
--- a/docs/.buildinfo
+++ b/docs/.buildinfo
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: 1713a5b2b0df61545c670b29a0cc2394
+config: 608fa2521195fa2771065e2da377c1f9
tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/docs/_modules/index.html b/docs/_modules/index.html
index 814b0ab..1f0ddd8 100644
--- a/docs/_modules/index.html
+++ b/docs/_modules/index.html
@@ -4,7 +4,7 @@
Source code for injectable.container.injection_container
if file.pathincls.LOADED_FILEPATHS:continuecls.LOADING_FILEPATH=file.path
- run_path(file.path)
+ try:
+ run_module(module_finder.find_module_name(file.path))
+ exceptAttributeError:
+ # This is needed for some corner cases involving pytest
+ # See more at https://github.com/pytest-dev/pytest/issues/9007
+ run_path(file.path)cls.LOADED_FILEPATHS.add(file.path)cls.LOADING_FILEPATH=None
@@ -211,7 +216,12 @@
Source code for injectable.container.injection_container
if file.pathincls.LOADED_FILEPATHS:continuecls.LOADING_FILEPATH=file.path
- run_path(file.path)
+ try:
+ run_module(module_finder.find_module_name(file.path))
+ exceptAttributeError:
+ # This is needed for some corner cases involving pytest
+ # See more at https://github.com/pytest-dev/pytest/issues/9007
+ run_path(file.path)cls.LOADED_FILEPATHS.add(file.path)cls.LOADING_FILEPATH=Nonecls.LOADING_DEFAULT_NAMESPACE=None
@@ -284,7 +294,7 @@
Injectable automatic dependency discovery system is inspired from Airflow’s DAG automatic
+discovery. So first all files in the search path are recursively read looking for any
+occurrence of the following four strings: @injectable, injectable(,
+@injectable_factory, and injectable_factory(. Then those files are executed as
+python modules so the decorators can register the injectable to the container.
+
This implementation leads to some issues:
+
+
If, for any reason, the code aliases the decorators to other incompatible names or
+do not use the decorator functions directly automatic dependency will fail and those
+injectables will never be registered to the container.
+
Any file containing these strings will be executed causing potential unintended
+side-effects such as file-level code outside classes and functions being executed.
+
The module of each injectable class may be loaded twice: one for in this automatic
+discovery step and another by the regular application operation. This will render
+impossible to run type checks for injected objects through the use of type or
+isinstance builtin functions. If one must type check using the type’s
+__qualname__ attribute is a possible workaround.
As described in this issue: https://github.com/pytest-dev/pytest/issues/9007 , pytest
+won’t work with injectable’s automatic dependency discovery system if one declares
+injectables in the same file of the test itself, load the injection container during the
+test and use relative imports in this file. This corner-case combination will lead to an
+AttributeError:'AssertionRewritingHook'objecthasnoattribute'get_code'.
+
Currently the workaround for this is either to use absolute imports in these files or to
+move the declaration of injectables to any other file other than the test’s file.