pax_global_header00006660000000000000000000000064143256444710014524gustar00rootroot0000000000000052 comment=3de9f013df4b470069d03d250224062e8cf15c49 colorama-0.4.6/000077500000000000000000000000001432564447100133305ustar00rootroot00000000000000colorama-0.4.6/.github/000077500000000000000000000000001432564447100146705ustar00rootroot00000000000000colorama-0.4.6/.github/FUNDING.yml000066400000000000000000000014331432564447100165060ustar00rootroot00000000000000# These are supported funding model platforms # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] # github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] # issuehunt: # Replace with a single IssueHunt username # ko_fi: # Replace with a single Ko-fi username # liberapay: # Replace with a single Liberapay username # open_collective: # Replace with a single Open Collective username # otechie: # Replace with a single Otechie username # patreon: # Replace with a single Patreon username custom: ["https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=2MZ9D2GMLYCUJ&item_name=Colorama¤cy_code=USD"] tidelift: "pypi/colorama" colorama-0.4.6/.github/workflows/000077500000000000000000000000001432564447100167255ustar00rootroot00000000000000colorama-0.4.6/.github/workflows/lint_python.yml000066400000000000000000000021171432564447100220200ustar00rootroot00000000000000name: 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 colorama-0.4.6/.github/workflows/test.yml000066400000000000000000000030551432564447100204320ustar00rootroot00000000000000name: 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.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.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 }} colorama-0.4.6/.gitignore000066400000000000000000000001461432564447100153210ustar00rootroot00000000000000*.pyc *.egg-info .coverage .tox/ /MANIFEST /build/ /dist/ /sandbox/ /tags virtualenv # PyCharm .idea colorama-0.4.6/CHANGELOG.rst000066400000000000000000000247011432564447100153550ustar00rootroot000000000000000.4.6 Current release * https://github.com/tartley/colorama/pull/139 Add alternative to 'init()', called 'just_fix_windows_console'. This fixes many longstanding problems with 'init', such as working incorrectly on modern Windows terminals, and wonkiness when init gets called multiple times. The intention is that it just makes all Windows terminals treat ANSI the same way as other terminals do. Many thanks the njsmith for fixing our messes. * https://github.com/tartley/colorama/pull/352 Support Windows 10's ANSI/VT console. This didn't exist when Colorama was created, and avoiding us causing havok there is long overdue. Thanks to segeviner for the initial approach, and to njsmith for getting it merged. * https://github.com/tartley/colorama/pull/338 Internal overhaul of package metadata declaration, which abolishes our use of the now heavily discouraged setuptools (and hence setup.py, setup.cfg and MANIFEST.in), in favor of hatchling (and hence pyproject.toml), generously contributed by ofek (author of hatchling). This includes dropping support Python3.5 and 3.6, which are EOL, and were already dropped from setuptools, so this should not affect our users. * https://github.com/tartley/colorama/pull/353 Attention to detail award to LqdBcnAtWork for a spelling fix in demo06 0.4.5 * 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 * 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 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. * Added Tidelift subscription information. 0.4.1 * Fix issue #196: prevent exponential number of calls when calling 'init' multiple times. Reported by bbayles and fixed by Delgan. 0.4.0 * Fix issue #142: reset LIGHT_EX colors with RESET_ALL. Reported by Delgan * Fix issue #147: ignore invalid "erase" ANSI codes. Reported by shin- * Fix issues #163 and #164: fix stream wrapping under PyCharm. Contributed by veleek and Delgan. * Thanks to jdufresne for various code cleanup and updates to documentation and project metadata. (pull requests #171, #172, #173, #174, #176, #177, #189, #190, #192) * #186: added contextlib magic methods to ansitowin32.StreamWrapper. Contributed by hoefling. * Fix issue #131: don't cache stdio handles, since they might be closed/changed by fd redirection. This fixes an issue with pytest. Contributed by segevfiner. * #146, #157: Drop support for EOL Python 2.5, 2.6, 3.1, 3.2 and 3.3, and add 3.6. Thanks to hugovk. 0.3.9 * Revert fix for issue #103 which causes problems for dependent applications 0.3.8 * Fix issue #121: "invalid escape sequence" deprecation fixes on Python 3.6+ * Fix issue #110: fix "set console title" when working with unicode strings * Fix issue #103: enable color when using "input" function on Python 3.5+ * Fix issue #95: enable color when stderr is a tty but stdout is not 0.3.7 * Fix issue #84: check if stream has 'closed' attribute before testing it * Fix issue #74: objects might become None at exit 0.3.6 * Fix issue #81: fix ValueError when a closed stream was used 0.3.5 * Bumping version to re-upload a wheel distribution 0.3.4 * Fix issue #47 and #80 - stream redirection now strips ANSI codes on Linux * Fix issue #53 - strip readline markers * Fix issue #32 - assign orig_stdout and orig_stderr when initialising * Fix issue #57 - Fore.RESET did not reset style of LIGHT_EX colors. Fixed by Andy Neff * Fix issue #51 - add context manager syntax. Thanks to Matt Olsen. * Fix issue #48 - colorama didn't work on Windows when environment variable 'TERM' was set. * Fix issue #54 - fix pylint errors in client code. * Changes to readme and other improvements by Marc Abramowitz and Zearin 0.3.3 * Fix Google Code issue #13 - support changing the console title with OSC escape sequence * Fix Google Code issue #16 - Add support for Windows xterm emulators * Fix Google Code issue #30 - implement \033[nK (clear line) * Fix Google Code issue #49 - no need to adjust for scroll when new position is already relative (CSI n A\B\C\D) * Fix Google Code issue #55 - erase_data fails on Python 3.x * Fix Google Code issue #46 - win32.COORD definition missing * Implement \033[0J and \033[1J (clear screen options) * Fix default ANSI parameters * Fix position after \033[2J (clear screen) * Add command shortcuts: colorama.Cursor, colorama.ansi.set_title, colorama.ansi.clear_line, colorama.ansi.clear_screen * Fix issue #22 - Importing fails for python3 on Windows * Thanks to John Szakmeister for adding support for light colors * Thanks to Charles Merriam for adding documentation to demos 0.3.2 * Thanks to Marc Schlaich (schlamar) for a setup.py fix for Python2.5 * Thanks to Jurko for fix on 64-bit Windows CPython2.5 w/o ctypes (Google Code issue #56) * Thanks to Remi Rampin for: * better github integration, incl rendered README and Travis config. * fixed forward slashes in README * Thanks to Florian Bruhin for fix when stdout or stderr are None * Thanks to Simeon Visser for: * closing a file handle using 'with' * updating classifiers to include Python 3.3 and 3.4 * Thanks to Thomas Weininger for fix ValueError on Windows (Google Code issue #50) 0.3.1 * Fixed crash on exit with closed stdout, with thanks to Marc Abramowitz. * Now uses setuptools if available, and falls back to distutils if not. * setup.py no longer imports anything from colorama source. 0.3.0 * Move repository to Git, https://github.com/tartley/colorama. (My Mercurial repo seemed to be corrupted, I couldn't commit nor view patches of old commits, even on fresh checkouts.) * Fix always-crash on non-Windows platforms, reported by Matt McCormick. * Fix Google Code issue #47, incompatible with pyreadline. 0.2.7 * Fix problem under 64-bit windows due to ctypes HANDLE size. Submitted by the rather magnificent Ben Hoyt. This fixes Google Code issue #43 0.2.6 * Add copyright & licensing info to every file, as requested by a large downstream project which has problems making sure that all 3rd party contributions have appropriate license. 0.2.5 * Several documentation & demo fixes. 0.2.4 * Fix to work on Windows 7. * Python 3 compatibility in docs and demos. * Add handling for 'cursor up' and 'get position' ANSI codes. 0.2.3 * Split changelog out into separate file. 0.2.2 * Fix bug which caused init() to raise, introduced in 0.2.1. * Remove asserts which cause problems in various circumstances. At least some users saw asserts fail on 'success' returned from win32 functions, even though the win32 functions appear to have worked correctly. 0.2.1 * Completely broken: I added a bug which caused init() to raise. * Added some documentation for cursor positioning and clear screen to README. * Add 'reinit' and 'deinit' functions, as suggested by Charles FOL and Romanov DA. 0.2 * Merge in changes from Daniel Griffith: Add ANSI cursor positioning & partial support for clear screen. Patch submitted by Oscar Lester, don't send RESET_ALL to non-tty. * Demos split into separate files and moved into their own directory. * Tweak sys.path in demos so they run against local source, not installed version of Colorama. 0.1.18 * Fix README (no such attr as Fore.DEFAULT, etc), kindly reported by nodakai. 0.1.17 * Prevent printing of garbage ANSI codes upon installing with pip 0.1.16 * Re-upload to fix previous error. Make clean now removes old MANIFEST. 0.1.15 * Completely broken. Distribution was empty due to leftover invalid MANIFEST file from building on a different platform. * Fix python3 incompatibility kindly reported by G |uumlaut| nter Kolousek 0.1.14 * Fix hard-coded reset to white-on-black colors. Fore.RESET, Back.RESET and Style.RESET_ALL now revert to the colors as they were when init() was called. Some lessons hopefully learned about testing prior to release. 0.1.13 * Completely broken: barfed when installed using pip. 0.1.12 * Completely broken: contained no source code. double oops. 0.1.11 * Completely broken: fatal import errors on Ubuntu. oops. 0.1.10 * Stop emulating 'bright' text with bright backgrounds. * Display 'normal' text using win32 normal foreground instead of bright. * Drop support for 'dim' text. 0.1.9 * Fix incompatibility with Python 2.5 and earlier. * 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 supersede the old 'wrap'. 0.1.7 * Python 3 compatible. * Fix: Now strips ansi on windows without necessarily converting it to win32 calls (eg. if output is not a tty.) * Fix: Flaky interaction of interleaved ansi sent to stdout and stderr. * Improved demo.sh (hg checkout only.) 0.1.6 * Fix ansi sequences with no params now default to parmlist of [0]. * Fix flaky behaviour of autoreset and reset_all atexit. * Fix stacking of repeated atexit calls - now just called once. * Fix ghastly import problems while running tests. * 'demo.py' (hg checkout only) now demonstrates autoreset and reset atexit. * Provide colorama.VERSION, used by setup.py. * Tests defanged so they no longer actually change terminal color when run. 0.1.5 * Now works on Ubuntu. 0.1.4 * Implemented RESET_ALL on application exit 0.1.3 * Implemented init(wrap=False) 0.1.2 * Implemented init(autoreset=True) 0.1.1 * Minor tidy 0.1 * Works on Windows for foreground color, background color, bright or dim .. |uumlaut| unicode:: U+00FC .. u with umlaut :trim: colorama-0.4.6/ENTERPRISE.md000066400000000000000000000055501432564447100153370ustar00rootroot00000000000000# Colorama for enterprise. *Available as part of the Tidelift Subscription.* Tidelift is working with the maintainers of Colorama and thousands of other open source projects to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [\[Learn More\]](https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=enterprise) [\[Request a demo\]](https://tidelift.com/subscription/request-a-demo?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=enterprise) ### Enterprise-ready open source software—managed for you The Tidelift Subscription is a managed open source subscription for application dependencies covering millions of open source projects across JavaScript, Python, Java, PHP, Ruby, .NET, and more. Your subscription includes: **Security updates:** Tidelift’s security response team coordinates patches for new breaking security vulnerabilities and alerts immediately through a private channel, so your software supply chain is always secure. **Licensing verification and indemnification:** Tidelift verifies license information to enable easy policy enforcement and adds intellectual property indemnification to cover creators and users in case something goes wrong. You always have a 100% up-to-date bill of materials for your dependencies to share with your legal team, customers, or partners. **Maintenance and code improvement:** Tidelift ensures the software you rely on keeps working as long as you need it to work. Your managed dependencies are actively maintained and we recruit additional maintainers where required. **Package selection and version guidance:** We help you choose the best open source packages from the start—and then guide you through updates to stay on the best releases as new issues arise. **Roadmap input:** Take a seat at the table with the creators behind the software you use. Tidelift’s participating maintainers earn more income as their software is used by more subscribers, so they’re interested in knowing what you need. **Tooling and cloud integration:** Tidelift works with GitHub, GitLab, BitBucket, and more. We support every cloud platform (and other deployment targets, too). The end result? All of the capabilities you expect from commercial-grade software, for the full breadth of open source you use. That means less time grappling with esoteric open source trivia, and more time building your own applications—and your business. [\[Learn More\]](https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=enterprise) [\[Request a demo\]](https://tidelift.com/subscription/request-a-demo?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=enterprise) colorama-0.4.6/LICENSE.txt000066400000000000000000000027231432564447100151570ustar00rootroot00000000000000Copyright (c) 2010 Jonathan Hartley All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holders, nor those of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. colorama-0.4.6/Makefile000066400000000000000000000030251432564447100147700ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE.txt file. # This makefile is just a cheatsheet to remind me of some commonly used # commands. I generally am executing these commands on Ubuntu, or on WindowsXP # with Cygwin binaries at the start of the PATH. NAME=colorama help: ## Display help for documented make targets. @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-7s\033[0m %s\n", $$1, $$2}' # bootstrap environment virtualenv=~/.virtualenvs/colorama pip=$(virtualenv)/bin/pip syspython=python3 python=$(virtualenv)/bin/python twine=$(virtualenv)/bin/twine clean: ## Remove build artifacts, .pyc files, virtualenv -rm -rf build dist MANIFEST colorama.egg-info $(virtualenv) -find . -type f -name '*.py[co]' -delete -o -type d -name __pycache__ -delete .PHONY: clean $(virtualenv): $(syspython) -m venv --clear $(virtualenv) $(pip) install --upgrade pip venv: $(virtualenv) ## Create or clear a virtualenv .PHONY: venv bootstrap: venv ## Populate the virtualenv $(pip) install -r requirements.txt -r requirements-dev.txt .PHONY: bootstrap # development tags: ## Create tags file ctags -R ${NAME} .PHONY: tags test: ## Run tests $(python) -m unittest discover -p *_test.py .PHONY: test # build packages build: ## Build a release (sdist and wheel) $(python) -m build .PHONY: build test-release: build ## Test a built release ./test-release .PHONY: test-release release: ## Upload a built release $(twine) upload dist/colorama-* .PHONY: release colorama-0.4.6/README-hacking.md000066400000000000000000000133071432564447100162150ustar00rootroot00000000000000# 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.rst is updated with everything since the last release, including links to merged PRs. Move the "Current release" comment from the previous version number. 2. First we'll make a candidate release. Ensure the '.rc1' suffix is present on `__version__` in `colorama/__init.py__.py`, eg: __version__ = '0.4.6rc1' 3. Run the tests locally on your preferred OS, just to save you from doing the subsequent 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. 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. Push to origin (This triggers a CI build, which we'll check later on) git push origin master 7. Build the distributables (sdist and wheel), on either OS: * Windows: `.\build.ps1` * Linux: `make build` 8. 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).) 9. Check the [CI builds](https://github.com/tartley/colorama/actions/) are complete and all passing. 10. Upload the distributables to PyPI: * On Windows: `.\release.ps1` * On Linux: `make release` 11. 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. 12. Maybe wait a day for anyone using pre-release installs to report any problems? 13. Remove the '.rcX' suffix from `__version__` in `colorama/__init__.py`. 14. Repeat steps 4 to 10, for the actual (non-candidate) release. 15. Bump the version number in `colorama/__init__.py`, and add a 'dev1' suffix, eg: `0.4.5dev1` so that any build artifacts created are clearly labelled as not a real release. Commit and push this (directly to master is fine.) colorama-0.4.6/README.rst000066400000000000000000000370771432564447100150350ustar00rootroot00000000000000.. image:: https://img.shields.io/pypi/v/colorama.svg :target: https://pypi.org/project/colorama/ :alt: Latest Version .. image:: https://img.shields.io/pypi/pyversions/colorama.svg :target: https://pypi.org/project/colorama/ :alt: Supported Python versions .. 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 ======== Makes ANSI escape character sequences (for producing colored terminal text and cursor positioning) work under MS Windows. .. |donate| image:: https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif :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 `_ | `Colorama for enterprise on Tidelift `_ If you find Colorama useful, please |donate| to the authors. Thank you! Installation ------------ Tested on CPython 2.7, 3.7, 3.8, 3.9 and 3.10 and Pypy 2.7 and 3.8. No requirements other than the standard library. .. code-block:: bash pip install colorama # or conda install -c anaconda colorama Description ----------- ANSI escape character sequences have long been used to produce colored terminal text and cursor positioning on Unix and Macs. Colorama makes this work on Windows, too, by wrapping ``stdout``, stripping ANSI sequences it finds (which would appear as gobbledygook in the output), and converting them into the appropriate win32 calls to modify the state of the terminal. On other platforms, Colorama does nothing. This has the upshot of providing a simple cross-platform API for printing colored terminal text from Python, and has the happy side-effect that existing applications or libraries which use ANSI sequences to produce colored output on Linux or Macs can now also work on Windows, simply by calling ``colorama.just_fix_windows_console()`` (since v0.4.6) or ``colorama.init()`` (all versions, but may have other side-effects – see below). An alternative approach is to install ``ansi.sys`` on Windows machines, which provides the same behaviour for all applications running in terminals. Colorama is intended for situations where that isn't easy (e.g., maybe your app doesn't have an installer.) Demo scripts in the source code repository print some colored text using ANSI sequences. Compare their output under Gnome-terminal's built in ANSI handling, versus on Windows Command-Prompt using Colorama: .. image:: https://github.com/tartley/colorama/raw/master/screenshots/ubuntu-demo.png :width: 661 :height: 357 :alt: ANSI sequences on Ubuntu under gnome-terminal. .. image:: https://github.com/tartley/colorama/raw/master/screenshots/windows-demo.png :width: 668 :height: 325 :alt: Same ANSI sequences on Windows, using Colorama. These screenshots show that, on Windows, Colorama does not support ANSI 'dim text'; it looks the same as 'normal text'. Usage ----- Initialisation .............. If the only thing you want from Colorama is to get ANSI escapes to work on Windows, then run: .. code-block:: python from colorama import just_fix_windows_console just_fix_windows_console() If you're on a recent version of Windows 10 or better, and your stdout/stderr are pointing to a Windows console, then this will flip the magic configuration switch to enable Windows' built-in ANSI support. If you're on an older version of Windows, and your stdout/stderr are pointing to a Windows console, then this will wrap ``sys.stdout`` and/or ``sys.stderr`` in a magic file object that intercepts ANSI escape sequences and issues the appropriate Win32 calls to emulate them. In all other circumstances, it does nothing whatsoever. Basically the idea is that this makes Windows act like Unix with respect to ANSI escape handling. It's safe to call this function multiple times. It's safe to call this function on non-Windows platforms, but it won't do anything. It's safe to call this function when one or both of your stdout/stderr are redirected to a file – it won't do anything to those streams. Alternatively, you can use the older interface with more features (but also more potential footguns): .. code-block:: python from colorama import init init() This does the same thing as ``just_fix_windows_console``, except for the following differences: - It's not safe to call ``init`` multiple times; you can end up with multiple layers of wrapping and broken ANSI support. - Colorama will apply a heuristic to guess whether stdout/stderr support ANSI, and if it thinks they don't, then it will wrap ``sys.stdout`` and ``sys.stderr`` in a magic file object that strips out ANSI escape sequences before printing them. This happens on all platforms, and can be convenient if you want to write your code to emit ANSI escape sequences unconditionally, and let Colorama decide whether they should actually be output. But note that Colorama's heuristic is not particularly clever. - ``init`` also accepts explicit keyword args to enable/disable various functionality – see below. To stop using Colorama before your program exits, simply call ``deinit()``. This will restore ``stdout`` and ``stderr`` to their original values, so that Colorama is disabled. To resume using Colorama again, call ``reinit()``; it is cheaper than calling ``init()`` again (but does the same thing). Most users should depend on ``colorama >= 0.4.6``, and use ``just_fix_windows_console``. The old ``init`` interface will be supported indefinitely for backwards compatibility, but we don't plan to fix any issues with it, also for backwards compatibility. Colored Output .............. Cross-platform printing of colored text can then be done using Colorama's constant shorthand for ANSI escape sequences. These are deliberately rudimentary, see below. .. code-block:: python from colorama import Fore, Back, Style print(Fore.RED + 'some red text') print(Back.GREEN + 'and with a green background') print(Style.DIM + 'and in dim text') print(Style.RESET_ALL) print('back to normal now') ...or simply by manually printing ANSI sequences from your own code: .. code-block:: python print('\033[31m' + 'some red text') print('\033[39m') # and reset to default color ...or, Colorama can be used in conjunction with existing ANSI libraries such as the venerable `Termcolor `_ 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: SIMILARLY, do not send PRs adding the generation of new ANSI types to Colorama. We are only interested in converting ANSI codes to win32 API calls, not shortcuts like the above to generate ANSI characters. .. code-block:: python from colorama import just_fix_windows_console from termcolor import colored # use Colorama to make Termcolor work on Windows too just_fix_windows_console() # then use Termcolor for all colored text output print(colored('Hello, World!', 'green', 'on_red')) Available formatting constants are:: Fore: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. Back: BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, RESET. Style: DIM, NORMAL, BRIGHT, RESET_ALL ``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 .................. ANSI codes to reposition the cursor are supported. See ``demos/demo06.py`` for an example of how to generate them. Init Keyword Args ................. ``init()`` accepts some ``**kwargs`` to override default behaviour. init(autoreset=False): If you find yourself repeatedly sending reset sequences to turn off color changes at the end of every print, then ``init(autoreset=True)`` will automate that: .. code-block:: python from colorama import init init(autoreset=True) print(Fore.RED + 'some red text') print('automatically back to default color again') init(strip=None): Pass ``True`` or ``False`` to override whether ANSI codes should be stripped from the output. The default behaviour is to strip if on Windows or if output is redirected (not a tty). init(convert=None): Pass ``True`` or ``False`` to override whether to convert ANSI codes in the output into win32 calls. The default behaviour is to convert if on Windows and output is to a tty (terminal). init(wrap=True): On Windows, Colorama works by replacing ``sys.stdout`` and ``sys.stderr`` with proxy objects, which override the ``.write()`` method to do their work. If this wrapping causes you problems, then this can be disabled by passing ``init(wrap=False)``. The default behaviour is to wrap if ``autoreset`` or ``strip`` or ``convert`` are True. When wrapping is disabled, colored printing on non-Windows platforms will continue to work as normal. To do cross-platform colored output, you can use Colorama's ``AnsiToWin32`` proxy directly: .. code-block:: python import sys from colorama import init, AnsiToWin32 init(wrap=False) stream = AnsiToWin32(sys.stderr).stream # Python 2 print >>stream, Fore.BLUE + 'blue text on stderr' # Python 3 print(Fore.BLUE + 'blue text on stderr', file=stream) Recognised ANSI Sequences ......................... ANSI sequences generally take the form:: ESC [ ; ... Where ```` is an integer, and ```` is a single letter. Zero or more params are passed to a ````. If no params are passed, it is generally synonymous with passing a single zero. No spaces exist in the sequence; they have been inserted here simply to read more easily. The only ANSI sequences that Colorama converts into win32 calls are:: ESC [ 0 m # reset all (colors and brightness) ESC [ 1 m # bright ESC [ 2 m # dim (looks same as normal brightness) ESC [ 22 m # normal brightness # FOREGROUND: ESC [ 30 m # black ESC [ 31 m # red ESC [ 32 m # green ESC [ 33 m # yellow ESC [ 34 m # blue ESC [ 35 m # magenta ESC [ 36 m # cyan ESC [ 37 m # white ESC [ 39 m # reset # BACKGROUND ESC [ 40 m # black ESC [ 41 m # red ESC [ 42 m # green ESC [ 43 m # yellow ESC [ 44 m # blue ESC [ 45 m # magenta ESC [ 46 m # cyan ESC [ 47 m # white ESC [ 49 m # reset # cursor positioning ESC [ y;x H # position cursor at x across, y down ESC [ y;x f # position cursor at x across, y down ESC [ n A # move cursor n lines up ESC [ n B # move cursor n lines down ESC [ n C # move cursor n characters forward ESC [ n D # move cursor n characters backward # clear the screen ESC [ mode J # clear the screen # clear the line ESC [ mode K # clear the line Multiple numeric params to the ``'m'`` command can be combined into a single sequence:: ESC [ 36 ; 45 ; 1 m # bright cyan text on magenta background All other ANSI sequences of the form ``ESC [ ; ... `` are silently stripped from the output on Windows. Any other form of ANSI sequence, such as single-character codes or alternative initial characters, are not recognised or stripped. It would be cool to add them though. Let me know if it would be useful for you, via the Issues on GitHub. Status & Known Problems ----------------------- I've personally only tested it on Windows XP (CMD, Console2), Ubuntu (gnome-terminal, xterm), and OS X. Some valid ANSI sequences aren't recognised. If you're hacking on the code, see `README-hacking.md`_. ESPECIALLY, see the explanation there of why we do not want PRs that allow Colorama to generate new types of ANSI codes. See outstanding issues and wish-list: https://github.com/tartley/colorama/issues If anything doesn't work for you, or doesn't do what you expected or hoped for, 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. .. _README-hacking.md: README-hacking.md License ------- Copyright Jonathan Hartley & Arnon Yaari, 2013-2020. BSD 3-Clause license; see LICENSE file. Professional support -------------------- .. |tideliftlogo| image:: https://cdn2.hubspot.net/hubfs/4008838/website/logos/logos_for_download/Tidelift_primary-shorthand-logo.png :alt: Tidelift :target: https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=readme .. list-table:: :widths: 10 100 * - |tideliftlogo| - Professional support for colorama is available as part of the `Tidelift Subscription`_. Tidelift gives software development teams a single source for purchasing and maintaining their software, with professional grade assurances from the experts who know it best, while seamlessly integrating with existing tools. .. _Tidelift Subscription: https://tidelift.com/subscription/pkg/pypi-colorama?utm_source=pypi-colorama&utm_medium=referral&utm_campaign=readme Thanks ------ See the CHANGELOG for more thanks! * Marc Schlaich (schlamar) for a ``setup.py`` fix for Python2.5. * Marc Abramowitz, reported & fixed a crash on exit with closed ``stdout``, providing a solution to issue #7's setuptools/distutils debate, and other fixes. * User 'eryksun', for guidance on correctly instantiating ``ctypes.windll``. * Matthew McCormick for politely pointing out a longstanding crash on non-Win. * Ben Hoyt, for a magnificent fix under 64-bit Windows. * Jesse at Empty Square for submitting a fix for examples in the README. * User 'jamessp', an observant documentation fix for cursor positioning. * User 'vaal1239', Dave Mckee & Lackner Kristof for a tiny but much-needed Win7 fix. * Julien Stuyck, for wisely suggesting Python3 compatible updates to README. * Daniel Griffith for multiple fabulous patches. * Oscar Lesta for a valuable fix to stop ANSI chars being sent to non-tty output. * Roger Binns, for many suggestions, valuable feedback, & bug reports. * Tim Golden for thought and much appreciated feedback on the initial idea. * User 'Zearin' for updates to the README file. * John Szakmeister for adding support for light colors * Charles Merriam for adding documentation to demos * Jurko for a fix on 64-bit Windows CPython2.5 w/o ctypes * Florian Bruhin for a fix when stdout or stderr are None * Thomas Weininger for fixing ValueError on Windows * Remi Rampin for better Github integration and fixes to the README file * Simeon Visser for closing a file handle using 'with' and updating classifiers 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. colorama-0.4.6/SECURITY.md000066400000000000000000000002761432564447100151260ustar00rootroot00000000000000# Security policy To report sensitive vulnerability information, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. colorama-0.4.6/bootstrap.ps1000066400000000000000000000004261432564447100157740ustar00rootroot00000000000000$syspython="python.exe" $ve="$HOME\.virtualenvs\colorama" $bin="$ve\Scripts" echo "Create $syspython virtualenv $ve" & $syspython -m venv --clear "$ve" & $bin\python.exe -m pip install --upgrade pip & $bin\python.exe -m pip install -r requirements.txt -r requirements-dev.txt colorama-0.4.6/build.ps1000066400000000000000000000002021432564447100150460ustar00rootroot00000000000000$ve="$HOME\.virtualenvs\colorama" $bin="$ve\Scripts" & $bin\python.exe -m pip install --upgrade build & $bin\python.exe -m build colorama-0.4.6/clean.ps1000066400000000000000000000003641432564447100150420ustar00rootroot00000000000000$syspython="python.exe" $ve="$HOME\.virtualenvs\colorama" remove-item -r -fo * -I build,dist,MANIFEST,colorama.egg-info,$ve,sandbox & $syspython -Bc "import pathlib, shutil; [shutil.rmtree(p) for p in pathlib.Path('.').rglob('__pycache__')]" colorama-0.4.6/colorama/000077500000000000000000000000001432564447100151255ustar00rootroot00000000000000colorama-0.4.6/colorama/__init__.py000066400000000000000000000004121432564447100172330ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from .initialise import init, deinit, reinit, colorama_text, just_fix_windows_console from .ansi import Fore, Back, Style, Cursor from .ansitowin32 import AnsiToWin32 __version__ = '0.4.6' colorama-0.4.6/colorama/ansi.py000066400000000000000000000047321432564447100164370ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. ''' This module generates ANSI character codes to printing colors to terminals. See: http://en.wikipedia.org/wiki/ANSI_escape_code ''' CSI = '\033[' OSC = '\033]' BEL = '\a' def code_to_chars(code): return CSI + str(code) + 'm' def set_title(title): return OSC + '2;' + title + BEL def clear_screen(mode=2): return CSI + str(mode) + 'J' def clear_line(mode=2): return CSI + str(mode) + 'K' class AnsiCodes(object): def __init__(self): # the subclasses declare class attributes which are numbers. # Upon instantiation we define instance attributes, which are the same # as the class attributes but wrapped with the ANSI escape sequence for name in dir(self): if not name.startswith('_'): value = getattr(self, name) setattr(self, name, code_to_chars(value)) class AnsiCursor(object): def UP(self, n=1): return CSI + str(n) + 'A' def DOWN(self, n=1): return CSI + str(n) + 'B' def FORWARD(self, n=1): return CSI + str(n) + 'C' def BACK(self, n=1): return CSI + str(n) + 'D' def POS(self, x=1, y=1): return CSI + str(y) + ';' + str(x) + 'H' class AnsiFore(AnsiCodes): BLACK = 30 RED = 31 GREEN = 32 YELLOW = 33 BLUE = 34 MAGENTA = 35 CYAN = 36 WHITE = 37 RESET = 39 # These are fairly well supported, but not part of the standard. LIGHTBLACK_EX = 90 LIGHTRED_EX = 91 LIGHTGREEN_EX = 92 LIGHTYELLOW_EX = 93 LIGHTBLUE_EX = 94 LIGHTMAGENTA_EX = 95 LIGHTCYAN_EX = 96 LIGHTWHITE_EX = 97 class AnsiBack(AnsiCodes): BLACK = 40 RED = 41 GREEN = 42 YELLOW = 43 BLUE = 44 MAGENTA = 45 CYAN = 46 WHITE = 47 RESET = 49 # These are fairly well supported, but not part of the standard. LIGHTBLACK_EX = 100 LIGHTRED_EX = 101 LIGHTGREEN_EX = 102 LIGHTYELLOW_EX = 103 LIGHTBLUE_EX = 104 LIGHTMAGENTA_EX = 105 LIGHTCYAN_EX = 106 LIGHTWHITE_EX = 107 class AnsiStyle(AnsiCodes): BRIGHT = 1 DIM = 2 NORMAL = 22 RESET_ALL = 0 Fore = AnsiFore() Back = AnsiBack() Style = AnsiStyle() Cursor = AnsiCursor() colorama-0.4.6/colorama/ansitowin32.py000066400000000000000000000255701432564447100176700ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import re import sys import os from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style, BEL from .winterm import enable_vt_processing, WinTerm, WinColor, WinStyle from .win32 import windll, winapi_test winterm = None if windll is not None: winterm = WinTerm() class StreamWrapper(object): ''' Wraps a stream (such as stdout), acting as a transparent proxy for all attribute access apart from method 'write()', which is delegated to our Converter instance. ''' def __init__(self, wrapped, converter): # double-underscore everything to prevent clashes with names of # attributes on the wrapped stream object. self.__wrapped = wrapped self.__convertor = converter def __getattr__(self, name): return getattr(self.__wrapped, name) def __enter__(self, *args, **kwargs): # special method lookup bypasses __getattr__/__getattribute__, see # https://stackoverflow.com/questions/12632894/why-doesnt-getattr-work-with-exit # thus, contextlib magic methods are not proxied via __getattr__ return self.__wrapped.__enter__(*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) def isatty(self): stream = self.__wrapped if 'PYCHARM_HOSTED' in os.environ: if stream is not None and (stream is sys.__stdout__ or stream is sys.__stderr__): return True try: stream_isatty = stream.isatty except AttributeError: return False else: return stream_isatty() @property def closed(self): stream = self.__wrapped try: return stream.closed # 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 class AnsiToWin32(object): ''' Implements a 'write()' method which, on Windows, will strip ANSI character sequences from the text, and if outputting to a tty, will convert them into win32 function calls. ''' ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer ANSI_OSC_RE = re.compile('\001?\033\\]([^\a]*)(\a)\002?') # Operating System Command def __init__(self, wrapped, convert=None, strip=None, autoreset=False): # The wrapped stream (normally sys.stdout or sys.stderr) self.wrapped = wrapped # should we reset colors to defaults after every .write() self.autoreset = autoreset # create the proxy wrapping our output stream self.stream = StreamWrapper(wrapped, self) on_windows = os.name == 'nt' # We test if the WinAPI works, because even if we are on Windows # we may be using a terminal that doesn't support the WinAPI # (e.g. Cygwin Terminal). In this case it's up to the terminal # to support the ANSI codes. conversion_supported = on_windows and winapi_test() try: fd = wrapped.fileno() except Exception: fd = -1 system_has_native_ansi = not on_windows or enable_vt_processing(fd) have_tty = not self.stream.closed and self.stream.isatty() need_conversion = conversion_supported and not system_has_native_ansi # should we strip ANSI sequences from our output? if strip is None: strip = need_conversion or not have_tty self.strip = strip # should we should convert ANSI sequences into win32 calls? if convert is None: convert = need_conversion and have_tty self.convert = convert # dict of ansi codes to win32 functions and parameters self.win32_calls = self.get_win32_calls() # are we wrapping stderr? self.on_stderr = self.wrapped is sys.stderr def should_wrap(self): ''' True if this class is actually needed. If false, then the output stream will not be affected, nor will win32 calls be issued, so wrapping stdout is not actually required. This will generally be False on non-Windows platforms, unless optional functionality like autoreset has been requested using kwargs to init() ''' return self.convert or self.strip or self.autoreset def get_win32_calls(self): if self.convert and winterm: return { AnsiStyle.RESET_ALL: (winterm.reset_all, ), AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), AnsiFore.RED: (winterm.fore, WinColor.RED), AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), AnsiFore.WHITE: (winterm.fore, WinColor.GREY), AnsiFore.RESET: (winterm.fore, ), AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), AnsiBack.BLACK: (winterm.back, WinColor.BLACK), AnsiBack.RED: (winterm.back, WinColor.RED), AnsiBack.GREEN: (winterm.back, WinColor.GREEN), AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), AnsiBack.BLUE: (winterm.back, WinColor.BLUE), AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), AnsiBack.CYAN: (winterm.back, WinColor.CYAN), AnsiBack.WHITE: (winterm.back, WinColor.GREY), AnsiBack.RESET: (winterm.back, ), AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), } return dict() def write(self, text): if self.strip or self.convert: self.write_and_convert(text) else: self.wrapped.write(text) self.wrapped.flush() if self.autoreset: self.reset_all() def reset_all(self): if self.convert: self.call_win32('m', (0,)) elif not self.strip and not self.stream.closed: self.wrapped.write(Style.RESET_ALL) def write_and_convert(self, text): ''' Write the given text to our wrapped stream, stripping any ANSI sequences from the text, and optionally converting them into win32 calls. ''' cursor = 0 text = self.convert_osc(text) for match in self.ANSI_CSI_RE.finditer(text): start, end = match.span() self.write_plain_text(text, cursor, start) self.convert_ansi(*match.groups()) cursor = end self.write_plain_text(text, cursor, len(text)) def write_plain_text(self, text, start, end): if start < end: self.wrapped.write(text[start:end]) self.wrapped.flush() def convert_ansi(self, paramstring, command): if self.convert: params = self.extract_params(command, paramstring) self.call_win32(command, params) def extract_params(self, command, paramstring): if command in 'Hf': params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) while len(params) < 2: # defaults: params = params + (1,) else: params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) if len(params) == 0: # defaults: if command in 'JKm': params = (0,) elif command in 'ABCD': params = (1,) return params def call_win32(self, command, params): if command == 'm': for param in params: if param in self.win32_calls: func_args = self.win32_calls[param] func = func_args[0] args = func_args[1:] kwargs = dict(on_stderr=self.on_stderr) func(*args, **kwargs) elif command in 'J': winterm.erase_screen(params[0], on_stderr=self.on_stderr) elif command in 'K': winterm.erase_line(params[0], on_stderr=self.on_stderr) elif command in 'Hf': # cursor position - absolute winterm.set_cursor_position(params, on_stderr=self.on_stderr) elif command in 'ABCD': # cursor position - relative n = params[0] # A - up, B - down, C - forward, D - back x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) def convert_osc(self, text): for match in self.ANSI_OSC_RE.finditer(text): start, end = match.span() text = text[:start] + text[end:] paramstring, command = match.groups() if command == BEL: if paramstring.count(";") == 1: params = paramstring.split(";") # 0 - change title and icon (we will only change title) # 1 - change icon (we don't support this) # 2 - change title if params[0] in '02': winterm.set_title(params[1]) return text def flush(self): self.wrapped.flush() colorama-0.4.6/colorama/initialise.py000066400000000000000000000063751432564447100176440ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import atexit import contextlib import sys from .ansitowin32 import AnsiToWin32 def _wipe_internal_state_for_tests(): global orig_stdout, orig_stderr orig_stdout = None orig_stderr = None global wrapped_stdout, wrapped_stderr wrapped_stdout = None wrapped_stderr = None global atexit_done atexit_done = False global fixed_windows_console fixed_windows_console = False try: # no-op if it wasn't registered atexit.unregister(reset_all) except AttributeError: # python 2: no atexit.unregister. Oh well, we did our best. pass def reset_all(): if AnsiToWin32 is not None: # Issue #74: objects might become None at exit AnsiToWin32(orig_stdout).reset_all() def init(autoreset=False, convert=None, strip=None, wrap=True): if not wrap and any([autoreset, convert, strip]): raise ValueError('wrap=False conflicts with any other arg=True') global wrapped_stdout, wrapped_stderr global orig_stdout, orig_stderr orig_stdout = sys.stdout orig_stderr = sys.stderr if sys.stdout is None: wrapped_stdout = None else: sys.stdout = wrapped_stdout = \ wrap_stream(orig_stdout, convert, strip, autoreset, wrap) if sys.stderr is None: wrapped_stderr = None else: sys.stderr = wrapped_stderr = \ wrap_stream(orig_stderr, convert, strip, autoreset, wrap) global atexit_done if not atexit_done: atexit.register(reset_all) atexit_done = True def deinit(): if orig_stdout is not None: sys.stdout = orig_stdout if orig_stderr is not None: sys.stderr = orig_stderr def just_fix_windows_console(): global fixed_windows_console if sys.platform != "win32": return if fixed_windows_console: return if wrapped_stdout is not None or wrapped_stderr is not None: # Someone already ran init() and it did stuff, so we won't second-guess them return # On newer versions of Windows, AnsiToWin32.__init__ will implicitly enable the # native ANSI support in the console as a side-effect. We only need to actually # replace sys.stdout/stderr if we're in the old-style conversion mode. new_stdout = AnsiToWin32(sys.stdout, convert=None, strip=None, autoreset=False) if new_stdout.convert: sys.stdout = new_stdout new_stderr = AnsiToWin32(sys.stderr, convert=None, strip=None, autoreset=False) if new_stderr.convert: sys.stderr = new_stderr fixed_windows_console = True @contextlib.contextmanager def colorama_text(*args, **kwargs): init(*args, **kwargs) try: yield finally: deinit() def reinit(): if wrapped_stdout is not None: sys.stdout = wrapped_stdout if wrapped_stderr is not None: sys.stderr = wrapped_stderr def wrap_stream(stream, convert, strip, autoreset, wrap): if wrap: wrapper = AnsiToWin32(stream, convert=convert, strip=strip, autoreset=autoreset) if wrapper.should_wrap(): stream = wrapper.stream return stream # Use this for initial setup as well, to reduce code duplication _wipe_internal_state_for_tests() colorama-0.4.6/colorama/tests/000077500000000000000000000000001432564447100162675ustar00rootroot00000000000000colorama-0.4.6/colorama/tests/__init__.py000066400000000000000000000001131432564447100203730ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. colorama-0.4.6/colorama/tests/ansi_test.py000066400000000000000000000054271432564447100206420ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import sys from unittest import TestCase, main from ..ansi import Back, Fore, Style from ..ansitowin32 import AnsiToWin32 stdout_orig = sys.stdout stderr_orig = sys.stderr class AnsiTest(TestCase): def setUp(self): # sanity check: stdout should be a file or StringIO object. # It will only be AnsiToWin32 if init() has previously wrapped it self.assertNotEqual(type(sys.stdout), AnsiToWin32) self.assertNotEqual(type(sys.stderr), AnsiToWin32) def tearDown(self): sys.stdout = stdout_orig sys.stderr = stderr_orig def testForeAttributes(self): self.assertEqual(Fore.BLACK, '\033[30m') self.assertEqual(Fore.RED, '\033[31m') self.assertEqual(Fore.GREEN, '\033[32m') self.assertEqual(Fore.YELLOW, '\033[33m') self.assertEqual(Fore.BLUE, '\033[34m') self.assertEqual(Fore.MAGENTA, '\033[35m') self.assertEqual(Fore.CYAN, '\033[36m') self.assertEqual(Fore.WHITE, '\033[37m') self.assertEqual(Fore.RESET, '\033[39m') # Check the light, extended versions. self.assertEqual(Fore.LIGHTBLACK_EX, '\033[90m') self.assertEqual(Fore.LIGHTRED_EX, '\033[91m') self.assertEqual(Fore.LIGHTGREEN_EX, '\033[92m') self.assertEqual(Fore.LIGHTYELLOW_EX, '\033[93m') self.assertEqual(Fore.LIGHTBLUE_EX, '\033[94m') self.assertEqual(Fore.LIGHTMAGENTA_EX, '\033[95m') self.assertEqual(Fore.LIGHTCYAN_EX, '\033[96m') self.assertEqual(Fore.LIGHTWHITE_EX, '\033[97m') def testBackAttributes(self): self.assertEqual(Back.BLACK, '\033[40m') self.assertEqual(Back.RED, '\033[41m') self.assertEqual(Back.GREEN, '\033[42m') self.assertEqual(Back.YELLOW, '\033[43m') self.assertEqual(Back.BLUE, '\033[44m') self.assertEqual(Back.MAGENTA, '\033[45m') self.assertEqual(Back.CYAN, '\033[46m') self.assertEqual(Back.WHITE, '\033[47m') self.assertEqual(Back.RESET, '\033[49m') # Check the light, extended versions. self.assertEqual(Back.LIGHTBLACK_EX, '\033[100m') self.assertEqual(Back.LIGHTRED_EX, '\033[101m') self.assertEqual(Back.LIGHTGREEN_EX, '\033[102m') self.assertEqual(Back.LIGHTYELLOW_EX, '\033[103m') self.assertEqual(Back.LIGHTBLUE_EX, '\033[104m') self.assertEqual(Back.LIGHTMAGENTA_EX, '\033[105m') self.assertEqual(Back.LIGHTCYAN_EX, '\033[106m') self.assertEqual(Back.LIGHTWHITE_EX, '\033[107m') def testStyleAttributes(self): self.assertEqual(Style.DIM, '\033[2m') self.assertEqual(Style.NORMAL, '\033[22m') self.assertEqual(Style.BRIGHT, '\033[1m') if __name__ == '__main__': main() colorama-0.4.6/colorama/tests/ansitowin32_test.py000066400000000000000000000246661432564447100220760ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from io import StringIO, TextIOWrapper from unittest import TestCase, main try: from contextlib import ExitStack except ImportError: # python 2 from contextlib2 import ExitStack try: from unittest.mock import MagicMock, Mock, patch except ImportError: from mock import MagicMock, Mock, patch from ..ansitowin32 import AnsiToWin32, StreamWrapper from ..win32 import ENABLE_VIRTUAL_TERMINAL_PROCESSING from .utils import osname class StreamWrapperTest(TestCase): def testIsAProxy(self): mockStream = Mock() wrapper = StreamWrapper(mockStream, None) self.assertTrue( wrapper.random_attr is mockStream.random_attr ) def testDelegatesWrite(self): mockStream = Mock() mockConverter = Mock() wrapper = StreamWrapper(mockStream, mockConverter) wrapper.write('hello') self.assertTrue(mockConverter.write.call_args, (('hello',), {})) def testDelegatesContext(self): mockConverter = Mock() s = StringIO() with StreamWrapper(s, mockConverter) as fp: fp.write(u'hello') self.assertTrue(s.closed) def testProxyNoContextManager(self): mockStream = MagicMock() mockStream.__enter__.side_effect = AttributeError() mockConverter = Mock() with self.assertRaises(AttributeError) as excinfo: 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): def testInit(self): mockStdout = Mock() auto = Mock() stream = AnsiToWin32(mockStdout, autoreset=auto) self.assertEqual(stream.wrapped, mockStdout) self.assertEqual(stream.autoreset, auto) @patch('colorama.ansitowin32.winterm', None) @patch('colorama.ansitowin32.winapi_test', lambda *_: True) def testStripIsTrueOnWindows(self): with osname('nt'): mockStdout = Mock() stream = AnsiToWin32(mockStdout) self.assertTrue(stream.strip) def testStripIsFalseOffWindows(self): with osname('posix'): mockStdout = Mock(closed=False) stream = AnsiToWin32(mockStdout) self.assertFalse(stream.strip) def testWriteStripsAnsi(self): mockStdout = Mock() stream = AnsiToWin32(mockStdout) stream.wrapped = Mock() stream.write_and_convert = Mock() stream.strip = True stream.write('abc') self.assertFalse(stream.wrapped.write.called) self.assertEqual(stream.write_and_convert.call_args, (('abc',), {})) def testWriteDoesNotStripAnsi(self): mockStdout = Mock() stream = AnsiToWin32(mockStdout) stream.wrapped = Mock() stream.write_and_convert = Mock() stream.strip = False stream.convert = False stream.write('abc') self.assertFalse(stream.write_and_convert.called) self.assertEqual(stream.wrapped.write.call_args, (('abc',), {})) def assert_autoresets(self, convert, autoreset=True): stream = AnsiToWin32(Mock()) stream.convert = convert stream.reset_all = Mock() stream.autoreset = autoreset stream.winterm = Mock() stream.write('abc') self.assertEqual(stream.reset_all.called, autoreset) def testWriteAutoresets(self): self.assert_autoresets(convert=True) self.assert_autoresets(convert=False) self.assert_autoresets(convert=True, autoreset=False) self.assert_autoresets(convert=False, autoreset=False) def testWriteAndConvertWritesPlainText(self): stream = AnsiToWin32(Mock()) stream.write_and_convert( 'abc' ) self.assertEqual( stream.wrapped.write.call_args, (('abc',), {}) ) def testWriteAndConvertStripsAllValidAnsi(self): stream = AnsiToWin32(Mock()) stream.call_win32 = Mock() data = [ 'abc\033[mdef', 'abc\033[0mdef', 'abc\033[2mdef', 'abc\033[02mdef', 'abc\033[002mdef', 'abc\033[40mdef', 'abc\033[040mdef', 'abc\033[0;1mdef', 'abc\033[40;50mdef', 'abc\033[50;30;40mdef', 'abc\033[Adef', 'abc\033[0Gdef', 'abc\033[1;20;128Hdef', ] for datum in data: stream.wrapped.write.reset_mock() stream.write_and_convert( datum ) self.assertEqual( [args[0] for args in stream.wrapped.write.call_args_list], [ ('abc',), ('def',) ] ) def testWriteAndConvertSkipsEmptySnippets(self): stream = AnsiToWin32(Mock()) stream.call_win32 = Mock() stream.write_and_convert( '\033[40m\033[41m' ) self.assertFalse( stream.wrapped.write.called ) def testWriteAndConvertCallsWin32WithParamsAndCommand(self): stream = AnsiToWin32(Mock()) stream.convert = True stream.call_win32 = Mock() stream.extract_params = Mock(return_value='params') data = { 'abc\033[adef': ('a', 'params'), 'abc\033[;;bdef': ('b', 'params'), 'abc\033[0cdef': ('c', 'params'), 'abc\033[;;0;;Gdef': ('G', 'params'), 'abc\033[1;20;128Hdef': ('H', 'params'), } for datum, expected in data.items(): stream.call_win32.reset_mock() stream.write_and_convert( datum ) self.assertEqual( stream.call_win32.call_args[0], expected ) def test_reset_all_shouldnt_raise_on_closed_orig_stdout(self): stream = StringIO() converter = AnsiToWin32(stream) stream.close() converter.reset_all() def test_wrap_shouldnt_raise_on_closed_orig_stdout(self): stream = StringIO() stream.close() 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): 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): stream = AnsiToWin32(Mock()) data = { '': (0,), ';;': (0,), '2': (2,), ';;002;;': (2,), '0;1': (0, 1), ';;003;;456;;': (3, 456), '11;22;33;44;55': (11, 22, 33, 44, 55), } for datum, expected in data.items(): self.assertEqual(stream.extract_params('m', datum), expected) def testCallWin32UsesLookup(self): listener = Mock() stream = AnsiToWin32(listener) stream.win32_calls = { 1: (lambda *_, **__: listener(11),), 2: (lambda *_, **__: listener(22),), 3: (lambda *_, **__: listener(33),), } stream.call_win32('m', (3, 1, 99, 2)) self.assertEqual( [a[0][0] for a in listener.call_args_list], [33, 11, 22] ) def test_osc_codes(self): mockStdout = Mock() stream = AnsiToWin32(mockStdout, convert=True) with patch('colorama.ansitowin32.winterm') as winterm: data = [ '\033]0\x07', # missing arguments '\033]0;foo\x08', # wrong OSC command '\033]0;colorama_test_title\x07', # should work '\033]1;colorama_test_title\x07', # wrong set command '\033]2;colorama_test_title\x07', # should work '\033]' + ';' * 64 + '\x08', # see issue #247 ] for code in data: stream.write(code) self.assertEqual(winterm.set_title.call_count, 2) def test_native_windows_ansi(self): with ExitStack() as stack: def p(a, b): stack.enter_context(patch(a, b, create=True)) # Pretend to be on Windows p("colorama.ansitowin32.os.name", "nt") p("colorama.ansitowin32.winapi_test", lambda: True) p("colorama.win32.winapi_test", lambda: True) p("colorama.winterm.win32.windll", "non-None") p("colorama.winterm.get_osfhandle", lambda _: 1234) # Pretend that our mock stream has native ANSI support p( "colorama.winterm.win32.GetConsoleMode", lambda _: ENABLE_VIRTUAL_TERMINAL_PROCESSING, ) SetConsoleMode = Mock() p("colorama.winterm.win32.SetConsoleMode", SetConsoleMode) stdout = Mock() stdout.closed = False stdout.isatty.return_value = True stdout.fileno.return_value = 1 # Our fake console says it has native vt support, so AnsiToWin32 should # enable that support and do nothing else. stream = AnsiToWin32(stdout) SetConsoleMode.assert_called_with(1234, ENABLE_VIRTUAL_TERMINAL_PROCESSING) self.assertFalse(stream.strip) self.assertFalse(stream.convert) self.assertFalse(stream.should_wrap()) # Now let's pretend we're on an old Windows console, that doesn't have # native ANSI support. p("colorama.winterm.win32.GetConsoleMode", lambda _: 0) SetConsoleMode = Mock() p("colorama.winterm.win32.SetConsoleMode", SetConsoleMode) stream = AnsiToWin32(stdout) SetConsoleMode.assert_called_with(1234, ENABLE_VIRTUAL_TERMINAL_PROCESSING) self.assertTrue(stream.strip) self.assertTrue(stream.convert) self.assertTrue(stream.should_wrap()) if __name__ == '__main__': main() colorama-0.4.6/colorama/tests/initialise_test.py000066400000000000000000000151251432564447100220360ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import sys from unittest import TestCase, main, skipUnless try: from unittest.mock import patch, Mock except ImportError: from mock import patch, Mock from ..ansitowin32 import StreamWrapper from ..initialise import init, just_fix_windows_console, _wipe_internal_state_for_tests from .utils import osname, replace_by orig_stdout = sys.stdout orig_stderr = sys.stderr class InitTest(TestCase): @skipUnless(sys.stdout.isatty(), "sys.stdout is not a tty") def setUp(self): # sanity check self.assertNotWrapped() def tearDown(self): _wipe_internal_state_for_tests() sys.stdout = orig_stdout sys.stderr = orig_stderr def assertWrapped(self): self.assertIsNot(sys.stdout, orig_stdout, 'stdout should be wrapped') self.assertIsNot(sys.stderr, orig_stderr, 'stderr should be wrapped') self.assertTrue(isinstance(sys.stdout, StreamWrapper), 'bad stdout wrapper') self.assertTrue(isinstance(sys.stderr, StreamWrapper), 'bad stderr wrapper') def assertNotWrapped(self): self.assertIs(sys.stdout, orig_stdout, 'stdout should not be wrapped') self.assertIs(sys.stderr, orig_stderr, 'stderr should not be wrapped') @patch('colorama.initialise.reset_all') @patch('colorama.ansitowin32.winapi_test', lambda *_: True) @patch('colorama.ansitowin32.enable_vt_processing', lambda *_: False) def testInitWrapsOnWindows(self, _): with osname("nt"): init() self.assertWrapped() @patch('colorama.initialise.reset_all') @patch('colorama.ansitowin32.winapi_test', lambda *_: False) def testInitDoesntWrapOnEmulatedWindows(self, _): with osname("nt"): init() self.assertNotWrapped() def testInitDoesntWrapOnNonWindows(self): with osname("posix"): init() self.assertNotWrapped() def testInitDoesntWrapIfNone(self): with replace_by(None): init() # We can't use assertNotWrapped here because replace_by(None) # changes stdout/stderr already. self.assertIsNone(sys.stdout) self.assertIsNone(sys.stderr) def testInitAutoresetOnWrapsOnAllPlatforms(self): with osname("posix"): init(autoreset=True) self.assertWrapped() def testInitWrapOffDoesntWrapOnWindows(self): with osname("nt"): init(wrap=False) self.assertNotWrapped() def testInitWrapOffIncompatibleWithAutoresetOn(self): self.assertRaises(ValueError, lambda: init(autoreset=True, wrap=False)) @patch('colorama.win32.SetConsoleTextAttribute') @patch('colorama.initialise.AnsiToWin32') def testAutoResetPassedOn(self, mockATW32, _): with osname("nt"): init(autoreset=True) self.assertEqual(len(mockATW32.call_args_list), 2) self.assertEqual(mockATW32.call_args_list[1][1]['autoreset'], True) self.assertEqual(mockATW32.call_args_list[0][1]['autoreset'], True) @patch('colorama.initialise.AnsiToWin32') def testAutoResetChangeable(self, mockATW32): with osname("nt"): init() init(autoreset=True) self.assertEqual(len(mockATW32.call_args_list), 4) self.assertEqual(mockATW32.call_args_list[2][1]['autoreset'], True) self.assertEqual(mockATW32.call_args_list[3][1]['autoreset'], True) init() self.assertEqual(len(mockATW32.call_args_list), 6) self.assertEqual( mockATW32.call_args_list[4][1]['autoreset'], False) self.assertEqual( mockATW32.call_args_list[5][1]['autoreset'], False) @patch('colorama.initialise.atexit.register') def testAtexitRegisteredOnlyOnce(self, mockRegister): init() self.assertTrue(mockRegister.called) mockRegister.reset_mock() init() self.assertFalse(mockRegister.called) class JustFixWindowsConsoleTest(TestCase): def _reset(self): _wipe_internal_state_for_tests() sys.stdout = orig_stdout sys.stderr = orig_stderr def tearDown(self): self._reset() @patch("colorama.ansitowin32.winapi_test", lambda: True) def testJustFixWindowsConsole(self): if sys.platform != "win32": # just_fix_windows_console should be a no-op just_fix_windows_console() self.assertIs(sys.stdout, orig_stdout) self.assertIs(sys.stderr, orig_stderr) else: def fake_std(): # Emulate stdout=not a tty, stderr=tty # to check that we handle both cases correctly stdout = Mock() stdout.closed = False stdout.isatty.return_value = False stdout.fileno.return_value = 1 sys.stdout = stdout stderr = Mock() stderr.closed = False stderr.isatty.return_value = True stderr.fileno.return_value = 2 sys.stderr = stderr for native_ansi in [False, True]: with patch( 'colorama.ansitowin32.enable_vt_processing', lambda *_: native_ansi ): self._reset() fake_std() # Regular single-call test prev_stdout = sys.stdout prev_stderr = sys.stderr just_fix_windows_console() self.assertIs(sys.stdout, prev_stdout) if native_ansi: self.assertIs(sys.stderr, prev_stderr) else: self.assertIsNot(sys.stderr, prev_stderr) # second call without resetting is always a no-op prev_stdout = sys.stdout prev_stderr = sys.stderr just_fix_windows_console() self.assertIs(sys.stdout, prev_stdout) self.assertIs(sys.stderr, prev_stderr) self._reset() fake_std() # If init() runs first, just_fix_windows_console should be a no-op init() prev_stdout = sys.stdout prev_stderr = sys.stderr just_fix_windows_console() self.assertIs(prev_stdout, sys.stdout) self.assertIs(prev_stderr, sys.stderr) if __name__ == '__main__': main() colorama-0.4.6/colorama/tests/isatty_test.py000066400000000000000000000035121432564447100212160ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import sys from unittest import TestCase, main from ..ansitowin32 import StreamWrapper, AnsiToWin32 from .utils import pycharm, replace_by, replace_original_by, StreamTTY, StreamNonTTY def is_a_tty(stream): return StreamWrapper(stream, None).isatty() class IsattyTest(TestCase): def test_TTY(self): tty = StreamTTY() self.assertTrue(is_a_tty(tty)) with pycharm(): self.assertTrue(is_a_tty(tty)) def test_nonTTY(self): non_tty = StreamNonTTY() self.assertFalse(is_a_tty(non_tty)) with pycharm(): self.assertFalse(is_a_tty(non_tty)) def test_withPycharm(self): with pycharm(): self.assertTrue(is_a_tty(sys.stderr)) self.assertTrue(is_a_tty(sys.stdout)) def test_withPycharmTTYOverride(self): tty = StreamTTY() with pycharm(), replace_by(tty): self.assertTrue(is_a_tty(tty)) def test_withPycharmNonTTYOverride(self): non_tty = StreamNonTTY() with pycharm(), replace_by(non_tty): self.assertFalse(is_a_tty(non_tty)) def test_withPycharmNoneOverride(self): with pycharm(): with replace_by(None), replace_original_by(None): self.assertFalse(is_a_tty(None)) self.assertFalse(is_a_tty(StreamNonTTY())) self.assertTrue(is_a_tty(StreamTTY())) def test_withPycharmStreamWrapped(self): with pycharm(): self.assertTrue(AnsiToWin32(StreamTTY()).stream.isatty()) self.assertFalse(AnsiToWin32(StreamNonTTY()).stream.isatty()) self.assertTrue(AnsiToWin32(sys.stdout).stream.isatty()) self.assertTrue(AnsiToWin32(sys.stderr).stream.isatty()) if __name__ == '__main__': main() colorama-0.4.6/colorama/tests/utils.py000066400000000000000000000020671432564447100200060ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from contextlib import contextmanager from io import StringIO import sys import os class StreamTTY(StringIO): def isatty(self): return True class StreamNonTTY(StringIO): def isatty(self): return False @contextmanager def osname(name): orig = os.name os.name = name yield os.name = orig @contextmanager def replace_by(stream): orig_stdout = sys.stdout orig_stderr = sys.stderr sys.stdout = stream sys.stderr = stream yield sys.stdout = orig_stdout sys.stderr = orig_stderr @contextmanager def replace_original_by(stream): orig_stdout = sys.__stdout__ orig_stderr = sys.__stderr__ sys.__stdout__ = stream sys.__stderr__ = stream yield sys.__stdout__ = orig_stdout sys.__stderr__ = orig_stderr @contextmanager def pycharm(): os.environ["PYCHARM_HOSTED"] = "1" non_tty = StreamNonTTY() with replace_by(non_tty), replace_original_by(non_tty): yield del os.environ["PYCHARM_HOSTED"] colorama-0.4.6/colorama/tests/winterm_test.py000066400000000000000000000071751432564447100213770ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. import sys from unittest import TestCase, main, skipUnless try: from unittest.mock import Mock, patch except ImportError: from mock import Mock, patch from ..winterm import WinColor, WinStyle, WinTerm class WinTermTest(TestCase): @patch('colorama.winterm.win32') def testInit(self, mockWin32): mockAttr = Mock() mockAttr.wAttributes = 7 + 6 * 16 + 8 mockWin32.GetConsoleScreenBufferInfo.return_value = mockAttr term = WinTerm() self.assertEqual(term._fore, 7) self.assertEqual(term._back, 6) self.assertEqual(term._style, 8) @skipUnless(sys.platform.startswith("win"), "requires Windows") def testGetAttrs(self): term = WinTerm() term._fore = 0 term._back = 0 term._style = 0 self.assertEqual(term.get_attrs(), 0) term._fore = WinColor.YELLOW self.assertEqual(term.get_attrs(), WinColor.YELLOW) term._back = WinColor.MAGENTA self.assertEqual( term.get_attrs(), WinColor.YELLOW + WinColor.MAGENTA * 16) term._style = WinStyle.BRIGHT self.assertEqual( term.get_attrs(), WinColor.YELLOW + WinColor.MAGENTA * 16 + WinStyle.BRIGHT) @patch('colorama.winterm.win32') def testResetAll(self, mockWin32): mockAttr = Mock() mockAttr.wAttributes = 1 + 2 * 16 + 8 mockWin32.GetConsoleScreenBufferInfo.return_value = mockAttr term = WinTerm() term.set_console = Mock() term._fore = -1 term._back = -1 term._style = -1 term.reset_all() self.assertEqual(term._fore, 1) self.assertEqual(term._back, 2) self.assertEqual(term._style, 8) self.assertEqual(term.set_console.called, True) @skipUnless(sys.platform.startswith("win"), "requires Windows") def testFore(self): term = WinTerm() term.set_console = Mock() term._fore = 0 term.fore(5) self.assertEqual(term._fore, 5) self.assertEqual(term.set_console.called, True) @skipUnless(sys.platform.startswith("win"), "requires Windows") def testBack(self): term = WinTerm() term.set_console = Mock() term._back = 0 term.back(5) self.assertEqual(term._back, 5) self.assertEqual(term.set_console.called, True) @skipUnless(sys.platform.startswith("win"), "requires Windows") def testStyle(self): term = WinTerm() term.set_console = Mock() term._style = 0 term.style(22) self.assertEqual(term._style, 22) self.assertEqual(term.set_console.called, True) @patch('colorama.winterm.win32') def testSetConsole(self, mockWin32): mockAttr = Mock() mockAttr.wAttributes = 0 mockWin32.GetConsoleScreenBufferInfo.return_value = mockAttr term = WinTerm() term.windll = Mock() term.set_console() self.assertEqual( mockWin32.SetConsoleTextAttribute.call_args, ((mockWin32.STDOUT, term.get_attrs()), {}) ) @patch('colorama.winterm.win32') def testSetConsoleOnStderr(self, mockWin32): mockAttr = Mock() mockAttr.wAttributes = 0 mockWin32.GetConsoleScreenBufferInfo.return_value = mockAttr term = WinTerm() term.windll = Mock() term.set_console(on_stderr=True) self.assertEqual( mockWin32.SetConsoleTextAttribute.call_args, ((mockWin32.STDERR, term.get_attrs()), {}) ) if __name__ == '__main__': main() colorama-0.4.6/colorama/win32.py000066400000000000000000000140451432564447100164450ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # from winbase.h STDOUT = -11 STDERR = -12 ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004 try: import ctypes from ctypes import LibraryLoader windll = LibraryLoader(ctypes.WinDLL) from ctypes import wintypes except (AttributeError, ImportError): windll = None SetConsoleTextAttribute = lambda *_: None winapi_test = lambda *_: None else: from ctypes import byref, Structure, c_char, POINTER COORD = wintypes._COORD class CONSOLE_SCREEN_BUFFER_INFO(Structure): """struct in wincon.h.""" _fields_ = [ ("dwSize", COORD), ("dwCursorPosition", COORD), ("wAttributes", wintypes.WORD), ("srWindow", wintypes.SMALL_RECT), ("dwMaximumWindowSize", COORD), ] def __str__(self): return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( self.dwSize.Y, self.dwSize.X , self.dwCursorPosition.Y, self.dwCursorPosition.X , self.wAttributes , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X ) _GetStdHandle = windll.kernel32.GetStdHandle _GetStdHandle.argtypes = [ wintypes.DWORD, ] _GetStdHandle.restype = wintypes.HANDLE _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo _GetConsoleScreenBufferInfo.argtypes = [ wintypes.HANDLE, POINTER(CONSOLE_SCREEN_BUFFER_INFO), ] _GetConsoleScreenBufferInfo.restype = wintypes.BOOL _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute _SetConsoleTextAttribute.argtypes = [ wintypes.HANDLE, wintypes.WORD, ] _SetConsoleTextAttribute.restype = wintypes.BOOL _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition _SetConsoleCursorPosition.argtypes = [ wintypes.HANDLE, COORD, ] _SetConsoleCursorPosition.restype = wintypes.BOOL _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA _FillConsoleOutputCharacterA.argtypes = [ wintypes.HANDLE, c_char, wintypes.DWORD, COORD, POINTER(wintypes.DWORD), ] _FillConsoleOutputCharacterA.restype = wintypes.BOOL _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute _FillConsoleOutputAttribute.argtypes = [ wintypes.HANDLE, wintypes.WORD, wintypes.DWORD, COORD, POINTER(wintypes.DWORD), ] _FillConsoleOutputAttribute.restype = wintypes.BOOL _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW _SetConsoleTitleW.argtypes = [ wintypes.LPCWSTR ] _SetConsoleTitleW.restype = wintypes.BOOL _GetConsoleMode = windll.kernel32.GetConsoleMode _GetConsoleMode.argtypes = [ wintypes.HANDLE, POINTER(wintypes.DWORD) ] _GetConsoleMode.restype = wintypes.BOOL _SetConsoleMode = windll.kernel32.SetConsoleMode _SetConsoleMode.argtypes = [ wintypes.HANDLE, wintypes.DWORD ] _SetConsoleMode.restype = wintypes.BOOL def _winapi_test(handle): csbi = CONSOLE_SCREEN_BUFFER_INFO() success = _GetConsoleScreenBufferInfo( handle, byref(csbi)) return bool(success) def winapi_test(): return any(_winapi_test(h) for h in (_GetStdHandle(STDOUT), _GetStdHandle(STDERR))) def GetConsoleScreenBufferInfo(stream_id=STDOUT): handle = _GetStdHandle(stream_id) csbi = CONSOLE_SCREEN_BUFFER_INFO() success = _GetConsoleScreenBufferInfo( handle, byref(csbi)) return csbi def SetConsoleTextAttribute(stream_id, attrs): handle = _GetStdHandle(stream_id) return _SetConsoleTextAttribute(handle, attrs) def SetConsoleCursorPosition(stream_id, position, adjust=True): position = COORD(*position) # If the position is out of range, do nothing. if position.Y <= 0 or position.X <= 0: return # Adjust for Windows' SetConsoleCursorPosition: # 1. being 0-based, while ANSI is 1-based. # 2. expecting (x,y), while ANSI uses (y,x). adjusted_position = COORD(position.Y - 1, position.X - 1) if adjust: # Adjust for viewport's scroll position sr = GetConsoleScreenBufferInfo(STDOUT).srWindow adjusted_position.Y += sr.Top adjusted_position.X += sr.Left # Resume normal processing handle = _GetStdHandle(stream_id) return _SetConsoleCursorPosition(handle, adjusted_position) def FillConsoleOutputCharacter(stream_id, char, length, start): handle = _GetStdHandle(stream_id) char = c_char(char.encode()) length = wintypes.DWORD(length) num_written = wintypes.DWORD(0) # Note that this is hard-coded for ANSI (vs wide) bytes. success = _FillConsoleOutputCharacterA( handle, char, length, start, byref(num_written)) return num_written.value def FillConsoleOutputAttribute(stream_id, attr, length, start): ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' handle = _GetStdHandle(stream_id) attribute = wintypes.WORD(attr) length = wintypes.DWORD(length) num_written = wintypes.DWORD(0) # Note that this is hard-coded for ANSI (vs wide) bytes. return _FillConsoleOutputAttribute( handle, attribute, length, start, byref(num_written)) def SetConsoleTitle(title): return _SetConsoleTitleW(title) def GetConsoleMode(handle): mode = wintypes.DWORD() success = _GetConsoleMode(handle, byref(mode)) if not success: raise ctypes.WinError() return mode.value def SetConsoleMode(handle, mode): success = _SetConsoleMode(handle, mode) if not success: raise ctypes.WinError() colorama-0.4.6/colorama/winterm.py000066400000000000000000000157361432564447100172000ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. try: from msvcrt import get_osfhandle except ImportError: def get_osfhandle(_): raise OSError("This isn't windows!") from . import win32 # from wincon.h class WinColor(object): BLACK = 0 BLUE = 1 GREEN = 2 CYAN = 3 RED = 4 MAGENTA = 5 YELLOW = 6 GREY = 7 # from wincon.h class WinStyle(object): NORMAL = 0x00 # dim text, dim background BRIGHT = 0x08 # bright text, dim background BRIGHT_BACKGROUND = 0x80 # dim text, bright background class WinTerm(object): def __init__(self): self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes self.set_attrs(self._default) self._default_fore = self._fore self._default_back = self._back self._default_style = self._style # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. # So that LIGHT_EX colors and BRIGHT style do not clobber each other, # we track them separately, since LIGHT_EX is overwritten by Fore/Back # and BRIGHT is overwritten by Style codes. self._light = 0 def get_attrs(self): return self._fore + self._back * 16 + (self._style | self._light) def set_attrs(self, value): self._fore = value & 7 self._back = (value >> 4) & 7 self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) def reset_all(self, on_stderr=None): self.set_attrs(self._default) self.set_console(attrs=self._default) self._light = 0 def fore(self, fore=None, light=False, on_stderr=False): if fore is None: fore = self._default_fore self._fore = fore # Emulate LIGHT_EX with BRIGHT Style if light: self._light |= WinStyle.BRIGHT else: self._light &= ~WinStyle.BRIGHT self.set_console(on_stderr=on_stderr) def back(self, back=None, light=False, on_stderr=False): if back is None: back = self._default_back self._back = back # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style if light: self._light |= WinStyle.BRIGHT_BACKGROUND else: self._light &= ~WinStyle.BRIGHT_BACKGROUND self.set_console(on_stderr=on_stderr) def style(self, style=None, on_stderr=False): if style is None: style = self._default_style self._style = style self.set_console(on_stderr=on_stderr) def set_console(self, attrs=None, on_stderr=False): if attrs is None: attrs = self.get_attrs() handle = win32.STDOUT if on_stderr: handle = win32.STDERR win32.SetConsoleTextAttribute(handle, attrs) def get_position(self, handle): position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition # Because Windows coordinates are 0-based, # and win32.SetConsoleCursorPosition expects 1-based. position.X += 1 position.Y += 1 return position def set_cursor_position(self, position=None, on_stderr=False): if position is None: # I'm not currently tracking the position, so there is no default. # position = self.get_position() return handle = win32.STDOUT if on_stderr: handle = win32.STDERR win32.SetConsoleCursorPosition(handle, position) def cursor_adjust(self, x, y, on_stderr=False): handle = win32.STDOUT if on_stderr: handle = win32.STDERR position = self.get_position(handle) adjusted_position = (position.Y + y, position.X + x) win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) def erase_screen(self, mode=0, on_stderr=False): # 0 should clear from the cursor to the end of the screen. # 1 should clear from the cursor to the beginning of the screen. # 2 should clear the entire screen, and move cursor to (1,1) handle = win32.STDOUT if on_stderr: handle = win32.STDERR csbi = win32.GetConsoleScreenBufferInfo(handle) # get the number of character cells in the current buffer cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y # get number of character cells before current cursor position cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X if mode == 0: from_coord = csbi.dwCursorPosition cells_to_erase = cells_in_screen - cells_before_cursor elif mode == 1: from_coord = win32.COORD(0, 0) cells_to_erase = cells_before_cursor elif mode == 2: from_coord = win32.COORD(0, 0) cells_to_erase = cells_in_screen else: # invalid mode return # fill the entire screen with blanks win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) # now set the buffer's attributes accordingly win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) if mode == 2: # put the cursor where needed win32.SetConsoleCursorPosition(handle, (1, 1)) def erase_line(self, mode=0, on_stderr=False): # 0 should clear from the cursor to the end of the line. # 1 should clear from the cursor to the beginning of the line. # 2 should clear the entire line. handle = win32.STDOUT if on_stderr: handle = win32.STDERR csbi = win32.GetConsoleScreenBufferInfo(handle) if mode == 0: from_coord = csbi.dwCursorPosition cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X elif mode == 1: from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) cells_to_erase = csbi.dwCursorPosition.X elif mode == 2: from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) cells_to_erase = csbi.dwSize.X else: # invalid mode return # fill the entire screen with blanks win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) # now set the buffer's attributes accordingly win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) def set_title(self, title): win32.SetConsoleTitle(title) def enable_vt_processing(fd): if win32.windll is None or not win32.winapi_test(): return False try: handle = get_osfhandle(fd) mode = win32.GetConsoleMode(handle) win32.SetConsoleMode( handle, mode | win32.ENABLE_VIRTUAL_TERMINAL_PROCESSING, ) mode = win32.GetConsoleMode(handle) if mode & win32.ENABLE_VIRTUAL_TERMINAL_PROCESSING: return True # Can get TypeError in testsuite where 'fd' is a Mock() except (OSError, TypeError): return False colorama-0.4.6/demos/000077500000000000000000000000001432564447100144375ustar00rootroot00000000000000colorama-0.4.6/demos/demo.bat000066400000000000000000000022631432564447100160560ustar00rootroot00000000000000:: Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. :: Script to demonstrate features of colorama. :: This demo is also used to verify correctness visually, because we don't :: have automated tests. :: Implemented as a bash script which invokes python so that we can test the :: behaviour on exit, which resets default colors again. :: print grid of all colors and brightnesses python demo01.py :: Simple demo of changing foreground, background and brightness. python demo02.py :: Demonstrate the different behavior when autoreset is True and False. python demo03.py :: check that stripped ANSI in redirected stderr does not affect stdout if exist demo04.out del demo04.out python demo04.py 2> demo04.out type demo04.out if exist demo04.out del 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 :: Demonstrate cursor relative movement: UP, DOWN, FORWARD, and BACK in colorama.CURSOR python demo07.py :: Demonstrate the use of a context manager instead of manually using init and deinit python demo08.py colorama-0.4.6/demos/demo.sh000066400000000000000000000022461432564447100157230ustar00rootroot00000000000000#!/usr/bin/env bash # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # Script to demonstrate features of colorama. # This demo is also used to verify correctness visually, because we don't have # automated tests. # Implemented as a bash script which invokes python so that we can test the # behaviour on exit, which resets default colors again. # print grid of all colors and brightnesses python demo01.py # Simple demo of changing foreground, background and brightness. python demo02.py # Demonstrate the different behavior when autoreset is True and False. python demo03.py # check that stripped ANSI in redirected stderr does not affect stdout rm -f demo04.out python demo04.py 2> demo04.out cat demo04.out rm -f demo04.out # Demonstrate the difference between colorama initialized with wrapping on and off. python demo05.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 # Demonstrate the use of a context manager instead of manually using init and deinit python demo08.py colorama-0.4.6/demos/demo01.py000066400000000000000000000040111432564447100160720ustar00rootroot00000000000000#!/usr/bin/python # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # print grid of all colors and brightnesses # uses stdout.write to write chars with no newline nor spaces between them # This should run more-or-less identically on Windows and Unix. from __future__ import print_function import sys # Add parent dir to sys path, so the following 'import colorama' always finds # the local source in preference to any installed version of colorama. import fixpath from colorama import just_fix_windows_console, Fore, Back, Style just_fix_windows_console() # Fore, Back and Style are convenience classes for the constant ANSI strings that set # the foreground, background and style. The don't have any magic of their own. FORES = [ Fore.BLACK, Fore.RED, Fore.GREEN, Fore.YELLOW, Fore.BLUE, Fore.MAGENTA, Fore.CYAN, Fore.WHITE ] BACKS = [ Back.BLACK, Back.RED, Back.GREEN, Back.YELLOW, Back.BLUE, Back.MAGENTA, Back.CYAN, Back.WHITE ] STYLES = [ Style.DIM, Style.NORMAL, Style.BRIGHT ] NAMES = { Fore.BLACK: 'black', Fore.RED: 'red', Fore.GREEN: 'green', Fore.YELLOW: 'yellow', Fore.BLUE: 'blue', Fore.MAGENTA: 'magenta', Fore.CYAN: 'cyan', Fore.WHITE: 'white' , Fore.RESET: 'reset', Back.BLACK: 'black', Back.RED: 'red', Back.GREEN: 'green', Back.YELLOW: 'yellow', Back.BLUE: 'blue', Back.MAGENTA: 'magenta', Back.CYAN: 'cyan', Back.WHITE: 'white', Back.RESET: 'reset' } # show the color names sys.stdout.write(' ') for foreground in FORES: sys.stdout.write('%s%-7s' % (foreground, NAMES[foreground])) print() # make a row for each background color for background in BACKS: sys.stdout.write('%s%-7s%s %s' % (background, NAMES[background], Back.RESET, background)) # make a column for each foreground color for foreground in FORES: sys.stdout.write(foreground) # show dim, normal bright for brightness in STYLES: sys.stdout.write('%sX ' % brightness) sys.stdout.write(Style.RESET_ALL + ' ' + background) print(Style.RESET_ALL) print() colorama-0.4.6/demos/demo02.py000066400000000000000000000011461432564447100161010ustar00rootroot00000000000000#!/usr/bin/python # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # Simple demo of changing foreground, background and brightness. from __future__ import print_function import fixpath from colorama import just_fix_windows_console, Fore, Back, Style just_fix_windows_console() print(Fore.GREEN + 'green, ' + Fore.RED + 'red, ' + Fore.RESET + 'normal, ' , end='') print(Back.GREEN + 'green, ' + Back.RED + 'red, ' + Back.RESET + 'normal, ' , end='') print(Style.DIM + 'dim, ' + Style.BRIGHT + 'bright, ' + Style.NORMAL + 'normal' , end=' ') print() colorama-0.4.6/demos/demo03.py000066400000000000000000000012521432564447100161000ustar00rootroot00000000000000#!/usr/bin/python # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # Demonstrate the different behavior when autoreset is True and False. from __future__ import print_function import fixpath from colorama import init, Fore, Back, Style init(autoreset=True) print(Fore.CYAN + Back.MAGENTA + Style.BRIGHT + 'Line 1: colored, with autoreset=True') print('Line 2: When auto reset is True, the color settings need to be set with every print.') init(autoreset=False) print(Fore.YELLOW + Back.BLUE + Style.BRIGHT + 'Line 3: colored, with autoreset=False') print('Line 4: When autoreset=False, the prior color settings linger (this is the default behavior).') colorama-0.4.6/demos/demo04.py000066400000000000000000000007341432564447100161050ustar00rootroot00000000000000#!/usr/bin/python # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # check that stripped ANSI in redirected stderr does not affect stdout from __future__ import print_function import sys import fixpath from colorama import init, Fore init() print(Fore.GREEN + 'GREEN set on stdout. ', end='') print(Fore.RED + 'RED redirected stderr', file=sys.stderr) print('Further stdout should be GREEN, i.e., the stderr redirection should not affect stdout.') colorama-0.4.6/demos/demo05.py000066400000000000000000000017271432564447100161110ustar00rootroot00000000000000#!/usr/bin/python # Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # Demonstrate the difference between colorama initialized with wrapping on and off. # The point of the demonstration is to show how the ANSI wrapping on Windows can be disabled. # The unwrapped cases will be interpreted with ANSI on Unix, but not on Windows. from __future__ import print_function import sys import fixpath from colorama import AnsiToWin32, init, Fore init() print('%sWrapped yellow going to stdout, via the default print function.' % Fore.YELLOW) init(wrap=False) print('%sUnwrapped CYAN going to stdout, via the default print function.' % Fore.CYAN) print('%sUnwrapped CYAN, using the file parameter to write via colorama the AnsiToWin32 function.' % Fore.CYAN, file=AnsiToWin32(sys.stdout)) print('%sUnwrapped RED going to stdout, via the default print function.' % Fore.RED) init() print('%sWrapped RED going to stdout, via the default print function.' % Fore.RED) colorama-0.4.6/demos/demo06.py000066400000000000000000000033731432564447100161110ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. from __future__ import print_function import fixpath import colorama from colorama import Fore, Back, Style, Cursor from random import randint, choice from string import printable # Demonstrate printing colored, random characters at random positions on the screen # Fore, Back and Style are convenience classes for the constant ANSI strings that set # the foreground, background and style. They don't have any magic of their own. FORES = [ Fore.BLACK, Fore.RED, Fore.GREEN, Fore.YELLOW, Fore.BLUE, Fore.MAGENTA, Fore.CYAN, Fore.WHITE ] BACKS = [ Back.BLACK, Back.RED, Back.GREEN, Back.YELLOW, Back.BLUE, Back.MAGENTA, Back.CYAN, Back.WHITE ] STYLES = [ Style.DIM, Style.NORMAL, Style.BRIGHT ] # This assumes your terminal is 80x24. Ansi minimum coordinate is (1,1). MINY, MAXY = 1, 24 MINX, MAXX = 1, 80 # set of printable ASCII characters, including a space. CHARS = ' ' + printable.strip() PASSES = 1000 def main(): colorama.just_fix_windows_console() pos = lambda y, x: Cursor.POS(x, y) # draw a white border. print(Back.WHITE, end='') print('%s%s' % (pos(MINY, MINX), ' '*MAXX), end='') for y in range(MINY, 1+MAXY): print('%s %s ' % (pos(y, MINX), pos(y, MAXX)), end='') print('%s%s' % (pos(MAXY, MINX), ' '*MAXX), end='') # draw some blinky lights for a while. for i in range(PASSES): print('%s%s%s%s%s' % (pos(randint(1+MINY,MAXY-1), randint(1+MINX,MAXX-1)), choice(FORES), choice(BACKS), choice(STYLES), choice(CHARS)), end='') # put cursor to top, left, and set color to white-on-black with normal brightness. print('%s%s%s%s' % (pos(MINY, MINX), Fore.WHITE, Back.BLACK, Style.NORMAL), end='') if __name__ == '__main__': main() colorama-0.4.6/demos/demo07.py000066400000000000000000000011251432564447100161030ustar00rootroot00000000000000from __future__ import print_function import fixpath import colorama # Demonstrate cursor relative movement: UP, DOWN, FORWARD, and BACK in colorama.CURSOR up = colorama.Cursor.UP down = colorama.Cursor.DOWN forward = colorama.Cursor.FORWARD back = colorama.Cursor.BACK def main(): """ expected output: 1a2 aba 3a4 """ colorama.just_fix_windows_console() print("aaa") print("aaa") print("aaa") print(forward() + up(2) + "b" + up() + back(2) + "1" + forward() + "2" + back(3) + down(2) + "3" + forward() + "4") if __name__ == '__main__': main() colorama-0.4.6/demos/demo08.py000066400000000000000000000005301432564447100161030ustar00rootroot00000000000000from __future__ import print_function import fixpath from colorama import colorama_text, Fore def main(): """automatically reset stdout""" with colorama_text(): print(Fore.GREEN + 'text is green') print(Fore.RESET + 'text is back to normal') print('text is back to stdout') if __name__ == '__main__': main() colorama-0.4.6/demos/demo09.py000066400000000000000000000015751432564447100161160ustar00rootroot00000000000000# 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)colorama-0.4.6/demos/fixpath.py000066400000000000000000000006001432564447100164500ustar00rootroot00000000000000# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. # Add demo dir's parent to sys path, so that 'import colorama' always finds # the local source in preference to any installed version of colorama. import sys from os.path import normpath, dirname, join local_colorama_module = normpath(join(dirname(__file__), '..')) sys.path.insert(0, local_colorama_module) colorama-0.4.6/pyproject.toml000066400000000000000000000030421432564447100162430ustar00rootroot00000000000000[build-system] requires = [ "hatchling>=0.25.1", ] build-backend = "hatchling.build" [project] name = "colorama" description = "Cross-platform colored terminal text." readme = "README.rst" license = "BSD-3-Clause" requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" authors = [ { name = "Jonathan Hartley", email = "tartley@tartley.com" }, ] keywords = [ "ansi", "color", "colour", "crossplatform", "terminal", "text", "windows", "xplatform", ] classifiers = [ "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "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", ] dynamic = [ "version", ] [project.urls] Homepage = "https://github.com/tartley/colorama" [tool.hatch.version] path = "colorama/__init__.py" [tool.hatch.build.targets.sdist] include = [ "/colorama", "/demos", "/CHANGELOG.rst", ] [tool.hatch.build.targets.wheel] include = [ "/colorama/*", ] colorama-0.4.6/release.ps1000066400000000000000000000002131432564447100153710ustar00rootroot00000000000000$ve="$HOME\.virtualenvs\colorama" $bin="$ve\Scripts" # Upload to PyPI. & $bin\twine.exe upload dist\colorama-*.tar.gz dist\colorama-*.whl colorama-0.4.6/requirements-dev.txt000066400000000000000000000001301432564447100173620ustar00rootroot00000000000000mock>=1.0.1;python_version<"3.3" twine>=3.1.1 contextlib2;python_version<"3" build -e . colorama-0.4.6/requirements.txt000066400000000000000000000000071432564447100166110ustar00rootroot00000000000000# none colorama-0.4.6/screenshots/000077500000000000000000000000001432564447100156705ustar00rootroot00000000000000colorama-0.4.6/screenshots/ubuntu-demo.png000066400000000000000000001634431432564447100206550ustar00rootroot00000000000000PNG  IHDRe5ItgAMA a cHRMz&u0`:pQ<bKGD pHYs+tIME8"`IDATx}y\WIBAQQ "ʢ \P,UR X6!, ""=`;tNZ팝cmr@Yqy}ON>}_}ٵkG9laC;0tpw;xCg<"hY'yO<~wēTǚ.nݰNZqΦ;:݃Et)TϤ 9r1#UfVdz?mLg?VMe7ia4j1ΣF9;=?Ww?}yGLL2i =n||ɾSL;c>~„\]M4i䉞:m{>N9q.G>n8^S|'M1^Iu8w S}'NnXgG}bWI{Ks>C{gdlW󟖜OwM~#ƹ7mxqzzkQ^Zwmv?'y9|'Ol wOOG+\- W/L1%Qql}EK<&Mz &N2y6:{8mˁ]S]Ӝ:ㅰh[t{ a٫Ԭ&v<=&Lp5s>Μ|{wn|zm+{wĕgwO}wΙoLvĿuCҔ.oin<8AQ$/>+^zՓfy%5z^?Qq>'LsΫ/\~7x*v˟=ƻw^7Gӝ>?mیgz w) nޚ_&YcӦMO>iӦU;>}\ɓԼGbǸ.6#$ W/B<ƺ?{m%!8\Ǻy^V5~|\5y^p5Yo_S=\]'/;/_=e\̜ܽ WR2aG6Q˗Ƀ<~wٿMNwN>geGKӖ. p=Zsf~6*4u䀀ӧO050p׮|}__'WΪMN8vıMvVU~ru׮Nso|QYiI^-EW_/=/WZVƧu}nToe/43dۅ W/_'Nt`Ǹq^|yVvg҃ǹy<ٿ/9Ⅻ/psͭ3qo{9^'^_Tt;160pzЬg͚9{v7ӎ+MFg\y_'8<{vіyA/>}hKGwnKˊsJd̛8#ÿf l 7qrrƻ/\mWr%]pekV,^_Z6!4dnhܰరй!swl+??у[?u}|Ƕ` U;moЎI]O [Bxϐǽ3_J:1o7EηWz+^_(a kzm?w}[/06"dny"#####E̟Ko5KoFDwS|\|SgڷO.\ܒ1n\}o+IQQ9: n?9szB^婷]|lh_:מ76;2w/\|ܽܿy>=3&fQl⨨.۹_.2U_%w}5zNl좸_\XBLdut~,.]<_x!;ύY4S7 &u,:n ^'Npt7^qO5ͽsI.9m'zv5}[18't:~{AyNT&ѿo^GjFΛKƍ0YShMجEm: ッ㷏_</i;bAxp=~lgVMgd>/^{KNKrxVp`.j7?c ƒ`~-3 [yca<ܿ9888oܿ/?s矾yXҽ 簫];ƎF~>@ؿ&'x 9?1¾w}߾ʑ@bQׄ1ǓKО9u-1X.A591rk誷0Fuif|#m\Џ;/;UlAw Ms#Y+Go7DyᘕK>*TߪUc3qǷ#9qd!aύWȷoOT"kqOЌ{e?/94$~̿o}ԡ! iE)Z/#|xi0!C'%pzlq֟OOk$թr[O]3LX{tl[ #|OvO7Ѩcv8w6t~Gج{=_ f|`e!T_sU矾&o|u ƺ.UdVd}kɯcޜgeÞ861n!al'O%]\T\e;:2oa&0O6H%-r+ b,}DĢa>*OT_-'' z Ll:Nt|vyӞ#3{ }я飄O7K=\699r~忾s^Qa)4?X}vZQЫ^^QL *w0Ecln'a7/zxG' ziy?Rx.4eyϫ02a?N>e*<ٿoMuPURq|jDsO=z?sq3 a})=Me,E| XrpppŅ/-ٔ"!~Ÿ0,^ƿ $!YM$؜ w~ .ÔvJYE\ O?>-Lw0|(Xt?;ҿk W?)fEca-.-jRq| >޻0F=3-X6#F yspppVhHp׸K0,$|ms]. f,"eS~y =?ԟTyC}6cݵ=?]Dvc{>'RɿLfy轺.W4]X`>~éCFN޿Ǚ<97>o5uwB؅:iNu>l88.#3'syxaQ>gXcD>^;Ey;fs=i 6|@:gVEzC憁C~O˿=T#t_uqppppp~-{xOɿ^l;ߵЄbL׎c"47dzKc#,6k H,[d/q_Yٙ ~=:3H %!1Ή`Ӎ~fܿ988888 ŻO(*Zxq|YűȔ3/MIFQB8ָ)bV&$CvB8LenM [9TiV88888 N[^\!gJlbw^|l n>PtdL-냜mq{1L< NW9*ryޕS2J#t|J8*p>ő43uk5;6suK;'yKq<DVa2Lxf{BXYBhSn!қo.s_\#_~f_0dz+E#q٢G/:9nS3yvaCy q@3,'o;xz8sD{ڎճ 4v2̶k<6ÿ_LwEx9q;tR陶 40keѩ_w.գ:琌I9~D^B[h.?5 <$6fC[)ܿ98888e~9~V._ ¾>C=ZZ먐c'fjPbҡV_|&d L+>~$'X`8p毙ާ8V=|@ /ŏo۫Gh320uhs>FC/sc5<`sFqx{JM~BP(+]W UOK]clSoɋemx-BP;\jXBӑ) 񦜨fB |Bv=P(d#;7LwRB#߃o\0D ,𷃃߫^EX3+bz3߫W,Dϔ'._qpppppu'("eX?p5ؾ}o30~4cGTs'w9Oo Av9T*@f 麾keJG3Ez$oGPKĥFJQ](s|lo sF_7R4oGg'O ?4,Ce#h=!`PHԜblUR4V`'Dyhނ 5up '%5j BVh&,#ȮؒU5ExԊQ=,rKcGmSڰ%[y^SJ)]6a%QPBmAji=y{Fg?~߫^\_޿)$+ F/0h&̀`l/B`=P ܀w#(+ (Īo` Jx 8ų;x5j0b‾14n@[K@0u(#/D kQ2級o XXÁr wf!r|U 0 5 X {"ꚱ]J;[2X6}1|*:ӿ)E4 1`j:j꼀,45 C`4#T:'v L!fDk,yHtÿ)d)5d6`V_2o`Ud5~Oo_.uK\R"Ye\O $#7,hjԄЁ>y)6$/*=@ b?307w񱿘?~%ʦÀz`x{=`NP>>gh@@슇 0Evݿ%Hގ4AEA{fL2$ wo N"CP! ,.f,1Cz#LDM":=!o#A>E/b Lx9S`$lFM|`@wbp Ey_ 44S-z]:2@9ÿ{@*`XӀ_G?cw_[4} *#QA{KX Eɿz%L wʯ꼀u}a 2 = C @ dm޾|&Zv oaisʉV&b=FPAkR[2vڢy_YW&p~ 1 PH,N;o@rt PֿONyM6V9ꉏ?UEuz5h)EXvGz h h~KqAƣ[^pK[L݁q&@DD 9c \y=ۯKu@~)u E>XTojTN6"i4";RRlI&LG TbhBć LJ=Q&0]Wq S`F=15xWL%I/xƣ8^BzOh @#~$ "ALH_ÿM$M<.zb Z9C_BƆ\;gȿ36@fJ"׎̔Ddqx;+%R_Qi[X=~S⼦6ݙk0 ysSM/cF j#|4BLD 5z!dt}5b I1 !ĩ^(wL&=r#c:Ep=r^]_ ( GO I˨=<غ9@[6023_g ,BR6DL:U9EX>J*6Yi#+̙Rs25PKxX56>!lxHz61ק_R”spAfzOR0Q{o@}=8G|S2®d]]Ogѿ7WWro\!aS &}C P# k8Yvv i:uYU6edp{(aݦS{ j X0@< U-yq㔡CA}r˭o}xdX~gYANKИ>#y qʊ!BAvm>su@@GS HѴL* Hm} b$͡bRPFf1he#cPd[m}JQь UR[UATl`=ٲiza:$@ $KQ$*_ ̇! 0A|Ajw!b%[fNCXJÝ1d C@`_( R[U3+ -m-ٴ|¿_]WT4|ERyUb7 Z6K+SJ+>(و/UPJ+2x=žcԗč5HlC;}!>=t,0&?$@ 0OS]BnOvHIzk5Ūof@5&=Cޮia>iT,u5৉%;0o&=2r{}tBO'c I @? ( IlB;! Bշ>Ñ$?M<L E4mK _0I{[}p d%JfcQ~@c4=vM_Oz8f.umd䧉llbuC?}DIcʩ;2i@kZXEۤ̍ 5f,g1mx%0ւڷ c1>?ώ%@`]~ ôHwt|nԧ1鈏FjQB Ȑ K1Lt\)'э%iH@)ĤfiQow$dt>.1iIkmOŤYm+EiQkf 4- whaq;ZlKnXޱJyqz>BK &M>}\fB<@ :?vf}\ZKnD* 补@@1 [Be#==E tКgrfwOO@KH._`ЧlaoeTMTZ HvՎY1rֲ{^Q?"= Zn lPL!K܂F^e#x)7eT5BkŔʒ]iUv1nȿsW!)!F[;*H Lz9wGӃe7擲[JR%b3Cs.!xvk/ 2M=@ M#!mnu9,@e"z 2Ms<2BXwdDbr'is vA^Q96#EvOOR`Cl P`mYӹrֺ{i6irWNdSϳ5M#wlWȑBD6  9p"z=йv;{zZ&HsLdӠ9N9fm?'%Ĩ/o-%K<wCڬQ+Z9sڷ<= h?F -x*A>zˀXZ$'mL,)7\ԟ2l/2WF SPАe*x]So 8 ~=5@E}z8*Av Odn=31Cjx@AO@e|+?ӆϛ6V4uOo?:xKS~ߋtF?h)tM?scp0?BHU@BHcOfߙ+ /iZY|䪝 D W.K=z,Fz- @Tj. M#AVFXdd#]59umAtMz&ȍJ[#g%lDHV?f3vBX#&K\!~.^R;Y }!`dsaVOð?v5p'K#sl 2\#{4M"~#,DDe#4t0T'96&#cP`d?w}KޚIk!HFU6i3Oݨ إ#P-K<-mИ>σBۆom)[2nE^f@`6~vݤ>"JuPNs%>íZ9i_+w=[.0LH@`l3!X&= `U]<7Pv'0`‚"Bc}xGќ6^c^WIM կfB,m&!>M_)^}= #cUĪuf¾-m!w>Q&gwxyJ?E/=1H![c8tB0#!Gx"(lRz'b2;V5OVYP~ 循rΉk̈́un;9 lT}y <T9!f]7]+#Tyw灁@7|t陋B QU~D+Wzvul d w%6 +S,l0?dϤ+J=~bfe_sisGU-Q HU:',w>2c}Ji]9ᨢ>MP%Gdy5ƪΉow42:Y 4Ӻԧ%V QE %]s H"s+J=;uOChJN.i2gc4qD3P^8VE}vN\{IbfdsDc7oܿsppppp># UΓ<9W(o{<9Oόq^{<9Oܿ.\~UG|QiN53!1j֑(ʺJё!_;==r^{t`lLvPc1]vid'es#(zM#,W30V(F2'JQZρՠZϴiz`]O e2$zsQ譺> &D=WEq a7b{}" eK 2[u}* }U$>#k{ ɱ2=FV?_i+0V~)eJ={gӎЖ*9o*L{1uRϜcwt֓<D@>@T@ lQ{(~k m*l1%a~>@a*1֧ F6,]lY@uXzB"CJ.֧b>(L((֧ASq[͖S`9{(9 _ *֧$3BT2?T`_%Oߵ3C-.-Yio}x^P/Hda) jSBc+h|j*0UT>}?q력3vK֮;O߁(+k/|Z8{p{#~  ! hXlTσ\G'=0қ` _TqY0KBF0 Bj)b5ekyOyV-C~|Z)@@ 5rM?zJoE2hZԧe,CDiQb<:$biI@IQ@E}z\ Tσқ"vYYSoZԧelVYgFp(-c5eZT盘ziIh' .[<\Sol?Oߧ^'O89c?Z-f:sQFsP_K9+c `Io]j%سYsʁvX'϶a~o\]!{֋gXg r#`oMzK_ALHt֭9yij(֤DρJ@NפgcJSXc,P{d F_*b1a6_\=<¢]|Bs섐¾YEVOE F HF kzۆ]d} #=c$\(7_5[>)-DrHAL8[?!ŭWϱ1yKv }"oMzBD%#ie# ҤgE7[?a^SzXZ 7!XZ~ ϡrg<+_]<0N>)۬ &$ثX@m^&$Ļ@9(@Pi5,` ƂVcx_Н>10@mQг+a\ T-mV!kB+y! u>1@j'hY~VK+A;;O9Fy`ҳ1FlJVb1R R]de0# E8`FBHDRlRz1yV͓YB )T5VcY0c.ZC3r<妣<^ݤlaszy4+=[X.%By-;|}JD-C_Ƚ#ֺi:MJ6ˈV͓њfg ZBUl$aCD0vyrNb [O( HUt,f"luBXpǖ.c񅮓uO )RLRɇ;#)cUuFؗw?2c}JRCSӺԧ9f*$5JP٥>/%Uo:a,I1r)HuOʕ9*ӄWђHڅ'-ı*duؗ(Oֱ>9~?)r'O<9OΓ7oߜ'yrܿsgΓ<9Ogܿ4yr9s<9OΓ7yr'o߿C.@2m; TG|y4BD^ LOB $ ڹσp;b$S@aX%iqN8"Wg0B*i dʜ=uade Lz6 I0R&!nj=[PT|96"QRf0FMw= LADYo.d"N1*(!G\_UO:^D*ꇄictO$aJXDYo.1̸ު (7H8aA*qyCFؕ1ק))lrA^&v٘V*ޠz~!alt׳/I&SSѪT'@Өj=>cJ=?1voo909 Q - LZ#GH[Fݩ1h:`!jҔq:0C0@u_Ȕ5Br֨׸aYPS_u_qӔmB?[ ٛa%(Xӱ͵D 4ad~UӔmBÃ$[iza:XK!jK0VM[!jmv}a7W /moepOvN8y&cg,ع蹉ɓmg~cgBP-k(sx9B餩{,29}fK֟>xZ8yf4VkS?̀8 [@RB${Us ߆jai,&j$!3<1OOﻄN^5Г= (@.t $C{s -ҝ0Gr.4ȑX&HZPRy-}1Гճf덼Pi#0k@\?E@\$m!M[![fKz$4TM4kȌ'ɋ(Ӻ.abW}ȷ'mO1w}rРqc @#@4m\#\h alX|Aط>ճ18n{FOo!&c9}f}kV{G>{ |ߜ Ź}a rnOK@nS~cr%[f{ kaO WlPc-xS?dS7x mVn3/ezV#=хX Zڢ Z"CiKcwF9Sb#6բ>x)=aSaZԧcr%ݨOK1=m2jQBRd=_/ E}:S?$)Du QmZ44tr;ݨOyuLz^|taƚmZԧЂh+Ӣ>~NLpG_>d~ݮ83d=}pϴ-Ī70#wxיGt $Zo c~2dRC=*;R Fh3TW;&kK )6y@jHrl3S)!y@ke3ӳDX )$+'Ɨ^}b-JFh3ԚRIv<;'jK{w>ayQh֎'*ֻ߳[tOOy)ҼZ dWxv.n՞WOgڿ ا"P <:vܵ} {mkUwۋ)@n?s6aSB@4[h\B ,A!ÉlC\@V[}lx0MS};컅&mWJ!p";LdS9:1jrNs}&J9 &iГP*;vzcn}]ɶ7~߲=Oxÿ[^ſ_z <|=1tηp^GmXñ-xNjO@C тgbe<էߏ[`S"ap쟫"MO-ظ;6Z^:hD CyUϿqћgg ?Czxz"p^Go$Л̍NghQӇ7T{z(hE}z-Vϣ͓Z`K&:aG"6Т>-A@=A @O7m9̍[w$fnE}ZN s-hQCYtW?f~<9~Oso(`o{=v# N @j:nBl?BHZ !=z}a d/- 3o2FB"tkod\i|+ hZ|`o;~H xW_= &Z07/Фgj+"|'Fn|d5@ȥwS-A2{¾%!!FQ!l$z7b|iEBX>!dKOyBL @f?wK SdRgѷB$ݘZb?vcm 0.eS.A-MzЍ"Б|"a,~B xW_=c2r6 -s^ڡIORG7RT\Nإwғ0L}V,>x wyUI^cfb$!leÄ́HB{| Q&= dcVaCuQ/I|@Xo/QD3ų;&5=5=!{Lmg3zvjdaljzv&GHxf}q@ <`{~ҝ'FdҳXXTUקL-Ċ 0NAHu}?d+ C'D22mHeIž+b2cǪ)r[eҬlaS|T֓?! CE26H<< y1-MnJnMU2{F?d{@$8:{F~8b{Pw=GEmRzguLF^X<mmVz7PGS|T gCDg#Q?ԁs 3Y/k>s&Fz-BP;\|lu Xu7/Y7i&|d,W,׍/r0y}bLTt DTZ7va͵}u)ˁBiAgF/)Sx:!g3t[0Qqze,"Cu=TpcKJ=5׭D%Mմ.f9rTQo&Ud(Xf}]'g: Oֱ>%)9VӺԧ^*ɷJn٥> W{UQf^3t42v)AY 6OR(At呁rб*|x0IgX|)q(Kr'Omt_`Ё^f;^r7<9OΓ7oܿ$:wFP({zZKyrܿ9395]ꤢ1B^ܞѱu3!wڣ#φ*H1RNŨmbr2cՠZϷF H;YB)*i;Qm-DGߞ=f0F~6”ɫ%zsc9jQoIlUW(׏ZWEqՆ a׎oT~W(L)[-Q֛KqfުPa]mtQ_'5>}Fk[!#1ק4erRϝ.cr3GmSЪuJ=kG5 cSyCX;YW(M)Tӥ$7xj=e*ZԳ֛ij=~1{J=/}zrp5BT#tR -Uc(BȔra˶VCP7Q_ 2/BZt*hJ]^@W802/mo#,ҭ}> `.ulH6B܌-#)ٻ-H7n+Anw@V4zz%{4/oH7nze9u@~%.IWxdN_ $իJ<(Hm}b].nٶtMbrdl.բ>>ʳiK=mE}:oc3Ogn5/1=p蹣5|MkSZ-s;q̩=ϵրv.Q;P'w){j{c}kcsZX[WE.ф2{uFU1jIj!̾Z`حy7bmnȱV;=\!ls*!Em5%Zm.alգӳ_x)֖ {mS'k/h,*&[ zw>UJjISjL㹷aܺZл{/<_ܨ o'N϶hhկ2_*͍՚'mTL㹷cݺzTO=9 !+FFlէo@*ņ4g0P'Z.O#wof[w>}Rtovzʂ(uyF2F3ӳʷP*J7Wj,RJ鎇yg7'`Z'N5|2tyY[מ GDu3O2N5:W}XN2BaR_:[lVWyމwC](r^ t(h(h?P-x^V{'v3̶ jmY32`!xņ{ ڌ-+Cn~DWR﹞қNءfnNfhQoC<3B Ei!Z?_J7ϪnNufhQthu_q%Z?_u+{\yhУN*:}N;wfZ}xF/|{ap8_-_X7dk !q=<7<#,݆^( 4T}th/p ?!$[ dN[/`W?4YcZk/Mzo#W-0 yعy(*{Z7)c+V d?Vcl$P(f+kpx_*^H16_(o߫qp|quyE'n] !,.u^z ^3ZPHٗ* VO}!m"m$Hí)nK&9}'۩#s[qBy^2Mz֧Ӎ"yHyMz<Ƣn'Wm1yKvj򼬢2Mz֧P֊hH*o E7W c''+׎5=w}sů0p =zSk~\{=uF= E{{hW{}׎W 啳Mhս%0y/ E'O+mVF2߫B@+m^ dwv')ACn~yFVsP."J"uBZis=t)GϮ\$T|Azve=HP3f}B*lw\w=Qų!/O*xkg B}~;Oy(MJVclP$T]n&JV(%H>F*З#`HUjIcbU%nԤYBjBUl$E06Ѕ Qke;Oy(MJVn1΍MVgmVz~<%A-d}F?T"-/g#rUIm1yժyZ7J-.Z[Bg#tT'=2>xhK9BPm>yxڞ+-Ts,[e#mYuO9f[UԛIjS%K}"7k"l cqz<^c}Jd)i]Ӳ '4MU%vI[i:cˋJ=;q#wmg ky'yr|T [ev=p{<9Oi;rZP:ov<9OΓ7o(N-#Bf:U@^c!ӟ!ґ$ aX\10CPA A`K\y[F\ة(2:r]%"6R+nwzI ȌZϴ%J=sb#ӳtӊ$e9("&(]IQQ+6TMVgJ=sb#Wt@>ТMOC| a3@=FE12 ahQۮšIu}"@@Uwe}t(eW+ӽ>+=w!=hpR_i%WalzzZU&e9(+&=/]v.wR iL/c|9_1Ʈd'_տeP0=qA-j*H}C \wAF(P,,쫖#,2qy#P/WtDJ5)aC   !R} ( !.|qҡCARZӿ><ͶNSj̳UqE4d!iycy ˫>'ǥ+ Ivk4=x(w,Os!>=./7QjllZj:6h#<]X+Lw=צSЂH1aHء>)b)J( )R>O:d`П}3rZ4 ;yBCm}RX\BRSZpϜ]}bP;ufaCO(Uj@ S\bB v c_+Ы&p.Ea㧉a2 K`3OOkĻܞ'k C!`,Xil _`4NQ!ݓo״>i.kÑFHF&DLP h Hsҟ'" {)GcF}Rs(kPE}R P+Z瑵Ǧߍp)FZrXE}RL(XD#o+n'5w)NO+N]XE}RITVK_)yd>x_x=;xtH[`kv͡gb[kEw7: E!Q-7h y4:!DZ6 STU@;zhӠŀfn#E) Mw5P)hvzzcQ ?dYxݫφ)Ju֧%:a|[k{ـURoExPS(̴Yx)jJ*M:BkŔʨv<ͼ>c'dz?Kvg׌jտ ݫx g78;Ы4[m[םD$9`"#Wv}W&6:Qww,#H{=Ȧ>F@^'sΪ==-#s#`"=D삼W(6#EEvOONd{-t#OF޶W;!2MS}P9hr"z}?M#?^}@.4'vȦ^9e#iD6 zr*4I;=|z1~h[Oߝ޿N?gB*@`P:lwTσ,ZDGӆt<)7>??Upa왹ʷ+wi voWYh[~Aɻ7hH@/7Z%X-ԇj930υ%l:EqXð?rõdK4#c^<1a t[>Ψ fHQ)F&=F*Ko&Wϱ]͛Fs׋_֤D}kH㶈sk3iOܨ,51ri~zʁb2Dm:? ׳]_KO93P } "M@}Aqj0??vtKbd\#[>J Mz&0Tyֻ98#\.0]&=}h]= ALOݨ<;}]إ{֞{=B8wG.t9Z~XP(vM;r]zc{''' ܑU.iX 5:7q&)|d,^&֑s0 l:<`.]C :3<\!oie,~ӵ\' s$ RuOqw܇=Iq! HTا,0RαxXOP])DOXsyC6 3Sӫ,1+J=2sxB]r:&>>.aÏұ>%AElt#jU'uvOZ >zc=aMS:֧HR X)Exz(3SR$.ۧacS:֧!4?'K}6n UQ)K.ڽ 'yrPܿyrܿ9s<9OΓ7߭#;sꀩbɨRQ(oVq[F.!,vlhCy~GT 0/C2mE Q.Wy\{3ˆ\ErёK!_;Uh>6:r{t`El';(bL(wzNVWg|91,"eJ}z(I7*vW@B(e~ˆNVgJ=sb#wt6ȟeQhR]t22"O;oS9+BXtB䗡Eyh?O#P=F1&;RϞƤrWiz>G(z08_gW,,/sPsWIz^j=(mIs(Wgc_+1v'Kg=9M!˄!50cu-_.._DHlSyty(!הu=.E.BA)jd0<),(B((E 9Bu?",l_L&[^ӮO,s(9$_L&5\pHyX QIH!xstzf .Oȭ5Y7"79^LFfA-OJC!Ĝ-yR?'ǥ"o$u[kL=%bP[4TJASAŠj F¾6b塌̾Vjx^J"C~.v4<A}ݭ&kzd.%oS*hI 'P[43Jh!OR>OeПgֵ]^LECm}RKi (TJ?g/2dw?ߺحk߻=N;rnةoQ>_3A+eIDATB)Z8vyBq̶=[cU(N~ގ:9p BqlűC֔RûηsMYRVۮlBU?c Q&ClРD|ymb!2}mu0܂ovM<)QRQSPM<&@ o/`d?k[)7Yj^&ʲ Ҥ:jCG2}UM&=#ܓߴcd]iY65h!-vt IϨ'gz h akO* P$u7#p1;B~\nH-E4b3 kca'\|;F~!}+5ѽQf]aUfIO3UM̞Z50;MzF݌`,rqyzԖnqol؜U]OjFi5SH&n=jϼo?6r] c8t1)ZG^7`*Υ-T`yE㱃{=ӮPt`k[8w7=^q+ojJU?y`ϫwK%p#KlUcpgri;Dz_kish36h™ˆbՂǦ gIø$#Mu-,uWddH|ÝYo+ mq7tqKsؚd9pS<ǵfшMT ᆳ샴(hr-QE} P 8PKP-Hrw>iPQm#+~7VKҊ%ZiQbqErբ>dQɥ8/hkR:-IRZD"E}ymc_}r<֣ĭΞ?[&oW[^}6TB*}>G#^߽l_%Eֵ=; /ѵfa4c}ڿ{z*WI[kI)QϽ^co'dzMG[-o?Z`ϡOiEG:{AicgϞn+:?ovcp7wwcuvR;PUߍ嫜c~HBHYB@^' Pf>!DܴkF|s`I;=笊diQWvz@kz=Ȧ^93Xv 﫜Ȧ>W9M}+H!`sG!R?4[Yz0F~i{{.G*:h@j'J}sΧCbdQ#Js rJil}fzr{u_|>Y{ZM^;~Dq&^ާ43m4sxLj4fHʀ!H5׽7*Ar}?ϥU0GRr1^ IvsJβysfW)7֝қ'bk bIcA@3@ AzMSrQSBD'*Aқ)vYYDMoZ'͢fI4#nZ הԟgղ:۵OJ(M4ҭj5eGzroj{6~_\Ə_:~wߎΞ9uKUyUws1:rC<MX|yv-Msn<މfrP}33hft 1Efo۰o\K]!wųbqxfQz`oMz8׏hK+Ń4陴t#ѕ%[FFX缌;͛Qzzq&=':sTNtMz&-e|SYҾ51r{~z+Plx#w04]6Uzzv]BXz)oBqwBN!+GnOӿw #׳.wa_Sϱr}`oMzPzoA_Ii3? f,Vc`Bn^НܴUϮSbQ`ZOsQг+qMPMR#_(j0rfz֔*}cJ2JUtloJ(UͳRƾqRqcn^Н'=NV?vO?~cceg+[ԮhhS?` B8~rա=bM-ZܩgIUSa.܇eZ83~r߸c=|gKBײF?'2K1KO|S1˷])PSqƓ.ь/XlN<H 5$}3(R`wqQU"njhFiRQPAQqITfeWmf>l* },{*}*1y=}۞'Fe6$_s?ù9{3] + Y JykO#_|~J/Mm>V.'=)_d^ę^$_'ꀑsZ-cpW8|9g߾gX<Ԭ8Ar괷cjlR# U}C;izI9(j31}JCESugEzBQOA|IJόs7 f!>5fObw 𚆦cŢξUFO8)N;EC(--*|bz9;'IqOUoA~hߡ8)NM?ctQ +g3>2?y,(aB2k T,Jmyul|sv6Vp>|FX!T F Ewb/@,v_JgzX DmoVHe'Ɗquj6)3~%-"`Zi~L9(,82dtR?S.jyῌϼ6VdZqb(sί\9d~> Z3e!@bY>?yRAYjQvBƖlv6&D=qeK:k> 9te^<uHO>'\8[̎_;'*  b} K8} 4y/rPZt<&cnv>ܑ88퍞Fc}sh2{^?Dy9>TT|_X<Q_7O@j̈4CPSl3\`3"Q; 9[s>v ~3!U=0>q T`<5h}\9:02/lzDDAtU,ڱp׃ʋDٯ9HRF7[58Y;Cq$b>Y{:;79iFASz uJ3/:SV$^*Z 7*NhyyڦS'6 Bu%h<3? dsA QyF2Zvcs}7,ek<[ԡ4Qf"{Iֲ%/S*?I* q]h,^Qkb yU˳-;6 d$A\tϬ}?_ʹWَ33#?d (cDGG!HT}7:>GϷnļ`,NQ&p0A +J?nVˏu}f,2!7"c S_ӎ3yϹzc椳ͧ*{,reFunȘ)B\(EL@\h,^g4?qճg;Oa"){I2  K|n}'&!`>ǎ *)},N8ٵX3P\XjN6]ν5`;\a7*cc~S9qe;z=V&]a;MWę{lLsc~#"Nt`=&vTM(_1[~u(|f ޜʄ8 كTX'1!-j?C⻸&lc5f4X\`0ӄ/*k?]OtX65r':A-銉3фY_1}"dƃ,b"!%*~ED]Xߘ)9&OtBT hBc?|I<.|/]Q[Wb"`GU|PVSp–SGo8^WWw_ZV !Ӵ?+L ~1Ɩ<WY ba&9tO gKEw:dAi&ǛjT[VK|cDCl0㜯?FmZ>r캻gA~4 B-S.8c>xgޔ^Ls~/D)1}ʥskvky>te9gק.)Ls>""1}skv]GI<.Q+T>r̦(*:1H m4Z;^w,k=w7uaq0Ƙ蜻w,c׊`8ZfxxG@ L+=nwq]cq7N7DD8.d3yB6l03ƽ'|y}ɧ;* Yqwq]~sD: ٌO,d38j11灵}кX(W }(.y"",d)t/pg.yFDYf$QjUhZ>soh>?_i*:Yt{6 ʲŅb.GkZ-0 }v7{׳2c}Ýg!VAü9hB˵:'&B}!z6D@+ *KΟܽqzY@ٮ&9#*3'hX~qb&0<ā&v˓J4;c5U jT|;ԲBTJZ 8Q/g+!G@| Venyu+clIp)tp1&U)RM'JJb7IO){Wص- 3r΅eZw(NtP.K|;@%.@ |qKi;Lc "ծ9rɚY5S.lId|wή]Nqɗsv|򩆀xT5(-|2@FHEP tC1|iu c- ~bO ;ѡ|ìǤE Ŝnk| 0=SQ@nY4x73~mKÌm?qυ`>3!2 ԠR<w Η~bO;|fƇEƏ)PT951Q7s~rÌK?qϝP>ZyFSS#K{w|ֻ&Aj76F+D4 7*6[E1.fkmZbƼ%vZg qqn`gu[Iˋsc/fkB-΍+]̸W&YhQ sMZgG?1^g>Gբq\gF`2ܴDfuk07mȲ:[խ`TN$|9|kGJ3~#pq,huv`$@z"8;!U\Ŝy]( ,K'.△&$Z(>*^fqǎ>?vTYVMj*)YVyQil8RwzYEmic̏7Lnnf4ؗ165=\Rug[Ď z'D O熙PO,3g +fKS IrNiyٝϔK&\s9m>w5kAx!ѼZdvM&z*IqR'?Gۺ_飺oq!SCqR'x]X^RLqR'I&?|?8)N7>$*IqR؅o7;'Iqkka:x18o,.;yđ\xQ9Zt_^s;LR#"*-pzRO=fW c-I/@DT\[z@if(#vH j) OV%uʣV ^ܹ3Cb3cYПOd01pZGq6V0V|d~>XLCBu||f9R[^֘?q~>2?Qb% />UCP[GIq?)_|0{;_Zi~L˓BTv(A*/>ň!z;s 9]X\B+o m> Ɇg'+dqpԟg/2W|d~>c"I m> %di'?sEm>/sGfQ=73,\Y!>q+2:?yRʽYjUvꅌ-ٜ6q"gS˼?RwԅY)NjD IvFN8O3pZ[~a{ժo23')2z^>y<'̞Y9>\i_};Z>#%MVx%l>-\PO DvR{T^ْq̈tICTȁ O.yjDOāh}^Y9ݬw%w NTDYDՈ IKblh(GDD Y~zoy;org;gNJTdtZUdyd^+WihJZT^TV1B[jiGe'Ahj-38*?I%-qM3'f'l.J\XeQko0[ K9J]ء8ժ 2Iܹ. 'PLR\t]yf7g/ekَS(HR΍tM3'1 P5\Qe,g췫>_ʹWg; CTÎ(q?*d"QFfΉx38|Z~3;>2?_%KĤ`2헳 YoAg?n~%?=A94#_Ո"*]xsYcͧ*;QMIL{#ba zͯv$o㱚͢xQaZAh`M6vkd)Yh8Mh.'fKecc"{>1Q8' b]O,ȌbDF䨰)8c?|رI<ҊbSK k[c6&ԑ]j̝7oĂEdGy)1dsY b{At|qb/@x4-ΒlɧPƩ] Ei!v-hZ>}9c|ɦ˧:6="dMQmZ>%]> -Yz!H)|gMoEgzl^RDʗ\q~{ޢߢ4Y[L+_}ɗsTwwTGGDg+񏠤Ϝsu;܅#+T B݉ғ UG6՟h4/.Nv߅'nWZuYΏ+8zj>,a1cyιY#pL001(G4 1ƙ&:.GOiD"tDٸa1g{=sw󎉀diTyc`cB6lg{k]>cE@2}b_=CL07Ō3vcmtݵ1'6\A!B6q79.yoD(B0-}EhZ>X97֞|'+T 4~М`>Ek)?|Ym֯ݝ93CV&:#(̻\cu]>mrop5<8J7yv q+B<MsljY ;*zv'UǠ0k#Ҷ?%8q972zv qba~_T6ޑ}vǩ,xuHGVws _VhBm˵羗 q)tN3}"A@FtFg˵羗k:'i?+@Ut _EG CB4}VmI;Ҏy0.R?+@LdtZn㟴\)%ןo>Y]{5U ;Lwt]TVT]VTG[nc=bUR5dO̽+2%a6_ƘX#׳ ]f="#U]$>jýc;ZT%*va7 -߻3˖m2:gjMUJjTdcDw j5%X>_3 /2w4JTJKbg;f@qfK0X>_9rB%_w;Ouj@uTZ-rOas5JEv;@,B}4c?D.YgQHcF5b*{~ONt06 jbqpIII'u7=mgu*=p{@+~1c^kcj̍[1#:)Bl2p=qnB; U8 mQܘ/3B]wu1^g̏SBlUz({@|⦧BlU:A^Gc_gژj<:c7ϧrSBl2sL枩?NTo, UX0 Q?Gcg ]3ǩ>]-g&$O|ڮhcnEsu-FQºŜyi NiYv L$d"8;1bνQ Wse䦄,△3ld ԈO8;1Q svZB<* MTTf%"n9[ %dt _^3G WD'S)%k"£UMBmy w;7+aaё5 ??VRvIAh[ -n O9:Mw'ĉ2uʣ'Ђo3ڌœJ͊S!I91^1"`=듲BAs"uzoYhNW.rR>"!"zNN1"ybI,u@ŜcP!` =gX<Լ&* \Ru[[=")^nh?AEE XgKSGϼtl=Eg< qڅ߆Wט>!IrQtN󊉰OԻ.Q> ^zv|\1}JIT!OIkߞe,^SJ>T8) %ow(N$o7IqR'M8)NS  7AAo   MA  o  AA& 7  AA  A  7AAo   MY5Ao77XdG\;@>}v\d  >P'E SKK,3ǎxn etIFiX;Pwepp{4 e۟&ܡ+\UMJ.A<l0@yt H  ѿ >Vv8HX y|7x@ 0?@[N([c5'uQ GvzmBE[lPSk+[Ϻ;u}:>}jJ֏<%رQRAlϴ'v=dr@v]Ůq]D U '* i6ʒOzYxڍ,ʑ>.%#f.[1VJŅXM㺴N)yݣUN(;I{w4(rIZ0Yd;hƲ}Ӏg-qlû1oӮN=/~A;k4O:tIh>ɚ$nF\WQnH\z7FT^}[?h4U$`5hIXt_5Y 1{V ^ ;(Fh+ Aq3Cu oSa{v^1``7Z'D()ǬCu$vU%M{D |B]̣˭~^h.vktTe$Â?m'1PU 'u\[1+".tr;@2t[ u+\=˶6(.ڤzTo?`ٵ'N"{?TW_- qGϚS#?>2ZuچcEG#tYd;>{5v{aQXXtwDd7dl퐑R xF4{JWzBmF9] ~Б6"YW5usx@3=o{)h)VgT/HUTz(uկ4{/ՕF*zdAuwء:A6f{p``%hV_5Hu٪4DmG7ϟO kwMc?𱀆;9.-XߘS,K| t<[8zupfc0G9-b={I@:YيmO W[~k;zf}\Lao>~d#"{6c_ySP;lsf ;=j$):֎y5z<~|;پAxRQ2_~Tl76QqJG+1@W [1X|27[uqȢݠ(wVM--KtiܢsDg{H@:PBBhNu$8}eGg?]f[ s?̟ςyNϴsJ*WRByk? ]''׶ϟ;}J0oQg|SUTmշ\gumUdbM]٩ =B0-"A/~eisK:|–ǭ߉;MtF6KWcLEe7A?,̯}ηu?돝Ph.g~E]ǬF&(b"'=FP.{k'e|hΌ!op@1 r UzvoT!=#%+nwykw~ }KFط}~,{zn3wߪw^O% 7^ 7 z~/oُ߯ͽl;}ws N sK߭F{>Ӟ۹uuzg]Q GvzmBEﯮjʒ_pbeZL9zVEMv4L:j[y}cۉ  wlZϗpop'/M}7狴gjxe *.oI<ԣ@v'~5ocTکqodso_s8*?U=%T -C"Kg,{l(JҬlq;+# ws}|fHp2^MBevquFHzUK_pQ!Ӷ5fmx wso-Kv/n1j?L[&Җ? )2P}zԆY[K?߳0w_qƯ^ wOύTQ-[^< ~c]feScU"Օz( mJAomIqX%X0B3JN 4+=~9덇   M& 7  A7><AAA_k^x~`*liZU˜߷!BUwhvz m,:wgOţWo{ x8 '—﫿A"c۪xqkcHN)q䃒ՆdО8㗃8_ܰ.Sh#i{kpƹզ-(˅/ιo;gQ.p2i$Γ⋪A?mg",LQ$BS:n`떄W^Um 3~4I7'N6 TUܡzڏGu\'Np@M5̟wACos;ߛ'!Hr~ ޜoyJo7gG7s^U泌sEz<gM/9)g._F넚=\X:xBd7jcqj+}\FQRM44ף=|aᬁVS gړz;29 b׸."~Ҫ^}$WZUᠣ /oqβ2о_#h gw_bƏUZq tkݨ@3ɾ/:N[#gbpkyv o3lGV^/o+O{1w?)ɵ%[Wu*kk{MmZq>j{d;@tYwH o֭;΃_sINC_1yc|@d72I8L ڼ]"Ceu~OŬz #2jQA8m#Aoƹf;l6Ԫ~eopn^J߲m<5sξMjck{ (iPwnNg_]/ZKXy3g76QqJG+1@:o_Y/9&A̟hZBamUyCXܚ6突Aq>}#+Zj۾?:-Gn6DEȷ=k&;\%>eCKlo<}|u ˢ٦ #7CX\]S٧bmC&A?q_o9GM5 9ghף|{&ngrśa/P(߮:csۧ|{2()ƹי .7 Nm3ׅ!A W-}G]LRx8hs2çu@0Q~2zFOKI̋tmz=y/dè.":ժǥ"#6Ao Z#E Z8%Y g/4̳b^_ܷ:De|oK}^:@sƎrC2oU  ӛ;/4 Bc"l]7 ( <esu5Ga˖̟SOH^PWaTv툵E8Vdؚ/vq s   M& o xMA  \sx Agg6s7L˷ [ s9`=Wuj<E;1?"MMD';`J'0@9ujN 0|G`@>sJq@ 0 獍?p3_wF]R1a7d̿S_~:O~5='RLm,@vLܻkvM[ͫkwӮc~ozvX Ŷs3Cooymϧk' wl xLOM nz^HSi;\ g,m?@ 0uvo W_ۍG\?7=N}@< 7Ufg` kw y_O:L  wq e}`<~PvKr2Vp?7>59;F$w?6VY;AAA  AMAo  AA~m  +(v|/K79? x1 bg\AemOy :^4{`K uP^=uEO~h AŠV 0/ ަ~C~O&?u3>m!(㠷eˏ#!+wI2X_ ti=Zo0؛C`Kk`N@6î ZvyH3`ǕuQ A/ߋݐw ~\0 f͛EOV:˄|ص- =13 !n3漩P ۡ;6~ q' hCZ-{C滶ٛ ^\Cuӛ7 n`6fBs ֿG_`k,~0hߖ07} X# Ѿ?4A:[uVl ݺ>_vS `j-`f_lȂ v }@/!`XsG@|/" L_ /lO%J!&8xc Kakh?pn" ;>, 1[êL=6~lm?Ağߵ`RDVP<#)2-~o~Yo7՘o ?Jn4deҖ>wyuJ.p闗Z7<R7Ĩ mHԙ6n?nA [hii0'n7]szrz)_w!>Υ[XcP#0ʹOPEAmst ,~VN'E6Enql];^|{͟7+aw.,c6Á7ZIG@ <^$PD!5 &"w{m1cBGa(~)lͅ7~PJ_ޚsZ4Pj~Cn/f104o [%F;5AgD9clGЍ\'d]bThrܾ;-aJB{}&섔հ= ^{e_Ppk%E!K X <²7!Q\a`gۙv;k9ܸ6qYGo?&><ßmX񐇀i0H)Pdsmda RبecO'wP uvbRΤe;aݱ~u {VT/,QX|x $Cy wL;QCIc(c[B<|0/H󐡀IP 4'w77Gڰog xf~p!?GE wΤ!Aq/#I3Q#zQe-^O& y#1jf&ŠYWѝnAv31jg|g̞-Qߔmu3~aKo?P& |q޼M G|A=lq-1GyK-/V4svqGWk%^}KJAܫ_|>h@lo%q:A`!is3j vS??}lHD"xvb\+/_.;k_?@林 ߎ o7?.Ė] 2١9 unj8aO/.n]Af3,h?7mE߰O#[z-l_qJx -[9,lҿb{zwۧpاB1Q)_4we#ǡ0ޚ?|\fO ++[+O6ů林 ߎ o7?`96q]w| zۻ]<3F[_^J%ANxt/?&q0gIvӋ<1ee_'Zrf3vg#>cξg=Fk;ݻcv{3 ղE Sd ~}:/=w%6?O<-}˜kzUAOv Nmis9_аL*Q7}<;M3~c-}YY$[G^?v3jȐ~O Y[jtdG,̪3_^sKOtq>Sz\ˏvfX|ak< <wK 8m7%6CY?p|>+an~7[ؼ~zf,>g?zryɨQ]jk+S?q~<һXӾasO&yOG_3Es9g?Lf7ژ^7Y&*Iڳ/sξ?1tΌ>MwAf;Cx;F,lf?f'qg?3ٯ_NIz9629}] _?jFmP_yJz3a >?fyP{'=>C o??GVO^olܢo 3}k-!$kNw;F/w;n5ɏva]`-+yA o SeOn'Bda Y{ߢ÷ 'oKHut8?xpEA53x]V<5.,1zG|G|vYk{B ݘ;l?:ߢޯ2C>v3AqOHJڱ_#zЍ\'d]bThJC)P x 7N۝*mܵ1"tCDٮM;~rwoAk  jO۹emZBDFbdVP<#)25~oz,tB/7AA?@uMo  UG1'/=\b]6w)  /_<9)Fׯuj|A/b*^7AAŏ?ӘEvnOQW6 u't07AAt 9??j7>pY  eΝ5ulkҁ7AAkm:m??FA ޮ<3Fg+>  3w+) _~o >z鸿 ,;?SǔNWWcuEa͉Rg.]xpP 8vX- 3mFmo6ݺAEY6h6"[é46hEVݜ,ʲK(eaFm[G 5Օe'-Qs6h6h{6]z9hko=?PԩS{tEXtCommentCreated with GIMPW%tEXtdate:create2018-09-26T00:01:04+00:00YR%tEXtdate:modify2018-09-26T00:01:04+00:00IENDB`colorama-0.4.6/screenshots/windows-demo.png000066400000000000000000000573601432564447100210250ustar00rootroot00000000000000PNG  IHDREgAMA a cHRMz&u0`:pQ<bKGD pHYs  tIMEd,]IDATxk,Gu&ܵal^/wW:)c R a.S:|u?7cÏy?~||| | ?~]Kۍ??[ˏ??OxOw~Þ'ּAQ{MzM?)7So3Om6???<<㖇7jn~ig7vv鯈_ i3i{Gμ#|GyGyGuGuG>}?__=k?~⹯s_}'Q;<'>Ki/G翾7z7z777/h+Qz¨~QԮ̋̋KKKKKM{{7Dm7lꛣGƬ[v֝_m|m)j+'A.7]xenʛUQӫ6>篺WWWW/5 ữu5ƭq71|m~/.j|~]Qk]ww[{ۿgQ{}^JQ qv7m\vOx=mQ5]kz{צ}`|}o?t{Ç޼ݸvo[ jx|_Y]/9j7}?3j72je#n񩿼%j+}o#j;www3m٨]z.'nI>l]~[v{w;?n{?EO&mQ.|??{u q4jC_)mc}J۟?HG??W#wGǏO>?(i{d9?|~|W/O}u>u}z{Ծۿ;;;ow|6=}/ק/@A u:H~ZH>=}=HRA'ԝrΜ9*_*V-]xo~ѯ|kO\zMׁA u:H~I۶|X^bw_;U6oA{ _'_ u:HRGDgϟ{卥Wn|U7>UGCeR?%94ZvR2}/?0I;w !߽RA u#2#罊?+R?#R=$${A u:H}^*f,xRs""#Ņ2#^GĤbw7?D/BoƇ_~Bi*W?]ÿ%7BLiz̻=ג+?r_uϷzIK?Ͽro=妟~޷߾7Royk%__L~{ HRA{ѳw&'<Q{J9I w !ėޢ~S~os!m j?g}_}㚫Bޞ}/~_bt=MW⮛eO} !_OI箽)ob3/~YqXLa_KB1܃7]?B#!uqOw΄~ƛ*w3!o_ Oτ#@!A u:H=(^!z>q7\3ԣ{A u:HR?sκLrDBJw{IAG~7@ u:H$.}mz6}yWxH?vrR)S\w'Z}_GHRR?uO_cI%mJπA u:v;/ȓΚCkz _A u:Hē:FDNbEW?aʪ<ࡿ= mbA u:HdCF*HRAꨧRA u:H}H m[ sV2VE/!uoRC uXjROH: u8դNeY uX1RRU%_AzyH:H@RouFƼhuFaF{0 ڍCSh"(k|;q GKSoxg@#&uܯ]_=hI}5So^u1MJͤ^?N&!\N$kȞU47Ve}nQm+))UD4wjVhӝ~oIyn-Vv>PE]١)ǘ=^FVMwyrDsEf[-S?W":N'j|>W>=q>') Qtf7uOV`F&.ԏ`<RcG2y+ʼ(R_ԏԏzq pr=^R/<~\ի@ 9~lhRց|BD^9n-U 1 "FpIYhJ OU7H1oYr S)'Lr>RR$ URO$md[z%G^` uu.{2ISHn"F/xG`iGy3h.qR_ZR4t)Qsn+I=sz4bjZys:%xHM(5be<_x~%%͇өWk RF]7hM(az`¨AziK:HI j_rnrSBz>1_,G;W]\rLU~&vQ\J &Y]Mex!-9 2 ?^۟ I]vI]K,V੃ԁ WxN=lܜ-zqSV. o#&L,mlx urd\R#ib4#pKF ezm ͌ZSc[D^S$9wq{ u""懜Rl)>x7QO:#Ըa:4nH*#DMDcϩ A=Iބ&m$ȪO,ײjxE|&B_Gbgaت:<򽉪W&j?p۴QWtocM9 ?OdM 3rWui8,Z~(PhX _f{GbX۠\]-Z^M.-bץiR&B%vJӏބ5w)+2mMϟGSI=]XrP]tu*:2u/|u;)qE)]CL+\#Zg! \}ǞrvWt:7?ER=\iPԦJy:aU>~e4m1|BgOAsmރERo%b)逸V[NܽK-WyQק!n-zhs^=r]I|t%pz[  Q;F~:3ʯIz 4Ƹʟ=?NS7ߋn [T"'&??]C__W*QC.[/J^=S~s92n̑r {r^n&ys:Kp䛉6/]Ɇ& (;+]lP*MĠg) =QdiR:L'\{L~4ڃ`0\6{{{uxR/<9MО3WE˧zh|/HXzr OҤ#*&[^M=&2wPr뾹KӺnC=)Kj.mhU^NОDfU^N|cxgBs jOWye$5Ѿz:*&ן~(-hU^IxSϑh3ewZQ$^2OPWՄw/0#O z^yU~RHЮU,\{|NTgiWfaz-^/n|_sXץt"$ߤI.1Vb_;2q_%=9xNsC$$i 斘*{&|hX gM~gHbسGbXFS*/zau'KUu97z[ǯퟜ>~HA}\凂&={s3 ݔ;-u]ӽs)ǟ? O:?s owGm&+շ[c\bF?^'XQsq/3syA%&SL"gkO($M)o|фЦ'&AuЦYϐ(dƔ7>h)r3J3՗f9R2nJy&40MԳפIs?7۟R@zyL,&b&8, #z2bQ ݳ7E|q ݳ7i+"Ugq =Xx#z&.*ߛŁ9_}ҽ**(>4G+LV**Ϟԓ@P a7Q{L~R2(xȹg?^R+9՝'[+\, [zAuWO³ ›]1 |=C.ʠ|ӟF=A6Z].Mxw)}#kzFvg<6s-# kng_qO;Ok u ۺu&3|sLB]ö~u=CIy,O7LJa1sw75GiAyG=ݻE*s),ZSۃh˜simʴW#]b\D'[XA>I.XJ@*NY*(//]0nX ƞ͹=vLv ´u䓝kA+ ֑Ovh PƞXܭ! 34ܭ3n3,ZG>I~j. R?m4C7#T%%cyx\=OqŐz**mzfAV;=]*m qm')'7we*U@x,WiBNW]oqgPPu߉?Z\q6Tt.'\?a=(߀Xݘ8Tjc; u'!ϾK6't¹ 38кP|'hڇ.7[@xh]U9&1Xխd9 CM"dBaRnϲ@xBIE =hw0.*vao ˾JiI ݲF<8^USJP,ݷU~+kk/o%UzI 2&E(^Y񳴬9,ߋ5 @eqg$ W*x~H"Qݭ2>zetWs{Qݦ:p]Z s# uFy`7g>Y]{]xI}Fc7ۓSTwhc7ɈqU]Ą$o [ePUcB ٞ]4R4Mz6ڻٸgTw_؟[M]wZp]室u?lRg5idi7ysaLˍ˙v!yI}VX&ngaMZ`iW,m(Փ4/ۅ@MbB]öNu>4/ O7{Lkևu=9WפyFvoLkIy]ge32T]viԋ{ؿCO = R?mzO@O ='HXO]=' u`ruU~B4>oϐS(7oA6L yH<kxBb"Ϧ?lg?Ph]U܅t¹څ5:<0lls}㽚3w/Ybqvuw<RړpɞDD~LtYb13TsUOWyA%]u]WOJ9A2H8>f=:h2_U7oK9~,*~6HzŽ;'U82~L3f?]*m~8Ck|\mW]IygRu6r*Ti u|SW?Hnz2mz:y$mong{ɩ}w]4Wy5? Au(/S[U^ /s"˞RPݮgATnr~Gw:o #/p;Gkج/9#nj |="fAugy;VA%vF=ϸ*M I7g]c&i W3г 7)oSʯ]؟mi-tZuN<=q$|˗g5ixQ>bt ;䬰&<(?f5lu=y~MgigY~ '~>װ-d>4#O7}&5liyݠ'g\]%gt u iydxdyUτmZ^YXet_?Uװݛx8}B!AO ='Ďr.MCO ='HXIO}s[ ^ ='GW;-Nk>QU,YzBO:'SדzHzBO =A*{BꌈI!S3s}Cz2b/]' uoz|hgSDޞ=FQSd>sSQ3sto'ٛ]o3[Dh˽{e<(A?44V]x}0YQ?{33nDPYF{W pvۃѠ]U~mc:XK؛mS?:ggsxc7sK80:ʯ 5DS*{&~ÚzzAOKAst_$1QWoh,qN/L9ɯ4nfS&[FTU~(h28~XSVg4)gw6u?{~:ݻr>]E~mc75ȁO.-Hh<#M@gQwg<^eB0{vugIx"F=O'<**W36K7Ix_"K$~P3LuG$TE= {vuW8TEz#gS2$[ʯ]؋g,"iLRȻՉ7˼ټ<:zV] ›2ˠ|hh73L>['DAx=CKePY7eI=Zf7'5~-[=C ў!EPM~&B An{F4+6i%FՒ4Ž2dM=b蠐^a~ [ ӏ˙zvk؂ I]dI~Bˍs9] k؂0qz;L+ 5iz$5l;C֤q#OoDkvHx]wxUT]??5:pzs& 9k,Y0˥\u巈 bcI~L4ț鳸Yj|`~S9}9KC9ol,9]Pzn3$`l$E3A3nI a 9qH̤O9mv]u]mO#.M7΁ᩯ-\*b쟮hf A㭌wxJsvPeWIbތ5F~7Φޅs)ǟSϜ9m~g4`NʢMRfѶBOFw4nI?iqNۣ⦲IT F{T/Q-Σ.q,Ag;y;sEۯy^MK=]^=&j{FqngOGA^=!'6Q~Nj`y;w~ `.{rZM~y칹 kmu5WtqݛNSH}4nhwzįf73$ Lq"ԋ׵k(TiSu͸8,Ui-03K8'Uڤ8gM=9'5^|Rm<-vA*m?*vﯛ|RmT]G֑OIqx:9_gH<|ӟEuܙYMDQ~9ܤ>Łss=|s̢9_g:e]Ⱕڅ(~v2U۩^ŧo3*0z._r0 }"!*yȹg7ɕѳ2,?&: W3$ϳO[ W3$T՝:X ›w?)bfTwIxvAc%1 |=C.꠺?R4zvlpʟ7;k}SS٣ 5-9^~'K8տ1bFSo3Ӣ?Wg,ǹqh_|3f[څܖ36x4#YuGyy˙)o|VYU^ʥ3SASYqH3S =Dg:\Gc&l[qgR>3ے'-bn>M&yMg<31)o!V.rY_Q8mn^w 'KD,nI/yLI| g5KlV.']j3=i=]壥;oJ-{f{Q>zdb{xh$l5H3z6|Op }}0ls SCd MJ|LoCR^)-ٜfQR[t3CvUlTw1D[ב9U׬N\͸R0JO7J[oN=#z&-*mΫggq!Jۼ3ba|?V;Hty :*CN6T^uVOkWn?hKPwJvvMjoRA|e]P|>KvPY!JO}k[R?ma]Yf#WQH=9bR1mN(}J+V| 7}&T57.(?f4cB+,.*31c"3)gYY~FlV]trxh]UM*;g4Uҳp_?߳) SWmi(=!ЏgQw ux+wZM jugsh}zn2m7xu/2n|=73ZYeOW \Sl7fstt9/NV6=ڮ꟮tnоBKug6mwyu]/iQWf6Hʟl1^5/ǞIS:ts S$ =7=P6m 7dԹ, TicϬ8=ǥ$QKS3ᩯ޷NG/Һ&kzr"nOM^ mMЮ*T'2[ziswYܓ gdCURnVb,, 򂫞{houqO4Li»B$[дnurb9ˉfpmA+R*)%2[ ryx7,\+ 9idn.~eJsؾK̿'߷?%_dL}S_ozBO =SCO ='HzBO =ARy0+OfxSx:HOxO:S::]Fv'0R峔07ڻYhuۃѨIO7x<>t-LwٶZevB+a>ѕSߪkYIwmco:NzBgGSbNL ddz~#!'`i=($ݙīg˿-=;$J\I$q/Q'+cdTlu,ʃA'_Z 5Gv#cSRmmgRΖ~9''ov2ROHwVWZ}~c) G}|>{>GogGy;쩤k(W ǙV>2<\S:dtT$J J9D۝IՑ9h47JNBlvdROr vmٛo)۹H{KYͅSfL˓R uX%OIoԽ+:zPva4~rאz w~A+q#uIH]}#nquБqiʅߗEH}Ho9R1< uXUO=uSݙԕ_M.b zԋn2X%^ҭSGw8ـ'S'vHmh>\ԁښ⁃yr<y"3:p.ґ'Sێ'm7\<{azҚcRUW9<,>TdMeG\"uoJ[azE1UQ+z$w:E?w2G8Bx uR':}\ǎ(XbO MC_z?9#R RO uS-gG }~p U?HH=,~h)HR=tURg{*ɾڼE77(2}d$| M{yUD*oOK!c&]T==<sy)Nt}L# ?'s{`ѹTݠH}9o>5)eSEl_zSeԋ'$d|ɹ>i˜f 3kw.aI]w]c"i{= qGI;\8/tbZgw_[D}Q;pB&WFa'2 ̧Џ'|0i>t0'e!3UAA+%;^nk;Ĝ^"6GRҗIOug8s<2~XY(}>^r]F4_IRN*N>t-ݒ,`˚NtɟHO=3lhN+ð~ha@a&NdQ?їw7z֤^<C.ڬKd$u/Ձz<{y &ov+ɵU_Gbxy`r|<:TF{^@"u+OQMp"ZR[6CN> T~pE7ݓ]2°qU+ksF=DzfR-֡@㮤SsJo/qM)|DnN5męrַ-̤d,Z>K謹!n[$w&u)_곈!>CHOqG98O $vÎo'Sס<X)RgrxS{X=6hS`=uOSxS:SAOxSxzZQ1/ZrرFvn+7ڃõH3J1Z?ߣ{G}-I]r)սcc;X^-<5;/VU_オ_DwbMP_}WS^*G4tV:Z+59;[{4,{.՞yI*ǤOsѽ_|t^n=5ϷL^of',!Y<黥xNn1{*'/`Љޫ/'Z ]>w<\^u B՞z5Av3V[eW8zܗ:W{Di1 yJ9kƟ 멏ܧu:;i^Ȏ(To :|2^We~JvKÝCu,z}ع~]gOE[H4׵3ޥg՝FNt0>/(zݳǟCS?oek7嗢캮K+OfQ+npw DBőRc7^$uͤεI`O *]i$_SAx,_7wT+7#O8^O^?T&׺osy63e+ߖB$ԝ=CZ kʀiH΋KE[]hO 4ᩓ_j?9 O7:z-THK ,fʭ._$Rufoujoǒԋ*nV'j;or;`=|=LzO ~DsE~SR>u3OXROLr,&g!1MUEFqoJJpJs9M:ƠUtg_F6[on|^[𻕝 T>*FkW{FvtJ351fQU]ޯ\?ќuK?Oplr5>Ty+yB8 Wif7uOV`F&.ԏ`<N۷3gΠJh2y+ʼ(R_'SAׇB# xmt:ARXI1%u@Oj:cw˭@pRy}aԥr` u8:Rx}1rxI}'ԑ'SwH@dέRGTS1W444444cl&R vH8ssˉTʉ/݁tEXtCommentCreated with GIMPW%tEXtdate:create2018-09-26T00:01:04+00:00YR%tEXtdate:modify2018-09-26T00:01:04+00:00IENDB`colorama-0.4.6/test-release000066400000000000000000000032361432564447100156540ustar00rootroot00000000000000#!/usr/bin/env bash # Test the currently built release of Colorama from the dist/ dir. # Run this before making a release. # # This should be run on Windows, because Colorama is mostly a no-op elsewhere. # Hmmm, this script should probably be a .bat file then? Nah, WSL FTW. # # Uploads package from the dist/ directory to the *test* PyPI. # Create a fresh virtualenvironment and install colorama from test PyPI. # Import Colorama and make trivial use of it. # Exit on error set -eu -o pipefail syspython=python3 bin="$HOME/.virtualenvs/colorama/bin" sandbox=test-release-playground # Upload to the test PyPI. $bin/twine upload --repository testpypi dist/colorama-* \ || echo " > Expect a 400 if package was already uploaded." # cd elsewhere so we cannot import from local source. mkdir -p $sandbox ( # Create a temporary disposable virtualenv. $syspython -m venv --clear $sandbox/venv # voodoo sleep. I saw the following install fail, due to expected version # not being listed at test.pypi.org, but then a few seconds later, re-run # manually, it worked fine. sleep 5 version=$(grep __version__ colorama/__init__.py | cut -d' ' -f3 | tr -d "'") cd $sandbox # Install the package we just uploaded. # (--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.\")" ) # Tidy up rm -rf $sandbox colorama-0.4.6/test-release.ps1000066400000000000000000000020061432564447100163500ustar00rootroot00000000000000$syspython="python.exe" $ve="$HOME\.virtualenvs\colorama" $bin="$ve\Scripts" # Upload to the test PyPI. & $bin\twine.exe upload --repository testpypi dist\colorama-* if(!$?) { write-host " > Expect a 400 if package was already uploaded" } # cd elsewhere so we cannot import from local source. mkdir -force sandbox | out-null cd sandbox # Create a temporary disposable virtualenv. & $syspython -m venv --clear venv # TODO: What is the windows/powershell equivalent of this: # version=$(grep __version__ colorama/__init__.py | cut -d' ' -f3 | tr -d "'") # Install the package we just uploaded. # (--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; colorama.init(); print(colorama.Fore.GREEN + ""OK Colorama "" + colorama.__version__ + "" from test pypi install."") "@ cd .. colorama-0.4.6/test.ps1000066400000000000000000000001531432564447100147330ustar00rootroot00000000000000$ve="$HOME\.virtualenvs\colorama" $bin="$ve\Scripts" & $bin\python.exe -m unittest discover -p *_test.py colorama-0.4.6/tox.ini000066400000000000000000000003021432564447100146360ustar00rootroot00000000000000[tox] isolated_build = true envlist = py27, py37, py38, py39, py310, pypy, pypy3 [testenv] deps = py27,pypy: mock py27,pypy: contextlib2 commands = python -m unittest discover -p *_test.py