Skip to main content

Notation

Declare metadata beside a function with a decorator and retrieve it later from a registry.

Installation

python -m pip install notation

Requires Python 3.8 or newer.

Usage

Annotate functions

Positional values are stored under integer keys starting at 0; keyword values are stored under their names. The decorator returns the original function unchanged.

from notation import Notation

notes = Notation()

@notes("public", method="GET")
def index():
    return "Hello, World!"

notes[index]   # {0: 'public', 'method': 'GET'}

Enumerate registered functions

The supplied dictionary becomes the instance namespace, so vars() returns it directly:

routes = Notation()

@routes(path="/hello")
def hello():
    return "Hello, World!"

handlers = {meta["path"]: fn for fn, meta in vars(routes).items()}

API

Notation(annotation=None) installs annotation, which must be a dict or None, as the instance's __dict__. A supplied dictionary is used directly, not copied, and vars(notation) returns it. None creates a new empty dictionary.

  • notation[key], notation[key] = value, key in notation operate on the backing dictionary.
  • notation.name reads, writes, or deletes the string key "name". A missing attribute raises AttributeError; a missing item raises KeyError.
  • bool(notation) is False when the backing dictionary is empty.
  • notation(*args, **kwargs) returns a decorator that stores {0: args[0], ..., **kwargs} under the decorated function and returns the function. Decorating the same function again replaces its metadata.

Because the dictionary is the instance namespace, keys that spell Python protocol hooks, such as __deepcopy__ or __getstate__, are visible to copy and pickle; avoid them as metadata keys. Overrides on dict subclasses, such as defaultdict.__missing__, apply to item access but not to attribute access. Iteration, len, get, item deletion, and equality are not provided; use vars(notation) instead.

Metadata is keyed by the exact function object. If another decorator replaces the function, the registry still refers to whichever object it was given. Decorators apply bottom-up, so apply Notation outermost to key the metadata by the object your module name refers to:

import functools

@notes("public", method="GET")
@functools.lru_cache
def index():
    return "Hello, World!"

notes[index]   # {0: 'public', 'method': 'GET'}

With the order reversed, notes stores metadata under the inner function and lru_cache binds index to a new wrapper, so notes[index] raises KeyError.

Tests

python -m pip install -e . mypy
python -m unittest discover -s tests
python -m mypy --strict src/notation tests/typecheck_notation.py

License

MIT. See LICENSE.

Metadata

Release files for notation 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for notation 1.0.0
File Interpreter ABI Platform
notation-1.0.0-py3-none-any.whl Python 3 none any Details

Release files / notation-1.0.0-py3-none-any.whl

Download URL notation-1.0.0-py3-none-any.whl
Size 4.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d8a808e319292d04ced4a318561fd84357b165129c6636c4fe4ec2a884c66674
BLAKE2b-256 checksum
How to use checksums
8d40b5066a2ff9381ab66e9834861dd6a9e3d2e0fd3b3203eb8298dff0cdd712
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.9

Release history Release notifications | RSS feed

1.0.1

2 release files

This release

1.0.0 This release

1 release file

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page