From 154e24909db588341c3b258bfecaaae83bd01b98 Mon Sep 17 00:00:00 2001
From: James Curtin <jameswcurtin@gmail.com>
Date: Wed, 27 Nov 2019 17:43:23 -0500
Subject: [PATCH] Warn when running Cookiecutter with incompatible python
 version

---
 hooks/__init__.py        |  0
 hooks/pre_gen_project.py | 45 ++++++++++++++++++++++------------------
 hooks/utils.py           | 19 +++++++++++++++++
 3 files changed, 44 insertions(+), 20 deletions(-)
 create mode 100644 hooks/__init__.py
 create mode 100644 hooks/utils.py

diff --git a/hooks/__init__.py b/hooks/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/hooks/pre_gen_project.py b/hooks/pre_gen_project.py
index 57b26303..e0232de2 100644
--- a/hooks/pre_gen_project.py
+++ b/hooks/pre_gen_project.py
@@ -2,37 +2,42 @@ import logging
 import re
 import sys
 
-LOGGER = logging.getLogger()
-MODULE_REGEX = r"^[_a-zA-Z][_a-zA-Z0-9]+$"
-
-
-class bcolors:
-    WARNING = "\033[93m"
-    ENDC = "\033[0m"
-    BOLD = "\033[1m"
-
+# Provide ability to import from the `hooks` directory
+sys.path.append("..")
 
-def colorize(escape_code, text):
-    code = getattr(bcolors, escape_code)
-    return f"{code}{text}{bcolors.ENDC}"
+logging.basicConfig()
+LOGGER = logging.getLogger(__name__)
+MODULE_REGEX = r"^[_a-zA-Z][_a-zA-Z0-9]+$"
 
 
-def log_warning(module_name):
+def check_python_version():
+    python_major_version = sys.version_info[0]
+    python_minor_version = sys.version_info[1]
+    # Must remain compatible with Python 2 to provide useful error message.
     warning = (
-        f"\n{colorize('WARNING', 'WARNING:')} {colorize('BOLD', module_name)}"
-        " is not a valid Python module name!\n"
-        "See https://www.python.org/dev/peps/pep-0008/#package-and-module-names"
-        " for naming standards.\n"
-    )
-    LOGGER.warning(warning)
+        "\nWARNING: You are running cookiecutter using "
+        "Python {}.{}, but a version >= Python 3.6+ is required.\n"
+        "Either install a more recent version of Python, or use the Docker instructions.\n"
+    ).format(python_major_version, python_minor_version)
+    if (python_major_version == 2) or (
+        python_major_version == 3 and python_minor_version < 6
+    ):
+        LOGGER.warning(warning)
+        sys.exit(1)
 
 
 def validate_python_module_name():
     module_name = "{{ cookiecutter.app_name }}"
     if not re.match(MODULE_REGEX, module_name):
-        log_warning(module_name)
+        log_module_name_warning(module_name, LOGGER)
         sys.exit(1)
 
 
 if __name__ == "__main__":
+    check_python_version()
+
+    # Import after validating Python version to prevent confusing SyntaxError
+    # for users with incompatible Python versions.
+    from hooks.utils import log_module_name_warning
+
     validate_python_module_name()
diff --git a/hooks/utils.py b/hooks/utils.py
new file mode 100644
index 00000000..a4580130
--- /dev/null
+++ b/hooks/utils.py
@@ -0,0 +1,19 @@
+class bcolors:
+    WARNING = "\033[93m"
+    ENDC = "\033[0m"
+    BOLD = "\033[1m"
+
+
+def colorize(escape_code, text):
+    code = getattr(bcolors, escape_code)
+    return f"{code}{text}{bcolors.ENDC}"
+
+
+def log_module_name_warning(module_name, logger):
+    warning = (
+        f"\n{colorize('WARNING', 'WARNING:')} {colorize('BOLD', module_name)}"
+        " is not a valid Python module name!\n"
+        "See https://www.python.org/dev/peps/pep-0008/#package-and-module-names"
+        " for naming standards.\n"
+    )
+    logger.warning(warning)
-- 
GitLab