Add sys_path_hacks/warn.py for easier modification of path warnings
This commit is contained in:
committed by
Kyle McCormick
parent
af958ada75
commit
b82ac1fc16
@@ -28,7 +28,7 @@ This deprecation will take place in the following steps:
|
||||
|
||||
2. For every module importable using the ``sys.path`` style (for instance, ``courseware``), duplicate that module structure into the ``sys_path_hacks/lms`` (or ``sys_path_hacks/studio``) directory. Each file in that directory should do a wild-card import of the corresponding ``lms.djangoapps.`` module, and should log a warning indicating where it was imported from. For example, in ``sys_path_hacks/lms/courseware/views/views.py``, it will wild-card import ``from lms.djangoapps.courseware.views.views import *``. The ``sys_path_hacks/clean.sh`` script will generate these files.
|
||||
|
||||
3. The ``sys.path`` modification will be changed to point to ``sys_path_hacks/lms``, rather than ``lms/djangoapps``. At this point, any code that references the modules directly will trigger warnings with logging about where the imports were coming from (to drive future cleanup efforts).
|
||||
3. The ``sys.path`` modification will be changed to point to ``sys_path_hacks/lms``, rather than ``lms/djangoapps``. At this point, any code that references the modules directly will trigger warnings with logging about where the imports were coming from (to drive future cleanup efforts). The warnings will be instances of ``SysPathHackWarning`` (subclass of ``DeprecationWarning``).
|
||||
|
||||
4. Fix all instances where the ``sys.path``-based modules were ``patch``-ed in unit tests, as those patches no longer work.
|
||||
|
||||
|
||||
@@ -1,17 +1,38 @@
|
||||
#! /bin/sh
|
||||
export TARGET=$1
|
||||
for path in $(find ${TARGET}/djangoapps/ -name '*.py' | grep -v migrations); do
|
||||
export new_path=$(echo $path | sed "s#${TARGET}/djangoapps/#sys_path_hacks/${TARGET}/#")
|
||||
export python_path=$(echo $path | sed "s#/#.#g" | sed "s#.py##" | sed "s#.__init__##")
|
||||
export old_python_path=$(echo $python_path | sed "s#${TARGET}.djangoapps.##")
|
||||
mkdir -p $(dirname $new_path)
|
||||
echo > $new_path <<SCRIPT
|
||||
import warnings
|
||||
import textwrap
|
||||
warnings.warn(textwrap.dedent("""\
|
||||
Importing $old_python_path instead of $python_path is deprecated. See https://github.com/edx/edx-platform/blob/master/docs/decisions/0007-sys-path-modification-removal.rst.
|
||||
""", stacklevel=2)
|
||||
#!/usr/bin/env bash
|
||||
# Example usage:
|
||||
# ~/edx-platform> sys_path_hacks/un_sys_path.sh lms
|
||||
# Writing sys_path_hacks/lms/.../xyz.py
|
||||
# ....
|
||||
# ~/edx-platform>
|
||||
|
||||
from $python_path import *
|
||||
SCRIPT
|
||||
# Shellchecks recommends using search/replace instead of sed. It's fine as is.
|
||||
# shellcheck disable=SC2001
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
TARGET="$1"
|
||||
for path in $(find "${TARGET}/djangoapps/" -name '*.py' | grep -v migrations); do
|
||||
if [[ "$path" == "${TARGET}/djangoapps/__init__.py" ]]; then
|
||||
# Skip unnecessary root __init__.py.
|
||||
continue
|
||||
fi
|
||||
if [[ "$path" == "lms/djangoapps/courseware/management/commands/import.py" ]]; then
|
||||
# Skip this file because its name is problematic for the sys path hack.
|
||||
# We've gone to prod with this excluded, and it hasn't been a problem.
|
||||
continue
|
||||
fi
|
||||
new_path=$(echo "$path" | sed "s#${TARGET}/djangoapps/#sys_path_hacks/${TARGET}/#")
|
||||
python_path=$(echo "$path" | sed "s#/#.#g" | sed "s#.py##" | sed "s#.__init__##")
|
||||
old_python_path=$(echo "$python_path" | sed "s#${TARGET}.djangoapps.##")
|
||||
echo "Writing ${new_path}"
|
||||
mkdir -p "$(dirname "$new_path")"
|
||||
{
|
||||
echo "from sys_path_hacks.warn import warn_deprecated_import"
|
||||
echo
|
||||
echo "warn_deprecated_import('${TARGET}.djangoapps', '${old_python_path}')"
|
||||
echo
|
||||
echo "from ${python_path} import *"
|
||||
} > "$new_path"
|
||||
done
|
||||
|
||||
44
sys_path_hacks/warn.py
Normal file
44
sys_path_hacks/warn.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
Utilities for warning about deprecated imports supported by the sys_path_hack/ system.
|
||||
|
||||
See /docs/decisions/0007-sys-path-modification-removal.rst for details.
|
||||
"""
|
||||
|
||||
import warnings
|
||||
|
||||
|
||||
class SysPathHackWarning(DeprecationWarning):
|
||||
"""
|
||||
A warning that a module is being imported from its old, non-prefixed location.
|
||||
|
||||
edx-platform modules should be imported from the root of the repository.
|
||||
For example, `from lms.djangoapps.course_wiki import views` is good.
|
||||
|
||||
However, we historically modify `sys.path` to allow importing relative to
|
||||
certain subdirectories. For example, `from course_wiki ipmort views` currently
|
||||
works.
|
||||
|
||||
We want to stardize on the prefixed version for a few different reasons.
|
||||
"""
|
||||
|
||||
def __init__(self, import_prefix, unprefixed_import_path):
|
||||
super().__init__()
|
||||
self.import_prefix = import_prefix
|
||||
self.unprefixed_import_path = unprefixed_import_path
|
||||
self.desired_import_path = import_prefix + "." + unprefixed_import_path
|
||||
|
||||
def __str__(self):
|
||||
return (
|
||||
"Importing {self.unprefixed_import_path} instead of "
|
||||
"{self.desired_import_path} is deprecated"
|
||||
).format(self=self)
|
||||
|
||||
|
||||
def warn_deprecated_import(import_prefix, unprefixed_import_path):
|
||||
"""
|
||||
Warn that a module is being imported from its old, non-prefixed location.
|
||||
"""
|
||||
warnings.warn(
|
||||
SysPathHackWarning(import_prefix, unprefixed_import_path),
|
||||
stacklevel=3, # Should surface the line that is doing the importing.
|
||||
)
|
||||
Reference in New Issue
Block a user