'Get the widget description from a module.
The module is inspected for classes that have a method
`get_widget_description`. The function calls this method and expects
a dictionary, which is used as keyword arguments for
:obj:`WidgetDescription`. This method also converts all signal types
into qualified names to prevent import problems when cached
descriptions are unpickled (the relevant code using this lists should
be able to handle missing types better).
Parameters
module (`module` or `str`): a module to inspect
Returns
An instance of :obj:`WidgetDescription`'

@classmethod
def from_module(cls, module):

    if isinstance(module, str):
        module = __import__(module, fromlist=[''])
    if module.__package__:
        package_name = module.__package__.rsplit('.', 1)[(-1)]
    else:
        package_name = None
    default_cat_name = (package_name if package_name else '')
    for widget_class in module.__dict__.values():
        if (not hasattr(widget_class, 'get_widget_description')):
            continue
        description = widget_class.get_widget_description()
        if (description is None):
            continue
        description = copy.deepcopy(description)
        for s in chain(description['inputs'], description['outputs']):
            s.type = ('%s.%s' % (s.type.__module__, s.type.__name__))
        description = WidgetDescription(**description)
        description.package = module.__package__
        description.category = (widget_class.category or default_cat_name)
        return description
    raise WidgetSpecificationError
