diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 064060d1b93cc812f0058c4a1ab1f18375aef0d7..29e740fd03f4eb77f2008cec76d249799bf59cce 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,7 +25,7 @@ Python 3.6:
 Documentation:
   script:
   - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/master/build-docs.sh
-  - export RELATE_LOCAL_TEST_SETTINGS=`pwd`/local_settings.example.py
+  - export RELATE_LOCAL_TEST_SETTINGS=`pwd`/local_settings_example.py
   - ". ./build-docs.sh"
   tags:
   - python3.5
diff --git a/course/management/commands/test.py b/course/management/commands/test.py
index 472148fdb43a5efa44d20883cf730e59ec5a90ad..2e2d9e15bcea85beabf8d6f6549dd624155f3abc 100644
--- a/course/management/commands/test.py
+++ b/course/management/commands/test.py
@@ -8,7 +8,7 @@ class Command(DjangoTestCommand):
             '--local_test_settings', action='store',
             dest='local_test_settings',
             help=('Overrides the default local test setting file path. '
-                  'The default value is "local_settings.example.py" in '
+                  'The default value is "local_settings_example.py" in '
                   'project root. Note that local settings for production '
                   '("local_settings.py") is not allowed to be used '
                   'for unit tests for security reason.')
diff --git a/doc/misc.rst b/doc/misc.rst
index 69f2c8f59248d0fde3b4885cc8936303eea732cb..f1022a8c6de82347ea94b76b76d2d7a830fab4f6 100644
--- a/doc/misc.rst
+++ b/doc/misc.rst
@@ -26,7 +26,7 @@ Install the dependencies::
 
 Copy (and, optionally, edit) the example configuration::
 
-    cp local_settings.example.py local_settings.py
+    cp local_settings_example.py local_settings.py
     vi local_settings.py
 
 Initialize the database::
diff --git a/local_settings.example.py b/local_settings_example.py
similarity index 100%
rename from local_settings.example.py
rename to local_settings_example.py
diff --git a/manage.py b/manage.py
index 6776c032fb2b2a54c35ddf400445f74790b5c061..9f7f9211eeada3c5fcc84ea9d7c5ea588278acb5 100755
--- a/manage.py
+++ b/manage.py
@@ -21,7 +21,7 @@ def get_local_test_settings_file(argv):
         raise
 
     if options.local_test_settings is None:
-        local_settings_file = "local_settings.example.py"
+        local_settings_file = "local_settings_example.py"
     else:
         local_settings_file = options.local_test_settings
 
diff --git a/relate/settings.py b/relate/settings.py
index 2a4752318c572fbe5055c20a3660787dbaace2d4..31e651c4520dd9792209fb4443844f210f40f4cb 100644
--- a/relate/settings.py
+++ b/relate/settings.py
@@ -14,6 +14,7 @@ if False:
 from django.conf.global_settings import STATICFILES_FINDERS, gettext_noop
 
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+import sys
 import os
 from os.path import join
 BASE_DIR = os.path.dirname(os.path.dirname(__file__))
@@ -27,17 +28,19 @@ if os.environ.get("RELATE_LOCAL_TEST_SETTINGS", None):
     assert _local_settings_file != os.environ["RELATE_LOCAL_TEST_SETTINGS"]
     _local_settings_file = os.environ["RELATE_LOCAL_TEST_SETTINGS"]
 
-local_settings = {
-        "__file__": _local_settings_file,
-        }
-try:
-    with open(_local_settings_file) as inf:
-        local_settings_contents = inf.read()
-except IOError:
-    pass
-else:
-    exec(compile(local_settings_contents, "local_settings.py", "exec"),
-            local_settings)
+if not os.path.isfile(_local_settings_file):
+    raise RuntimeError(
+        "Management command '%(cmd_name)s' failed to run "
+        "because '%(local_settings_file)s' is missing."
+        % {"cmd_name": sys.argv[1],
+           "local_settings_file": _local_settings_file})
+
+local_settings_module_name, ext = (
+    os.path.splitext(os.path.split(_local_settings_file)[-1]))
+assert ext == ".py"
+exec("import %s as local_settings_module" % local_settings_module_name)
+
+local_settings = local_settings_module.__dict__  # type: ignore  # noqa
 
 # {{{ django: apps
 
diff --git a/run-tests-for-ci.sh b/run-tests-for-ci.sh
index a574ca7d2b4ac5467c726599e8007e5a293aabaa..564aeae82b4d39fc81ca8764d6dd9e72f3db8783 100644
--- a/run-tests-for-ci.sh
+++ b/run-tests-for-ci.sh
@@ -62,7 +62,7 @@ fi
 
 $PIP install -r req.txt
 
-cp local_settings.example.py local_settings.py
+cp local_settings_example.py local_settings.py
 
 # Make sure i18n literals marked correctly
 ${PY_EXE} manage.py makemessages --no-location --ignore=req.txt > output.txt
diff --git a/setup.cfg b/setup.cfg
index 5c6d185ddf48226d1bc5e9ad37b91678e14786a9..d595f7774c00d1592488cdfca1810f1c635d9293 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -17,7 +17,7 @@ omit =
     exercise-docker.py
     update-attempt-ids.py
     setup.py
-    local_settings.example.py
+    local_settings_example.py
     course/page/code_feedback.py
     course/page/code_runpy_backend.py
     */wsgi.py
diff --git a/tests/test_checks.py b/tests/test_checks.py
index fdf29b89e910533a5607dfcf7ef2335bd412ae8f..e81fe2d709319ac909c3bb16e36954c71156e2c0 100644
--- a/tests/test_checks.py
+++ b/tests/test_checks.py
@@ -509,7 +509,7 @@ class CheckGitRoot(CheckRelateSettingsBase):
 class CheckRelateCourseLanguages(CheckRelateSettingsBase):
     """
     For this tests to pass, LANGUAGE_CODE, LANGUAGES, USE_I18N in
-    local_settings.example.py should not be configured"""
+    local_settings_example.py should not be configured"""
 
     msg_id_prefix = "relate_languages"
 
diff --git a/tests/test_views.py b/tests/test_views.py
index 77b0ef153ab062a7d622129b7b57e5d069bfbb3c..796a066c65ae1984510f55e2ca5c5df322eadc74 100644
--- a/tests/test_views.py
+++ b/tests/test_views.py
@@ -35,7 +35,7 @@ from tests.utils import mock
 DATE_TIME_PICKER_TIME_FORMAT = "%Y-%m-%d %H:%M"
 
 RELATE_FACILITIES = {
-    # intentionally to be different from local_settings.example.py
+    # intentionally to be different from local_settings_example.py
     "test_center1": {
         "ip_ranges": [
             "192.168.100.0/24",