﻿ticket	summary	type	release	owner	status	created	modified	_description	_reporter
14074	Incompatible with Trac 1.2 (genshi) and 1.4+ (jinja2)	defect	1.4		new	2021-10-25T22:01:57+02:00	2021-11-25T00:36:49+01:00	"When instaled and url `/pydoc`

{{{
TemplateNotFound: Template ""macros.html"" not found
}}}


{{{
File ""venvp27/lib/python2.7/site-packages/trac/web/main.py"", line 639, in dispatch_request          
  dispatcher.dispatch(req)
File ""venvp27/lib/python2.7/site-packages/trac/web/main.py"", line 271, in dispatch          
  method=method)
File ""venvp27/lib/python2.7/site-packages/trac/web/chrome.py"", line 1452, in render_template          
  fragment, iterable, method)
File ""venvp27/lib/python2.7/site-packages/trac/web/chrome.py"", line 1793, in _render_genshi_template          
  stream = template.generate(**data)
File ""venvp27/lib/python2.7/site-packages/genshi/template/base.py"", line 568, in generate          
  stream = self.stream
File ""venvp27/lib/python2.7/site-packages/genshi/template/base.py"", line 457, in stream          
  self._prepare_self()
File ""venvp27/lib/python2.7/site-packages/genshi/template/base.py"", line 476, in _prepare_self          
  self._stream = list(self._prepare(self._stream, inlined))
File ""venvp27/lib/python2.7/site-packages/genshi/template/base.py"", line 517, in _prepare          
  cls=cls or self.__class__)
File ""venvp27/lib/python2.7/site-packages/genshi/template/loader.py"", line 248, in load          
  raise TemplateNotFound(filename, search_path)
}}}
"	anonymous
4904	Render documentation for modules packaged in EGG | ZIP files | PEP-302 compatible sources	enhancement	0.11	Alec Thomas	new	2009-04-08T21:01:27+02:00	2021-01-21T17:52:24+01:00	"
I implemented this enhancement when I was setting up the Trac environment I use to manage the development of many plugins (especially [https://opensvn.csie.org/traccgi/swlcu/wiki/En/Devel/TracGViz/ TracGViz plugin] which is meant to embed '''iGoogle gadgets''' in wiki pages using WikiFormatting). I'm used to see in action in the same site the plugins I build (yes, I eat my own dog food ;). That time I realized that even when '''TracGViz plugin''' was installed and living in `sys.path`, its documentation wasnt shown, and its path was not included in the index page.

I discovered that this was due to two main reasons:

  - For the index page, PyDocPlugin filters `sys.path` explicitly so that only the plugins found 
    in the file system be considered.
  - For the module documentation, the fact is that the implementation relies on `imp` 
    module to load the modules the documentation will be extracted from. This feature
    is kind of deprecated after '''PEP 302 -- New Import Hooks''' has been aproved.

Therefore I wrote a patch to solve the second issue. You can see it in action to generate the [https://opensvn.csie.org/traccgi/swlcu/wiki/En/Devel/TracGViz/ApiDocs#APIReference API reference documentation] for '''TracGViz plugin'''.

{{{
#!diff

--- tracpydoc_old.py	2007-02-19 16:52:18.000000000 -0500
+++ tracpydoc_new.py	2009-03-28 21:10:22.000000000 -0500
@@ -169,30 +169,96 @@
 
     def load_object(self, fullobject):
         """""" Load an arbitrary object from a full dotted path. """"""
+        self.log.debug(""Preparing docs for %s"", fullobject)
         fullspec = fullobject.split('.')
         i = 0
         module = mfile = mdescr = None
         mpath = self.syspath
+        self.log.debug(""Using PATH = %s"", mpath)
         # Find module
+        import sys
         if fullspec[0] in sys.builtin_module_names:
             module = __import__(fullspec[0], None, None)
             i += 1
         else:
-            while i < len(fullspec):
+
+#            I removed this since it is not compatible with PEP 302 
+#            import hooks and it doesn't load the modules packaged 
+#            in zip | egg files.
+
+#            while i < len(fullspec):
+#                try:
+#                    f, p, mdescr = imp.find_module(fullspec[i], mpath)
+#                    if mfile:
+#                        mfile.close()
+#                    mfile, mpath = f, [p]
+#                    i += 1
+#                except ImportError:
+#                    break
+            mname = fullspec[0]
+            import sys              # Ensure loaders cache is updated
+            
+            def importer(path):
                 try:
-                    f, p, mdescr = imp.find_module(fullspec[i], mpath)
-                    if mfile:
-                        mfile.close()
-                    mfile, mpath = f, [p]
-                    i += 1
-                except ImportError:
+                    return sys.path_importer_cache[path]
+                except KeyError: # Not in cache. Try path hooks instead
+                    for imp_type in sys.path_hooks:
+                        try:
+                            return imp_type(path)
+                        except:
+                            pass
+                    else:        # No further choices.
+                        return imp.NullImporter(path)
+            for path in mpath:
+                i = 0
+                _imp = importer(path)
+                if isinstance(_imp, imp.NullImporter):
+                        continue
+                if _imp is None:  # Legacy code. No importer object :(
+                    mpath = [path]
+                    while i < len(fullspec):
+                        try:
+                            f, p, mdescr = imp.find_module(fullspec[i], mpath)
+                            if mfile:
+                                mfile.close()
+                            mfile, mpath = f, [p]
+                            i += 1
+                        except ImportError:
+                            break
+                else:
+                    mname = ''
+                    while i < len(fullspec):
+                        try:
+                            mname+= fullspec[i]
+                            self.log.debug(""Trying importer '%s' for object '%s'"", 
+                                    _imp, mname)
+                            if _imp.find_module(mname) is None:
+                                break
+                            self.log.debug(""Ok"")
+                            path = os.path.join(path, fullspec[i])
+                            i += 1
+                            self.log.debug(""Setting new path %s"", path)
+                            _imp = importer(path)
+                            self.log.debug(""New importer %s"", _imp)
+                            mname+= '.'
+                        except Exception, exc:
+                            self.log.debug(""Error %s message '%s'"", \
+                                            exc.__class__,
+                                            str(exc))
+                self.log.debug(""Search for '%s' stopped at %d"", 
+                            fullobject, i)
+                if i > 0:
                     break
+            else:
+                self.log.debug(""Unable to import '%s'"", fullobject)
+                raise ImportError, fullobject
             try:
                 mname = ""."".join(fullspec[0:i])
-                if sys.modules.has_key(mname):
-                    module =  sys.modules[mname]
-                elif mname and mdescr:
-                    module = imp.load_module(mname, mfile, mpath[0], mdescr)
+                self.log.debug(""Module name %s"", mname)
+                __import__(mname, None, None)
+                self.log.debug(""Retrieving %s from sys.path"", mname)
+                module =  sys.modules[mname]
+                self.log.debug(""Ok"")
             finally:
                 if mfile:
                     mfile.close()
@@ -237,7 +303,9 @@
 
     def _makedoc(self, target, visibility):
         """"""Warning: this helper method returns a `str` object.""""""
+        self.log.debug('Loading module and object')
         module, object = self.load_object(target)
+        self.log.debug('Module and object loaded')
         try:
             self.makedoc_lock.acquire()
             if visibility == 'private' or \
}}}

The first issue still remains open, since that PEP doesnt provide standards for module enumeration.

Best Regards,

Olemis Lang
"	Olemis Lang
688	Generate PyDoc by providing SVN path instead of sys.path	defect	0.10	Christian Boos	new	2006-09-04T18:17:30+02:00	2007-05-08T21:18:45+02:00	Not sure if this is possible, but would like ability to generate docs with PyDoc by providing an SVN path, instead of sys.path.	alex@…
164	Pydoc Heisenbugs	defect		Alec Thomas	assigned	2006-01-31T22:15:59+01:00	2007-04-04T00:48:37+02:00	"I am getting really weird, seemingly random glitches from the Pydoc plugin.

Things like it will say that no documentation is found for a file, but if I refresh a few times it might show me the docs, and then go back to ""not found"" the next time I load the page. 

Below is a traceback from on of the common errors. This error will also sometimes show up on a wiki page if I have used a [pydoc:] link on it.

{{{
Traceback (most recent call last):
  File ""/usr/lib/python2.4/site-packages/trac/web/modpython_frontend.py"", line 206, in handler
    dispatch_request(mpr.path_info, mpr, env)
  File ""/usr/lib/python2.4/site-packages/trac/web/main.py"", line 139, in dispatch_request
    dispatcher.dispatch(req)
  File ""/usr/lib/python2.4/site-packages/trac/web/main.py"", line 107, in dispatch
    resp = chosen_handler.process_request(req)
  File ""/usr/lib/python2.4/site-packages/trac/wiki/web_ui.py"", line 116, in process_request
    self._render_view(req, db, page)
  File ""/usr/lib/python2.4/site-packages/trac/wiki/web_ui.py"", line 364, in _render_view
    req.hdf['wiki.page_html'] = wiki_to_html(page.text, self.env, req)
  File ""/usr/lib/python2.4/site-packages/trac/wiki/formatter.py"", line 744, in wiki_to_html
    Formatter(env, req, absurls, db).format(wikitext, out, escape_newlines)
  File ""/usr/lib/python2.4/site-packages/trac/wiki/formatter.py"", line 599, in format
    result = re.sub(self.rules, self.replace, line)
  File ""/usr/lib/python2.4/sre.py"", line 142, in sub
    return _compile(pattern, 0).sub(repl, string, count)
  File ""/usr/lib/python2.4/site-packages/trac/wiki/formatter.py"", line 221, in replace
    return getattr(self, '_' + itype + '_formatter')(match, fullmatch)
  File ""/usr/lib/python2.4/site-packages/trac/wiki/formatter.py"", line 290, in _lhref_formatter
    return self._make_link(ns, target, match, label)
  File ""/usr/lib/python2.4/site-packages/trac/wiki/formatter.py"", line 295, in _make_link
    util.escape(label, False))
  File ""build/bdist.linux-i686/egg/tracpydoc/tracpydoc.py"", line 322, in _pydoc_formatter
  File ""build/bdist.linux-i686/egg/tracpydoc/tracpydoc.py"", line 195, in load_object
  File ""/var/www/gopetsdev/head/snofight/main.py"", line 3, in ?
    import pygame, sys
  File ""/usr/lib/python2.4/site-packages/pygame/__init__.py"", line 71, in ?
    Color = color.Color
NameError: name 'color' is not defined
}}}"	Noah Kantrowitz
1098	latest epydoc supports static parsing of sources	task	0.10	Alec Thomas	new	2007-01-15T09:52:30+01:00	2007-01-15T09:52:30+01:00	"http://epydoc.sourceforge.net/whatsnew.html

(I couldn't update the wiki, Trac thought it was spam)"	oripel
274	Want configurable module search path	enhancement	0.8	Alec Thomas	new	2006-04-03T19:01:54+02:00	2006-12-24T07:24:18+01:00	It'd be cool to have an option in the {{{[pydoc]}}} section of {{{trac.ini}}} to set the search path that PyDocPlugin uses, rather than having to change the global sys.path.	dcrosta@…
471	Parse documentation of objects as WikiMarkup	enhancement	0.10	Alec Thomas	new	2006-06-29T18:30:23+02:00	2006-06-29T18:30:23+02:00	"Allow WikiMarkup to be used in
documentation. This will greatly
enhance documentation and allow
you to link various bits of documentation,
relating them to Trac Links, etc."	James Mills
