Skip to content

Commit 2aa769b

Browse files
authored
Merge pull request numpy#19916 from DimitriPapadopoulos/make_lite.py_python2.7
MAINT: Repair `make_lite.py`
2 parents c2ad604 + a12e0d1 commit 2aa769b

File tree

4 files changed

+43
-25
lines changed

4 files changed

+43
-25
lines changed

numpy/linalg/lapack_lite/README.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ automatically from a directory of LAPACK source files.
1212
You'll need `plex 2.0.0dev`_, available from PyPI, installed to do the
1313
appropriate scrubbing. As of writing, **this is only available for python 2.7**,
1414
and is unlikely to ever be ported to python 3.
15+
As a result, all the Python scripts in this directory must remain compatible
16+
with Python 2.7, even though NumPy itself no longer supports this version,
17+
until these scripts are rewritten to use something other than ``plex``.
1518

1619
.. _plex 2.0.0dev: https://pypi.python.org/pypi/plex/
1720

1821
The routines that ``lapack_litemodule.c`` wraps are listed in
1922
``wrapped_routines``, along with a few exceptions that aren't picked up
2023
properly. Assuming that you have an unpacked LAPACK source tree in
21-
``~/LAPACK``, you generate the new routines in this directory with::
24+
``/tmp/lapack-3.x.x``, you generate the new routines in this directory with::
2225

23-
$ python ./make_lite.py wrapped_routines ~/LAPACK
26+
$ ./make_lite.py wrapped_routines /tmp/lapack-3.x.x
2427

2528
This will grab the right routines, with dependencies, put them into the
2629
appropriate ``f2c_*.f`` files, run ``f2c`` over them, then do some scrubbing

numpy/linalg/lapack_lite/clapack_scrub.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python2.7
2+
# WARNING! This a Python 2 script. Read README.rst for rationale.
23
import os
34
import re
45
import sys
5-
from io import StringIO
66

77
from plex import Scanner, Str, Lexicon, Opt, Bol, State, AnyChar, TEXT, IGNORE
88
from plex.traditional import re as Re
99

10+
try:
11+
from io import BytesIO as UStringIO # Python 2
12+
except ImportError:
13+
from io import StringIO as UStringIO # Python 3
14+
1015

1116
class MyScanner(Scanner):
1217
def __init__(self, info, name='<default>'):
@@ -22,8 +27,8 @@ def sep_seq(sequence, sep):
2227
return pat
2328

2429
def runScanner(data, scanner_class, lexicon=None):
25-
info = StringIO(data)
26-
outfo = StringIO()
30+
info = UStringIO(data)
31+
outfo = UStringIO()
2732
if lexicon is not None:
2833
scanner = scanner_class(lexicon, info)
2934
else:
@@ -190,7 +195,7 @@ def HaveBlankLines(line):
190195
return SourceLines
191196

192197
state = SourceLines
193-
for line in StringIO(source):
198+
for line in UStringIO(source):
194199
state = state(line)
195200
comments.flushTo(lines)
196201
return lines.getValue()
@@ -218,7 +223,7 @@ def OutOfHeader(line):
218223
return OutOfHeader
219224

220225
state = LookingForHeader
221-
for line in StringIO(source):
226+
for line in UStringIO(source):
222227
state = state(line)
223228
return lines.getValue()
224229

@@ -227,7 +232,7 @@ def removeSubroutinePrototypes(source):
227232
r'/\* Subroutine \*/^\s*(?:(?:inline|static)\s+){0,2}(?!else|typedef|return)\w+\s+\*?\s*(\w+)\s*\([^0]+\)\s*;?'
228233
)
229234
lines = LineQueue()
230-
for line in StringIO(source):
235+
for line in UStringIO(source):
231236
if not expression.match(line):
232237
lines.add(line)
233238

@@ -249,7 +254,7 @@ def InBuiltInFunctions(line):
249254
return InBuiltInFunctions
250255

251256
state = LookingForBuiltinFunctions
252-
for line in StringIO(source):
257+
for line in UStringIO(source):
253258
state = state(line)
254259
return lines.getValue()
255260

numpy/linalg/lapack_lite/fortran.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# WARNING! This a Python 2 script. Read README.rst for rationale.
12
import re
23
import itertools
34

@@ -44,6 +45,8 @@ def __next__(self):
4445
line = line.rstrip()
4546
return line
4647

48+
next = __next__
49+
4750

4851
class PushbackIterator:
4952
"""PushbackIterator(iterable)
@@ -69,6 +72,8 @@ def __next__(self):
6972
def pushback(self, item):
7073
self.buffer.append(item)
7174

75+
next = __next__
76+
7277

7378
def fortranSourceLines(fo):
7479
"""Return an iterator over statement lines of a Fortran source file.

numpy/linalg/lapack_lite/make_lite.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python2.7
2+
# WARNING! This a Python 2 script. Read README.rst for rationale.
23
"""
34
Usage: make_lite.py <wrapped_routines_file> <lapack_dir>
45
@@ -20,7 +21,10 @@
2021
import fortran
2122
import clapack_scrub
2223

23-
from shutil import which
24+
try:
25+
from distutils.spawn import find_executable as which # Python 2
26+
except ImportError:
27+
from shutil import which # Python 3
2428

2529
# Arguments to pass to f2c. You'll always want -A for ANSI C prototypes
2630
# Others of interest: -a to not make variables static by default
@@ -81,7 +85,8 @@ def dependencies(self):
8185
return self._dependencies
8286

8387
def __repr__(self):
84-
return f'FortranRoutine({self.name!r}, filename={self.filename!r})'
88+
return "FortranRoutine({!r}, filename={!r})".format(self.name,
89+
self.filename)
8590

8691
class UnknownFortranRoutine(FortranRoutine):
8792
"""Wrapper for a Fortran routine for which the corresponding file
@@ -193,7 +198,7 @@ def allRoutinesByType(self, typename):
193198
def printRoutineNames(desc, routines):
194199
print(desc)
195200
for r in routines:
196-
print(f'\t{r.name}')
201+
print('\t%s' % r.name)
197202

198203
def getLapackRoutines(wrapped_routines, ignores, lapack_dir):
199204
blas_src_dir = os.path.join(lapack_dir, 'BLAS', 'SRC')
@@ -243,7 +248,7 @@ def dumpRoutineNames(library, output_dir):
243248
with open(filename, 'w') as fo:
244249
for r in routines:
245250
deps = r.dependencies()
246-
fo.write(f"{r.name}: {' '.join(deps)}\n")
251+
fo.write('%s: %s\n' % (r.name, ' '.join(deps)))
247252

248253
def concatenateRoutines(routines, output_file):
249254
with open(output_file, 'w') as output_fo:
@@ -261,8 +266,8 @@ def runF2C(fortran_filename, output_dir):
261266
subprocess.check_call(
262267
["f2c"] + F2C_ARGS + ['-d', output_dir, fortran_filename]
263268
)
264-
except subprocess.CalledProcessError as e:
265-
raise F2CError from e
269+
except subprocess.CalledProcessError:
270+
raise F2CError
266271

267272
def scrubF2CSource(c_file):
268273
with open(c_file) as fo:
@@ -275,8 +280,8 @@ def scrubF2CSource(c_file):
275280
def ensure_executable(name):
276281
try:
277282
which(name)
278-
except Exception as ex:
279-
raise SystemExit(name + ' not found') from ex
283+
except Exception:
284+
raise SystemExit(name + ' not found')
280285

281286
def create_name_header(output_dir):
282287
routine_re = re.compile(r'^ (subroutine|.* function)\s+(\w+)\(.*$',
@@ -316,13 +321,13 @@ def create_name_header(output_dir):
316321

317322
# Rename BLAS/LAPACK symbols
318323
for name in sorted(symbols):
319-
f.write(f'#define {name}_ BLAS_FUNC({name})\n')
324+
f.write("#define %s_ BLAS_FUNC(%s)\n" % (name, name))
320325

321326
# Rename also symbols that f2c exports itself
322327
f.write("\n"
323328
"/* Symbols exported by f2c.c */\n")
324329
for name in sorted(f2c_symbols):
325-
f.write(f'#define {name} numpy_lapack_lite_{name}\n')
330+
f.write("#define %s numpy_lapack_lite_%s\n" % (name, name))
326331

327332
def main():
328333
if len(sys.argv) != 3:
@@ -348,21 +353,21 @@ def main():
348353
dumpRoutineNames(library, output_dir)
349354

350355
for typename in types:
351-
fortran_file = os.path.join(output_dir, f'f2c_{typename}.f')
356+
fortran_file = os.path.join(output_dir, 'f2c_%s.f' % typename)
352357
c_file = fortran_file[:-2] + '.c'
353-
print(f'creating {c_file} ...')
358+
print('creating %s ...' % c_file)
354359
routines = library.allRoutinesByType(typename)
355360
concatenateRoutines(routines, fortran_file)
356361

357362
# apply the patchpatch
358363
patch_file = os.path.basename(fortran_file) + '.patch'
359364
if os.path.exists(patch_file):
360365
subprocess.check_call(['patch', '-u', fortran_file, patch_file])
361-
print(f'Patched {fortran_file}')
366+
print("Patched {}".format(fortran_file))
362367
try:
363368
runF2C(fortran_file, output_dir)
364369
except F2CError:
365-
print(f'f2c failed on {fortran_file}')
370+
print('f2c failed on %s' % fortran_file)
366371
break
367372
scrubF2CSource(c_file)
368373

0 commit comments

Comments
 (0)