Skip to main content

Fancy `defer` for Python >= 3.12 (partially supported in Python 3.11)

Project description

Fancy defer for Python >= 3.12 (partially supported in Python 3.11)

Python package Coverage Status

Installation

You may install deferrer by running

# PyPI
pip install deferrer

or

# conda-forge
conda install -c conda-forge deferrer

.

Usage

defer

There are two designed ways to use defer. You may use either of them, or mix them up.

One is to use defer as a syntactic sugar in the form of defer and .... Example:

>>> from deferrer import defer

>>> def f():
...     defer and print("deferred")
...     print("normal")

>>> import sys
>>> if sys.version_info < (3, 12):
...     from deferrer import defer_scope
...     f = defer_scope(f)

>>> f()
normal
deferred

The other is to use defer as a function wrapper. Example:

>>> from deferrer import defer

>>> def f():
...     defer(print)("deferred")
...     print("normal")

>>> import sys
>>> if sys.version_info < (3, 12):
...     from deferrer import defer_scope
...     f = defer_scope(f)

>>> f()
normal
deferred

Note that when the deferred function can be invoke with no arguments, an empty call is not required, which means defer can be used as a decorator. Example:

>>> from deferrer import defer

>>> def f():
...     @defer
...     def _():
...         print("deferred")
...
...     print("normal")

>>> import sys
>>> if sys.version_info < (3, 12):
...     from deferrer import defer_scope
...     f = defer_scope(f)

>>> f()
normal
deferred

defer_scope

You can use defer_scope to declare a code range that deferred actions should be gathered in and executed after.

It's not rare that you may want to defer some actions in a loop and get them executed at the end of each cycle. But unlike some other languages, loops in Python don't create new scopes, which makes it inconvenient to use defer in them. defer_scope can be used to wrap an iterable to gather deferred actions in each iteration and execute them at the end of the iteration. Example:

>>> from deferrer import defer, defer_scope

>>> def f():
...     for i in defer_scope(range(3)):
...         defer and print("deferred", i)
...         print("normal", i)

>>> f()
normal 0
deferred 0
normal 1
deferred 1
normal 2
deferred 2

Sometimes, you may want to use defer outside of a function. defer_scope can be used as a context manager to gather deferred actions when it's entered and execute them when it's exited. Example:

>>> from deferrer import defer, defer_scope

>>> with defer_scope():
...     # Note that `defer and ...` itself is an expression, and
...     # its value (i.e. the `defer` object) may get printed by
...     # some interpretters.
...     # Use an assignment to suppress the printing behavior.
...     _ = defer and print("deferred")
...     print("normal")
normal
deferred

Also, defer_scope can be used to wrap a function to help defer to work properly in Python 3.11. Note that locals() in Python 3.11 returns a copy of the local scope, which makes it impossible for defer to inject deferred actions into the real local scope. Without a function level defer_scope, deferred actions would be executed immediately after they are evaluated.

Known Limitations

  • deferrer has only been tested on CPython. It may not work on other Python implementations.
  • defer must not be used together with await. Code like defer and await ... is syntactically acceptable but will cause segmentetation fault without being detected beforehand.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

deferrer-1.1.0.tar.gz (14.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

deferrer-1.1.0-py3-none-any.whl (14.8 kB view details)

Uploaded Python 3

File details

Details for the file deferrer-1.1.0.tar.gz.

File metadata

  • Download URL: deferrer-1.1.0.tar.gz
  • Upload date:
  • Size: 14.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for deferrer-1.1.0.tar.gz
Algorithm Hash digest
SHA256 5dc87882b6bdaac1eb1ae39155f62f4a47a168f3fd8c460c96bcc3347c2f38ab
MD5 faad907effc1c6f5e06a82e7f1da3e5f
BLAKE2b-256 ec862438573bd84684f0ae7723702a01b2e59abb912447ea7714ebbd6681c025

See more details on using hashes here.

Provenance

The following attestation bundles were made for deferrer-1.1.0.tar.gz:

Publisher: python-publish.yml on Azureblade3808/py-deferrer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file deferrer-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: deferrer-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for deferrer-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ae3697792059065f7d094ba2c8f2c43fb34a497d993530d3ec91323bbf9871b9
MD5 35cb3986a1a00960fc8be10dc7ed7e56
BLAKE2b-256 bbb7485d3b97cba5cf46dc0401a4085b8a2acb1338b799fabce61fc179570e76

See more details on using hashes here.

Provenance

The following attestation bundles were made for deferrer-1.1.0-py3-none-any.whl:

Publisher: python-publish.yml on Azureblade3808/py-deferrer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page