Skip to content

Commit ca83511

Browse files
committed
2to3: Apply unicode fixer.
The unicode fixer strips the u from u'hi' and converts the unicode type to str. The first won't work for Python 2 and instead we replace the u prefix with the sixu function borrowed from the six compatibility package. That function calls the unicode constructor with the 'unicode_escape' encoder so that the many tests using escaped unicode characters like u'\u0900' will be handled correctly. That makes the sixu function a bit different from the asunicode function currently in numpy.compat and also provides a target that can be converted back to the u prefix when support for Python 3.2 is dropped. Python 3.3 reintroduced the u prefix for compatibility. The unicode fixer also replaces 'unicode' with 'str' as 'unicode' is no longer a builtin in Python 3. For code compatibility, 'unicode' is defined either as 'str' or 'unicode' in numpy.compat so that checks like if isinstance(x, unicode): ... will work properly for all python versions. Closes #3089.
1 parent fc5b8cc commit ca83511

File tree

3 files changed

+63
-46
lines changed

3 files changed

+63
-46
lines changed

numpydoc/docscrape_sphinx.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
from __future__ import division, absolute_import, print_function
22

3-
import re, inspect, textwrap, pydoc
3+
import re, inspect, textwrap, pydoc, aya
44
import sphinx
55
import collections
66
from .docscrape import NumpyDocString, FunctionDoc, ClassDoc
77

8+
if sys.version_info[0] >= 3:
9+
sixu = lambda s: s
10+
else:
11+
sixu = lambda s: unicode(s, 'unicode_escape')
12+
13+
814
class SphinxDocString(NumpyDocString):
915
def __init__(self, docstring, config={}):
1016
self.use_plots = config.get('use_plots', False)
@@ -95,11 +101,11 @@ def _str_member_list(self, name):
95101

96102
if others:
97103
maxlen_0 = max(3, max([len(x[0]) for x in others]))
98-
hdr = u"="*maxlen_0 + u" " + u"="*10
99-
fmt = u'%%%ds %%s ' % (maxlen_0,)
104+
hdr = sixu("=")*maxlen_0 + sixu(" ") + sixu("=")*10
105+
fmt = sixu('%%%ds %%s ') % (maxlen_0,)
100106
out += ['', hdr]
101107
for param, param_type, desc in others:
102-
desc = u" ".join(x.strip() for x in desc).strip()
108+
desc = sixu(" ").join(x.strip() for x in desc).strip()
103109
if param_type:
104110
desc = "(%s) %s" % (param_type, desc)
105111
out += [fmt % (param.strip(), desc)]

numpydoc/numpydoc.py

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,22 @@
1717
"""
1818
from __future__ import division, absolute_import, print_function
1919

20+
import os, sys, re, pydoc
2021
import sphinx
22+
import inspect
2123
import collections
2224

2325
if sphinx.__version__ < '1.0.1':
2426
raise RuntimeError("Sphinx 1.0.1 or newer is required")
2527

26-
import os, sys, re, pydoc
2728
from .docscrape_sphinx import get_doc_object, SphinxDocString
2829
from sphinx.util.compat import Directive
29-
import inspect
30+
31+
if sys.version_info[0] >= 3:
32+
sixu = lambda s: s
33+
else:
34+
sixu = lambda s: unicode(s, 'unicode_escape')
35+
3036

3137
def mangle_docstrings(app, what, name, obj, options, lines,
3238
reference_offset=[0]):
@@ -36,32 +42,32 @@ def mangle_docstrings(app, what, name, obj, options, lines,
3642

3743
if what == 'module':
3844
# Strip top title
39-
title_re = re.compile(u'^\\s*[#*=]{4,}\\n[a-z0-9 -]+\\n[#*=]{4,}\\s*',
45+
title_re = re.compile(sixu('^\\s*[#*=]{4,}\\n[a-z0-9 -]+\\n[#*=]{4,}\\s*'),
4046
re.I|re.S)
41-
lines[:] = title_re.sub(u'', u"\n".join(lines)).split(u"\n")
47+
lines[:] = title_re.sub(sixu(''), sixu("\n").join(lines)).split(sixu("\n"))
4248
else:
43-
doc = get_doc_object(obj, what, u"\n".join(lines), config=cfg)
49+
doc = get_doc_object(obj, what, sixu("\n").join(lines), config=cfg)
4450
if sys.version_info[0] >= 3:
4551
doc = str(doc)
4652
else:
4753
doc = str(doc).decode('utf-8')
48-
lines[:] = doc.split(u"\n")
54+
lines[:] = doc.split(sixu("\n"))
4955

5056
if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
5157
obj.__name__:
5258
if hasattr(obj, '__module__'):
53-
v = dict(full_name=u"%s.%s" % (obj.__module__, obj.__name__))
59+
v = dict(full_name=sixu("%s.%s") % (obj.__module__, obj.__name__))
5460
else:
5561
v = dict(full_name=obj.__name__)
56-
lines += [u'', u'.. htmlonly::', u'']
57-
lines += [u' %s' % x for x in
62+
lines += [sixu(''), sixu('.. htmlonly::'), sixu('')]
63+
lines += [sixu(' %s') % x for x in
5864
(app.config.numpydoc_edit_link % v).split("\n")]
5965

6066
# replace reference numbers so that there are no duplicates
6167
references = []
6268
for line in lines:
6369
line = line.strip()
64-
m = re.match(u'^.. \\[([a-z0-9_.-])\\]', line, re.I)
70+
m = re.match(sixu('^.. \\[([a-z0-9_.-])\\]'), line, re.I)
6571
if m:
6672
references.append(m.group(1))
6773

@@ -70,14 +76,14 @@ def mangle_docstrings(app, what, name, obj, options, lines,
7076
if references:
7177
for i, line in enumerate(lines):
7278
for r in references:
73-
if re.match(u'^\\d+$', r):
74-
new_r = u"R%d" % (reference_offset[0] + int(r))
79+
if re.match(sixu('^\\d+$'), r):
80+
new_r = sixu("R%d") % (reference_offset[0] + int(r))
7581
else:
76-
new_r = u"%s%d" % (r, reference_offset[0])
77-
lines[i] = lines[i].replace(u'[%s]_' % r,
78-
u'[%s]_' % new_r)
79-
lines[i] = lines[i].replace(u'.. [%s]' % r,
80-
u'.. [%s]' % new_r)
82+
new_r = sixu("%s%d") % (r, reference_offset[0])
83+
lines[i] = lines[i].replace(sixu('[%s]_') % r,
84+
sixu('[%s]_') % new_r)
85+
lines[i] = lines[i].replace(sixu('.. [%s]') % r,
86+
sixu('.. [%s]') % new_r)
8187

8288
reference_offset[0] += len(references)
8389

@@ -93,8 +99,8 @@ def mangle_signature(app, what, name, obj, options, sig, retann):
9399

94100
doc = SphinxDocString(pydoc.getdoc(obj))
95101
if doc['Signature']:
96-
sig = re.sub(u"^[^(]*", u"", doc['Signature'])
97-
return sig, u''
102+
sig = re.sub(sixu("^[^(]*"), sixu(""), doc['Signature'])
103+
return sig, sixu('')
98104

99105
def setup(app, get_doc_object_=get_doc_object):
100106
if not hasattr(app, 'add_config_value'):

numpydoc/tests/test_docscrape.py

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77
from numpydoc.docscrape_sphinx import SphinxDocString, SphinxClassDoc
88
from nose.tools import *
99

10+
if sys.version_info[0] >= 3:
11+
sixu = lambda s: s
12+
else:
13+
sixu = lambda s: unicode(s, 'unicode_escape')
14+
15+
1016
doc_txt = '''\
1117
numpy.multivariate_normal(mean, cov, shape=None, spam=None)
1218
@@ -220,12 +226,12 @@ def test_str():
220226
221227
Raises
222228
------
223-
RuntimeError :
229+
RuntimeError :
224230
Some error
225231
226232
Warns
227233
-----
228-
RuntimeWarning :
234+
RuntimeWarning :
229235
Some warning
230236
231237
Warnings
@@ -324,7 +330,7 @@ def test_sphinx_str():
324330
The drawn samples, arranged according to `shape`. If the
325331
shape given is (m,n,...), then the shape of `out` is is
326332
(m,n,...,N).
327-
333+
328334
In other words, each entry ``out[i,j,...,:]`` is an N-dimensional
329335
value drawn from the distribution.
330336
@@ -333,16 +339,16 @@ def test_sphinx_str():
333339
**spam** : parrot
334340
335341
A parrot off its mortal coil.
336-
342+
337343
:Raises:
338344
339-
**RuntimeError** :
345+
**RuntimeError** :
340346
341347
Some error
342348
343349
:Warns:
344350
345-
**RuntimeWarning** :
351+
**RuntimeWarning** :
346352
347353
Some warning
348354
@@ -351,12 +357,12 @@ def test_sphinx_str():
351357
Certain warnings apply.
352358
353359
.. seealso::
354-
360+
355361
:obj:`some`, :obj:`other`, :obj:`funcs`
356-
362+
357363
:obj:`otherfunc`
358364
relationship
359-
365+
360366
.. rubric:: Notes
361367
362368
Instead of specifying the full covariance matrix, popular
@@ -403,7 +409,7 @@ def test_sphinx_str():
403409
[True, True]
404410
""")
405411

406-
412+
407413
doc2 = NumpyDocString("""
408414
Returns array of indices of the maximum values of along the given axis.
409415
@@ -558,9 +564,9 @@ def test_unicode():
558564
""")
559565
assert isinstance(doc['Summary'][0], str)
560566
if sys.version_info[0] >= 3:
561-
assert doc['Summary'][0] == u'öäöäöäöäöåååå'
567+
assert doc['Summary'][0] == sixu('öäöäöäöäöåååå')
562568
else:
563-
assert doc['Summary'][0] == u'öäöäöäöäöåååå'.encode('utf-8')
569+
assert doc['Summary'][0] == sixu('öäöäöäöäöåååå').encode('utf-8')
564570

565571
def test_plot_examples():
566572
cfg = dict(use_plots=True)
@@ -578,7 +584,7 @@ def test_plot_examples():
578584
Examples
579585
--------
580586
.. plot::
581-
587+
582588
import matplotlib.pyplot as plt
583589
plt.plot([1,2,3],[4,5,6])
584590
plt.show()
@@ -695,13 +701,13 @@ def test_class_members_doc():
695701
696702
Methods
697703
-------
698-
a :
704+
a :
699705
700-
b :
706+
b :
701707
702-
c :
708+
c :
703709
704-
.. index::
710+
.. index::
705711
706712
""")
707713

@@ -728,21 +734,20 @@ def test_class_members_doc_sphinx():
728734
.. rubric:: Attributes
729735
730736
=== ==========
731-
t (float) Current time.
732-
y (ndarray) Current variable values.
737+
t (float) Current time.
738+
y (ndarray) Current variable values.
733739
=== ==========
734740
735741
.. rubric:: Methods
736742
737743
=== ==========
738-
a
739-
b
740-
c
744+
a
745+
b
746+
c
741747
=== ==========
742748
743749
""")
744750

745751
if __name__ == "__main__":
746752
import nose
747753
nose.run()
748-

0 commit comments

Comments
 (0)