diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 00000000..f8a20eda
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,8 @@
+# Contributing
+
+## Build documentation locally
+
+Using tox:
+```shell
+$ tox -e docs
+```
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
new file mode 100644
index 00000000..e4f0e0b3
--- /dev/null
+++ b/.github/SECURITY.md
@@ -0,0 +1,13 @@
+# Security Policy
+
+## Supported Versions
+
+Security updates are applied only to the latest release.
+
+## Reporting a Vulnerability
+
+If you have discovered a security vulnerability in this project, please report it privately. **Do not disclose it as a public issue.** This gives us time to work with you to fix the issue before public exposure, reducing the chance that the exploit will be used before a patch is released.
+
+Please disclose it at [security advisory](https://github.com/PythonCharmers/python-future/security/advisories/new).
+
+This project is maintained by a team of volunteers on a reasonable-effort basis. As such, please give us at least 90 days to work on a fix before public exposure.
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..bcefff65
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,46 @@
+name: CI
+
+on:
+ pull_request:
+ push:
+
+concurrency:
+ group: ${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ strategy:
+ fail-fast: false
+ matrix:
+ versions:
+ # - python: "2.6"
+ - python: "2.7"
+ - python: "3.3"
+ - python: "3.4"
+ - python: "3.5"
+ - python: "3.6"
+ - python: "3.7"
+ - python: "3.8"
+ - python: "3.9"
+
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - if: ${{ matrix.versions.python != '2.6' }}
+ run: |
+ docker build \
+ . \
+ --build-arg PYTHON_VERSION=${{ matrix.versions.python }} \
+ -t jmadler/python-future-builder:${{ matrix.versions.python }}
+ - if: ${{ matrix.versions.python == '2.6' }}
+ run: |
+ docker build \
+ . \
+ -f 2.6.Dockerfile \
+ -t jmadler/python-future-builder:${{ matrix.versions.python }}
+ - run: |
+ docker run \
+ -e PYTHON_VERSION=${{ matrix.versions.python }} \
+ jmadler/python-future-builder:${{ matrix.versions.python }} \
+ /root/python-future/test.sh
diff --git a/.gitignore b/.gitignore
index 8c52a551..1b8eaeb5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,8 @@ develop-eggs
.installed.cfg
lib
lib64
+MANIFEST
+MANIFEST.in
# Backup files
*.bak
@@ -41,3 +43,9 @@ nosetests.xml
.mr.developer.cfg
.project
.pydevproject
+
+# PyCharm / IntelliJ
+.idea
+
+# Generated test file
+mytempfile.py
diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml
new file mode 100644
index 00000000..dd8d0d65
--- /dev/null
+++ b/.pre-commit-hooks.yaml
@@ -0,0 +1,15 @@
+- id: futurize
+ name: futurize
+ description: Futurize your Py2 code to ensure it is runnable on Py3.
+ language: python
+ types: [python]
+ entry: futurize -w -n --no-diffs
+ args: [--stage1]
+
+- id: pasteurize
+ name: pasteurize
+ description: Pasteurize your Py3 code to ensure it is runnable on Py2.
+ language: python
+ language_version: python3
+ types: [python]
+ entry: pasteurize -w -n --no-diffs
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index eb28e459..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-sudo: false
-language: python
-cache: pip
-
-matrix:
- include:
- - python: 2.6
- env: TOXENV=py26
- - python: 2.7
- env: TOXENV=py27
- - python: 3.3
- env: TOXENV=py33
- - python: 3.4
- env: TOXENV=py34
- - python: 3.5
- env: TOXENV=py35
- - python: 3.6
- env: TOXENV=py36
- - python: 3.7
- env: TOXENV=py37
- dist: xenial # required for Python 3.7 (travis-ci/travis-ci#9069)
- sudo: required # required for Python 3.7 (travis-ci/travis-ci#9069)
-
-install:
- - pip install tox==2.9.1
- - pip install virtualenv==15.2.0
- - pip install py==1.4.30
- - pip install pluggy==0.5.2
-
-before_script:
- # Run flake8 tests only on Python 2.7 and 3.7...
- # 1) stop the build if there are Python syntax errors or undefined names
- # 2) exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
- - if [[ $TRAVIS_PYTHON_VERSION == *.7 ]]; then
- pip install flake8;
- flake8 . --count --exit-zero --select=E901,E999,F821,F822,F823 --show-source --statistics;
- flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics;
- fi
-
-script:
- - tox
diff --git a/2.6.Dockerfile b/2.6.Dockerfile
new file mode 100644
index 00000000..efaf3809
--- /dev/null
+++ b/2.6.Dockerfile
@@ -0,0 +1,26 @@
+FROM mrupgrade/deadsnakes:2.6
+
+RUN mkdir -p ~/.pip/ && echo '[global] \n\
+trusted-host = pypi.python.org\n\
+ pypi.org\n\
+ files.pythonhosted.org\n\
+' >> ~/.pip/pip.conf
+
+RUN apt-get update && \
+ apt-get install -y curl
+
+RUN mkdir -p /root/pip && \
+ cd /root/pip && \
+ curl -O https://files.pythonhosted.org/packages/8a/e9/8468cd68b582b06ef554be0b96b59f59779627131aad48f8a5bce4b13450/wheel-0.29.0-py2.py3-none-any.whl && \
+ curl -O https://files.pythonhosted.org/packages/31/77/3781f65cafe55480b56914def99022a5d2965a4bb269655c89ef2f1de3cd/importlib-1.0.4.zip && \
+ curl -O https://files.pythonhosted.org/packages/ef/41/d8a61f1b2ba308e96b36106e95024977e30129355fd12087f23e4b9852a1/pytest-3.2.5-py2.py3-none-any.whl && \
+ curl -O https://files.pythonhosted.org/packages/f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl && \
+ curl -O https://files.pythonhosted.org/packages/72/20/7f0f433060a962200b7272b8c12ba90ef5b903e218174301d0abfd523813/unittest2-1.1.0-py2.py3-none-any.whl && \
+ curl -O https://files.pythonhosted.org/packages/53/67/9620edf7803ab867b175e4fd23c7b8bd8eba11cb761514dcd2e726ef07da/py-1.4.34-py2.py3-none-any.whl && \
+ curl -O https://files.pythonhosted.org/packages/53/25/ef88e8e45db141faa9598fbf7ad0062df8f50f881a36ed6a0073e1572126/ordereddict-1.1.tar.gz && \
+ curl -O https://files.pythonhosted.org/packages/17/0a/6ac05a3723017a967193456a2efa0aa9ac4b51456891af1e2353bb9de21e/traceback2-1.4.0-py2.py3-none-any.whl && \
+ curl -O https://files.pythonhosted.org/packages/65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl && \
+ curl -O https://files.pythonhosted.org/packages/c7/a3/c5da2a44c85bfbb6eebcfc1dde24933f8704441b98fdde6528f4831757a6/linecache2-1.0.0-py2.py3-none-any.whl
+
+WORKDIR /root/python-future
+ADD . /root/python-future
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 00000000..c859757f
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,7 @@
+ARG PYTHON_VERSION
+FROM python:${PYTHON_VERSION}-slim
+
+ENV LC_ALL=C.UTF-8
+
+WORKDIR /root/python-future
+ADD . /root/python-future
diff --git a/LICENSE.txt b/LICENSE.txt
index d41c85d1..275cafd3 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2013-2018 Python Charmers Pty Ltd, Australia
+Copyright (c) 2013-2024 Python Charmers, Australia
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.rst b/README.rst
index 807ea2a0..a3aceb7d 100644
--- a/README.rst
+++ b/README.rst
@@ -3,6 +3,9 @@
Overview: Easy, clean, reliable Python 2/3 compatibility
========================================================
+.. image:: https://github.com/PythonCharmers/python-future/actions/workflows/ci.yml/badge.svg?branch=master
+ :target: https://github.com/PythonCharmers/python-future/actions/workflows/ci.yml?query=branch%3Amaster
+
``python-future`` is the missing compatibility layer between Python 2 and
Python 3. It allows you to use a single, clean Python 3.x-compatible
codebase to support both Python 2 and Python 3 with minimal overhead.
@@ -13,18 +16,27 @@ ports of features from Python 3 and 2. It also comes with ``futurize`` and
either Py2 or Py3 code easily to support both Python 2 and 3 in a single
clean Py3-style codebase, module by module.
-Notable projects that use ``python-future`` for Python 2/3 compatibility
-are `Mezzanine `_ and `ObsPy
-`_.
+The ``python-future`` project has been downloaded over 1.7 billion times.
+
+.. _status
+
+Status
+------
+
+The ``python-future`` project was created in 2013 to attempt to save Python from
+the schism of version incompatibility that was threatening to tear apart the
+language (as Perl 6 contributed to the death of Perl).
+
+That time is now past. Thanks to a huge porting effort across the Python
+community, Python 3 eventually thrived. Python 2 reached its end of life in
+2020 and the ``python-future`` package should no longer be necessary. Use it to
+help with porting legacy code to Python 3 but don't depend on it for new code.
.. _features:
Features
--------
-.. image:: https://travis-ci.org/PythonCharmers/python-future.svg?branch=master
- :target: https://travis-ci.org/PythonCharmers/python-future
-
- ``future.builtins`` package (also available as ``builtins`` on Py2) provides
backports and remappings for 20 builtins with different semantics on Py3
versus Py2
@@ -57,6 +69,8 @@ Features
decoding the backported ``str`` and ``bytes`` objects. [This feature is
currently in alpha.]
+- support for pre-commit hooks
+
.. _code-examples:
Code examples
@@ -218,11 +232,14 @@ into this code which runs on both Py2 and Py3:
name = input()
greet(name)
+The first four lines have no effect under Python 3 and can be removed from
+the codebase when Python 2 compatibility is no longer required.
+
See :ref:`forwards-conversion` and :ref:`backwards-conversion` for more details.
Automatic translation
----------------------
+~~~~~~~~~~~~~~~~~~~~~
The ``past`` package can automatically translate some simple Python 2
modules to Python 3 upon import. The goal is to support the "long tail" of
@@ -243,7 +260,7 @@ Example:
$ python3
- >>> from past import autotranslate
+ >>> from past.translation import autotranslate
>>> autotranslate(['plotrique'])
>>> import plotrique
@@ -259,30 +276,64 @@ properly to a Python 2/3 compatible codebase using a tool like
Note: the auto-translation feature is still in alpha; it needs more testing and
development, and will likely never be perfect.
-For more info, see :ref:`translation`.
+
+Pre-commit hooks
+~~~~~~~~~~~~~~~~
+
+`Pre-commit `_ is a framework for managing and maintaining
+multi-language pre-commit hooks.
+
+In case you need to port your project from Python 2 to Python 3, you might consider
+using such hook during the transition period.
+
+First:
+
+.. code-block:: bash
+
+ $ pip install pre-commit
+
+and then in your project's directory:
+
+.. code-block:: bash
+
+ $ pre-commit install
+
+Next, you need to add this entry to your ``.pre-commit-config.yaml``
+
+.. code-block:: yaml
+
+ - repo: https://github.com/PythonCharmers/python-future
+ rev: master
+ hooks:
+ - id: futurize
+ args: [--both-stages]
+
+The ``args`` part is optional, by default only stage1 is applied.
Licensing
---------
:Author: Ed Schofield, Jordan M. Adler, et al
-:Copyright: 2013-2018 Python Charmers Pty Ltd, Australia.
+:Copyright: 2013-2024 Python Charmers, Australia.
+
+:Sponsors: Python Charmers: https://pythoncharmers.com
-:Sponsors: Python Charmers Pty Ltd, Australia, and Python Charmers Pte
- Ltd, Singapore. http://pythoncharmers.com
-
- Pinterest https://opensource.pinterest.com/
+ Pinterest https://opensource.pinterest.com
-:Licence: MIT. See ``LICENSE.txt`` or `here `_.
+:Licence: MIT. See ``LICENSE.txt`` or `here `_.
-:Other credits: See `here `_.
+:Other credits: See `here `_.
+Docs
+----
+See the docs `here `_.
Next steps
----------
If you are new to Python-Future, check out the `Quickstart Guide
-`_.
+`_.
For an update on changes in the latest version, see the `What's New
-`_ page.
+`_ page.
diff --git a/TESTING.txt b/TESTING.txt
index 1c29b6a6..b2ad5c65 100644
--- a/TESTING.txt
+++ b/TESTING.txt
@@ -1,7 +1,11 @@
-Currently the tests are passing on OS X and Linux on Python 2.7 and 3.4.
+A docker image, python-future-builder, is used to do testing and building. The test suite can be run with:
-The test suite can be run with:
+ $ bash build.sh
- $ tox
+which tests the module under a number of different python versions, where available, or with:
-which tests the module under a number of different python versions, where available.
+ $ py.test
+
+To execute a single test:
+
+ $ pytest -k test_chained_exceptions_stacktrace
diff --git a/docs/3rd-party-py3k-compat-code/jinja2_compat.py b/docs/3rd-party-py3k-compat-code/jinja2_compat.py
index 1326cbc6..0456faae 100644
--- a/docs/3rd-party-py3k-compat-code/jinja2_compat.py
+++ b/docs/3rd-party-py3k-compat-code/jinja2_compat.py
@@ -85,7 +85,7 @@ def encode_filename(filename):
def with_metaclass(meta, *bases):
# This requires a bit of explanation: the basic idea is to make a
- # dummy metaclass for one level of class instanciation that replaces
+ # dummy metaclass for one level of class instantiation that replaces
# itself with the actual metaclass. Because of internal type checks
# we also need to make sure that we downgrade the custom metaclass
# for one level to something closer to type (that's why __call__ and
diff --git a/docs/_templates/navbar.html b/docs/_templates/navbar.html
index b77fb767..fc96b5ca 100644
--- a/docs/_templates/navbar.html
+++ b/docs/_templates/navbar.html
@@ -12,7 +12,6 @@
-
{% if theme_navbar_title -%}{{ theme_navbar_title|e }}{%- else -%}{{ project|e }}{%- endif -%}
{{ version|e }}
diff --git a/docs/_templates/sidebarintro.html b/docs/_templates/sidebarintro.html
index e4433221..25325ec3 100644
--- a/docs/_templates/sidebarintro.html
+++ b/docs/_templates/sidebarintro.html
@@ -1,7 +1,7 @@
Easy, clean, reliable Python 2/3 compatibility
- Table of Contents
+ Table of Contents