We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Raise ImportError when installing/importing with old versions of Python, Astropy, & NumPy
We decided that PlasmaPy will only be supported for:
- Python version > 3.6
- Astropy version > 2.0
- NumPy version > 1.13

However, when I try to run:
```ShellSession
python setup.py install
```
from the command line with Python 3.5 then I get a `SyntaxError` for syntax that is new in version 3.6.

When I try to run
```Python
import plasmapy
```
in Python 3.6 with Astropy 1.3.1, then I get an exception since one of the constants imported from Astropy was renamed in 2.0.

We should raise an appropriate exception (probably an `ImportError`) when we try to install or import PlasmaPy with any of the unsupported versions above.  We should also have appropriate and useful error messages for any of these situations.  The pull request to close this issue would involve editing `setup.py`, `requirements/base.txt`, and `plasmapy/__init__.py`.

Thank you!
Nick

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plasmapy/__init__.py`
Content:
```
1 from ._metadata import (
2     name as __name__,
3     version as __version__,
4     description as __doc__,
5     author as __author__,
6 )
7 
8 from .classes import Plasma
9 from . import classes
10 from . import constants
11 from . import atomic
12 from . import math
13 from . import physics
14 from . import utils
15 
16 import sys
17 import warnings
18 
19 if sys.version_info[:2] < (3, 6):  # coveralls: ignore
20     warnings.warn("PlasmaPy does not support Python 3.5 and below")
21
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/plasmapy/__init__.py b/plasmapy/__init__.py
--- a/plasmapy/__init__.py
+++ b/plasmapy/__init__.py
@@ -5,16 +5,81 @@
     author as __author__,
 )
 
-from .classes import Plasma
-from . import classes
-from . import constants
-from . import atomic
-from . import math
-from . import physics
-from . import utils
-
 import sys
 import warnings
 
-if sys.version_info[:2] < (3, 6):  # coveralls: ignore
+__minimum_python_version__ = '3.6'
+__minimum_numpy_version__ = '1.13.0'
+__minimum_astropy_version__ = '2.0.0'
+
+
+def _split_version(version):
+    return tuple(int(ver) for ver in version.split('.'))
+
+
+def _min_required_version(required, current):  # coveralls: ignore
+    """ Return `True` if the current version meets the required minimum
+        version and `False` if not/ if not installed.
+
+        Right now `required` and `current` are just '.' separated strings
+        but it would be good to make this more general and accept modules.
+    """
+    return _split_version(current) >= _split_version(required)
+
+
+def _check_numpy_version():  # coveralls: ignore
+    """ Make sure numpy in installed and meets the minimum version requirements
+    """
+    required_version = False
+    np_ver = None
+
+    try:
+        from numpy import __version__ as np_ver
+        required_version = _min_required_version(__minimum_numpy_version__,
+                                                 np_ver)
+    except ImportError:
+        pass
+
+    if not required_version:
+        ver_error = ("Numpy {} or above is required for PlasmaPy. The "
+                     "currently installed version is {}"
+                     ).format(__minimum_numpy_version__, np_ver)
+        raise ImportError(ver_error)
+
+
+def _check_astropy_version():  # coveralls: ignore
+    """ Make sure astropy in installed and meets the minimum version requirements
+    """
+    required_version = False
+    ap_ver = None
+
+    try:
+        from astropy import __version__ as ap_ver
+        required_version = _min_required_version(__minimum_astropy_version__,
+                                                 ap_ver)
+    except ImportError:
+        pass
+
+    if not required_version:
+        ver_error = ("Astropy {} or above is required for PlasmaPy. The "
+                     "currently installed version is {}"
+                     ).format(__minimum_astropy_version__, ap_ver)
+        raise ImportError(ver_error)
+
+
+if (sys.version_info < _split_version(__minimum_python_version__)):  # coveralls: ignore
     warnings.warn("PlasmaPy does not support Python 3.5 and below")
+
+_check_numpy_version()
+_check_astropy_version()
+
+try:
+    from .classes import Plasma
+    from . import classes
+    from . import constants
+    from . import atomic
+    from . import math
+    from . import physics
+    from . import utils
+except Exception:
+    raise ImportError("Unable to load PlasmaPy subpackages.")

{"golden_diff": "diff --git a/plasmapy/__init__.py b/plasmapy/__init__.py\n--- a/plasmapy/__init__.py\n+++ b/plasmapy/__init__.py\n@@ -5,16 +5,81 @@\n     author as __author__,\n )\n \n-from .classes import Plasma\n-from . import classes\n-from . import constants\n-from . import atomic\n-from . import math\n-from . import physics\n-from . import utils\n-\n import sys\n import warnings\n \n-if sys.version_info[:2] < (3, 6):  # coveralls: ignore\n+__minimum_python_version__ = '3.6'\n+__minimum_numpy_version__ = '1.13.0'\n+__minimum_astropy_version__ = '2.0.0'\n+\n+\n+def _split_version(version):\n+    return tuple(int(ver) for ver in version.split('.'))\n+\n+\n+def _min_required_version(required, current):  # coveralls: ignore\n+    \"\"\" Return `True` if the current version meets the required minimum\n+        version and `False` if not/ if not installed.\n+\n+        Right now `required` and `current` are just '.' separated strings\n+        but it would be good to make this more general and accept modules.\n+    \"\"\"\n+    return _split_version(current) >= _split_version(required)\n+\n+\n+def _check_numpy_version():  # coveralls: ignore\n+    \"\"\" Make sure numpy in installed and meets the minimum version requirements\n+    \"\"\"\n+    required_version = False\n+    np_ver = None\n+\n+    try:\n+        from numpy import __version__ as np_ver\n+        required_version = _min_required_version(__minimum_numpy_version__,\n+                                                 np_ver)\n+    except ImportError:\n+        pass\n+\n+    if not required_version:\n+        ver_error = (\"Numpy {} or above is required for PlasmaPy. The \"\n+                     \"currently installed version is {}\"\n+                     ).format(__minimum_numpy_version__, np_ver)\n+        raise ImportError(ver_error)\n+\n+\n+def _check_astropy_version():  # coveralls: ignore\n+    \"\"\" Make sure astropy in installed and meets the minimum version requirements\n+    \"\"\"\n+    required_version = False\n+    ap_ver = None\n+\n+    try:\n+        from astropy import __version__ as ap_ver\n+        required_version = _min_required_version(__minimum_astropy_version__,\n+                                                 ap_ver)\n+    except ImportError:\n+        pass\n+\n+    if not required_version:\n+        ver_error = (\"Astropy {} or above is required for PlasmaPy. The \"\n+                     \"currently installed version is {}\"\n+                     ).format(__minimum_astropy_version__, ap_ver)\n+        raise ImportError(ver_error)\n+\n+\n+if (sys.version_info < _split_version(__minimum_python_version__)):  # coveralls: ignore\n     warnings.warn(\"PlasmaPy does not support Python 3.5 and below\")\n+\n+_check_numpy_version()\n+_check_astropy_version()\n+\n+try:\n+    from .classes import Plasma\n+    from . import classes\n+    from . import constants\n+    from . import atomic\n+    from . import math\n+    from . import physics\n+    from . import utils\n+except Exception:\n+    raise ImportError(\"Unable to load PlasmaPy subpackages.\")\n", "issue": "Raise ImportError when installing/importing with old versions of Python, Astropy, & NumPy\nWe decided that PlasmaPy will only be supported for:\r\n- Python version > 3.6\r\n- Astropy version > 2.0\r\n- NumPy version > 1.13\r\n\r\nHowever, when I try to run:\r\n```ShellSession\r\npython setup.py install\r\n```\r\nfrom the command line with Python 3.5 then I get a `SyntaxError` for syntax that is new in version 3.6.\r\n\r\nWhen I try to run\r\n```Python\r\nimport plasmapy\r\n```\r\nin Python 3.6 with Astropy 1.3.1, then I get an exception since one of the constants imported from Astropy was renamed in 2.0.\r\n\r\nWe should raise an appropriate exception (probably an `ImportError`) when we try to install or import PlasmaPy with any of the unsupported versions above.  We should also have appropriate and useful error messages for any of these situations.  The pull request to close this issue would involve editing `setup.py`, `requirements/base.txt`, and `plasmapy/__init__.py`.\r\n\r\nThank you!\r\nNick\n", "before_files": [{"content": "from ._metadata import (\n    name as __name__,\n    version as __version__,\n    description as __doc__,\n    author as __author__,\n)\n\nfrom .classes import Plasma\nfrom . import classes\nfrom . import constants\nfrom . import atomic\nfrom . import math\nfrom . import physics\nfrom . import utils\n\nimport sys\nimport warnings\n\nif sys.version_info[:2] < (3, 6):  # coveralls: ignore\n    warnings.warn(\"PlasmaPy does not support Python 3.5 and below\")\n", "path": "plasmapy/__init__.py"}], "after_files": [{"content": "from ._metadata import (\n    name as __name__,\n    version as __version__,\n    description as __doc__,\n    author as __author__,\n)\n\nimport sys\nimport warnings\n\n__minimum_python_version__ = '3.6'\n__minimum_numpy_version__ = '1.13.0'\n__minimum_astropy_version__ = '2.0.0'\n\n\ndef _split_version(version):\n    return tuple(int(ver) for ver in version.split('.'))\n\n\ndef _min_required_version(required, current):  # coveralls: ignore\n    \"\"\" Return `True` if the current version meets the required minimum\n        version and `False` if not/ if not installed.\n\n        Right now `required` and `current` are just '.' separated strings\n        but it would be good to make this more general and accept modules.\n    \"\"\"\n    return _split_version(current) >= _split_version(required)\n\n\ndef _check_numpy_version():  # coveralls: ignore\n    \"\"\" Make sure numpy in installed and meets the minimum version requirements\n    \"\"\"\n    required_version = False\n    np_ver = None\n\n    try:\n        from numpy import __version__ as np_ver\n        required_version = _min_required_version(__minimum_numpy_version__,\n                                                 np_ver)\n    except ImportError:\n        pass\n\n    if not required_version:\n        ver_error = (\"Numpy {} or above is required for PlasmaPy. The \"\n                     \"currently installed version is {}\"\n                     ).format(__minimum_numpy_version__, np_ver)\n        raise ImportError(ver_error)\n\n\ndef _check_astropy_version():  # coveralls: ignore\n    \"\"\" Make sure astropy in installed and meets the minimum version requirements\n    \"\"\"\n    required_version = False\n    ap_ver = None\n\n    try:\n        from astropy import __version__ as ap_ver\n        required_version = _min_required_version(__minimum_astropy_version__,\n                                                 ap_ver)\n    except ImportError:\n        pass\n\n    if not required_version:\n        ver_error = (\"Astropy {} or above is required for PlasmaPy. The \"\n                     \"currently installed version is {}\"\n                     ).format(__minimum_astropy_version__, ap_ver)\n        raise ImportError(ver_error)\n\n\nif (sys.version_info < _split_version(__minimum_python_version__)):  # coveralls: ignore\n    warnings.warn(\"PlasmaPy does not support Python 3.5 and below\")\n\n_check_numpy_version()\n_check_astropy_version()\n\ntry:\n    from .classes import Plasma\n    from . import classes\n    from . import constants\n    from . import atomic\n    from . import math\n    from . import physics\n    from . import utils\nexcept Exception:\n    raise ImportError(\"Unable to load PlasmaPy subpackages.\")\n", "path": "plasmapy/__init__.py"}]}