Skip to content
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
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/question.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name: Question or consultation
about: Ask anything about this project
title: ''
labels: guestion
labels: question
assignees: pomponchik

---
Expand Down
19 changes: 9 additions & 10 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t", "3.15.0-alpha.1"]

steps:
- uses: actions/checkout@v4
Expand All @@ -26,18 +25,18 @@ jobs:
shell: bash
run: pip install .

- name: Run mypy
shell: bash
run: mypy displayhooks --strict

- name: Run mypy for tests
shell: bash
run: mypy tests

- name: Run ruff
shell: bash
run: ruff check displayhooks

- name: Run ruff for tests
shell: bash
run: ruff check tests

- name: Run mypy
shell: bash
run: mypy --strict displayhooks

- name: Run mypy for tests
shell: bash
run: mypy tests
3 changes: 1 addition & 2 deletions .github/workflows/tests_and_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ jobs:
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
python-version:
["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13", "3.14", "3.14t", "3.15.0-alpha.1"]

steps:
- uses: actions/checkout@v4
Expand Down
1 change: 0 additions & 1 deletion .ruff.toml

This file was deleted.

31 changes: 18 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
# displayhooks
<details>
<summary>ⓘ</summary>

[![Downloads](https://static.pepy.tech/badge/displayhooks/month)](https://pepy.tech/project/displayhooks)
[![Downloads](https://static.pepy.tech/badge/displayhooks)](https://pepy.tech/project/displayhooks)
[![Coverage Status](https://coveralls.io/repos/github/pomponchik/displayhooks/badge.svg?branch=main)](https://coveralls.io/github/pomponchik/displayhooks?branch=main)
[![Lines of code](https://sloc.xyz/github/pomponchik/displayhooks/?category=code)](https://github.com/boyter/scc/)
[![Hits-of-Code](https://hitsofcode.com/github/pomponchik/displayhooks?branch=main)](https://hitsofcode.com/github/pomponchik/displayhooks/view?branch=main)
[![Test-Package](https://github.com/pomponchik/displayhooks/actions/workflows/tests_and_coverage.yml/badge.svg)](https://github.com/pomponchik/metronomes/actions/workflows/tests_and_coverage.yml)
[![Coverage Status](https://coveralls.io/repos/github/mutating/displayhooks/badge.svg?branch=main)](https://coveralls.io/github/mutating/displayhooks?branch=main)
[![Lines of code](https://sloc.xyz/github/mutating/displayhooks/?category=code)](https://github.com/boyter/scc/)
[![Hits-of-Code](https://hitsofcode.com/github/mutating/displayhooks?branch=main)](https://hitsofcode.com/github/mutating/displayhooks/view?branch=main)
[![Test-Package](https://github.com/mutating/displayhooks/actions/workflows/tests_and_coverage.yml/badge.svg)](https://github.com/mutating/metronomes/actions/workflows/tests_and_coverage.yml)
[![Python versions](https://img.shields.io/pypi/pyversions/displayhooks.svg)](https://pypi.python.org/pypi/displayhooks)
[![PyPI version](https://badge.fury.io/py/displayhooks.svg)](https://badge.fury.io/py/displayhooks)
[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/mutating/displayhooks)

</details>

It's a micro library for manipulating [`sys.displayhook`](https://docs.python.org/3/library/sys.html#sys.displayhook).
![logo](https://raw.githubusercontent.com/mutating/displayhooks/develop/docs/assets/logo_1.svg)

When you need to change the standard behavior of `displayhook`, with this library you will do it:

It's a micro-library for customizing [`sys.displayhook`](https://docs.python.org/3/library/sys.html#sys.displayhook).

If you need to change the default behavior of `sys.displayhook`, this library lets you do it:

- 💎 declaratively
- 🫥 compactly
Expand All @@ -24,7 +30,7 @@ When you need to change the standard behavior of `displayhook`, with this librar
## Table of contents

- [**Quick start**](#quick-start)
- [**Change the displayed value**](#change-the-displayed-value)
- [**Transform displayed values**](#transform-displayed-values)
- [**Prohibiting the display of certain types of values**](#prohibiting-the-display-of-certain-types-of-values)
- [**Automatic recovery of the default hook**](#automatic-recovery-of-the-default-hook)

Expand All @@ -37,7 +43,7 @@ Install it:
pip install displayhooks
```

And use:
Then use it:

```python
import sys
Expand All @@ -51,9 +57,9 @@ sys.displayhook(666)
# [nothing!]
```

## Change the displayed value
## Transform displayed values

You can declaratively declare a converter function for the printed values. What it returns will be used to call the original `displayhook` function.
You can declaratively define a converter function for displayed values. Its return value will be passed to the original `displayhook` function.

```python
import sys
Expand All @@ -67,8 +73,7 @@ sys.displayhook("What’s gone with that boy, I wonder? You TOM!")
#> 'what’s gone with that boy, i wonder? you tom!'
```

If your function returns `None`, nothing will be printed.

If your function returns `None`, nothing is displayed.

## Prohibiting the display of certain types of values

Expand Down
10 changes: 7 additions & 3 deletions displayhooks/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from displayhooks.converter import converted_displayhook as converted_displayhook # noqa: F401
from displayhooks.autorestore import autorestore_displayhook as autorestore_displayhook # noqa: F401
from displayhooks.not_display import not_display as not_display # noqa: F401
from displayhooks.autorestore import (
autorestore_displayhook as autorestore_displayhook,
)
from displayhooks.converter import (
converted_displayhook as converted_displayhook,
)
from displayhooks.not_display import not_display as not_display
3 changes: 1 addition & 2 deletions displayhooks/autorestore.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
else:
from typing_extensions import ParamSpec # pragma: no cover

from typing import TypeVar, Callable
from functools import wraps

from typing import Callable, TypeVar

FunctionParameters = ParamSpec('FunctionParameters')
ReturningValue = TypeVar('ReturningValue')
Expand Down
5 changes: 2 additions & 3 deletions displayhooks/converter.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import sys
from typing import Callable, Any
from threading import Lock
from functools import wraps

from threading import Lock
from typing import Any, Callable

lock = Lock()

Expand Down
2 changes: 1 addition & 1 deletion displayhooks/not_display.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Type, Any
from typing import Any, Type

from displayhooks.converter import converted_displayhook

Expand Down
476 changes: 476 additions & 0 deletions docs/assets/logo_1.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
476 changes: 476 additions & 0 deletions docs/assets/logo_2.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 11 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = 'setuptools.build_meta'

[project]
name = 'displayhooks'
version = '0.0.5'
version = '0.0.6'
authors = [
{ name='Evgeniy Blinov', email='zheni-b@yandex.ru' },
]
Expand All @@ -26,6 +26,9 @@ classifiers = [
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: 3.14',
'Programming Language :: Python :: 3.15',
'Programming Language :: Python :: Free Threading',
'Programming Language :: Python :: Free Threading :: 3 - Stable',
'License :: OSI Approved :: MIT License',
'Topic :: Software Development :: Libraries',
'Intended Audience :: Developers',
Expand All @@ -43,6 +46,11 @@ keywords = [
paths_to_mutate="displayhooks"
runner="pytest"

[tool.ruff]
lint.ignore = ['E501', 'E712', 'PTH123', 'PTH118', 'PLR2004', 'PTH107', 'SIM105', 'SIM102', 'RET503', 'PLR0912', 'C901', 'RUF001']
lint.select = ["ERA001", "YTT", "ASYNC", "BLE", "B", "A", "COM", "INP", "PIE", "T20", "PT", "RSE", "RET", "SIM", "SLOT", "TID252", "ARG", "PTH", "I", "C90", "N", "E", "W", "D201", "D202", "D419", "F", "PL", "PLE", "PLR", "PLW", "RUF", "TRY201", "TRY400", "TRY401"]
format.quote-style = "single"

[project.urls]
'Source' = 'https://github.com/pomponchik/displayhooks'
'Tracker' = 'https://github.com/pomponchik/displayhooks/issues'
'Source' = 'https://github.com/mutating/displayhooks'
'Tracker' = 'https://github.com/mutating/displayhooks/issues'
2 changes: 1 addition & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ coverage==7.6.1
twine==6.1.0
wheel==0.41.2
build==1.2.2.post1
ruff==0.14.5
ruff==0.14.6
mypy==1.14.1
mutmut==3.2.3
full_match==0.0.3
42 changes: 21 additions & 21 deletions tests/test_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@

import pytest

from displayhooks import converted_displayhook, autorestore_displayhook
from displayhooks import autorestore_displayhook, converted_displayhook


@pytest.mark.parametrize(
['value'],
'value',
[
('kek',),
('lol',),
(1,),
(1.5,),
'kek',
'lol',
1,
1.5,
],
)
@autorestore_displayhook
Expand All @@ -29,7 +29,7 @@ def new_displayhook(value: Any) -> Any:

output = buffer.getvalue()

assert output == f'{repr(value)}\n'
assert output == f'{value!r}\n'


@autorestore_displayhook
Expand All @@ -48,18 +48,18 @@ def new_displayhook(value: Any) -> Any:


@pytest.mark.parametrize(
['value'],
'value',
[
('kek',),
('lol',),
(1,),
(1.5,),
'kek',
'lol',
1,
1.5,
],
)
@autorestore_displayhook
def test_elliminating_convertion(value):
@converted_displayhook
def new_displayhook(value: Any) -> Any:
def new_displayhook(value: Any) -> Any: # noqa: ARG001
return None

buffer = io.StringIO()
Expand All @@ -74,7 +74,7 @@ def new_displayhook(value: Any) -> Any:
@autorestore_displayhook
def test_elliminating_convertion_with_none():
@converted_displayhook
def new_displayhook(value: Any) -> Any:
def new_displayhook(value: Any) -> Any: # noqa: ARG001
return None

buffer = io.StringIO()
Expand All @@ -87,18 +87,18 @@ def new_displayhook(value: Any) -> Any:


@pytest.mark.parametrize(
['value'],
'value',
[
('kek',),
('lol',),
(1,),
(1.5,),
'kek',
'lol',
1,
1.5,
],
)
@autorestore_displayhook
def test_real_convertion(value):
@converted_displayhook
def new_displayhook(value: Any) -> Any:
def new_displayhook(value: Any) -> Any: # noqa: ARG001
return 'cheburek'

buffer = io.StringIO()
Expand All @@ -107,4 +107,4 @@ def new_displayhook(value: Any) -> Any:

output = buffer.getvalue()

assert output == f'{repr("cheburek")}\n'
assert output == f'{"cheburek"!r}\n'
20 changes: 10 additions & 10 deletions tests/test_not_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from displayhooks import not_display, autorestore_displayhook
from displayhooks import autorestore_displayhook, not_display


@autorestore_displayhook
Expand All @@ -19,21 +19,21 @@ def display_something(something):
return buffer.getvalue()

assert display_something(5) == ''
assert display_something('kek') == f'{repr("kek")}\n'
assert display_something('kek') == f'{"kek"!r}\n'


@pytest.mark.parametrize(
['callable'],
'some_callable',
[
(lambda: not_display(int, float),),
(lambda: [not_display(int), not_display(float)],), # type: ignore[func-returns-value]
(lambda: not_display(float, int),),
(lambda: [not_display(float), not_display(int)],), # type: ignore[func-returns-value]
lambda: not_display(int, float),
lambda: [not_display(int), not_display(float)], # type: ignore[func-returns-value]
lambda: not_display(float, int),
lambda: [not_display(float), not_display(int)], # type: ignore[func-returns-value]
],
)
@autorestore_displayhook
def test_not_display_ints_and_floats(callable):
callable()
def test_not_display_ints_and_floats(some_callable):
some_callable()

def display_something(something):
buffer = io.StringIO()
Expand All @@ -44,4 +44,4 @@ def display_something(something):

assert display_something(5) == ''
assert display_something(5.5) == ''
assert display_something('kek') == f'{repr("kek")}\n'
assert display_something('kek') == f'{"kek"!r}\n'
Loading