Repository: redis/redis-py

Issue:
redis-py version attribute should be decoupled from the redis module
Following the conversation from https://github.com/redis/redis-py/issues/1625#issuecomment-991744836 looks like importing `redis` module prior to installation in `setup.py` for `version` attribute is not ideal.

Currently there are two places where module version is required.
- `setup.py` for module installation
- `redis/__init__.py` for module level `__version__` attribute

One way to fix this is to maintain a `version.py` file in top level directory and using that as source of truth in both the above places. 

@chayim @hartwork What do you think? I can create a PR for this :)


Discussion:
> looks like importing `redis` module prior to installation in `setup.py` for `version` attribute is not ideal.

When `setup.py` is being run, the current working directory is the first entry in `sys.path` so that Python will find the local redis package, installed or not. To see it in action, this diff may help:

```diff
diff --git a/setup.py b/setup.py
index 58d753f..ac8fc79 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,10 @@
 #!/usr/bin/env python
 from setuptools import find_packages, setup
 
+import sys
+print('\nPYTHONPATH:', file=sys.stderr)
+print('\n'.join(f'- {p!r}' for p in sys.path), file=sys.stderr)
+
 import redis
 
 setup(
```

> One way to fix this is to maintain a `version.py` file in top level directory and using that as source of truth in both the above places.

`version.py` sounds troublesome, since (1) we must not install it and (2) `redis.__version__` would need to come somewhere without that file being present.

Personally, I think touching this may make things worse.  `redis.__init__` is likely doing to much but it cannot do less now, because of keeping API backwards compatability. Reading from a plain text file would mean that file needs to be read on every import, as well. Would that really help? I'm not sure.

These are all of the things that using poetry (#1658) solves, for our package build and management - though I'm sure that will introduce new items to track down.

Reading versions from a file will at the very least make things slower and should be avoided.

As we're not (currently) going to solve these items with poetry - my goal would still be to move to a *pyproject.toml* like solution, and move the ball forward on [PEP 516](https://www.python.org/dev/peps/pep-0516/) / [PEP 517](https://www.python.org/dev/peps/pep-0517/) changes.

@ashwani99 Does tackling that interest you?
We are also seeing this issue in `django-redis` CI, when using master. 
[Here](https://github.com/jazzband/django-redis/runs/4504387991?check_suite_focus=true) are the logs. 
Is there something that I can do to help?
Nothing here - @ashwani99 did a fantastic job and his PR triggers highlights part of this issue, as discussed. Assigned to myself.

Resolving patch:
diff --git a/redis/__init__.py b/redis/__init__.py
--- a/redis/__init__.py
+++ b/redis/__init__.py
@@ -1,3 +1,10 @@
+import sys
+
+if sys.version_info >= (3, 8):
+    from importlib import metadata
+else:
+    import importlib_metadata as metadata
+
 from redis.client import Redis, StrictRedis
 from redis.cluster import RedisCluster
 from redis.connection import (
@@ -38,7 +45,10 @@ def int_or_str(value):
         return value
 
 
-__version__ = "4.1.0rc2"
+try:
+    __version__ = metadata.version("redis")
+except metadata.PackageNotFoundError:
+    __version__ = "99.99.99"
 
 
 VERSION = tuple(map(int_or_str, __version__.split(".")))
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -1,8 +1,6 @@
 #!/usr/bin/env python
 from setuptools import find_packages, setup
 
-import redis
-
 setup(
     name="redis",
     description="Python client for Redis database and key-value store",
@@ -10,7 +8,7 @@
     long_description_content_type="text/markdown",
     keywords=["Redis", "key-value store", "database"],
     license="MIT",
-    version=redis.__version__,
+    version="4.1.0rc2",
     packages=find_packages(
         include=[
             "redis",
@@ -26,12 +24,10 @@
     author="Redis Inc.",
     author_email="oss@redis.com",
     python_requires=">=3.6",
-    setup_requires=[
-        "packaging>=21.3",
-    ],
     install_requires=[
         "deprecated>=1.2.3",
         "packaging>=21.3",
+        'importlib-metadata >= 1.0; python_version < "3.8"',
     ],
     classifiers=[
         "Development Status :: 5 - Production/Stable",


Test patch: