diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml
new file mode 100644
index 00000000..fb218d88
--- /dev/null
+++ b/.github/workflows/lint_python.yml
@@ -0,0 +1,24 @@
+name: lint_python
+on: [pull_request, push]
+jobs:
+ lint_python:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
+ - run: pip install --upgrade pip wheel
+ - run: pip install bandit black codespell flake8 flake8-bugbear
+ flake8-comprehensions isort mypy pytest pyupgrade safety
+ - run: bandit --recursive --skip B311 .
+ - run: black --check . || true
+ - run: codespell # --ignore-words-list="" --skip="*.css,*.js,*.lock"
+ - run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
+ - run: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88
+ --show-source --statistics
+ - run: isort --check-only --profile black . || true
+ - run: pip install -r requirements.txt
+ - run: mkdir --parents --verbose .mypy_cache
+ - run: mypy --ignore-missing-imports --install-types --non-interactive . || true
+ - run: pytest .
+ - run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true
+ - run: safety check
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..eefd55ca
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,56 @@
+name: Test
+
+on: [push, pull_request, workflow_dispatch]
+
+env:
+ FORCE_COLOR: 1
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ["pypy-2.7", "pypy-3.8", "2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10"]
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ include:
+ # Add new helper variables to existing jobs
+ - {python-version: "pypy-2.7", toxenv: "pypy"}
+ - {python-version: "pypy-3.8", toxenv: "pypy3"}
+ - {python-version: "2.7", toxenv: "py27"}
+ - {python-version: "3.5", toxenv: "py35"}
+ - {python-version: "3.6", toxenv: "py36"}
+ - {python-version: "3.7", toxenv: "py37"}
+ - {python-version: "3.8", toxenv: "py38"}
+ - {python-version: "3.9", toxenv: "py39"}
+ - {python-version: "3.10", toxenv: "py310"}
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ - name: Get pip cache dir
+ id: pip-cache
+ run: |
+ echo "::set-output name=dir::$(pip cache dir)"
+
+ - name: Cache
+ uses: actions/cache@v2
+ with:
+ path: ${{ steps.pip-cache.outputs.dir }}
+ key:
+ ${{ matrix.os }}-${{ matrix.python-version }}-v1-${{ hashFiles('**/tox.ini') }}
+ restore-keys: |
+ ${{ matrix.os }}-${{ matrix.python-version }}-v1-
+
+ - name: Install dependencies
+ run: |
+ python -m pip install tox
+
+ - name: Tox tests
+ run: |
+ tox -e ${{ matrix.toxenv }}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 7e11b000..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-language: python
-cache: pip
-matrix:
- include:
- - python: 2.7
- - python: 3.8
- - arch: arm64
- python: 3.7
- - arch: amd64
- python: 3.7
- - python: 3.6
- - python: 3.5
- - python: pypy
-install:
- - "pip install mock"
-script: "python -m unittest discover -p *_test.py"
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index f88f449b..2d028f68 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,6 +1,24 @@
+0.4.5 In progress, unreleased
+ * Catch a racy ValueError that could occur on exit.
+ * Create README-hacking.md, for Colorama contributors.
+ * Tweak some README unicode characters that don't render correctly on PyPI.
+ * Fix some tests that were failing on some operating systems.
+ * Add support for Python 3.9.
+ * Add support for PyPy3.
+ * Add support for pickling with the ``dill`` module.
+0.4.4 Current release
+ * Re-org of README, to put the most insteresting parts near the top.
+ * Added Linux makefile targets and Windows powershell scripts to
+ automate bootstrapping a development environment, and automate the
+ process of testing wheels before they are uploaded to PyPI.
+ * Use stdlib unittest.mock where available
+ * Travis CI now also builds on arm64
+ * Demo06 demonstrates existing cursor positioning feature
+ * Fix OSC regex & handling to prevent hang or crash
+ * Document enterprise support by Tidelift
0.4.3
* Fix release 0.4.2 which was uploaded with missing files.
-0.4.2
+0.4.2 BROKEN DO NOT USE
* #228: Drop support for EOL Python 3.4, and add 3.7 and 3.8.
Thanks to hugovk.
* Several additions and fixes to documentation and metadata.
@@ -150,7 +168,7 @@
* Remove setup.py dependency on setuptools, now uses stdlib distutils.
0.1.8
* Fix ghastly errors all over the place on Ubuntu.
- * Add init kwargs 'convert' and 'strip', which supercede the old 'wrap'.
+ * Add init kwargs 'convert' and 'strip', which supersede the old 'wrap'.
0.1.7
* Python 3 compatible.
* Fix: Now strips ansi on windows without necessarily converting it to
diff --git a/Makefile b/Makefile
index 53682844..924a1b60 100644
--- a/Makefile
+++ b/Makefile
@@ -50,16 +50,16 @@ test: ## Run tests
# build packages
-build: ## Build an sdist and wheel
+build: ## Build a release (sdist and wheel)
$(python) -m pip install --upgrade setuptools wheel
$(python) setup.py sdist bdist_wheel
-.PHONY: sdist
+.PHONY: build
-test-release: build
+test-release: build ## Test a built release
./test-release
.PHONY: test-release
-release: ## Upload our sdist and wheel
- $(twine) upload dist/colorama-$(version)-*
+release: ## Upload a built release
+ $(twine) upload dist/colorama-$(version)*
.PHONY: release
diff --git a/README-hacking.md b/README-hacking.md
new file mode 100644
index 00000000..1213aa43
--- /dev/null
+++ b/README-hacking.md
@@ -0,0 +1,134 @@
+# Colorama Development
+
+Help and fixes are welcome!
+
+Although Colorama has no requirements other than the Python standard library,
+development requires some Python packages, which are captured in
+requirements-dev.txt.
+
+Throughout, if you're on a Mac, you can probably do something similar to the
+Linux instructions. Either use the makefile directly, or look in it to see
+what commands it executes, and manually execute something similar. PRs to
+automate for Mac appreciated! Especially if they just made the existing Linux
+Makefile targets work on Mac too.
+
+## Desired changes
+
+Colorama is unexpectedly popular, and is now a transitive dependency of many
+popular and high profile projects. If we break backwards compatibility, even in a
+subtle way, we can break applications - or pip installs - for lots of people.
+
+In addition, the project already takes more time & energy to maintain than
+the maintainers currently have available - for example the original author
+is now a parent, and no longer uses Windows, so time and motivation for this
+project are both much lower than they used to be.
+
+As a result of both the above, we are very conservative in what sorts of
+changes we can accept. Generally, we are not keen on new features. Even if
+they are small, they still add to the future maintenance burden, increasing
+the surface area into which future bugs or compatibility breaks could be
+introduced.
+
+This is especially true if they are new ways to generate ANSI codes (e.g.
+context managers for handling Fore, Back or Style changes.), since it has
+always been Colorama's stance that if you want to print ANSI codes, then yes
+we can help out with that in a rudimentary way, but if you want to do advanced
+things, then you should be using a different library that specializes in that,
+such as Termcolor, Blessings, or Rich. These libraries are much better than
+Colorama at generating ANSI codes for colors and the like, and probably
+already include the feature you are trying to add to Colorama, plus many
+more.
+
+In addition to using those libraries, if you call colorama.init(), then your
+fancy new colors, etc, will also work on Windows. This is the main purpose
+of Colorama.
+
+The kinds of submissions we would encourage work towards that goal, or fix
+bugs, or improve compatibility across operating systems or environements.
+
+## Makefile and PowerShell scripts
+
+Some common commands are captured as Linux makefile targets (which could
+perhaps be coaxed into running on OSX in Bash), and as Windows PowerShell
+scripts.
+
+| Task | Linux | Windows |
+|---------------------------------|---------------------|----------------------|
+| Create & populate virtualenv. | `make bootstrap` | `.\bootstrap.ps1` |
+| Run tests. | `make test` | `.\test.ps1` |
+| Build a wheel. | `make build` | `.\build.ps1` |
+| Test the wheel. | `make test-release` | `.\test-release.ps1` |
+| Release the wheel on PyPI | `make release` | `.\release.ps1` |
+| Clean generated files & builds. | `make clean` | `.\clean.ps1` |
+
+The Makefile is self-documenting, so 'make' with no args will describe each
+target.
+
+## Release checklist
+
+1. Check the CHANGELOG is updated with everything since the last release.
+
+2. First we'll make a candidate release. Ensure the '-candidate1' suffix is
+ present on `__version__` in `colorama/__init.py__.py`.
+
+3. Run the tests locally on your preferred OS, just to save you from doing
+ the following time-consuming steps while there are still obvious problems
+ in the code:
+
+ * Windows:
+ * First allow powershell to execute scripts, see:
+ https://stackoverflow.com/a/32328091
+ * `powershell bootstrap.ps1`
+ * `powershell test.ps1`
+ * Linux:
+ * `make bootstrap`
+ * `make test`
+
+4. Verify you're all committed, merged to master, and pushed to origin (This
+ triggers a CI build, which we'll check later on)
+
+5. Tag the current commit with the `__version__` from `colorama/__init__.py`.
+ We should start using
+ [annotated tags for releases](https://www.tartley.com/posts/til-git-annotated-tags/), so:
+
+ git tag -a -m "" $version
+ git push --follow-tags
+
+6. Build the distributables (sdist and wheel), on either OS:
+
+ * Windows: `.\build.ps1`
+ * Linux: `make build`
+
+7. Test the distributables on both OS. Whichever one you do 2nd will get an
+ HTTP 400 response on uploading to test.pypi.org, but outputs a message
+ saying this is expected and carries on:
+
+ * Windows: `.\test-release.ps1`
+ * Linux: `make test-release`
+
+ (This currently only tests the wheel, but
+ [should soon test the sdist too](https://github.com/tartley/colorama/issues/286).)
+
+8. Check the [CI builds](https://github.com/tartley/colorama/actions/)
+ are complete and all passing.
+
+9. Upload the distributables to PyPI:
+
+ * On Windows: `.\release.ps1`
+ * On Linux: `make release`
+
+10. Test by installing the candidate version from PyPI, and sanity check it with
+ 'demo.sh', making sure this is running against the PyPI installation, not
+ local source.
+
+11. Maybe wait a day for anyone using pre-release installs to report any
+ problems?
+
+12. Remove the '.candidateX' suffix from `__version__` in
+ `colorama/__init__.py`.
+
+13. Repeat steps 5 to 10, for the actual (non-candidate) release.
+
+14. Bump the version number in `colorama/__init__.py`, and add the '-pre'
+ suffix again, ready for the next release. Commit and push this (directly to
+ master is fine.)
diff --git a/README.rst b/README.rst
index e44933da..9a349ac1 100644
--- a/README.rst
+++ b/README.rst
@@ -6,8 +6,8 @@
:target: https://pypi.org/project/colorama/
:alt: Supported Python versions
-.. image:: https://travis-ci.org/tartley/colorama.svg?branch=master
- :target: https://travis-ci.org/tartley/colorama
+.. image:: https://github.com/tartley/colorama/actions/workflows/test.yml/badge.svg
+ :target: https://github.com/tartley/colorama/actions/workflows/test.yml
:alt: Build Status
Colorama
@@ -20,8 +20,8 @@ cursor positioning) work under MS Windows.
:target: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2MZ9D2GMLYCUJ&item_name=Colorama¤cy_code=USD
:alt: Donate with Paypal
-`PyPI for releases `_ ·
-`Github for source `_ ·
+`PyPI for releases `_ |
+`Github for source `_ |
`Colorama for enterprise on Tidelift `_
If you find Colorama useful, please |donate| to the authors. Thank you!
@@ -30,6 +30,10 @@ If you find Colorama useful, please |donate| to the authors. Thank you!
Installation
------------
+Tested on CPython 2.7, 3.5, 3.6, 3.7, 3.8, 3.9 and 3.10 and Pypy 2.7 and 3.6.
+
+No requirements other than the standard library.
+
.. code-block:: bash
pip install colorama
@@ -93,9 +97,12 @@ text sent to ``stdout`` or ``stderr``, and replace them with equivalent Win32
calls.
On other platforms, calling ``init()`` has no effect (unless you request other
-optional functionality; see "Init Keyword Args", below). By design, this permits
-applications to call ``init()`` unconditionally on all platforms, after which
-ANSI output should just work.
+optional functionality, see "Init Keyword Args" below; or if output
+is redirected). By design, this permits applications to call ``init()``
+unconditionally on all platforms, after which ANSI output should just work.
+
+On all platforms, if output is redirected, ANSI escape sequences are completely
+stripped out.
To stop using Colorama before your program exits, simply call ``deinit()``.
This will restore ``stdout`` and ``stderr`` to their original values, so that
@@ -107,7 +114,8 @@ Colored Output
..............
Cross-platform printing of colored text can then be done using Colorama's
-constant shorthand for ANSI escape sequences:
+constant shorthand for ANSI escape sequences. These are deliberately
+rudimentary, see below.
.. code-block:: python
@@ -127,8 +135,13 @@ constant shorthand for ANSI escape sequences:
...or, Colorama can be used in conjunction with existing ANSI libraries
such as the venerable `Termcolor `_
-or the fabulous `Blessings `_.
-This is highly recommended for anything more than trivial coloring:
+the fabulous `Blessings `_,
+or the incredible `_Rich `_.
+
+If you wish Colorama's Fore, Back and Style constants were more capable,
+then consider using one of the above highly capable libraries to generate
+colors, etc, and use Colorama just for its primary purpose: to convert
+those ANSI sequences to also work on Windows:
.. code-block:: python
@@ -150,6 +163,11 @@ Available formatting constants are::
``Style.RESET_ALL`` resets foreground, background, and brightness. Colorama will
perform this reset automatically on program exit.
+These are fairly well supported, but not part of the standard::
+
+ Fore: LIGHTBLACK_EX, LIGHTRED_EX, LIGHTGREEN_EX, LIGHTYELLOW_EX, LIGHTBLUE_EX, LIGHTMAGENTA_EX, LIGHTCYAN_EX, LIGHTWHITE_EX
+ Back: LIGHTBLACK_EX, LIGHTRED_EX, LIGHTGREEN_EX, LIGHTYELLOW_EX, LIGHTBLUE_EX, LIGHTMAGENTA_EX, LIGHTCYAN_EX, LIGHTWHITE_EX
+
Cursor Positioning
..................
@@ -296,6 +314,10 @@ I'd love to hear about it on that issues list, would be delighted by patches,
and would be happy to grant commit access to anyone who submits a working patch
or two.
+If you're hacking on the code, see `README-hacking.md`_.
+
+.. _README-hacking.md: README-hacking.md
+
License
-------
@@ -304,51 +326,6 @@ Copyright Jonathan Hartley & Arnon Yaari, 2013-2020. BSD 3-Clause license; see
LICENSE file.
-Development
------------
-
-Help and fixes welcome!
-
-Tested on CPython 2.7, 3.5, 3.6, 3.7 and 3.8.
-
-No requirements other than the standard library.
-Development requirements are captured in requirements-dev.txt.
-
-To create and populate a virtual environment::
-
- ./bootstrap.ps1 # Windows
- make bootstrap # Linux
-
-To run tests::
-
- ./test.ps1 # Windows
- make test # Linux
-
-If you use nose to run the tests, you must pass the ``-s`` flag; otherwise,
-``nosetests`` applies its own proxy to ``stdout``, which confuses the unit
-tests.
-
-To build a local wheel file::
-
- ./build.ps1 # Windows
- make build # Linux
-
-To test the wheel, (upload to test PyPI, then 'pip install' & use it)::
-
- ./test-release.ps1 # Windows
- make test-release # Linux
-
-To upload the wheel to PyPI::
-
- ./release.ps1 # Windows
- make release # Linux
-
-To clean all generated files, builds, virtualenv::
-
- ./clean.ps1 # Windows
- make clean # Linux
-
-
Professional support
--------------------
@@ -401,4 +378,3 @@ Thanks
to include Python 3.3 and 3.4
* Andy Neff for fixing RESET of LIGHT_EX colors.
* Jonathan Hartley for the initial idea and implementation.
-
diff --git a/bootstrap.ps1 b/bootstrap.ps1
index 3260f8b4..53ba3314 100644
--- a/bootstrap.ps1
+++ b/bootstrap.ps1
@@ -1,4 +1,4 @@
-$syspython="python3.8.exe"
+$syspython="python.exe"
$ve="$HOME\.virtualenvs\colorama"
$bin="$ve\Scripts"
diff --git a/clean.ps1 b/clean.ps1
index de9ba5ae..a2a59af3 100644
--- a/clean.ps1
+++ b/clean.ps1
@@ -1,4 +1,4 @@
-$syspython="python3.8.exe"
+$syspython="python.exe"
$ve="$HOME\.virtualenvs\colorama"
remove-item -r -fo * -I build,dist,MANIFEST,colorama.egg-info,$ve,sandbox
diff --git a/colorama/__init__.py b/colorama/__init__.py
index b149ed79..9138a8cc 100644
--- a/colorama/__init__.py
+++ b/colorama/__init__.py
@@ -3,4 +3,4 @@
from .ansi import Fore, Back, Style, Cursor
from .ansitowin32 import AnsiToWin32
-__version__ = '0.4.4'
+__version__ = '0.4.5'
diff --git a/colorama/ansitowin32.py b/colorama/ansitowin32.py
index 6039a054..3db248ba 100644
--- a/colorama/ansitowin32.py
+++ b/colorama/ansitowin32.py
@@ -37,6 +37,12 @@ def __enter__(self, *args, **kwargs):
def __exit__(self, *args, **kwargs):
return self.__wrapped.__exit__(*args, **kwargs)
+ def __setstate__(self, state):
+ self.__dict__ = state
+
+ def __getstate__(self):
+ return self.__dict__
+
def write(self, text):
self.__convertor.write(text)
@@ -57,7 +63,9 @@ def closed(self):
stream = self.__wrapped
try:
return stream.closed
- except AttributeError:
+ # AttributeError in the case that the stream doesn't support being closed
+ # ValueError for the case that the stream has already been detached when atexit runs
+ except (AttributeError, ValueError):
return True
diff --git a/colorama/tests/ansitowin32_test.py b/colorama/tests/ansitowin32_test.py
index 99ebd292..bbc647ba 100644
--- a/colorama/tests/ansitowin32_test.py
+++ b/colorama/tests/ansitowin32_test.py
@@ -1,5 +1,5 @@
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
-from io import StringIO
+from io import StringIO, TextIOWrapper
from unittest import TestCase, main
try:
@@ -40,6 +40,17 @@ def testProxyNoContextManager(self):
with StreamWrapper(mockStream, mockConverter) as wrapper:
wrapper.write('hello')
+ def test_closed_shouldnt_raise_on_closed_stream(self):
+ stream = StringIO()
+ stream.close()
+ wrapper = StreamWrapper(stream, None)
+ self.assertEqual(wrapper.closed, True)
+
+ def test_closed_shouldnt_raise_on_detached_stream(self):
+ stream = TextIOWrapper(StringIO())
+ stream.detach()
+ wrapper = StreamWrapper(stream, None)
+ self.assertEqual(wrapper.closed, True)
class AnsiToWin32Test(TestCase):
@@ -170,13 +181,19 @@ def test_reset_all_shouldnt_raise_on_closed_orig_stdout(self):
def test_wrap_shouldnt_raise_on_closed_orig_stdout(self):
stream = StringIO()
stream.close()
- converter = AnsiToWin32(stream)
- self.assertFalse(converter.strip)
+ with \
+ patch("colorama.ansitowin32.os.name", "nt"), \
+ patch("colorama.ansitowin32.winapi_test", lambda: True):
+ converter = AnsiToWin32(stream)
+ self.assertTrue(converter.strip)
self.assertFalse(converter.convert)
def test_wrap_shouldnt_raise_on_missing_closed_attr(self):
- converter = AnsiToWin32(object())
- self.assertFalse(converter.strip)
+ with \
+ patch("colorama.ansitowin32.os.name", "nt"), \
+ patch("colorama.ansitowin32.winapi_test", lambda: True):
+ converter = AnsiToWin32(object())
+ self.assertTrue(converter.strip)
self.assertFalse(converter.convert)
def testExtractParams(self):
diff --git a/colorama/tests/initialise_test.py b/colorama/tests/initialise_test.py
index 4acea46d..7bbd18f9 100644
--- a/colorama/tests/initialise_test.py
+++ b/colorama/tests/initialise_test.py
@@ -1,5 +1,4 @@
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
-import os
import sys
from unittest import TestCase, main, skipUnless
@@ -10,7 +9,7 @@
from ..ansitowin32 import StreamWrapper
from ..initialise import init
-from .utils import osname, redirected_output, replace_by
+from .utils import osname, replace_by
orig_stdout = sys.stdout
orig_stderr = sys.stderr
diff --git a/colorama/tests/utils.py b/colorama/tests/utils.py
index 3e393fbb..472fafb4 100644
--- a/colorama/tests/utils.py
+++ b/colorama/tests/utils.py
@@ -4,10 +4,6 @@
import sys
import os
-try:
- from unittest.mock import Mock
-except ImportError:
- from mock import Mock
class StreamTTY(StringIO):
def isatty(self):
@@ -24,14 +20,6 @@ def osname(name):
yield
os.name = orig
-@contextmanager
-def redirected_output():
- orig = sys.stdout
- sys.stdout = Mock()
- sys.stdout.isatty = lambda: False
- yield
- sys.stdout = orig
-
@contextmanager
def replace_by(stream):
orig_stdout = sys.stdout
diff --git a/demos/demo.sh b/demos/demo.sh
index d8cbbcca..eb05b076 100644
--- a/demos/demo.sh
+++ b/demos/demo.sh
@@ -27,8 +27,9 @@ rm -f demo04.out
# Demonstrate the difference between colorama initialized with wrapping on and off.
python demo05.py
-# Demonstrate printing colored, random characters at random positions on the screen
-python demo06.py
+# Skip demo06
+# It is too visually disruptive,
+# making it hard to see whether any of the demos are working correctly.
# Demonstrate cursor relative movement: UP, DOWN, FORWARD, and BACK in colorama.CURSOR
python demo07.py
diff --git a/demos/demo09.py b/demos/demo09.py
new file mode 100644
index 00000000..e4b898f8
--- /dev/null
+++ b/demos/demo09.py
@@ -0,0 +1,21 @@
+# https://www.youtube.com/watch?v=F5a8RLY2N8M&list=PL1_riyn9sOjcKIAYzo7f8drxD-Yg9La-D&index=61
+# Generic colorama demo using command line arguments
+# By George Ogden
+from colorama import Fore, Back, Style, init
+import argparse
+parser = argparse.ArgumentParser("colorama demo")
+
+def format(module):
+ return list(map(lambda x: x.lower(),module.__dict__.keys()))
+
+def find(module,item):
+ return module.__dict__[item.upper()]
+
+parser.add_argument("-c","--colour",choices=format(Fore),default="RESET")
+parser.add_argument("-b","--background",choices=format(Back),default="RESET")
+parser.add_argument("-s","--style",choices=format(Style),default="RESET_ALL")
+parser.add_argument("-t","--text",default="Lorem ipsum dolor sit amet")
+
+args = parser.parse_args()
+
+print(find(Style,args.style) + find(Fore,args.colour) + find(Back,args.background) + args.text + Style.RESET_ALL)
\ No newline at end of file
diff --git a/release.ps1 b/release.ps1
index e01014d0..ac4e2682 100644
--- a/release.ps1
+++ b/release.ps1
@@ -3,5 +3,5 @@ $bin="$ve\Scripts"
$version="$(& $bin\python.exe setup.py --version)"
# Upload to PyPI.
-& $bin\twine.exe upload dist\colorama-$version-*
+& $bin\twine.exe upload dist\colorama-$version*.tar.gz dist\colorama-$version-*.whl
diff --git a/setup.py b/setup.py
index 31720d02..4221fe1b 100644
--- a/setup.py
+++ b/setup.py
@@ -3,6 +3,7 @@
from __future__ import with_statement
+from io import open
import os
import re
try:
@@ -14,8 +15,9 @@
NAME = 'colorama'
-def read_file(path):
- with open(os.path.join(os.path.dirname(__file__), path)) as fp:
+def read_file(path, encoding='ascii'):
+ with open(os.path.join(os.path.dirname(__file__), path),
+ encoding=encoding) as fp:
return fp.read()
def _get_version_match(content):
@@ -57,6 +59,8 @@ def get_version(path):
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Terminals',
diff --git a/test-release b/test-release
index fc20b06e..d22eec1a 100644
--- a/test-release
+++ b/test-release
@@ -13,13 +13,13 @@
# Exit on error
set -eu -o pipefail
-syspython=python3.8
+syspython=python3
bin="$HOME/.virtualenvs/colorama/bin"
version=$($bin/python setup.py --version)
sandbox=test-release-playground
# Upload to the test PyPI.
-$bin/twine upload --repository testpypi dist/colorama-$version-* \
+$bin/twine upload --repository testpypi dist/colorama-$version* \
|| echo " > Expect a 400 if package was already uploaded."
# cd elsewhere so we cannot import from local source.
@@ -31,7 +31,8 @@ mkdir -p $sandbox
$syspython -m venv --clear venv
# Install the package we just uploaded.
- venv/bin/python -m pip --quiet install --index-url https://test.pypi.org/simple colorama==$version
+ # (--extra-index-url for this project's requirements)
+ venv/bin/python -m pip --quiet install --index-url https://test.pypi.org/simple --extra-index-url https://pypi.org/simple colorama==$version
# Import and use Colorama from the temp virtualenv.
venv/bin/python -c "import colorama; colorama.init(); print(colorama.Fore.GREEN + \"OK: Colorama\", colorama.__version__, \"from test pypi install.\")"
diff --git a/test-release.ps1 b/test-release.ps1
index 0466cf91..950dfdaa 100644
--- a/test-release.ps1
+++ b/test-release.ps1
@@ -1,4 +1,4 @@
-$syspython="python3.8.exe"
+$syspython="python.exe"
$ve="$HOME\.virtualenvs\colorama"
$bin="$ve\Scripts"
$version="$(& $bin\python.exe setup.py --version)"
@@ -17,7 +17,8 @@ cd sandbox
& $syspython -m venv --clear venv
# Install the package we just uploaded.
-venv\Scripts\python -m pip --quiet install --index-url https://test.pypi.org/simple colorama==$version
+# (--extra-index-url for this project's requirements)
+venv\Scripts\python -m pip --quiet install --index-url https://test.pypi.org/simple --extra-index-url https://pypi.org/simple colorama==$version
# Import and use colorama from the temp virtualenv.
venv\Scripts\python.exe -c @"
import colorama;
diff --git a/tox.ini b/tox.ini
index aa8c7830..721d811d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = py27, py35, py36, py37, py38, pypy
+envlist = py27, py35, py36, py37, py38, py39, py310, pypy, pypy3
[testenv]
deps = py27,pypy: mock