Skip to main content

short-con: Constants collections without hassle

Motivation

When your Python code needs constants, the process often starts simply enough with the worthy goal of getting the magic strings and numbers out of your code.

BLACK = 'black'
WHITE = 'white'

KING = 0
QUEEN = 9
ROOK = 5
BISHOP = 3
KNIGHT = 3
PAWN = 1

At some point, you might need to operate on those constants in groups, so you add some derived constants. We've hardly gotten out of the gate and the journey already seems tedious.

COLORS = (BLACK, WHITE)
PIECES = (KING, QUEEN, ROOK, BISHOP, KNIGHT, PAWN)

Starting in Python 3.4, the enum library became available:

from enum import Enum

Colors = Enum('Colors', 'BLACK WHITE')
Pieces = Enum('Pieces', dict(KING = 0, QUEEN = 9, ROOK = 5, BISHOP = 3, KNIGHT = 3, PAWN = 1))

Although that library helps a lot, there is one annoyance. We started with the simple goal of wrangling magic strings and values, but we end up forced to interact with special enum instances:

Pieces.QUEEN        # Will this give us the value we want? No.
Pieces.QUEEN.value  # Dig a level deeper, friend.

Although there are use cases where such formalism might be desirable, in the vast majority of practical programming situations the intermediate object is just a hassle — a form of robustness theater rather than an actual best practice with concrete benefits.

An easier way

The short-con project simplifies the creation of constants collections: just supply names and values via keyword arguments.

from short_con import cons

PIECES = cons(king = 0, queen = 9, rook = 5, bishop = 3, knight = 3, pawn = 1)

Behind the scenes cons() defines a frozen dataclass and then returns an instance of that class.

Pieces.queen = 99   # Fails with FrozenInstanceError.

The underlying values are directly accessible — no need to interact with a bureaucratic object standing guard in the middle:

PIECES.queen == 9  # True

The object is directly iterable and convertible to other collections, in the manner of dict.items():

for name, value in PIECES:
    print(name, value)

d = dict(PIECES)
tups = list(PIECES)

The object also supports relevant read-only dict behaviors:

# Always supported.
PIECES['queen']      # 9
len(PIECES)          # 6
'queen' in PIECES    # True

# Supported if the attribute names do not conflict with the method names.
PIECES.keys()        # ('king', 'queen', 'rook', 'bishop', 'knight', 'pawn')
PIECES.values()      # (0, 9, 5, 3, 3, 1)
PIECES.get('rook')   # 5
PIECES.get('blort')  # None

For situations when the values are the same as the attribute names, usage is even more compact: just supply names as positional arguments or via one or more space-delimited strings.

COLORS = cons('black white')
COLORS = cons('black', 'white')

print(COLORS)  # ShortCon(black='black', white='white')

The library also supports the creation of enum-like collections: supply the names and, optionally, start and step parameters to control the generation of the numeric values.

PETS1 = enumcons('dog cat parrot')
PETS2 = enumcons('dog cat parrot', start = 100, step = -10)

print(PETS1)  # ShortCon(dog=1, cat=2, parrot=3)
print(PETS2)  # ShortCon(dog=100, cat=90, parrot=80)

Finally, the library provides a constants() function that supports (1) the ability to control the class name of the underlying dataclass, and (2) use cases where the constant values can be computed from the names. The first argument to constant() should be the names and values (via a dict) or just the names (via a list, tuple, or space-delimited str).

COLORS = constants(
    'black white',         # dict, list, tuple, or str
    cls_name = 'Colors',
    val_func = str.upper,  # Callable: f(NAME) => VALUE
)

print(COLORS)  # Colors(black='BLACK', white='WHITE')

Metadata

Release files for short-con 2.0.0

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

Source distribution (sdist)

Source distribution for short-con 2.0.0
File Size Uploaded
short-con-2.0.0.tar.gz 7.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for short-con 2.0.0
File Interpreter ABI Platform
short_con-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 13.7 kB

Release files / short-con-2.0.0.tar.gz

Download URL short-con-2.0.0.tar.gz
Size 7.6 kB
Tags Source
SHA-256 checksum
How to use checksums
f00e96cf9007e94a4af372efb4bfe74ee95f38c64ecc960a2c2de5ebbac25ba1
BLAKE2b-256 checksum
How to use checksums
a7aff84f9726747762ecadf691e5f04e5c5271dbc6ea790be90b102c1ff06556
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.4

Release files / short_con-2.0.0-py3-none-any.whl

Download URL short_con-2.0.0-py3-none-any.whl
Size 6.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9c568fe4ecf381ff89d850796ac465844b650d99ccbe63d259452132c5bee710
BLAKE2b-256 checksum
How to use checksums
03833a40329116e5e081712698aef195177f78e2597e209d0f2f9b5f7bccac94
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.9.4

Release history Release notifications | RSS feed

2.2.0

2 release files

2.1.0

2 release files

This release

2.0.0 This release

2 release files

1.3.0

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.2

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

0.1.0

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