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
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
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
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)
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()