
I have been thinking about this proposal and it will clearly work - however it is not beautiful. Would it be acceptable to not implement these directory operations but tell people to move to the src object and then use the operation on the entry. Steve On 12 February 2013 21:28, Andre Merzky <andre@merzky.net> wrote:
Hi all,
we have been rethinking the method overloading problem for the Python bindings again. As a reminder, this is the problem:
- A namespace entry has a method 'entry.copy (tgt, flags)'
- A namespace directory inherits from the entry, and adds another copy method: 'dir.copy (src, tgt, flags)'
- Python though does not do method overloading, but only method *overwriting*. For that reasons, based on a suggestion of Paul, we renamed the conflicting methods on entry level with a '_self' postfix: 'entry.copy_self (tgt, flags)'.
It seems we found a way to implement real method overloading thouhg -- and since the code overhead is not too bad, we would like to propose that mechanism for the SAGA Python bindings.
First, these are the methods we are talking about, sorted by signature types:
def copy (self, tgt, flags=None, ttype=None) : pass def copy (self, src, tgt, flags=None, ttype=None) : pass def link (self, tgt, flags=None, ttype=None) : pass def link (self, src, tgt, flags=None, ttype=None) : pass def move (self, tgt, flags=None, ttype=None) : pass def move (self, src, tgt, flags=None, ttype=None) : pass
def get_size (self, flags=None, ttype=None) : pass def get_size (self, tgt, flags=None, ttype=None) : pass def remove (self, flags=None, ttype=None) : pass def remove (self, tgt, flags=None, ttype=None) : pass
def is_dir (self, ttype=None) : pass def is_dir (self, tgt, ttype=None) : pass def is_entry (self, ttype=None) : pass def is_entry (self, tgt, ttype=None) : pass def is_file (self, ttype=None) : pass def is_file (self, tgt, ttype=None) : pass def is_link (self, ttype=None) : pass def is_link (self, tgt, ttype=None) : pass def read_link (self, ttype=None) : pass def read_link (self, tgt, ttype=None) : pass
So, the differences are never in the keyword args (kwargs), but always in the args w/o keyword. The kwargs are always flags, i.e. integers, or enums, which we can also define as integers.
As said: Python does not allow method overloading, only method replacement. But it *does* allow for variable parameter lists (*args, **kwargs). We can deselect the int types from the args, and count the remaining arguments:
d = {'src' : 'src', 'tgt' : 'tgt', 'flags' : 3, 'ttype' : 2} l = list (v for v in d.values () if not isinstance (v, int))
print len(l) # 2
So, one can code the following:
class ns.entry :
# def copy (self, tgt, flags=None, ttype=None) : pass # def copy (self, src, tgt, flags=None, ttype=None) : pass def copy (self, *args, **kwargs) :
non_int_args = args + list (v for v in kwargs.values () \ if not v == None and not isinstance (v, int)) if len (non_int_args) == 2 : return self._adaptor.copy_self (args, kwargs) if len (non_int_args) == 3 : return self._adaptor.copy (args, kwargs)
raise BadParameter ("signature mismatch: copy (url, [url], flags, ttype)")
All further signature checks are automatically done on CPI / adaptor level -- although one could here add type checking for flags and ttypes at this point.
We think this makes the API significantly cleaner and easier to use -- so please let us know what you think...
Best, Andre.
-- There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton -- saga-rg mailing list saga-rg@ogf.org https://www.ogf.org/mailman/listinfo/saga-rg