Skip to content

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:

python
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:

bash
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.

The preferred long-term solution is to upgrade Jinja2 to a version compatible with newer markupsafe versions:

bash
pip install --upgrade Jinja2

This ensures compatibility with the latest markupsafe version while maintaining security updates and features.

bash
pip install --upgrade Jinja2
bash
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:

yaml
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:

bash
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:

bash
# 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: Removed soft_unicode
  • jinja2 version 3.0.0: Updated to use soft_str instead

You can check your dependency tree to identify compatibility issues:

bash
pip install pipdeptree
pipdeptree -r -p markupsafe

Preventing Future Issues

To avoid similar dependency conflicts:

  1. Use virtual environments for project isolation
  2. Pin dependencies in requirements.txt with compatible versions
  3. Regularly update packages to maintain compatibility
  4. Check dependency trees before major version upgrades

Best Practice

Always specify exact versions in production environments to ensure consistent behavior:

txt
# requirements.txt
jinja2==3.1.2
markupsafe==2.1.1

Troubleshooting Steps

If you continue to experience issues:

  1. Verify installation:

    bash
    python -c "import markupsafe; print(markupsafe.__version__)"
  2. Check Jinja2 version:

    bash
    python -c "import jinja2; print(jinja2.__version__)"
  3. Refresh virtual environment:

    bash
    deactivate
    source venv/bin/activate  # or equivalent for your setup
  4. 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.