Skip to content
Open
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
4 changes: 2 additions & 2 deletions progressbar/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,13 +429,13 @@ class AttributeDict(dict):
AttributeError: No such attribute: spam
"""

def __getattr__(self, name: str) -> int:
def __getattr__(self, name: str) -> types.Any:
if name in self:
return self[name]
else:
raise AttributeError(f'No such attribute: {name}')

def __setattr__(self, name: str, value: int) -> None:
def __setattr__(self, name: str, value: types.Any) -> None:
self[name] = value

def __delattr__(self, name: str) -> None:
Expand Down
54 changes: 54 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,57 @@ def raise_error():

fd.isatty = raise_error
assert not progressbar.env.is_ansi_terminal(fd)


@pytest.mark.parametrize(
'value,expected',
[
('', ''),
(b'', b''),
('\x1b[31m', ''),
(b'\x1b[31m', b''),
('\x1b[1m\x1b[31mtext\x1b[0m', 'text'),
(b'\x1b[1m\x1b[31mtext\x1b[0m', b'text'),
('\x1b[38;5;208mhello world\x1b[0m', 'hello world'),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Consider adding a test case for 24-bit (TrueColor) ANSI sequences to ensure they are also correctly stripped by no_color.

        ('\x1b[38;5;208mhello world\x1b[0m', 'hello world'),
        ('\x1b[38;2;255;0;0mred\x1b[0m', 'red'),

],
)
def test_no_color(value, expected) -> None:
assert progressbar.utils.no_color(value) == expected
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The tests use progressbar.utils, but this submodule is not explicitly imported in the file. Given that progressbar.env is explicitly imported at line 6, it is recommended to also explicitly import progressbar.utils at the top of the file to ensure the tests run correctly and maintain consistency with the existing import style.



def test_no_color_type_error() -> None:
with pytest.raises(TypeError):
progressbar.utils.no_color(123)


@pytest.mark.parametrize(
'value,expected',
[
('', 0),
(b'', 0),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

While test_len_color includes an empty bytes case, it would be beneficial to add a test case for bytes containing ANSI escape sequences to ensure len_color handles bytes with formatting correctly, similar to the string cases.

Suggested change
(b'', 0),
(b'', 0),
(b'\x1b[31mtext\x1b[0m', 4),

('\x1b[31m', 0),
('\x1b[1m\x1b[31mtext\x1b[0m', 4),
('\x1b[38;5;208mhello world\x1b[0m', 11),
],
)
def test_len_color(value, expected) -> None:
assert progressbar.utils.len_color(value) == expected


def test_attribute_dict_empty() -> None:
attrs = progressbar.utils.AttributeDict()
assert len(attrs) == 0
with pytest.raises(AttributeError):
attrs.missing


def test_attribute_dict_set_get_del() -> None:
attrs = progressbar.utils.AttributeDict()
attrs.spam = 123
assert attrs['spam'] == 123
assert attrs.spam == 123
del attrs.spam
with pytest.raises(AttributeError):
attrs.spam
with pytest.raises(AttributeError):
del attrs.spam