Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] anytype: A Runtime Type-checker Abstraction Layer for the Ages #355

Open
leycec opened this issue Apr 4, 2024 · 3 comments

Comments

@leycec
Copy link
Member

leycec commented Apr 4, 2024

This feature request was inspired by this spicy @JulesGM pull request for Facebook's Hydra. Basically, Hydra is likely to eventually support a configuration API that will enable end users to notify Hydra of their preferred runtime type-checker (e.g., @beartype, typeguard, [whatevahs]). Of course, you prefer @beartype. You are reading this. But not everybody feels similarly. (Read: some people are wrong.)

Interestingly, jaxtyping offers a similar runtime type-checker-agnostic @jaxtyping.jaxtyped(typechecker=beartype.beartype) API to that of the proposed hydra.utils.instantiate(cfg, target_wrapper=beartype.beartype) API:

# Import both the annotation and the `jaxtyped` decorator from `jaxtyping`
from jaxtyping import Array, Float, jaxtyped

# Use your favourite typechecker: usually one of the two lines below.
from beartype import beartype as typechecker  # <-- this is what you want, of course
#from typeguard import typechecked as typechecker

# Type-check a function
@jaxtyped(typechecker=typechecker)
def batch_outer_product(x: Float[Array, "b c1"],
                        y: Float[Array, "b c2"]
                      ) -> Float[Array, "b c1 c2"]:
    return x[:, :, None] * y[:, None, :]

So for so good. You're in good company, @JulesGM. But I've been wondering... can we eventually simplify and streamline the process of selecting competing runtime type-checkers or is literally every Python package ever going to now define its own non-orthogonal proprietary API for selecting competing runtime type-checkers? It's the latter, isn't it? I'm sighing. You can almost feel the hot fetid breath I'm exhaling all over your keyboard. 😮‍💨

If we accept the current status quo and do nothing,what will happen, guaranteed then user headaches explode combinatorially. Currently, users have to manually notify every Python package of their preferred runtime type-checker with an API unique to that package. Instead, users should be able to trivially, publicly, and globally notify every Python package of their preferred runtime type-checker all-at-once simultaneously with just a single Python statement. Instead, we're now facing the exact opposite scenario.

Introducing...

anytype: Utopia Never Seemed So Far Away

I'd make anytype. But I can barely make @beartype. The core dogma is easy-peasy, though: it's QtPy, but for runtime type-checking. Let's crack this nut. In a nutshell, anytype would:

  • Be a thin high-level abstraction layer over lower-level runtime type-checkers.
  • Only support features commonly supported by all runtime type-checkers.
  • Provide a uniform API for performing runtime type-checking.
  • Provide a configuration API for selecting between supported runtime type-checkers.
  • Internally delegate all runtime type-checking to the currently configured type-checker.

Downstream packages like Hydra and jaxtyping would then simply import anytype and use that high-level API without concern for the currently configured type-checker. For example, the @anytype.anytype decorator would be a shim for either the @beartype.beartype or comparable @typeguard.typechecked decorators: e.g.,

from anytype import anytype  # <-- type-checker-agnostic decorator for the win
from dataclasses import dataclass

@anytype  # <-- you just won the internet. congrats
@dataclass
class ExampleDataclass:
    name: str
    unit_price: float
    quantity_on_hand: int = 0

inst = ExampleDataclass("a name", 123.32, 23)
# Is ok

inst = ExampleDataclass(123, None, 23)
# Breaks

Downstream users and apps would then also import and configure anytype to adopt their preferred runtime type-checker. For example, the public anytype.configure() function might accept a checker parameter whose value is an AnytypeChecker enumeration member identifying the desired runtime type-checker: e.g.,

# Probably in the "{your_app}.__init__" subpackage to ensure this happens early:
from anytype import AnytypeChecker, configure
configure(checker=AnytypeChecker.beartype)  # <-- feel the hot claws as they rake your codebase!

Of course, nobody has time, energy, inclination, money, or sufficient goodwill towards humanity. Nobody will ever do that. I am nobody, too. Still, a utopian dreamer dreams. If not here on GitHub, then where? Nordic Gods above, where!?


i am very tired and must now lie on a door

Addendum: If anyone who is not me would like to make anytype happen, just ping me. The @beartype organization will greedily happily host your anytype package as an official @beartype project at https://github.com/beartype/anytype.

You know. If you want the visibility and marketing and fuzzy bear feels. Just sayin'. Sadly, since the emphasis is "who is not me," this may never happen. I'd personally love to make this happen, but time is scarce and fleeting. I hope for a divine intervention.

@JulesGM
Copy link

JulesGM commented Apr 4, 2024

(btw did you see the beartype hydra-zen integration? They really like beartype over there https://mit-ll-responsible-ai.github.io/hydra-zen/how_to/beartype.html#runtime-type-checking)

@leycec
Copy link
Member Author

leycec commented Apr 5, 2024

Oh, snap! hydra-zen is @rsokl's hot baby. He's been an ardent cheerleader of @beartype for... wait. Has it been literally years now? This is depressing me. @rsokl found @beartype when it was just a squalling infant in a wicker basket that did nothing except spew spittle everywhere. Therefore, I am an ardent cheerleader of hydra-zen.

I still feel bad for quietly taking down the hydra-zen icon from the front page of the @beartype docos. I had this grandiose moustache-twirling idea about selling my body soul for GitHub Sponsors-funded ad icons. But... nobody ever signed up for that, because it turns out that other humans are sane. Years later, the @beartype docos are still bereft of icons. It's literally the worst of all possible outcomes! I failed capitalism, so capitalism failed me. Common story.

I should just put those icons back. But... I am very tired. Let's pass out on the bed face-first instead. 😴

@rsokl
Copy link

rsokl commented Apr 5, 2024

hi @leycec ! miss you! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants