-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Right now, if you set up your own ProxyModule, the initialization code makes use of three different types of fallback callables – functions that get called with an attribute name that can’t be normally found in any of the ProxyModule target modules or mappings:
-
Module-level
__getattr__(…)functions – like e.g. this one – which these are a relatively new sort of thing. They take the name of a key or attribute or whatever, and either return something (literally anything, I believe) or raise anAttributeErrorabout it. -
Dictionary-subtype
__missing__(…)methods – as you can see from the link above to theChainModuleMap.__missing__(…)source, this method gets called when__getitem__(…)can’t cut the mustard. It’s a method, so there’s aselfin there – otherwise it’s like the module__getattr__(…)function: take a key, return a thing, or raise. The exception to be raised in this case is aKeyError, but as long as that’s been considered, one can pull the bound method off a dictionary instance and treat it more or less like the module function. -
Arbitrary, user-furnished callables – my point of concern in this issue. Consider the callable I threw together for the inline test that covers this feature:
def fallback_function(key): if key.isupper(): return f"NO DOGG: {key}" raise KeyError(key)
… There’s a criterion the function uses to decide if it should return or raise, and what it raises is a specific exception type. This type of thing is fine if you’re actually implementing one of the special function hooks from 1) or 2). But for these one-off callable fallback things, should we be aiming for something more, I dunno, casual?
Like in the clu.dispatch module, most functions are wrapped and re-wrapped to ensure that safe, sane, and non-idiotic return values happen. Granted, all that stuff concerns itself with orderly-shutdown semantics and POSIX signals and other nuances necessitated by the meshing of several real-world boundary APIs. Whatever, we can do the same thing here, doggie.
The question before you is: should we wrap the non-dunder, non-special-to-Python fallback callables, like to eschew exception mechanics in favor of (say) some sort of sentinel? Or some sleight-of-yield abstractions that allow for statefulness, maybe? Do people want that?