Beispiel #1
0
    def __setup(self):
        """Setup the module sub-tree."""
        # Detect packages
        if hasattr(self._module, '__file__') and \
               (self._module.__file__.endswith('__init__.py') or
                self._module.__file__.endswith('__init__.pyc')or
                self._module.__file__.endswith('__init__.pyo')):
            for dir in self._module.__path__:
                for file in os.listdir(dir):
                    if file in IGNORE_FILES or file in self._children:
                        continue
                    path = os.path.join(dir, file)

                    if (os.path.isdir(path) and
                        '__init__.py' in os.listdir(path)):
                        fullname = self._module.__name__ + '.' + file
                        module = safe_import(fullname)
                        if module is not None:
                            self._children[file] = Module(self, file, module)

                    elif os.path.isfile(path) and file.endswith('.py') and \
                             not file.startswith('__init__'):
                        name = file[:-3]
                        fullname = self._module.__name__ + '.' + name
                        module = safe_import(fullname)
                        if module is not None:
                            self._children[name] = Module(self, name, module)

                    elif os.path.isfile(path) and file.endswith('.zcml'):
                        self._children[file] = ZCMLFile(path, self._module,
                                                        self, file)

                    elif os.path.isfile(path) and file.endswith('.txt'):
                        self._children[file] = TextFile(path, file, self)

        # Setup classes in module, if any are available.
        zope.deprecation.__show__.off()
        for name in self._module.__dict__.keys():
            attr = getattr(self._module, name)
            # We do not want to register duplicates or instances
            if hasattr(attr, '__module__') and \
                   attr.__module__ == self._module.__name__:

                if not hasattr(attr, '__name__') or \
                       attr.__name__ != name:
                    continue

                if isinstance(attr, (types.ClassType, types.TypeType)):
                    self._children[name] = Class(self, name, attr)

                if isinstance(attr, InterfaceClass):
                    self._children[name] = LocationProxy(attr, self, name)

                elif type(attr) is types.FunctionType:
                    self._children[name] = Function(self, name, attr)

        zope.deprecation.__show__.on()
    def get(self, key, default=None):
        """See zope.container.interfaces.IReadContainer."""
        obj = self._children.get(key, default)
        if obj is not default:
            return obj


        if self.getPath():
            # Look for a nested module we didn't previously discover.

            # Note that when path is empty, that means we are the global
            # module (CodeModule) and if we get here, we're asking to find
            # a module outside of the registered root modules. We don't
            # look for those things.

            # A common case for this to come up is 'menus' for the 'zope.app'
            # module. The 'menus' module is dynamically generated through ZCML.

            path = self.getPath() + '.' + key

            obj = safe_import(path)

            if obj is not None:
                self._children[key] = child = Module(self, key, obj)
                # Caching this in _children may be pointless, we were
                # most likely a copy using withParentAndName in the
                # first place.
                return child

        # Maybe it is a simple attribute of the module
        obj = getattr(self._module, key, default)
        if obj is not default:
            obj = LocationProxy(obj, self, key)

        return obj
Beispiel #3
0
 def setup(self):
     """Setup module and class tree."""
     if self.__isSetup:
         return
     for name, mod in zope.component.getUtilitiesFor(IAPIDocRootModule):
         module = safe_import(mod)
         if module is not None:
             self._children[name] = Module(self, name, module)
     self.__isSetup = True
    def setup(self):
        """Setup module and class tree."""
        if self.__isSetup:
            return
        self.__isSetup = True
        self._children = {}
        for name, mod in zope.component.getUtilitiesFor(IAPIDocRootModule):
            module = safe_import(mod)
            if module is not None:
                self._children[name] = Module(self, name, module)

        # And the builtins are always available, since that's the
        # most common root module linked to from docs.
        builtin_module = safe_import('__builtin__') or safe_import('builtins')
        assert builtin_module is not None
        builtin_module = Module(self, builtin_module.__name__, builtin_module)
        # Register with both names for consistency in the tests between Py2 and Py3
        self._children['builtins'] = self._children['__builtin__'] = builtin_module
Beispiel #5
0
def isReferencable(path):
    """Return whether the Python path is referencable."""
    # Sometimes no path exists, so make a simple check first; example: None
    if path is None:
        return False

    # There are certain paths that we do not want to reference, most often
    # because they are outside the scope of this documentation
    for exclude_name in IGNORE_MODULES:
        if path.startswith(exclude_name):
            return False
    split_path = path.rsplit('.', 1)
    if len(split_path) == 2:
        module_name, obj_name = split_path
    else:
        module_name, obj_name = split_path[0], None

    # Do not allow private attributes to be accessible
    if (obj_name is not None and
        obj_name.startswith('_') and
        not (obj_name.startswith('__') and obj_name.endswith('__'))):
        return False
    module = safe_import(module_name)
    if module is None:
        return False

    # If the module imported correctly and no name is provided, then we are
    # all good.
    if obj_name is None:
        return True

    obj = getattr(module, obj_name, _marker)
    if obj is _marker:
        return False
    # Detect singeltons; those are not referencable in apidoc (yet)
    if hasattr(obj, '__class__') and getPythonPath(obj.__class__) == path:
        return False
    return True
Beispiel #6
0
    def get(self, key, default=None):
        """See zope.app.container.interfaces.IReadContainer."""
        obj = self._children.get(key, default)
        if obj is not default:
            return obj

        # We are actually able to find much more than we promise
        if self.getPath():
            path = self.getPath() + '.' + key
        else:
            path = key
        obj = safe_import(path)

        if obj is not None:
            return Module(self, key, obj)

        # Maybe it is a simple attribute of the module
        if obj is None:
            obj = getattr(self._module, key, default)
            if obj is not default:
                obj = LocationProxy(obj, self, key)

        return obj
    def __setup_package(self):
        # Detect packages
        # __file__ can be None, especially with namespace packages on
        # Python 3.7
        module_file = getattr(self._module, '__file__', None) or ''
        module_path = getattr(self._module, '__path__', None)
        if module_file.endswith(('__init__.py', '__init__.pyc', '__init__.pyo')):
            self._package = True
        elif hasattr(self._module, '__package__'):
            # Detect namespace packages, especially (but not limited
            # to) Python 3 with implicit namespace packages:

            # "When the module is a package, its
            # __package__ value should be set to its __name__. When
            # the module is not a package, __package__ should be set
            # to the empty string for top-level modules, or for
            # submodules, to the parent package's "

            # Note that everything has __package__ on Python 3, but not
            # necessarily on Python 2.
            pkg_name = self._module.__package__
            self._package = pkg_name and self._module.__name__ == pkg_name
        else:
            # Python 2. Lets do some introspection. Namespace packages
            # often have an empty file. Note that path isn't necessarily
            # indexable.
            if (module_file == ''
                and module_path
                and os.path.isdir(list(module_path)[0])):
                self._package = True

        if not self._package:
            return

        for mod_dir in module_path:
            # TODO: If we are dealing with eggs, we will not have a
            # directory right away. For now we just ignore zipped eggs;
            # later we want to unzip it.
            if not os.path.isdir(mod_dir):
                continue

            for mod_file in os.listdir(mod_dir):
                if mod_file in IGNORE_FILES or mod_file in self._children:
                    continue

                path = os.path.join(mod_dir, mod_file)

                if os.path.isdir(path) and '__init__.py' in os.listdir(path):
                    # subpackage
                    # XXX Python 3 implicit packages don't have __init__.py

                    fullname = self._module.__name__ + '.' + mod_file
                    module = safe_import(fullname)
                    if module is not None:
                        self._children[mod_file] = Module(self, mod_file, module)
                elif os.path.isfile(path):
                    if mod_file.endswith('.py') and not mod_file.startswith('__init__'):
                        # module
                        name = mod_file[:-3]
                        fullname = self._module.__name__ + '.' + name
                        module = safe_import(fullname)
                        if module is not None:
                            self._children[name] = Module(self, name, module)

                    elif mod_file.endswith('.zcml'):
                        self._children[mod_file] = ZCMLFile(path, self._module,
                                                            self, mod_file)

                    elif  mod_file.endswith(('.txt', '.rst')):
                        self._children[mod_file] = TextFile(path, mod_file, self)
Beispiel #8
0
    def __setup(self):
        """Setup the module sub-tree."""
        # Detect packages
        if hasattr(self._module, '__file__') and \
               (self._module.__file__.endswith('__init__.py') or
                self._module.__file__.endswith('__init__.pyc')or
                self._module.__file__.endswith('__init__.pyo')):
            self._package = True
            for dir in self._module.__path__:
                # TODO: If we are dealing with eggs, we will not have a
                # directory right away. For now we just ignore zipped eggs;
                # later we want to unzip it.
                if not os.path.isdir(dir):
                    continue
                for file in os.listdir(dir):
                    if file in IGNORE_FILES or file in self._children:
                        continue
                    path = os.path.join(dir, file)

                    if (os.path.isdir(path) and
                        '__init__.py' in os.listdir(path)):
                        # subpackage
                        fullname = self._module.__name__ + '.' + file
                        module = safe_import(fullname)
                        if module is not None:
                            self._children[file] = Module(self, file, module)

                    elif os.path.isfile(path) and file.endswith('.py') and \
                             not file.startswith('__init__'):
                        # module
                        name = file[:-3]
                        fullname = self._module.__name__ + '.' + name
                        module = safe_import(fullname)
                        if module is not None:
                            self._children[name] = Module(self, name, module)

                    elif os.path.isfile(path) and file.endswith('.zcml'):
                        self._children[file] = ZCMLFile(path, self._module,
                                                        self, file)

                    elif os.path.isfile(path) and file.endswith('.txt'):
                        self._children[file] = TextFile(path, file, self)

        # List the classes and functions in module, if any are available.
        zope.deprecation.__show__.off()
        module_decl = self.getDeclaration()
        ifaces = list(module_decl)
        if ifaces:
            # The module has an interface declaration.  Yay!
            names = set()
            for iface in ifaces:
                names.update(iface.names())
        else:
            names = getattr(self._module, '__all__', None)
            if names is None:
                # The module doesn't declare its interface.  Boo!
                # Guess what names to document, avoiding aliases and names
                # imported from other modules.
                names = []
                for name in self._module.__dict__.keys():
                    attr = getattr(self._module, name, None)
                    attr_module = getattr(attr, '__module__', None)
                    if attr_module != self._module.__name__:
                        continue
                    if getattr(attr, '__name__', None) != name:
                        continue
                    names.append(name)

        for name in names:
            # If there is something the same name beneath, then module should
            # have priority.
            if name in self._children:
                continue

            attr = getattr(self._module, name, None)
            if attr is None:
                continue

	    if isinstance(attr, hookable):
		attr = attr.implementation

            if isinstance(attr, (types.ClassType, types.TypeType)):
                self._children[name] = Class(self, name, attr)

            elif isinstance(attr, InterfaceClass):
                self._children[name] = LocationProxy(attr, self, name)

            elif isinstance(attr, types.FunctionType):
                doc = attr.__doc__
                if not doc:
                    f = module_decl.get(name)
                    if f is not None:
                        doc = f.__doc__
                self._children[name] = Function(self, name, attr, doc=doc)

        zope.deprecation.__show__.on()