Commits

Anonymous committed 68c2599

autodoc uses the module charset now

Comments (0)

Files changed (1)

sphinx/ext/autodoc.py

     :license: BSD.
 """
 
+import re
 import types
 import inspect
 import textwrap
+import linecache
 
 from docutils import nodes
 from docutils.parsers.rst import directives
 except NameError:
     base_exception = Exception
 
+_charset_re = re.compile(r'coding[:=]\s*([-\w.]+)')
+_module_charsets = {}
+
 
 def prepare_docstring(s):
     """
     return [firstline] + otherlines.splitlines() + ['']
 
 
+def get_module_charset(module):
+    """Return the charset of the given module."""
+    if module in _module_charsets:
+        return _module_charsets[module]
+    filename = __import__(module, None, None, ['']).__file__
+    if filename[-4:] in ('.pyc', '.pyo'):
+        filename = filename[:-1]
+    for line in [linecache.getline(filename, x) for x in (1, 2)]:
+        match = _charset_re.search(line)
+        if match is not None:
+            charset = match.group(1)
+            break
+    else:
+        charset = 'ascii'
+    _module_charsets[module] = charset
+    return charset
+
+
 def generate_rst(what, name, members, undoc, add_content,
                  document, lineno, indent=''):
     env = document.settings.env
     if what == 'module' and env.config.automodule_skip_lines:
         docstring = '\n'.join(docstring.splitlines()
                               [env.config.automodule_skip_lines:])
+
+    # get the encoding of the docstring
+    module = getattr(todoc, '__module__', None)
+    if module is not None:
+        docstring = docstring.decode(get_module_charset(module))
+
     docstring = prepare_docstring(docstring)
     for i, line in enumerate(docstring):
         result.append(indent + line, '<docstring of %s>' % name, i)