Metadata-Version: 2.1
Name: ObjectDelegator
Version: 1.1
Summary: This minimal yet powerful library allows delegation of an objects: methods, properties, and his own member objects, to an object who owns it. Recursive delegation is also supported.Use the simple API to handle delegations.
Home-page: https://github.com/YairMZ/ObjectDelegator
Author: Yair Mazal
Author-email: mazaly@post.bgu.ac.il
License: GNU General Public License v3.0
Download-URL: https://github.com/YairMZ/ObjectDelegator/archive/v1.1.tar.gz
Keywords: OOP,delegation,composition
Platform: UNKNOWN
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: OS Independent
Classifier: Development Status :: 3 - Alpha
Classifier: Topic :: Software Development :: Object Brokering
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# Delegate objects powerfully
This minimal yet powerful library allows delegating an object's: methods, properties, and his own member objects, to its owner. Recursive delegation is also supported.

Use the simple API to handle delegations.

From wikipedia, what is delegation:
> In object-oriented programming, delegation refers to evaluating a member
> (property or method) of one object (the receiver) in the context of another
> original object (the sender). Delegation can be done explicitly, by passing
> the sending object to the receiving object, which can be done in any
> object-oriented language; or implicitly, by the member lookup rules of the
> language, which requires language support for the feature.


# Installation

This is python3 only with no dependencies, simply:

    pip install ObjectDelegator

# Examples
ObjectDelegator is used by inheriting from `Delegeator` class. Delegation is then handled via the API, and delegated 
objects can simply be referred to as if they members of the original class subclassing `Delegeator`.

Define some dummy classes for the sake of example:

```
class RabbitHole:
    def __init__(self, txt):
        self.down_we_go = txt

class Foo:
    foo_property = 'hi'
    not_delegated_property = 'bye'
    rabbit = RabbitHole('first rabbit')

    # noinspection PyMethodMayBeStatic
    def foo(self):
        """dummy method"""
        return 'foo'

class Bar:
    rabbit_too = RabbitHole('second rabbit')
    boring = 2
```

Now define a class which inherits from `Delegeator`:

```
class Master(Delegator):
    def __init__(self):
        self.foo_obj = Foo()
        self.bar_obj = Bar()
        self.test = 1

# instantiate a master
master = Master()
```

Delegate using the `set_delegated_members` method of the `Delegeator`:

```
# use a diciotionary with keys as objects delegating members, and values as their members 
master.set_delegated_members({'foo_obj': ['foo', 'foo_property', 'rabbit'], 'bar_obj': ['rabbit_too']})
```

Delegation is versatile:

```
# can delegate methods
master.foo() # => 'foo'
# can delegate properties
master.foo_property # => 'hi'
# or even other objects
master.rabbit.down_we_go # => 'first rabbit'
# and another rabbit hole instance
master.rabbit_too.down_we_go # => 'second rabbit'
```

## API
The API allows to:

 - Delegate objects (see above).
 - Find potential objects which can delegate their members to the master:

```
master.get_possible_objects_to_delegate_to()  # => ['bar_obj', 'foo_obj', 'test', 'foo', 'foo_property', 'rabbit', 'rabbit_too']
```

 - Find potential members which can be delegated to the master:

```
master.get_possible_members_to_delegate()  # => {'bar_obj': ['boring', 'rabbit_too'], 'foo_obj': ['foo', 'foo_property', 'not_delegated_property', 'rabbit'], 'test': ['as_integer_ratio', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'numerator', 'real', 'to_bytes'], 'foo': [], ...}
```

 - List currently delegated members:

```
master.get_delegated_members()  # => {'foo_obj': ['foo', 'foo_property', 'rabbit'], 'bar_obj': ['rabbit_too']}
```

 - Add further _recursive_ delegation:

```
# Note that rabbit itself was delegated before
master.set_delegated_members({'rabbit': ['down_we_go']})
master.down_we_go   # => first rabbit
```

 - Raise a ValueError if we try to delegate to objects of the sae name

```
# if we try to delegate the second rabbit we get a ValueError as we can't have two members with the same name (down_we_go)
master.set_delegated_members({'rabbit_too': ['down_we_go']})
```

 - Remove delegations for a specific object:

```
master.remove_delegations_for_object('rabbit')
# Now we may delegate the other rabbit
master.set_delegated_members({'rabbit_too': ['down_we_go']})
master.down_we_go  # => second rabbit
```

 - clear all delegations:

```
master.clear_all_delegations()
```

