Source code for ways.core.compat

#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''Python 2/3 compatibility classes and functions.

Yes, import six is awesome. This just covers whatever six doesn't.

'''

# IMPORT STANDARD LIBRARIES
import types
import inspect

# IMPORT THIRD-PARTY LIBRARIES
import six


[docs]class DirMixIn(object): # pylint: disable=too-few-public-methods ''''Mix-in to make implementing __dir__ method in subclasses simpler. In Python 2, you can't call super() in __dir__. This mixin lets you do it. Example: >>> class Something(object): >>> def __dir__(self): >>> return super(Something, self).__dir__() >>> print(dir(Something())) # Raises AttributeError >>> class Something(DirMixIn, object): >>> def __dir__(self): >>> return super(Something, self).__dir__() >>> print(dir(Something())) # Works That's all there is to it. ''' def __dir__(self): '''Re-implement Python's __dir__ method, for Python 2. In Python 3, which actually has support for super().__dir__(), just return the super's result. Returns: list[str]: The __dir__ of this object or class. ''' if six.PY3: return super(DirMixIn, self).__dir__() # Reference: # http://www.quora.com/How-dir-is-implemented-Is-there-any-PEP-related-to-that # def get_attrs(obj): '''list[str]: The attributes on the class + its base classes.''' try: dict_types = (dict, types.DictProxyType) except AttributeError: # Python 3.x dict_types = dict if not hasattr(obj, '__dict__'): return [] # slots only if not isinstance(obj.__dict__, dict_types): raise TypeError("%s.__dict__ is not a dictionary" "" % obj.__name__) attrs = set() for cls_ in inspect.getmro(obj): attrs.update(cls_.__dict__.keys()) return attrs def dir2(obj): '''Try to get the object's class and return its attributes.''' try: obj = obj.__class__ except AttributeError: pass return sorted(get_attrs(obj)) return dir2(self)