ImportError: cannot import name 'soft_unicode' from 'markupsafe'
This ImportError occurs when an older version of Jinja2 (or a dependent package) tries to import the soft_unicode
function from markupsafe
, which was removed in version 2.1.0. The error is common in Python environments where package version compatibility isn't properly maintained.
Problem Overview
The core issue stems from a breaking change introduced in markupsafe
version 2.1.0, where the soft_unicode
function was removed and replaced with soft_str
. Older versions of Jinja2 (and packages that depend on it) continue to reference the removed function, causing import failures.
The error typically appears as:
ImportError: cannot import name 'soft_unicode' from 'markupsafe'
Solution Approaches
1. Downgrade MarkupSafe (Quick Fix)
The most straightforward solution is to downgrade markupsafe
to a version that still includes soft_unicode
:
pip install markupsafe==2.0.1
WARNING
This is a temporary workaround that may cause dependency conflicts with other packages requiring newer versions of markupsafe
.
2. Upgrade Jinja2 (Recommended)
The preferred long-term solution is to upgrade Jinja2 to a version compatible with newer markupsafe
versions:
pip install --upgrade Jinja2
This ensures compatibility with the latest markupsafe
version while maintaining security updates and features.
pip install --upgrade Jinja2
conda update jinja2
3. Fix Docker Environment
If using Docker with Airflow (as in the original question), modify your docker-compose.yml
to specify the compatible markupsafe
version:
webserver:
image: puckel/docker-airflow:1.10.4
build:
context: https://github.com/puckel/docker-airflow.git#1.10.4
dockerfile: Dockerfile
args:
AIRFLOW_DEPS: gcp_api,s3
PYTHON_DEPS: MarkupSafe==2.0.1
Rebuild your containers after making this change:
docker-compose down
docker-compose up -d --build
4. Complete Environment Refresh
If downgrading doesn't work, you may need to completely remove and reinstall the package:
# Remove existing installation
pip uninstall markupsafe
# Clear any residual files (location may vary)
rm -rf /usr/local/lib/python*/site-packages/markupsafe
rm -rf /usr/local/lib/python*/site-packages/MarkupSafe-*.dist-info
# Reinstall compatible version
pip install markupsafe==2.0.1
Underlying Cause
The breaking change occurred when markupsafe
replaced soft_unicode
with soft_str
for better Python 3 compatibility. This change was introduced in:
markupsafe
version 2.1.0: Removedsoft_unicode
jinja2
version 3.0.0: Updated to usesoft_str
instead
You can check your dependency tree to identify compatibility issues:
pip install pipdeptree
pipdeptree -r -p markupsafe
Preventing Future Issues
To avoid similar dependency conflicts:
- Use virtual environments for project isolation
- Pin dependencies in
requirements.txt
with compatible versions - Regularly update packages to maintain compatibility
- Check dependency trees before major version upgrades
Best Practice
Always specify exact versions in production environments to ensure consistent behavior:
# requirements.txt
jinja2==3.1.2
markupsafe==2.1.1
Troubleshooting Steps
If you continue to experience issues:
Verify installation:
bashpython -c "import markupsafe; print(markupsafe.__version__)"
Check Jinja2 version:
bashpython -c "import jinja2; print(jinja2.__version__)"
Refresh virtual environment:
bashdeactivate source venv/bin/activate # or equivalent for your setup
Consider environment managers like
conda
that handle dependency resolution more rigorously.
Conclusion
The soft_unicode
import error is a classic dependency compatibility issue. While downgrading markupsafe
provides a quick fix, upgrading dependent packages (especially Jinja2) is the recommended long-term solution. Always maintain consistent dependency versions across development and production environments to prevent such issues.