[WIP] Feature Dependency Management #501
Closed
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TODO:
Outstanding questions:
prophet
optional dependency indetect
currently has two dependencies:pystan
andPyMeeus
(viafbprophet
) both of which are under"GNU General Public License v3 (GPLv3)"
license. They weren't coming up with prior license checks because the script that checks the licenses usesextras=all
in thetox-env
settings but there is noall
optional dependency option by default for pip installs instead it just gives a warning which I think is silenced inCI
. Now that I've addedall
for the optional dependencies work, they've turned up. These are optional dependencies so this isn't really an issue but it raises the question of how we should be checking the licenses? i.e. do we look at all the dependencies or just the defaults? If we check all we should flag those that are optional so we know how much of an issue it is, etc... For now, I've set the license checks to only run on the default dependencies.What is this PR?
This PR addresses optional dependency import functionality for Alibi Detect. The core behaviour this adds is to throw errors informing the user if they haven't installed the necessary optional dependency for the functionality they wish to use. These errors are thrown at use time rather than at import.
There are three behaviours in general:
backend
should be one of'tensorflow'
or'torch'
but not neither.This PR addresses behaviours 1 and 3 above.
Note:
In order to manually test alibi-detect in each of the different environments developers can use:
and this will give them a REPL with the
<env>
optional dependencies installed.For example:
make repl tox-env=torch
will give them the torch optional dependency environment REPL.The main changes are:
1. MissingDependency
The MissingDependency metaclass is used to allow imports that have missing dependencies. If these imports are used later they will throw an error.
Implementation
The basic pattern is to replace constructs that require uninstalled dependencies with something like:
We also use an import function which should be used throughout by developers when importing constructs dependent on optional dependencies in order to ensure consistent behaviour. This looks roughly like:
The above is called with:
The above raises an error if the user attempts to access an attribute or call the object.
UsefulClass
object is missing optional dependencies.pip install alibi-detect[optional-dependency]
.2. Refactoring:
The idea here is wherever the is an object that is dependent on an optional install the relevant functionality should be fenced off into a single file or collection of files. Access to that object should be via the
__init__.py
file. Within the__init__.py
we will implement theMissingDependency
pattern mentioned above.Note on Type checking issue:
import_optional
function returns an object instance rather than an object. This will cause typechecking to failif not all optional dependencies are installed. Because of this we also need to 1. Conditionally import the true object
dependent on
TYPE_CHECKING
and 2. Use forward referencing within typing constructs such asUnion
. We use forwardreferencing because in a user environment the optional dependency may not be installed in which case it'll be replaced
with an instance of the MissingDependency class. This will throw an error when passed to
Union
. SeeCONTRIBUTING.md
note for more details and example.3. Tests:
The tests import all the named objects from the public API of alibi and test that they throw the correct errors if the relevant optional dependencies are not installed. If these tests fail, it is likely that:
functionality should work for the default alibi-detect install. If this is not the case you should add the exported object name to the
dependency_map
in the relevant test.MissingDependency
class. In this case, see the docs string for theutils.missing_dependency
m1odule.Notes:
tox
from the terminal. The environments will take a long time to build the first time but afterwards, this should be a quick process.setup.cfg
file and add atestenv
environment as well as to theextra-requires.txt
file__init__.py
files.See also Further Notes