Xion / pyduck

Utility framework for easier & more robust duck typing in Python
http://xion.github.com/pyduck
4 stars 0 forks source link

General "examine arguments" decorator #9

Open Xion opened 12 years ago

Xion commented 12 years ago

code>@expects</code seems to be an example of a more general utilty decorator that we might call an 'argument examiner'. Such decorator goes through the argument list and does something to argument values - presumbly based on parameters passed earlier to decorator itself.

As an example, code>@expects</code checks whether argument implements particular interface or is instance of specific type. Other examples might include a specific transformation of arguments, such as transforming a database object primary key (ID) into an ORM object.

While such decorator is not hard to write, there are some issues related to handling positional (args) and keyword (*kwargs) arguments. that could be addressed by writing a generalized arguments' examiner. The code>@expects</code decorator would be then using this decorator as a basis.

Below there is an example of implementing a decorator upon such argument examiner:

class OrmCoerceDecorator(Examiner):
    # 'spec' is argument value got in decorator initialization
    # 'actual' comes from function call
    def _process_argument(self, spec, actual):
        if not isinstance(actual, spec): # assume 'spec' is ORM class
            return db_session.get_by_primary_key(actual)

orm_coerce = OrmCoerceDecorator

The usage would be as follows:

@orm_coerce(User)
def reset_password(user):
    user.password = None # accessing object field
    send_password_recovery_mail(user)

# somewhere in website request handler
current_user_id = session.get('user_id')
reset_password(user_id) # works with just an ID thanks to @orm_coerce

To sum up, the task is to implement the Examiner class shown above and to base code>@expects</code upon it.

Xion commented 12 years ago

Implemented. The decorator class is called ExamineArgumentsDecorator and code>@expects</code is now based upon it. Usage is pretty much consistent with the proposal above.

It remains to be documented on project page.