Setuptools command crashes under Python 3.3

Nikolaus Rath avatarNikolaus Rath created an issue

Consider this minimal project:

$ md sphinx; cd sphinx
$ md rst
$ cat > conf.py
master_doc = 'about'

$ cat > setup.py
from setuptools import setup, find_packages
setup(
    name = "HelloWorld",
    version = "0.1",
    packages = find_packages(),
)

$ cat > about.rst
Title
=====

Hello, world!

When running with sphinx-build . doc, it works just fine. However, when running with setuptools, it crashes:

$ python3.3 -m pdb setup.py build_sphinx -a -E
> /home/nikratio/tmp/sphinx2/setup.py(3)<module>()
-> from setuptools import setup, find_packages
(Pdb) c
running build_sphinx
Running Sphinx v1.2b1
building [html]: all source files
updating environment: 1 added, 0 changed, 0 removed
Traceback (most recent call last):                                                                           
  File "/usr/lib/python3.3/pdb.py", line 1658, in main
    pdb._runscript(mainpyfile)
  File "/usr/lib/python3.3/pdb.py", line 1539, in _runscript
    self.run(statement)
  File "/usr/lib/python3.3/bdb.py", line 405, in run
    exec(cmd, globals, locals)
  File "<string>", line 1, in <module>
  File "/home/nikratio/tmp/sphinx2/setup.py", line 3, in <module>
    from setuptools import setup, find_packages
  File "/usr/lib/python3.3/distutils/core.py", line 148, in setup
    dist.run_commands()
  File "/usr/lib/python3.3/distutils/dist.py", line 917, in run_commands
    self.run_command(cmd)
  File "/usr/lib/python3.3/distutils/dist.py", line 936, in run_command
    cmd_obj.run()
  File "/home/nikratio/.local/lib/python3.3/site-packages/sphinx/setup_command.py", line 143, in run
    app.build(force_all=self.all_files)
  File "/home/nikratio/.local/lib/python3.3/site-packages/sphinx/application.py", line 207, in build
    self.builder.build_all()
  File "/home/nikratio/.local/lib/python3.3/site-packages/sphinx/builders/__init__.py", line 174, in build_all
    self.build(None, summary='all source files', method='all')
  File "/home/nikratio/.local/lib/python3.3/site-packages/sphinx/builders/__init__.py", line 231, in build
    purple, length):
  File "/home/nikratio/.local/lib/python3.3/site-packages/sphinx/builders/__init__.py", line 131, in status_iterator
    for item in iterable:
  File "/home/nikratio/.local/lib/python3.3/site-packages/sphinx/environment.py", line 458, in update_generator
    self.read_doc(docname, app=app)
  File "/home/nikratio/.local/lib/python3.3/site-packages/sphinx/environment.py", line 601, in read_doc
    pub.set_components(None, 'restructuredtext', None)
  File "/home/nikratio/.local/lib/python3.3/site-packages/docutils/core.py", line 96, in set_components
    self.reader.set_parser(parser_name)
  File "/home/nikratio/.local/lib/python3.3/site-packages/docutils/readers/__init__.py", line 63, in set_parser
    parser_class = parsers.get_parser_class(parser_name)
  File "/home/nikratio/.local/lib/python3.3/site-packages/docutils/parsers/__init__.py", line 53, in get_parser_class
    return module.Parser
AttributeError: 'module' object has no attribute 'Parser'
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /home/nikratio/.local/lib/python3.3/site-packages/docutils/parsers/__init__.py(53)get_parser_class()
-> return module.Parser
(Pdb) p module
<module 'rst' (namespace)>
(Pdb) p module.__path__
_NamespacePath(['./rst'])

Removing the rst directory fixes the problem. However, this is rather unfortunate as rst often holds the documentation sources.

I suspect this is related to http://sourceforge.net/p/docutils/bugs/228/.

Comments (11)

  1. Nikolaus Rath

    A second ingredient for this to happen is PEP 420 (implicit namespaces). Somehow the rst directory ends up creating an implicit namespace. This is why it still works fine in Python 3.2.

  2. Nikolaus Rath

    Here's a monkeypatch for people who want to temporarily work around the issue:

    def fix_docutils():
        '''Work around https://bitbucket.org/birkenfeld/sphinx/issue/1154/'''
    
        import docutils.parsers 
        from docutils.parsers import rst
        old_getclass = docutils.parsers.get_parser_class
    
        # Check if bug is there
        try:
            old_getclass('rst')
        except AttributeError:
            pass
        else:
            return
    
        def get_parser_class(parser_name):
            """Return the Parser class from the `parser_name` module."""
            if parser_name in ('rst', 'restructuredtext'):
                return rst.Parser
            else:
                return old_getclass(parser_name)
        docutils.parsers.get_parser_class = get_parser_class
    
        assert docutils.parsers.get_parser_class('rst') is rst.Parser
    
  3. Takayuki Shimizukawa

    Sorry, I couldn't reproduce the issue.

    Python 3.3.1
    setuptools 0.9.7
    docutils==0.10
    jinja2==2.7.1
    markupsafe==0.18
    pygments==1.6
    sphinx==1.2b1
    

    or

    Python 3.3.1
    setuptools 0.9.7
    docutils==0.11
    jinja2==2.7.1
    markupsafe==0.18
    pygments==1.6
    sphinx==1.2b1
    
  4. Georg Brandl

    Hmm, I can't reproduce with docutils 0.11 (but with 0.10). In any case, it looks like setup.py and the documentation root are in the same directory, which is an uncommon setup, so I wouldn't worry about it too much.

  5. Log in to comment
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.