Skip to content

Commit

Permalink
reduced superfluous content in wrapped classes
Browse files Browse the repository at this point in the history
Signed-off-by: Nick Papior <nickpapior@gmail.com>
  • Loading branch information
zerothi committed Oct 26, 2023
1 parent c2ebad7 commit d12344b
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 25 deletions.
19 changes: 8 additions & 11 deletions src/sisl/_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
Here is a small snippet showing how to utilize this module.
"""
from functools import update_wrapper
import logging
from abc import ABCMeta, abstractmethod
from collections import ChainMap, namedtuple
Expand Down Expand Up @@ -223,11 +224,11 @@ def __init__(self, obj, *args, **kwargs): # pylint: disable=W0231


class MethodDispatcher(AbstractDispatcher):
__slots__ = ("_method", "_obj")
__slots__ = ("_obj",)

def __init__(self, method, dispatchs=None, default=None, obj=None, **attrs):
super().__init__(dispatchs, default, **attrs)
self._method = method
update_wrapper(self, method)

# In python3 a method *always* have the __self__ key
# In case the method is bound on a class.
Expand All @@ -236,34 +237,30 @@ def __init__(self, method, dispatchs=None, default=None, obj=None, **attrs):
else:
self._obj = obj

# This will probably fail for PYTHONOPTIMIZE=2
self.__call__.__func__.__doc__ = method.__doc__
# Storing the name is required for help on functions
self.__name__ = method.__name__
_log.info(f"__init__ {self.__class__.__name__}", extra={"obj": self})

def copy(self):
""" Create a copy of this object (making a new child for the dispatch lookup) """
_log.debug(f"copy {self.__class__.__name__}", extra={"obj": self})
return self.__class__(self._method, self._dispatchs.new_child(), self._default,
return self.__class__(self.__wrapped__, self._dispatchs.new_child(), self._default,
self._obj, **self._attrs)

def renew(self, **attrs):
""" Create a new class with updated attributes """
_log.debug(f"renew {self.__class__.__name__}", extra={"obj": self})
return self.__class__(self._method, self._dispatchs, self._default,
return self.__class__(self.__wrapped__, self._dispatchs, self._default,
self._obj, **{**self._attrs, **attrs})

def __call__(self, *args, **kwargs):
_log.debug(f"call {self.__class__.__name__}{args}", extra={"obj": self})
if self._default is None:
return self._method(*args, **kwargs)
return self._dispatchs[self._default](self._obj, **self._attrs).dispatch(self._method)(*args, **kwargs)
return self.__wrapped__(*args, **kwargs)
return self._dispatchs[self._default](self._obj, **self._attrs).dispatch(self.__wrapped__)(*args, **kwargs)

def __getitem__(self, key):
r""" Get method using dispatch according to `key` """
_log.debug(f"__getitem__ {self.__class__.__name__},key={key}", extra={"obj": self})
return self._dispatchs[key](self._obj, **self._attrs).dispatch(self._method)
return self._dispatchs[key](self._obj, **self._attrs).dispatch(self.__wrapped__)

__getattr__ = __getitem__

Expand Down
28 changes: 14 additions & 14 deletions src/sisl/io/_multiple.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def __init__(self,
# this makes it work like a function bound to an instance (func.__self__
# works for instances)
self.__self__ = obj
self.__func__ = func
# this is already sliced, sub-slicing shouldn't work (at least for now)
update_wrapper(self, func)
self.key = key
if skip_func is None:
self.skip_func = func
Expand All @@ -39,14 +40,12 @@ def __init__(self,
def postprocess(ret):
return ret
self.postprocess = postprocess
# this is already sliced, sub-slicing shouldn't work (at least for now)
update_wrapper(self, func)

def __call__(self, *args, **kwargs):
""" Defer call to the function """
# Now handle the arguments
obj = self.__self__
func = self.__func__
func = self.__wrapped__
key = self.key
skip_func = self.skip_func

Expand Down Expand Up @@ -134,23 +133,25 @@ def __init__(self,
default_slice: Optional[Any]=None,
**kwargs):
self.__self__ = obj
self.__func__ = func
# first update to the wrapped function
update_wrapper(self, func)
self.slicer = slicer
self.default_slice = default_slice
self.kwargs = kwargs
self._update_doc()

def _update_doc(self):
# first update to the wrapped function
update_wrapper(self, self.__func__)
def __str__(self):
# trying to bypass the documentationt
return self.__doc__

def _update_doc(self):
# Override name to display slice handling in help
default_slice = self.default_slice
if self.default_slice is None:
default_slice = 0

self.__name__ = f"{self.__name__}[...|{default_slice!r}]"
name = self.__func__.__name__
name = self.__wrapped__.__name__
self.__name__ = f"{name}[...|{default_slice!r}]"
try:
doc = self.__doc__
except AttributeError:
Expand Down Expand Up @@ -201,14 +202,14 @@ def _update_doc(self):

def __call__(self, *args, **kwargs):
if self.default_slice is None:
return self.__func__(self.__self__, *args, **kwargs)
return self.__wrapped__(self.__self__, *args, **kwargs)
return self[self.default_slice](*args, **kwargs)

def __getitem__(self, key):
"""Extract sub items of multiple function calls as an indexed list """
return self.slicer(
obj=self.__self__,
func=self.__func__,
func=self.__wrapped__,
key=key,
**self.kwargs
)
Expand All @@ -235,13 +236,12 @@ def __init__(self, **kwargs):

# this is the decorator call
def __call__(self, func):
self.__func__ = func
# update doc str etc.
update_wrapper(self, func)
return self

def __get__(self, obj, objtype=None):
func = self.__func__
func = self.__wrapped__

if obj is None:
# ensure that we can get documentation
Expand Down

0 comments on commit d12344b

Please sign in to comment.