Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintainace release #51

Merged
merged 6 commits into from
Dec 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,20 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
max-parallel: 4
max-parallel: 8
matrix:
python-version: [2.7, 3.5, 3.6, 3.7]
python-version: [3.7, 3.8, 3.9, "3.10", 3.11]
os: [ubuntu-latest, windows-latest, macOS-latest]
include:
- os: ubuntu-18.04
python-version: 3.5
- os: ubuntu-18.04
python-version: 3.6

steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Setup build and test environment
Expand All @@ -29,7 +34,7 @@ jobs:
- name: Lint with flake8
run: |
pip install flake8
flake8 --show-source src/ tests/
flake8 --show-source colorful/ tests/
- name: Test with pytest
run: |
coverage run --parallel -m pytest
Expand All @@ -41,7 +46,7 @@ jobs:
- name: Upload coverage to Codecov
# codecov only runs on Linux
if: startsWith(matrix.os, 'ubuntu-')
uses: codecov/codecov-action@v1.0.0
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
Expand All @@ -53,20 +58,20 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- name: Set up Python 3.7
- uses: actions/checkout@v3
- name: Set up Python 3.11
if: startsWith(github.event.ref, 'refs/tags')
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: 3.7
python-version: 3.11
- name: Build Package
if: startsWith(github.event.ref, 'refs/tags')
run: |
python -m pip install --upgrade pip setuptools wheel
python setup.py sdist bdist_wheel --universal
- name: Publish Package on PyPI
if: startsWith(github.event.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@master
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.pypi_token }}
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ print(cf.red('你好'))

## Usage

**colorful** supports all major Python versions: *2.7*, *3.4*, *3.5*, *3.6* and *3.7*. <br>
**colorful** supports all major Python versions: *3.5*, *3.6* and *3.7*, *3.8*, *3.9*, *3.10*, *3.11*. <br>
We recommend to use the latest version released on [PyPI](https://pypi.python.org/pypi/colorful):

```bash
Expand Down Expand Up @@ -318,8 +318,6 @@ cf.print('{c.red}I am red{c.reset}', end='', file=open('log.txt', 'a+'))

The `cf.print()` method accepts the same arguments as the Python 3.X [built-in print()](https://docs.python.org/3/library/functions.html#print) function.

*Note: for Python 2 you have to import the print function: `from __future__ import print_function`.*

#### (5) Style a string with [`str.format()`](https://docs.python.org/3.6/library/stdtypes.html#str.format)

```python
Expand Down
60 changes: 10 additions & 50 deletions colorful/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,12 @@
:license: MIT, see LICENSE for more details.
"""

from __future__ import print_function
from __future__ import unicode_literals

import os
import sys

from . import ansi
from . import colors
from . import styles
from . import terminal
from .utils import PY2, DEFAULT_ENCODING, UNICODE

#: Holds the name of the env variable which is
# used as path to the default rgb.txt file
Expand Down Expand Up @@ -218,10 +213,7 @@ def style_string(string, ansi_style, colormode, nested=False):
ansi_start_code, ansi_end_code = ansi_style

# replace nest placeholders with the current begin style
if PY2:
if isinstance(string, str):
string = string.decode(DEFAULT_ENCODING)
string = UNICODE(string).replace(ansi.NEST_PLACEHOLDER, ansi_start_code)
string = str(string).replace(ansi.NEST_PLACEHOLDER, ansi_start_code)

return '{start_code}{string}{end_code}{nest_ph}'.format(
start_code=ansi_start_code,
Expand All @@ -235,28 +227,15 @@ class ColorfulString(object):
Represents a colored string
"""
def __init__(self, orig_string, styled_string, colorful_ctx):
self.orig_string = orig_string
self.styled_string = styled_string
self.orig_string = str(orig_string)
self.styled_string = str(styled_string)
self.colorful_ctx = colorful_ctx

if PY2:
def __unicode__(self):
if self.colorful_ctx.colormode == terminal.NO_COLORS:
return self.orig_string
else:
return self.styled_string

def __str__(self):
if self.colorful_ctx.colormode == terminal.NO_COLORS:
return self.orig_string.encode(DEFAULT_ENCODING)
else:
return self.styled_string.encode(DEFAULT_ENCODING)
else:
def __str__(self):
if self.colorful_ctx.colormode == terminal.NO_COLORS:
return self.orig_string
else:
return self.styled_string
def __str__(self):
if self.colorful_ctx.colormode == terminal.NO_COLORS:
return self.orig_string
else:
return self.styled_string

def __len__(self):
return len(self.orig_string)
Expand Down Expand Up @@ -497,7 +476,7 @@ def str(self, string):
"""
return ColorfulString(string, string, self)

def print(self, *objects, **options):
def print(self, *objects, sep=' ', end='\n', file=None, flush=False):
"""
Print the given objects to the given file stream.
See https://docs.python.org/3/library/functions.html#print
Expand All @@ -511,27 +490,8 @@ def print(self, *objects, **options):
:param file: the file stream to write to
:param bool flush: if the stream should be flushed
"""
# NOTE: change signature to same as print() built-in function as
# soon as Python 2.7 is not supported anymore.
# If causes problems because of the keyword args after *args
allowed_options = {'sep', 'end', 'file', 'flush'}
given_options = set(options.keys())
if not given_options.issubset(allowed_options):
raise TypeError('Colorful.print() got unexpected keyword arguments: {0}'.format(
', '.join(given_options.difference(allowed_options))))

sep = options.get('sep', ' ')
end = options.get('end', '\n')
file = options.get('file', sys.stdout)
flush = options.get('flush', False)

styled_objects = [self.format(o) for o in objects]
print(*styled_objects, sep=sep, end=end, file=file)

# NOTE: if Python 2.7 support is dropped we can directly forward the
# flush keyword argument to the print() function.
if flush:
file.flush()
print(*styled_objects, sep=sep, end=end, file=file, flush=flush)

class ColorfulStyle(object):
"""
Expand Down
15 changes: 0 additions & 15 deletions colorful/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,6 @@
:license: MIT, see LICENSE for more details.
"""
import re
import sys

PY2 = sys.version_info.major == 2

if PY2:
UNICODE = unicode # noqa
else:
UNICODE = str

# Catch error in case sys.stdout was patched with an object that doesn't provide
# the 'encoding' attribute.
try:
DEFAULT_ENCODING = sys.stdout.encoding or 'utf-8'
except AttributeError:
DEFAULT_ENCODING = 'utf-8'


def hex_to_rgb(value):
Expand Down
6 changes: 4 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,15 @@ def read_version():
'Operating System :: MacOS :: MacOS X',
'Operating System :: Microsoft :: Windows',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: Implementation',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy'
Expand Down
35 changes: 18 additions & 17 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@
:license: MIT, see LICENSE for more details.
"""

# NOTE: only used for Colorful.print()
from __future__ import print_function

import os
import sys

Expand All @@ -23,7 +20,6 @@

import colorful.core as core # noqa
import colorful.terminal as terminal # noqa
from colorful.utils import UNICODE # noqa


@pytest.mark.parametrize('style_string,expected', [
Expand Down Expand Up @@ -617,18 +613,6 @@ def test_colorful_direct_print(capsys):
assert err == ''


def test_colorful_print_wrong_argument():
"""
Test calling the colorful.print method with wrong arguments
"""
colorful = core.Colorful(colormode=terminal.ANSI_8_COLORS)

with pytest.raises(TypeError) as exc:
colorful.print('Never printed because of argument error', foo=42)

assert str(exc.value) == 'Colorful.print() got unexpected keyword arguments: foo'


@pytest.mark.parametrize('method_name, expected', [
('bold', 'No, I am your father'),
('struckthrough', 'No, I am your father'),
Expand Down Expand Up @@ -786,7 +770,7 @@ def test_unicode_support():
styled_s = colorful.black(s)

# test basic unicode support
assert UNICODE(styled_s) == u'\033[30m🐧🎉🐧\033[39m'
assert str(styled_s) == u'\033[30m🐧🎉🐧\033[39m'


def test_combining_styles():
Expand Down Expand Up @@ -862,6 +846,23 @@ def test_colorfulstring_format_protocol_no_placeholder_when_disabled():
assert str(s) == "foo: bar"


def test_underling_type_should_be_stored_as_str():
"""
This test ensures that __str__ is correctly implement
if the input is not a str.
Otherwise Python complains:
TypeError: __str__ returned non-string (type int)
"""
# given
colorful = core.Colorful(colormode=terminal.NO_COLORS)

# when
s = "foo: {}".format(str(colorful.red(1)))

# then
assert str(s) == "foo: 1"


@pytest.mark.parametrize("style_a_name, style_b_name, expected_equal", [
pytest.param("red", "red", True, id="red == red"),
pytest.param("red", "blue", False, id="red != blue"),
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = flake8,py27,pypy,py34,py35,py36,py37
envlist = flake8,pypy,py35,py36,py37,py38,py39,py310,py311
skip_missing_interpreters = True

[testenv]
Expand Down