{"id":26246261,"url":"https://github.com/emcd/python-absence","last_synced_at":"2025-04-23T20:27:13.324Z","repository":{"id":269121147,"uuid":"906495955","full_name":"emcd/python-absence","owner":"emcd","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-11T03:53:37.000Z","size":81,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-11T04:25:22.276Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/emcd.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-12-21T04:18:00.000Z","updated_at":"2025-04-11T03:53:40.000Z","dependencies_parsed_at":"2025-04-11T04:31:54.715Z","dependency_job_id":null,"html_url":"https://github.com/emcd/python-absence","commit_stats":null,"previous_names":["emcd/python-absence"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emcd%2Fpython-absence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emcd%2Fpython-absence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emcd%2Fpython-absence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emcd%2Fpython-absence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emcd","download_url":"https://codeload.github.com/emcd/python-absence/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250508194,"owners_count":21442174,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-13T13:17:44.239Z","updated_at":"2025-04-23T20:27:13.317Z","avatar_url":"https://github.com/emcd.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. vim: set fileencoding=utf-8:\n.. -*- coding: utf-8 -*-\n.. +--------------------------------------------------------------------------+\n   |                                                                          |\n   | Licensed under the Apache License, Version 2.0 (the \"License\");          |\n   | you may not use this file except in compliance with the License.         |\n   | You may obtain a copy of the License at                                  |\n   |                                                                          |\n   |     http://www.apache.org/licenses/LICENSE-2.0                           |\n   |                                                                          |\n   | Unless required by applicable law or agreed to in writing, software      |\n   | distributed under the License is distributed on an \"AS IS\" BASIS,        |\n   | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |\n   | See the License for the specific language governing permissions and      |\n   | limitations under the License.                                           |\n   |                                                                          |\n   +--------------------------------------------------------------------------+\n\n*******************************************************************************\n                                    absence                                    \n*******************************************************************************\n\n.. image:: https://img.shields.io/pypi/v/absence\n   :alt: Package Version\n   :target: https://pypi.org/project/absence/\n\n.. image:: https://img.shields.io/pypi/status/absence\n   :alt: PyPI - Status\n   :target: https://pypi.org/project/absence/\n\n.. image:: https://github.com/emcd/python-absence/actions/workflows/tester.yaml/badge.svg?branch=master\u0026event=push\n   :alt: Tests Status\n   :target: https://github.com/emcd/python-absence/actions/workflows/tester.yaml\n\n.. image:: https://emcd.github.io/python-absence/coverage.svg\n   :alt: Code Coverage Percentage\n   :target: https://github.com/emcd/python-absence/actions/workflows/tester.yaml\n\n.. image:: https://img.shields.io/github/license/emcd/python-absence\n   :alt: Project License\n   :target: https://github.com/emcd/python-absence/blob/master/LICENSE.txt\n\n.. image:: https://img.shields.io/pypi/pyversions/absence\n   :alt: Python Versions\n   :target: https://pypi.org/project/absence/\n\n\n🕳️ A Python library package which provides a **sentinel for absent values** - a\nfalsey, immutable singleton that represents the absence of a value in contexts\nwhere ``None`` or ``False`` may be valid values.\n\n\nKey Features ⭐\n===============================================================================\n\n* 1️⃣  **Absence Sentinel**: A falsey singleton which represents absence.\n* 🏭 **Absence Factory**: Create custom absence sentinels for package-specific\n  or arbitrary needs.\n* 𝒇 **Predicate Functions**: Determine if a value is absent.\n* 🔍 **Type Support**: Type alias for optional values which may be absent.\n  (Similar to ``typing.Optional`` and its relation to ``None``.)\n* 🌟 **Builtins Integration**: Can install singleton and predicate function\n  into Python builtins.\n\n\nInstallation 📦\n===============================================================================\n\n::\n\n    pip install absence\n\n\nExamples 💡\n===============================================================================\n\nUse the ``absent`` sentinel to represent missing values:\n\n\u003e\u003e\u003e from dataclasses import dataclass\n\u003e\u003e\u003e from absence import absent, is_absent, Absential\n\u003e\u003e\u003e @dataclass\n... class User:\n...     name: str | None\n...     email: str | None\n\u003e\u003e\u003e def apply_partial_update(\n...     user: User,\n...     name: Absential[ str | None ] = absent,\n...     email: Absential[ str | None ] = absent,\n... ) -\u003e User:\n...     ''' Updates user fields if values provided.\n...\n...         Absent value means \"don't change\".\n...         None value means \"clear field\".\n...     '''\n...     if not is_absent( name ): user.name = name\n...     if not is_absent( email ): user.email = email\n...     return user\n\u003e\u003e\u003e user = User( name = 'Alice', email = 'alice@example.com' )\n\u003e\u003e\u003e # Clear name but leave email unchanged\n\u003e\u003e\u003e updated = apply_partial_update( user, name = None )\n\u003e\u003e\u003e updated.name  # Cleared to None\n\u003e\u003e\u003e updated.email  # Unchanged\n'alice@example.com'\n\u003e\u003e\u003e # Update both fields\n\u003e\u003e\u003e updated = apply_partial_update( user, name = 'Bob', email = 'bob@example.com' )\n\u003e\u003e\u003e updated.name\n'Bob'\n\u003e\u003e\u003e updated.email\n'bob@example.com'\n\nCreate package-specific absence sentinels:\n\n\u003e\u003e\u003e from absence import AbsenceFactory\n\u003e\u003e\u003e MISSING = AbsenceFactory( )\n\u003e\u003e\u003e bool( MISSING )\nFalse\n\n\nUse Cases 🎯\n===============================================================================\n\n* 🔄 **Optional Arguments**: When ``None`` is a valid argument value but you\n  need to detect absence.\n* 🎯 **Sentinel Values**: When you need a unique, falsey object to represent\n  missing or invalid states.\n* 🧩 **Type Safety**: When you want explicit typing for values that may be\n  absent.\n\n\nComparison with Alternatives 🤔\n===============================================================================\n\n+-------------------------+----------+---------+------------+------------+\n| Alternative             | Truthy?  | Unique? | Picklable? | Scope      |\n+=========================+==========+=========+============+============+\n| ``object()``            | Yes      | Yes     | No         | Arbitrary  |\n+-------------------------+----------+---------+------------+------------+\n| PEP 661 Sentinels       | Optional | Yes     | Yes        | Per-Module |\n+-------------------------+----------+---------+------------+------------+\n| ``dataclasses.MISSING`` | Yes      | Yes     | No         | Global     |\n+-------------------------+----------+---------+------------+------------+\n| ``typing.NoDefault``    | Yes      | Yes     | Yes        | Global     |\n+-------------------------+----------+---------+------------+------------+\n| ``absence.absent``      | No       | Yes     | No         | Global     |\n+-------------------------+----------+---------+------------+------------+\n\nThe ``absent`` sentinel combines falsey behavior with global uniqueness,\nmaking it particularly suitable for representing missing values in contexts\nwhere ``None`` might be a valid value. The companion ``AbsenceFactory``\nallows creation of arbitrary absence sentinels, when needed, such as for\nspecific packages.\n\nSee `PEP 661 (\"Sentinel Values\") \u003chttps://peps.python.org/pep-0661/\u003e`_,\n`typing.NoDefault\n\u003chttps://docs.python.org/3/library/typing.html#typing.NoDefault\u003e`_, and\n`dataclasses.MISSING\n\u003chttps://docs.python.org/3/library/dataclasses.html#dataclasses.MISSING\u003e`_ for\nmore details on alternatives.\n\n\n`More Flair \u003chttps://www.imdb.com/title/tt0151804/characters/nm0431918\u003e`_\n===============================================================================\n\n.. image:: https://img.shields.io/github/last-commit/emcd/python-absence\n   :alt: GitHub last commit\n   :target: https://github.com/emcd/python-absence\n\n.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-inverted-border-orange.json\n   :alt: Copier\n   :target: https://github.com/copier-org/copier\n\n.. image:: https://img.shields.io/badge/%F0%9F%A5%9A-Hatch-4051b5.svg\n   :alt: Hatch\n   :target: https://github.com/pypa/hatch\n\n.. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit\n   :alt: pre-commit\n   :target: https://github.com/pre-commit/pre-commit\n\n.. image:: https://microsoft.github.io/pyright/img/pyright_badge.svg\n   :alt: Pyright\n   :target: https://microsoft.github.io/pyright\n\n.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\n   :alt: Ruff\n   :target: https://github.com/astral-sh/ruff\n\n.. image:: https://img.shields.io/pypi/implementation/absence\n   :alt: PyPI - Implementation\n   :target: https://pypi.org/project/absence/\n\n.. image:: https://img.shields.io/pypi/wheel/absence\n   :alt: PyPI - Wheel\n   :target: https://pypi.org/project/absence/\n\n\nOther Projects by This Author 🌟\n===============================================================================\n\n\n* `python-accretive \u003chttps://github.com/emcd/python-accretive\u003e`_\n    - PyPI: `accretive \u003chttps://pypi.org/project/accretive/\u003e`_\n\n    🌌 A Python library package which provides **accretive data structures** - collections which can grow but never shrink.\n* `python-falsifier \u003chttps://github.com/emcd/python-falsifier\u003e`_\n    - PyPI: `falsifier \u003chttps://pypi.org/project/falsifier/\u003e`_\n\n    🎭 A very simple Python library package which provides a **base class for falsey objects** - objects that evaluate to ``False`` in boolean contexts.\n* `python-frigid \u003chttps://github.com/emcd/python-frigid\u003e`_\n    - PyPI: `frigid \u003chttps://pypi.org/project/frigid/\u003e`_\n\n    🔒 A Python library package which provides **immutable data structures** - collections which cannot be modified after creation.\n* `python-icecream-truck \u003chttps://github.com/emcd/python-icecream-truck\u003e`_\n    - PyPI: `icecream-truck \u003chttps://pypi.org/project/icecream-truck/\u003e`_\n\n    🍦 **Flavorful Debugging** - A Python library which enhances the powerful and well-known ``icecream`` package with flavored traces, configuration hierarchies, customized outputs, ready-made recipes, and more.\n* `python-mimeogram \u003chttps://github.com/emcd/python-mimeogram\u003e`_\n    - PyPI: `mimeogram \u003chttps://pypi.org/project/mimeogram/\u003e`_\n\n    📨 A command-line tool for **exchanging collections of files with Large Language Models** - bundle multiple files into a single clipboard-ready document while preserving directory structure and metadata... good for code reviews, project sharing, and LLM interactions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femcd%2Fpython-absence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femcd%2Fpython-absence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femcd%2Fpython-absence/lists"}