Skip to content
This repository was archived by the owner on Mar 12, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SCM syntax highlighting
pixi.lock linguist-language=YAML linguist-generated=true
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

# pixi environments
.pixi
*.egg-info
17 changes: 17 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[project]
authors = [{ name = "quantity-dev contributors" }]
dependencies = []
name = "dimension-api"
requires-python = ">= 3.12"
version = "0.0.1.dev0"

[build-system]
build-backend = "hatchling.build"
requires = ["hatchling"]

[tool.pixi.project]
channels = ["https://prefix.dev/conda-forge"]
platforms = ["win-64", "linux-64", "osx-64", "osx-arm64"]

[tool.pixi.pypi-dependencies]
dimension_api = { path = ".", editable = true }
13 changes: 13 additions & 0 deletions src/dimension_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
"""Dimension API."""

from typing import Protocol, Self, runtime_checkable

__version__ = "0.0.1.dev0"
__all__ = ["Dimension"]

@runtime_checkable
class Dimension(Protocol):
def __eq__(self, other: Self, /) -> bool: ...
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure: requiring __eq__ to work with other: Self seems like a more restrictive requirement (though, I'm often unsure how to interpret object used as a type annotation). Unresolving this thread for now.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess object in an annotation within the object class is effectively doing the same as what Self is doing?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might, but in any other context I take it as meaning "this variable cannot be assume to conform to any interface", which is radically different.
I suspect maybe @nstarman knows whether they are truly equivalent here.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comparison dunder methods are complicated. They are meant to work with all input, returning NotImplemented if they don't know how to perform the comparison, and bool if they do (obv numpy extends this to Array[bool]).
What we want is approximately

@overload
def __eq__(self, other: object) -> NotImplemented: ...
@overload
def __eq__(self, other: Self) -> bool: ...
def __eq__(self, other: object) -> NotImplemented | bool

A problem in Python is that type checkers really don't like if you annotate the return type as NotImplemented | bool!
@jorenham, I'm looking at optype for how to type this precisely, but AFAIK it should just be

def __eq__(self, other: object) -> bool

Which is the builtin, but here and elsewhere we should add some docs!

def __eq__(self, other: object) -> bool
    """Equality comparison.
     
     Comparison between two Dimension objects (of the same type) must return a `bool`.
     Comparison with other objects is outside the scope of this API.

     """

def __mul__(self, other: Self, /) -> Self: ...
def __div__(self, other: Self, /) -> Self: ...
def __pow__(self, other: int, /) -> Self: ...