Skip to main content

Add your description here

Project description

ibis-enum

ibis-enum provides a single utility: IbisEnum. It is like a plain enum.Enum, except it has better interoperability with ibis. It is modeled after ordered enums in DuckDB, PostgreSQL, and MySQL.

  • They are have an ordering, eg Priority.LOW < Priority.MEDIUM < Priority.HIGH
  • They provide useful conversion methods to convert between the string-y and int-y representations.
  • They can be compared against both plain python and ibis values, with sane coercion that is friendly but hopefully avoids footguns. eg Priority.LOW < ibis.literal("HIGH") works as expected, resulting in an ibis BooleanValue expression that would execute to True. Note that plain string comparison of "LOW" < "HIGH" would evaluate to False!
  • They have great type annotations!
  • They are well-tested, linted, and formatted.
  • MIT licensed.

I would consider this as being in Beta status. It is pretty simple, and I would trust it's implementation to be mostly bug free, and I don't see TOO many reasons to change the public API, but I probably still will alittle bit. So to keep me from breaking you, use a lockfile.

Installation

Available on PyPI as ibis-enum.

uv add ibis-enum

Quick Start

from ibis_enum import IbisEnum

class Priority(IbisEnum):
	# Values must be ints. The order of the members is determined by the ints.
    LOW = 0
    MEDIUM = 1
    HIGH = 2
    URGENT = 3
	# Names are case sensitive:
	# low = 5 would result in a distinct enum value
	
	# Member values MUST be unique.
	# ALSO_MEDIUM = 1 # This would error

Creation

Using plain python values:

assert Priority.MEDIUM == Priority("MEDIUM")
assert Priority.MEDIUM == Priority(1)
Priority("bogus") # errors
Priority(999) # errors
Priority("medium") # errors, case mismatch

Conversion

You can convert python values to the int-y or string-y form using classmethods:

assert Priority.to_stringy(Priority.MEDIUM) == "MEDIUM"
assert Priority.to_stringy("MEDIUM") == "MEDIUM"
assert Priority.to_stringy(1) == "MEDIUM"

assert Priority.to_integery(Priority.MEDIUM) == 1
assert Priority.to_integery("MEDIUM") == 1
assert Priority.to_integery(1) == 1

And you can convert ibis values, which give you back ibis StringValue and IntegerValues:

assert Priority.to_stringy(ibis.literal("MEDIUM")).execute() == "MEDIUM"
assert Priority.to_stringy(ibis.literal(1)).execute() == "MEDIUM"

assert Priority.to_integery(ibis.literal("MEDIUM")).execute() == 1
assert Priority.to_integery(ibis.literal(1)).execute() == 1

Comparison and Ordering

IbisEnum members can be compared to other IbisEnums, plain python ints and strs which give back plain bools as you would expect:

assert Priority.LOW < Priority.HIGH
assert Priority.LOW < "HIGH"
assert Priority.LOW < 2

Comparing to an ibis Value results in an ibis BooleanValue. Any StringValue's are converted to the integer level when ordering is important! Otherwise we avoid casting whenever we don't need it, for optimal performance.

assert (Priority.LOW == ibis.literal("HIGH")).execute() is True
assert (Priority.LOW < ibis.literal(2)).execute() is True

Comparison Warning

For comparisons with Ibis values, the enum member MUST be on the left-hand side:

Priority.HIGH == ibis.literal(1)
Priority.HIGH > ibis.literal(1)
# etc

The reverse form may fail:

ibis.literal(1) == Priority.HIGH
ibis.literal(1) < Priority.HIGH
# etc

This is due a limitation of Ibis that we don't have control over. When python sees X == Y, it first calls X.__eq__(Y), then if that returns NotImplemented then it falls back to Y.__eq__(X). ibis.Value.__eq__(self, <enum value>) throws an error instead of returning a NotImplemented as it probably should. So, we need instead for Enum.__eq__(self, <ibis value>) to be the comparison operator caled first. To guarantee this, the enum needs to be on the left hand side of the comparison.

Why Not Plain Enum?

Built-in enum.Enum is fine for Python-only comparisons, but it does not know how to compare itself to Ibis expressions.

import enum
import ibis

class PlainPriority(enum.Enum):
    LOW = 0
    MEDIUM = 1
    HIGH = 2
    URGENT = 3

# This would error!
Priority.HIGH == ibis.literal(2)

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

ibis_enum-0.2.0.tar.gz (5.8 kB view details)

Uploaded Source

Built Distribution

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

ibis_enum-0.2.0-py3-none-any.whl (6.6 kB view details)

Uploaded Python 3

File details

Details for the file ibis_enum-0.2.0.tar.gz.

File metadata

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

File hashes

Hashes for ibis_enum-0.2.0.tar.gz
Algorithm Hash digest
SHA256 a713d518369b5d19fa03634d7ea4df25f980136d48c8dee48c8e08501390c5a3
MD5 c3b469b1e176da97ac24204ef9b5cd84
BLAKE2b-256 4d79b957dfc20b1ee14880c56c5874ea54fec849d43f070f6b442bbf15d756f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for ibis_enum-0.2.0.tar.gz:

Publisher: release.yml on NickCrews/ibis-enum

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

File details

Details for the file ibis_enum-0.2.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for ibis_enum-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fdd116a6f1cd2c72de8b3c6f54821116b52851626340895e33dabb81af7f3524
MD5 6f866f1e137024aeb324c5e0af8444a3
BLAKE2b-256 0f195dd3e145107a05e689ec5c90d082de9ab207d94de43186159d0e89dc426f

See more details on using hashes here.

Provenance

The following attestation bundles were made for ibis_enum-0.2.0-py3-none-any.whl:

Publisher: release.yml on NickCrews/ibis-enum

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