Skip to main content

pint-cf

This package extends Pint with a CF-compliant unit registry and formatter.

Features

  • A CF-compliant Pint UnitRegistry, understanding UDUNITS-2 unit strings.
  • A cf format for Unit/Quantity, to write results back out as CF strings.
  • CFContext, to correctly read CF's units_metadata temperature attribute.
  • CF units that UDUNITS-2 itself doesn't define (level, psu, decibel, sverdrup's Sv symbol, ...), included by default.

Known limitations:

  • No support for time coordinates (e.g. days since 2001-01-01) or climate calendars (e.g. 360_day). Use cftime for those instead.
  • decibel/bel are treated as plain dimensionless ratio units, matching cfunits/cf-units - CF's own reference level for a dB value depends on the variable's standard_name, but neither of those reference packages resolves it either, so pint-cf follows the same convention rather than the letter of the spec.

Installation

Install via pip:

pip install pint-cf

Usage

Create a CF-ready unit registry with cf_unitregistry(). This also registers the cf format.

from pint_cf import cf_unitregistry

ureg = cf_unitregistry()

q = ureg('10 meters per second^2').to('km s-2')

print(f"{q:cf}")   # 0.01 kilometer-second^-2
print(f"{q:~cf}")  # 0.01 km/s2

Temperature units_metadata

CF distinguishes an on-scale temperature (e.g. today's temperature) from a temperature difference (e.g. an anomaly) with a units_metadata attribute - the plain units string alone can't tell them apart.

When reading a variable that has this attribute, wrap the value in CFContext:

from pint_cf import cf_unitregistry, CFContext

ureg = cf_unitregistry()

with CFContext(units_metadata="temperature: difference"):
    q = ureg.Quantity(1, "degree_C")

print(q.units)  # delta_degree_Celsius

Without CFContext (or with units_metadata absent), nothing changes - an on-scale temperature is read as usual.

When writing a result back out, cf_attributes_for does the reverse: it derives the units_metadata attribute from an already-computed Unit or Quantity, ready to merge into a NetCDF variable's attributes:

from pint_cf import cf_attributes_for

print(cf_attributes_for(q))                   # {"units_metadata": "temperature: difference"}
print(cf_attributes_for(ureg.Unit("meter")))  # {} - not a temperature unit

ds[name].attrs.update(cf_attributes_for(q.units))

This round-trips exactly for Celsius and Fahrenheit. Kelvin and Rankine have no zero-offset, so on-scale and difference look identical for them - cf_attributes_for reports "temperature: unknown" rather than guessing.

CF units not in UDUNITS-2

CF defines a few units that UDUNITS-2 doesn't (details), sourced from cfunits. cf_unitregistry() includes them by default:

Unit Behavior
level, sigma_level, layer Dimensionless; kept only for legacy COARDS files, so using one raises a DeprecationWarning.
practical_salinity_unit / psu 1e-3, not 1 (CF's own FAQ is out of date here).
decibel / dB, bel Plain dimensionless ratio units (see "Known limitations" above).
sverdrup / Sv Sv now means sverdrup (ocean volume transport), not sievert - sievert itself still works by its full name.

Pass cf_extensions=False to cf_unitregistry() for a registry that matches plain UDUNITS-2 instead, without any of these additions.

Third-party notices

The UDUNITS-2 unit database this package is built on is redistributed under its own license - see THIRD_PARTY_LICENSES.md.

Metadata

Release files for pint-cf 0.2.1

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

Source distribution (sdist)

Source distribution for pint-cf 0.2.1
File Size Uploaded
pint_cf-0.2.1.tar.gz 44.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pint-cf 0.2.1
File Interpreter ABI Platform
pint_cf-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 82.7 kB

Release files / pint_cf-0.2.1.tar.gz

Download URL pint_cf-0.2.1.tar.gz
Size 44.5 kB
Tags Source
SHA-256 checksum
How to use checksums
ac17b5a3bae01e88e7420fab9de7d59d12aa154497fc04739b7db4a2a9deee57
BLAKE2b-256 checksum
How to use checksums
30f284442c0904dac2829f2730b0c039d2a387066c820d7e32f19346f82579ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 13, 2026.

Transparency log

Release files / pint_cf-0.2.1-py3-none-any.whl

Download URL pint_cf-0.2.1-py3-none-any.whl
Size 38.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2794b2e618d9bf461212a4857d818afb8d72cef57b8c4301dad4276278237c3d
BLAKE2b-256 checksum
How to use checksums
47694f63252fa93378128d61b8a9c76ec74ccdbc44446a7678a775c705cdcaf5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 13, 2026.

Transparency log
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