Skip to content

Pythonic access to generated command methods #11

@jesteria

Description

@jesteria

Summary

Commands generated from the decoration of method functions should be accessible as they appear to be in code, nevermind that they have been transmuted into Command classes.

class Main(command):

    def __call__(self):
        self.action()

    @cmd
    def action(self):
        …

Currently, the expression self.action() in Main.__call__ will not invoke a method; rather, it will attempt to instantiate a new instance of the Command subclass, action, (but in fact fail).

This is counter-intuitive.

It's not that access to the instance-bound method is impossible. Rather, it would be self['action'].__call__(). However, in this special case, due to decorator manufacture of Command classes, we should likely provide better support for reasonable, syntactic expectations.

Limitations

  • Command.__getitem__ should not change. This is the only way of accessing the hierarchy of Command instances; and, as a novel implementation, it's free to operate however it needs.
  • It might make sense to change how this works for all cmd-generated classes; but, it might not. @cmd is, relatively, more intended for generating classes which have some distinct utility. @cmdmethod, on the other hand, generates classes whose instantiation is only important to their execution, and it is unlikely that (easy) access to their instance is needed. Regardless, the syntactic issue applies to all such decorated method functions, and there's likely little to be gained from distinguishing the two here, particularly so long as the instance remains accessible via subscription.

Implementation

The manufactured class may include a (mix-in) descriptor interface, with __get__ defined, such that reference to the class, (from the parent, for example, or otherwise), returns the instance-bound function, rather than the class, (attached to its instance as either __call__ or prepare).

It shouldn't make a difference to the implementation whether this is general to manufactured commands or not, (since outside of method context __get__ simply isn't involved).

Note: We could instead merely return the command instance, but the goal is to satisfy syntactic expectation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions