ยปCore Development>Code coverage>Lib/fileinput.py

Python code coverage for Lib/fileinput.py

#countcontent
1n/a"""Helper class to quickly write a loop over all standard input files.
2n/a
3n/aTypical use is:
4n/a
5n/a import fileinput
6n/a for line in fileinput.input():
7n/a process(line)
8n/a
9n/aThis iterates over the lines of all files listed in sys.argv[1:],
10n/adefaulting to sys.stdin if the list is empty. If a filename is '-' it
11n/ais also replaced by sys.stdin. To specify an alternative list of
12n/afilenames, pass it as the argument to input(). A single file name is
13n/aalso allowed.
14n/a
15n/aFunctions filename(), lineno() return the filename and cumulative line
16n/anumber of the line that has just been read; filelineno() returns its
17n/aline number in the current file; isfirstline() returns true iff the
18n/aline just read is the first line of its file; isstdin() returns true
19n/aiff the line was read from sys.stdin. Function nextfile() closes the
20n/acurrent file so that the next iteration will read the first line from
21n/athe next file (if any); lines not read from the file will not count
22n/atowards the cumulative line count; the filename is not changed until
23n/aafter the first line of the next file has been read. Function close()
24n/acloses the sequence.
25n/a
26n/aBefore any lines have been read, filename() returns None and both line
27n/anumbers are zero; nextfile() has no effect. After all lines have been
28n/aread, filename() and the line number functions return the values
29n/apertaining to the last line read; nextfile() has no effect.
30n/a
31n/aAll files are opened in text mode by default, you can override this by
32n/asetting the mode parameter to input() or FileInput.__init__().
33n/aIf an I/O error occurs during opening or reading a file, the OSError
34n/aexception is raised.
35n/a
36n/aIf sys.stdin is used more than once, the second and further use will
37n/areturn no lines, except perhaps for interactive use, or if it has been
38n/aexplicitly reset (e.g. using sys.stdin.seek(0)).
39n/a
40n/aEmpty files are opened and immediately closed; the only time their
41n/apresence in the list of filenames is noticeable at all is when the
42n/alast file opened is empty.
43n/a
44n/aIt is possible that the last line of a file doesn't end in a newline
45n/acharacter; otherwise lines are returned including the trailing
46n/anewline.
47n/a
48n/aClass FileInput is the implementation; its methods filename(),
49n/alineno(), fileline(), isfirstline(), isstdin(), nextfile() and close()
50n/acorrespond to the functions in the module. In addition it has a
51n/areadline() method which returns the next input line, and a
52n/a__getitem__() method which implements the sequence behavior. The
53n/asequence must be accessed in strictly sequential order; sequence
54n/aaccess and readline() cannot be mixed.
55n/a
56n/aOptional in-place filtering: if the keyword argument inplace=1 is
57n/apassed to input() or to the FileInput constructor, the file is moved
58n/ato a backup file and standard output is directed to the input file.
59n/aThis makes it possible to write a filter that rewrites its input file
60n/ain place. If the keyword argument backup=".<some extension>" is also
61n/agiven, it specifies the extension for the backup file, and the backup
62n/afile remains around; by default, the extension is ".bak" and it is
63n/adeleted when the output file is closed. In-place filtering is
64n/adisabled when standard input is read. XXX The current implementation
65n/adoes not work for MS-DOS 8+3 filesystems.
66n/a
67n/aXXX Possible additions:
68n/a
69n/a- optional getopt argument processing
70n/a- isatty()
71n/a- read(), read(size), even readlines()
72n/a
73n/a"""
74n/a
75n/aimport sys, os
76n/a
77n/a__all__ = ["input", "close", "nextfile", "filename", "lineno", "filelineno",
78n/a "fileno", "isfirstline", "isstdin", "FileInput", "hook_compressed",
79n/a "hook_encoded"]
80n/a
81n/a_state = None
82n/a
83n/adef input(files=None, inplace=False, backup="", bufsize=0,
84n/a mode="r", openhook=None):
85n/a """Return an instance of the FileInput class, which can be iterated.
86n/a
87n/a The parameters are passed to the constructor of the FileInput class.
88n/a The returned instance, in addition to being an iterator,
89n/a keeps global state for the functions of this module,.
90n/a """
91n/a global _state
92n/a if _state and _state._file:
93n/a raise RuntimeError("input() already active")
94n/a _state = FileInput(files, inplace, backup, bufsize, mode, openhook)
95n/a return _state
96n/a
97n/adef close():
98n/a """Close the sequence."""
99n/a global _state
100n/a state = _state
101n/a _state = None
102n/a if state:
103n/a state.close()
104n/a
105n/adef nextfile():
106n/a """
107n/a Close the current file so that the next iteration will read the first
108n/a line from the next file (if any); lines not read from the file will
109n/a not count towards the cumulative line count. The filename is not
110n/a changed until after the first line of the next file has been read.
111n/a Before the first line has been read, this function has no effect;
112n/a it cannot be used to skip the first file. After the last line of the
113n/a last file has been read, this function has no effect.
114n/a """
115n/a if not _state:
116n/a raise RuntimeError("no active input()")
117n/a return _state.nextfile()
118n/a
119n/adef filename():
120n/a """
121n/a Return the name of the file currently being read.
122n/a Before the first line has been read, returns None.
123n/a """
124n/a if not _state:
125n/a raise RuntimeError("no active input()")
126n/a return _state.filename()
127n/a
128n/adef lineno():
129n/a """
130n/a Return the cumulative line number of the line that has just been read.
131n/a Before the first line has been read, returns 0. After the last line
132n/a of the last file has been read, returns the line number of that line.
133n/a """
134n/a if not _state:
135n/a raise RuntimeError("no active input()")
136n/a return _state.lineno()
137n/a
138n/adef filelineno():
139n/a """
140n/a Return the line number in the current file. Before the first line
141n/a has been read, returns 0. After the last line of the last file has
142n/a been read, returns the line number of that line within the file.
143n/a """
144n/a if not _state:
145n/a raise RuntimeError("no active input()")
146n/a return _state.filelineno()
147n/a
148n/adef fileno():
149n/a """
150n/a Return the file number of the current file. When no file is currently
151n/a opened, returns -1.
152n/a """
153n/a if not _state:
154n/a raise RuntimeError("no active input()")
155n/a return _state.fileno()
156n/a
157n/adef isfirstline():
158n/a """
159n/a Returns true the line just read is the first line of its file,
160n/a otherwise returns false.
161n/a """
162n/a if not _state:
163n/a raise RuntimeError("no active input()")
164n/a return _state.isfirstline()
165n/a
166n/adef isstdin():
167n/a """
168n/a Returns true if the last line was read from sys.stdin,
169n/a otherwise returns false.
170n/a """
171n/a if not _state:
172n/a raise RuntimeError("no active input()")
173n/a return _state.isstdin()
174n/a
175n/aclass FileInput:
176n/a """FileInput([files[, inplace[, backup[, bufsize, [, mode[, openhook]]]]]])
177n/a
178n/a Class FileInput is the implementation of the module; its methods
179n/a filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),
180n/a nextfile() and close() correspond to the functions of the same name
181n/a in the module.
182n/a In addition it has a readline() method which returns the next
183n/a input line, and a __getitem__() method which implements the
184n/a sequence behavior. The sequence must be accessed in strictly
185n/a sequential order; random access and readline() cannot be mixed.
186n/a """
187n/a
188n/a def __init__(self, files=None, inplace=False, backup="", bufsize=0,
189n/a mode="r", openhook=None):
190n/a if isinstance(files, str):
191n/a files = (files,)
192n/a else:
193n/a if files is None:
194n/a files = sys.argv[1:]
195n/a if not files:
196n/a files = ('-',)
197n/a else:
198n/a files = tuple(files)
199n/a self._files = files
200n/a self._inplace = inplace
201n/a self._backup = backup
202n/a if bufsize:
203n/a import warnings
204n/a warnings.warn('bufsize is deprecated and ignored',
205n/a DeprecationWarning, stacklevel=2)
206n/a self._savestdout = None
207n/a self._output = None
208n/a self._filename = None
209n/a self._startlineno = 0
210n/a self._filelineno = 0
211n/a self._file = None
212n/a self._isstdin = False
213n/a self._backupfilename = None
214n/a # restrict mode argument to reading modes
215n/a if mode not in ('r', 'rU', 'U', 'rb'):
216n/a raise ValueError("FileInput opening mode must be one of "
217n/a "'r', 'rU', 'U' and 'rb'")
218n/a if 'U' in mode:
219n/a import warnings
220n/a warnings.warn("'U' mode is deprecated",
221n/a DeprecationWarning, 2)
222n/a self._mode = mode
223n/a if openhook:
224n/a if inplace:
225n/a raise ValueError("FileInput cannot use an opening hook in inplace mode")
226n/a if not callable(openhook):
227n/a raise ValueError("FileInput openhook must be callable")
228n/a self._openhook = openhook
229n/a
230n/a def __del__(self):
231n/a self.close()
232n/a
233n/a def close(self):
234n/a try:
235n/a self.nextfile()
236n/a finally:
237n/a self._files = ()
238n/a
239n/a def __enter__(self):
240n/a return self
241n/a
242n/a def __exit__(self, type, value, traceback):
243n/a self.close()
244n/a
245n/a def __iter__(self):
246n/a return self
247n/a
248n/a def __next__(self):
249n/a while True:
250n/a line = self._readline()
251n/a if line:
252n/a self._filelineno += 1
253n/a return line
254n/a if not self._file:
255n/a raise StopIteration
256n/a self.nextfile()
257n/a # repeat with next file
258n/a
259n/a def __getitem__(self, i):
260n/a if i != self.lineno():
261n/a raise RuntimeError("accessing lines out of order")
262n/a try:
263n/a return self.__next__()
264n/a except StopIteration:
265n/a raise IndexError("end of input reached")
266n/a
267n/a def nextfile(self):
268n/a savestdout = self._savestdout
269n/a self._savestdout = None
270n/a if savestdout:
271n/a sys.stdout = savestdout
272n/a
273n/a output = self._output
274n/a self._output = None
275n/a try:
276n/a if output:
277n/a output.close()
278n/a finally:
279n/a file = self._file
280n/a self._file = None
281n/a try:
282n/a del self._readline # restore FileInput._readline
283n/a except AttributeError:
284n/a pass
285n/a try:
286n/a if file and not self._isstdin:
287n/a file.close()
288n/a finally:
289n/a backupfilename = self._backupfilename
290n/a self._backupfilename = None
291n/a if backupfilename and not self._backup:
292n/a try: os.unlink(backupfilename)
293n/a except OSError: pass
294n/a
295n/a self._isstdin = False
296n/a
297n/a def readline(self):
298n/a while True:
299n/a line = self._readline()
300n/a if line:
301n/a self._filelineno += 1
302n/a return line
303n/a if not self._file:
304n/a return line
305n/a self.nextfile()
306n/a # repeat with next file
307n/a
308n/a def _readline(self):
309n/a if not self._files:
310n/a if 'b' in self._mode:
311n/a return b''
312n/a else:
313n/a return ''
314n/a self._filename = self._files[0]
315n/a self._files = self._files[1:]
316n/a self._startlineno = self.lineno()
317n/a self._filelineno = 0
318n/a self._file = None
319n/a self._isstdin = False
320n/a self._backupfilename = 0
321n/a if self._filename == '-':
322n/a self._filename = '<stdin>'
323n/a if 'b' in self._mode:
324n/a self._file = getattr(sys.stdin, 'buffer', sys.stdin)
325n/a else:
326n/a self._file = sys.stdin
327n/a self._isstdin = True
328n/a else:
329n/a if self._inplace:
330n/a self._backupfilename = (
331n/a self._filename + (self._backup or ".bak"))
332n/a try:
333n/a os.unlink(self._backupfilename)
334n/a except OSError:
335n/a pass
336n/a # The next few lines may raise OSError
337n/a os.rename(self._filename, self._backupfilename)
338n/a self._file = open(self._backupfilename, self._mode)
339n/a try:
340n/a perm = os.fstat(self._file.fileno()).st_mode
341n/a except OSError:
342n/a self._output = open(self._filename, "w")
343n/a else:
344n/a mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
345n/a if hasattr(os, 'O_BINARY'):
346n/a mode |= os.O_BINARY
347n/a
348n/a fd = os.open(self._filename, mode, perm)
349n/a self._output = os.fdopen(fd, "w")
350n/a try:
351n/a if hasattr(os, 'chmod'):
352n/a os.chmod(self._filename, perm)
353n/a except OSError:
354n/a pass
355n/a self._savestdout = sys.stdout
356n/a sys.stdout = self._output
357n/a else:
358n/a # This may raise OSError
359n/a if self._openhook:
360n/a self._file = self._openhook(self._filename, self._mode)
361n/a else:
362n/a self._file = open(self._filename, self._mode)
363n/a self._readline = self._file.readline # hide FileInput._readline
364n/a return self._readline()
365n/a
366n/a def filename(self):
367n/a return self._filename
368n/a
369n/a def lineno(self):
370n/a return self._startlineno + self._filelineno
371n/a
372n/a def filelineno(self):
373n/a return self._filelineno
374n/a
375n/a def fileno(self):
376n/a if self._file:
377n/a try:
378n/a return self._file.fileno()
379n/a except ValueError:
380n/a return -1
381n/a else:
382n/a return -1
383n/a
384n/a def isfirstline(self):
385n/a return self._filelineno == 1
386n/a
387n/a def isstdin(self):
388n/a return self._isstdin
389n/a
390n/a
391n/adef hook_compressed(filename, mode):
392n/a ext = os.path.splitext(filename)[1]
393n/a if ext == '.gz':
394n/a import gzip
395n/a return gzip.open(filename, mode)
396n/a elif ext == '.bz2':
397n/a import bz2
398n/a return bz2.BZ2File(filename, mode)
399n/a else:
400n/a return open(filename, mode)
401n/a
402n/a
403n/adef hook_encoded(encoding, errors=None):
404n/a def openhook(filename, mode):
405n/a return open(filename, mode, encoding=encoding, errors=errors)
406n/a return openhook
407n/a
408n/a
409n/adef _test():
410n/a import getopt
411n/a inplace = False
412n/a backup = False
413n/a opts, args = getopt.getopt(sys.argv[1:], "ib:")
414n/a for o, a in opts:
415n/a if o == '-i': inplace = True
416n/a if o == '-b': backup = a
417n/a for line in input(args, inplace=inplace, backup=backup):
418n/a if line[-1:] == '\n': line = line[:-1]
419n/a if line[-1:] == '\r': line = line[:-1]
420n/a print("%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
421n/a isfirstline() and "*" or "", line))
422n/a print("%d: %s[%d]" % (lineno(), filename(), filelineno()))
423n/a
424n/aif __name__ == '__main__':
425n/a _test()