From ea5bee5184641c00763ae541f8cf48590c62b934 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Tue, 17 Mar 2026 14:57:12 +0300 Subject: [PATCH 1/9] Update sentinel examples to use code formatting for consistency --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 54eca3d..d843cf6 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Python's built-in [`None`](https://docs.python.org/3/library/constants.html#None ## The problem -Programmers encounter uncertainty everywhere. We [don't know](https://en.wikipedia.org/wiki/Semipredicate_problem) in advance whether a user will enter a valid value into a form, or whether a given operation on two numbers is possible. To highlight uncertainty as a separate entity, programmers have come up with so-called [sentinel objects](https://en.wikipedia.org/wiki/Sentinel_value). These can take many forms: [NULL](https://en.wikipedia.org/wiki/Null_pointer), [`None`](https://docs.python.org/3/library/constants.html#None), [nil](https://ru.wikipedia.org/wiki/Nil), [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined), [NaN](https://en.wikipedia.org/wiki/NaN), and an infinite number of others. +Programmers encounter uncertainty everywhere. We [don't know](https://en.wikipedia.org/wiki/Semipredicate_problem) in advance whether a user will enter a valid value into a form, or whether a given operation on two numbers is possible. To highlight uncertainty as a separate entity, programmers have come up with so-called [sentinel objects](https://en.wikipedia.org/wiki/Sentinel_value). These can take many forms: [`NULL`](https://en.wikipedia.org/wiki/Null_pointer), [`None`](https://docs.python.org/3/library/constants.html#None), [`nil`](https://ru.wikipedia.org/wiki/Nil), [`undefined`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined), [`NaN`](https://en.wikipedia.org/wiki/NaN), and an infinite number of others. Different programming languages and environments offer [different models](#analogs) for representing uncertainty as objects. This is usually related to how a particular language has evolved and what forms of uncertainty its users most often encounter. Broadly, I see [three](https://numberwarrior.wordpress.com/2010/07/30/is-one-two-many-a-myth/) main models: From eb2de0f5093bc63f201c26bb7d86227cd60da77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 20:34:07 +0300 Subject: [PATCH 2/9] Bump version to 0.0.14 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 63e6956..639129a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "denial" -version = "0.0.13" +version = "0.0.14" authors = [{ name = "Evgeniy Blinov", email = "zheni-b@yandex.ru" }] description = "Is one None not enough for you? There's more" readme = "README.md" From 6314dd0f2f160f4b977aee83b7950fd2234e7a46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 20:34:39 +0300 Subject: [PATCH 3/9] Update printo version requirement to 0.0.27 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 639129a..4f6bc43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,7 @@ description = "Is one None not enough for you? There's more" readme = "README.md" requires-python = ">=3.8" dependencies = [ - 'printo>=0.0.22', + 'printo>=0.0.27', 'locklib>=0.0.20', 'typing_extensions ; python_version <= "3.10"', ] From d81b2260880b7ab9a38fdb39fa46223d6fca76eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 20:35:50 +0300 Subject: [PATCH 4/9] Add .qwen to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 248d031..02ab341 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ uv.lock .ropeproject node_modules mutants +.qwen From b286d7b2bb5f4c0cd3f6d76dae7329f0353f52bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 20:37:29 +0300 Subject: [PATCH 5/9] Replace describe_data_object with describe_call in InnerNoneType.__repr__ --- denial/inner.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/denial/inner.py b/denial/inner.py index 22e966f..502147a 100644 --- a/denial/inner.py +++ b/denial/inner.py @@ -3,7 +3,7 @@ from typing import Any, Optional, Union from locklib import ContextLockProtocol -from printo import describe_data_object, not_none +from printo import describe_call, not_none from denial.errors import ( DoubleSingletonsInstantiationError, @@ -48,7 +48,7 @@ def __hash__(self) -> int: def __repr__(self) -> str: if self.id == 0 and self.auto: return 'InnerNone' - return describe_data_object(type(self).__name__, (self.id,), {'doc': self.doc, 'auto': self.auto}, filters={'auto': lambda x: x != True, 'doc': not_none}) + return describe_call(type(self).__name__, (self.id,), {'doc': self.doc, 'auto': self.auto}, filters={'auto': lambda x: x != True, 'doc': not_none}) def __bool__(self) -> bool: return False From 96bc89ce3a4bf47ea9d6e1cd0fae3504afb253f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 20:51:59 +0300 Subject: [PATCH 6/9] Update locklib version to 0.0.21 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4f6bc43..fcb417c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ readme = "README.md" requires-python = ">=3.8" dependencies = [ 'printo>=0.0.27', - 'locklib>=0.0.20', + 'locklib>=0.0.21', 'typing_extensions ; python_version <= "3.10"', ] classifiers = [ From 5bcb57b51d8a9a88b76ea1c56e184a6775b04c19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 20:52:46 +0300 Subject: [PATCH 7/9] Add Typing :: Typed classifier to project metadata --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index fcb417c..bfc94af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,6 +34,7 @@ classifiers = [ 'License :: OSI Approved :: MIT License', 'Intended Audience :: Developers', 'Topic :: Software Development :: Libraries', + 'Typing :: Typed', ] keywords = ['None', 'sentinel'] From 8d6c3147179d2a29e087717863a6cc7cb24b67f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 20:57:40 +0300 Subject: [PATCH 8/9] Update InnerNoneType.__repr__ to use list for id parameter --- denial/inner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/denial/inner.py b/denial/inner.py index 502147a..edcda81 100644 --- a/denial/inner.py +++ b/denial/inner.py @@ -48,7 +48,7 @@ def __hash__(self) -> int: def __repr__(self) -> str: if self.id == 0 and self.auto: return 'InnerNone' - return describe_call(type(self).__name__, (self.id,), {'doc': self.doc, 'auto': self.auto}, filters={'auto': lambda x: x != True, 'doc': not_none}) + return describe_call(type(self).__name__, [self.id], {'doc': self.doc, 'auto': self.auto}, filters={'auto': lambda x: x != True, 'doc': not_none}) def __bool__(self) -> bool: return False From ea7aff75f21a2a42b5b17b730c437a3ff513f7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=95=D0=B2=D0=B3=D0=B5=D0=BD=D0=B8=D0=B9=20=D0=91=D0=BB?= =?UTF-8?q?=D0=B8=D0=BD=D0=BE=D0=B2?= Date: Wed, 22 Apr 2026 21:06:29 +0300 Subject: [PATCH 9/9] Update pyproject.toml to use single quotes consistently --- pyproject.toml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bfc94af..d18b48f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,21 +1,21 @@ [build-system] -requires = ["setuptools==68.0.0"] -build-backend = "setuptools.build_meta" +requires = ['setuptools==68.0.0'] +build-backend = 'setuptools.build_meta' [project] -name = "denial" -version = "0.0.14" -authors = [{ name = "Evgeniy Blinov", email = "zheni-b@yandex.ru" }] +name = 'denial' +version = '0.0.14' +authors = [{ name = 'Evgeniy Blinov', email = 'zheni-b@yandex.ru' }] description = "Is one None not enough for you? There's more" -readme = "README.md" -requires-python = ">=3.8" +readme = 'README.md' +requires-python = '>=3.8' dependencies = [ 'printo>=0.0.27', 'locklib>=0.0.21', 'typing_extensions ; python_version <= "3.10"', ] classifiers = [ - "Operating System :: OS Independent", + 'Operating System :: OS Independent', 'Operating System :: MacOS :: MacOS X', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX', @@ -39,19 +39,19 @@ classifiers = [ keywords = ['None', 'sentinel'] [tool.setuptools.package-data] -"denial" = ["py.typed"] +"denial" = ['py.typed'] [tool.mutmut] -paths_to_mutate = "denial" -runner = "pytest" +paths_to_mutate = 'denial' +runner = 'pytest' [tool.pytest.ini_options] -markers = ["mypy_testing"] +markers = ['mypy_testing'] [tool.ruff] lint.ignore = ['E501', 'E712', 'PTH123', 'PTH118', 'PLR2004', 'PTH107', 'SIM105', 'SIM102', 'RET503', 'PLR0912', 'C901'] -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" +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/mutating/denial'