Repository: tensorflow/addons

Issue:
List TensorFlow as an "extra" requirement to install the correct TFA for a given TF version
When installing `tensorflow_addons` without specifying an exact version, users may install a version that is incompatible with their existing TensorFlow version.  

As such, users are advised to check the [Python Op Compatibility Matrix](https://github.com/tensorflow/addons#python-op-compatibility-matrix) and manually install the correct version of TFA to be safe.

For most Python projects, this can be taken care of automatically by listing a specific `tensorflow` version(s) as a requirement in the `setup.py` file:

```
install_requires=['tensorflow>=2.2,<2.4']
```

I suspect that this project does not do this because of the various different pip package names TensorFlow uses (e.g., `tf-nightly`, `tensorflow-gpu`, `tensorflow-cpu`).  By having such a requirement, user could accidentally install two different versions of TensorFlow at the same time.

To get around this, we could introduce an extra requirement:

```
extras_require = {'tensorflow': ['tensorflow>=2.2,<2.4']}
```

This way, users will only get automatic dependency resolution when running `pip install tensorflow_addons[tensorflow]`.

The benefit of doing this is that if a new version of TFA is released that no longer supports TensorFlow 2.2 (for example), pip will fall back to installing the previous version of TFA if the user has TF 2.2 installed.


Discussion:
The origin was https://github.com/tensorflow/addons/pull/974
Thanks for the added context, @bhack!  

Looks like the reason for the removal was indeed to do with `tf-nightly` and `tensorflow-cpu`, so the approach described here should not conflict with that.  We could even, if desired, add additional extras like `tensorflow_addons[tensorflow-cpu]` for these use cases.

What do you think @seanpmorgan?

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -76,6 +76,8 @@ def has_ext_modules(self):
 
 
 project_name, version = get_project_name_version()
+min_tf_version = version["MIN_TF_VERSION"]
+max_tf_version = version["MAX_TF_VERSION"]
 setup(
     name=project_name,
     version=version["__version__"],
@@ -86,6 +88,15 @@ def has_ext_modules(self):
     packages=find_packages(),
     ext_modules=get_ext_modules(),
     install_requires=Path("requirements.txt").read_text().splitlines(),
+    extras_require={
+        "tensorflow": ["tensorflow>={},<{}".format(min_tf_version, max_tf_version)],
+        "tensorflow-gpu": [
+            "tensorflow-gpu>={},<{}".format(min_tf_version, max_tf_version)
+        ],
+        "tensorflow-cpu": [
+            "tensorflow-cpu>={},<{}".format(min_tf_version, max_tf_version)
+        ],
+    },
     include_package_data=True,
     zip_safe=False,
     distclass=BinaryDistribution,
diff --git a/tensorflow_addons/utils/ensure_tf_install.py b/tensorflow_addons/utils/ensure_tf_install.py
--- a/tensorflow_addons/utils/ensure_tf_install.py
+++ b/tensorflow_addons/utils/ensure_tf_install.py
@@ -23,8 +23,7 @@
 
 import tensorflow as tf
 
-MIN_TF_VERSION = "2.2.0"
-MAX_TF_VERSION = "2.4.0"
+from tensorflow_addons.version import MIN_TF_VERSION, MAX_TF_VERSION
 
 
 def _check_tf_version():
diff --git a/tensorflow_addons/version.py b/tensorflow_addons/version.py
--- a/tensorflow_addons/version.py
+++ b/tensorflow_addons/version.py
@@ -14,6 +14,10 @@
 # ============================================================================
 """Define TensorFlow Addons version information."""
 
+# Required TensorFlow version [min, max)
+MIN_TF_VERSION = "2.2.0"
+MAX_TF_VERSION = "2.4.0"
+
 # We follow Semantic Versioning (https://semver.org/)
 _MAJOR_VERSION = "0"
 _MINOR_VERSION = "12"


Test patch: