src/pylib/Lib/io

Search:
Group by:
Source   Edit  

NOTE: not support js currently

different from Python

open

Its param: closefd, opener is not implemented yet

seek

There is difference that Python's TextIOBase.seek will reset state of encoder at some conditions, while Nim doesn't have access to encoder's state Therefore, seek here doesn't change that

iter over file

Python's __next__ will yield newline as part of result but Nim's iterator lines does not

Types

BufferedIOBase = ref object of IOBase
Source   Edit  
BufferedRandom = ref object of BufferedIOBase
Source   Edit  
BufferedReader = ref object of BufferedIOBase
Source   Edit  
BufferedWriter = ref object of BufferedIOBase
Source   Edit  
FileIO = ref object of RawIOBase
Source   Edit  
IOBase = ref object of RootObj
  closed*: bool
  
Source   Edit  
NoEncTextIOBase = ref object of IOBase
  
no encoding conversion is performed on underlying file. used for those stream whose encoding is alreadly utf-8 Source   Edit  
NoEncTextIOWrapper = ref object of NoEncTextIOBase
  name*: PyStr
  mode*: PyStr
Source   Edit  
RawIOBase = ref object of IOBase
Source   Edit  
TextIOWrapper = ref object of NoEncTextIOWrapper
  ## do not use string, so is always valid
  
Source   Edit  
UnsupportedOperation = object of OSError
Source   Edit  

Consts

DefEncoding = ""
Source   Edit  
DefNewLine = "None"
here it's used to mean open(...newline=None) in Python (i.e. Universial NewLine) Source   Edit  
LocaleEncoding = "locale"
Source   Edit  
SEEK_CUR = 1
Source   Edit  
SEEK_END = 2
Source   Edit  
SEEK_SET = 0
Source   Edit  

Procs

func encoding(s: TextIOWrapper): PyStr {....raises: [], tags: [], forbids: [].}
Source   Edit  
func errors(s: TextIOWrapper): PyStr {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc fileno(f: IOBase): int {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc flush(f: IOBase) {....raises: [], tags: [WriteIOEffect], forbids: [].}
Source   Edit  
proc initBufAsPy(nfile: var File; buf: int) {....raises: [], tags: [], forbids: [].}
init buffering as Python's Source   Edit  
func isatty(f: IOBase): bool {....raises: [], tags: [], forbids: [].}
Source   Edit  
proc newNoEncTextIO(file: File; name: string; newline = DefNewLine): NoEncTextIOWrapper {.
    ...raises: [ValueError], tags: [], forbids: [].}
Source   Edit  
proc raiseOsOrFileNotFoundError(file: int) {....raises: [OSError], tags: [],
    forbids: [].}
Source   Edit  
proc raiseOsOrFileNotFoundError[T](file: PathLike[T])
Source   Edit  
proc read(self: NoEncTextIOWrapper): PyStr {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
Source   Edit  
proc read(self: NoEncTextIOWrapper; size: int): PyStr {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
Source   Edit  
proc read(self: RawIOBase): PyBytes {....raises: [IOError], tags: [ReadIOEffect],
                                      forbids: [].}
Source   Edit  
proc read(self: RawIOBase; size: int): PyBytes {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
Source   Edit  
proc read(self: TextIOWrapper): PyStr {....raises: [IOError, Exception],
                                        tags: [ReadIOEffect, RootEffect],
                                        forbids: [].}
Source   Edit  
proc read(self: TextIOWrapper; size: int): PyStr {....raises: [IOError, Exception],
    tags: [ReadIOEffect, RootEffect], forbids: [].}
Source   Edit  
proc readline(self: NoEncTextIOWrapper): PyStr {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
Source   Edit  
proc readline(self: NoEncTextIOWrapper; size: int): PyStr {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
..warning:: size is currently in bytes, not in characters Source   Edit  
proc readline(self: RawIOBase): PyBytes {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
Source   Edit  
proc readline(self: RawIOBase; size: Natural): PyBytes {....raises: [IOError],
    tags: [ReadIOEffect], forbids: [].}
Source   Edit  
proc readline(self: TextIOWrapper): PyStr {....raises: [IOError, Exception],
    tags: [ReadIOEffect, RootEffect], forbids: [].}
Python's readline

Example:

import std/strutils
const fn = "tempfiletest"
proc check(ls: varargs[string], newline: string) =
  var f = open(fn, newline=newline)
  for l in ls:
    let s = f.readline()
    assert s == l, 
      "expected $#, but got $#, with newline=$#" % [l.repr, s.repr, newline.repr]
    
  f.close()

writeFile fn, "abc\r\n123\n-\r_"

check "abc\n", "123\n", "-\n", "_", newline=DefNewLine
check "abc\r\n", "123\n", "-\r", "_", newline=""
check "abc\r", "\n123\n-\r", "_", newline="\r"
check "abc\r\n", "123\n", "-\r_", newline="\n"
check "abc\r\n", "123\n-\r_", newline="\r\n"
Source   Edit  
proc readline(self: TextIOWrapper; size: Natural): PyStr {.
    ...raises: [IOError, Exception], tags: [ReadIOEffect, RootEffect], forbids: [].}
Source   Edit  
func tell(f: IOBase): int64 {....raises: [IOError], tags: [], forbids: [].}
Source   Edit  
proc truncate(self: IOBase): int {.discardable, ...raises: [IOError, OSError],
                                   tags: [], forbids: [].}

Example:

const fn = "tempfiletest"
var f = open(fn, "w+")
discard f.write("123")
f.seek(0)
f.truncate()
assert f.read() == ""
f.close()
Source   Edit  
proc truncate(self: IOBase; size: int64): int64 {.discardable,
    ...raises: [OSError], tags: [], forbids: [].}
Source   Edit  
proc write(self: NoEncTextIOWrapper; s: PyStr): int {.discardable,
    ...raises: [Exception], tags: [RootEffect], forbids: [].}
Source   Edit  
proc write(self: RawIOBase; s: PyBytes): int {.discardable, ...raises: [IOError],
    tags: [WriteIOEffect], forbids: [].}
Source   Edit  
proc write(self: TextIOWrapper; s: PyStr): int {.discardable,
    ...raises: [Exception], tags: [RootEffect], forbids: [].}

Writes the s to the stream and return the number of characters written

The following is from Python's doc of open: if newline is None, any 'n' characters written are translated to the system default line separator, os.linesep. If newline is "" or 'n', no translation takes place. If newline is any of the other legal values, any 'n' characters written are translated to the given string.

Example:

const fn = "tempfiletest"
proc checkW(s, dest: string, newline=DefNewLine, encoding=DefEncoding;
    writeLen=dest.len  # dest.len returns bytes size
  ) =
  var f = open(fn, 'w', newline=newline, encoding=encoding)
  assert writeLen == f.write s
  f.close()
  let res = readFile fn
  assert dest == res, "expected "&dest.repr&" but got "&res.repr
checkW "1\n2", when defined(windows): "1\r\n2" else: "1\n2"
checkW "1\n2", "1\p2"  # same as above
checkW "1\n2", "1\r2", newline="\r"
checkW "我", "我", encoding="utf-8", writeLen=1
Source   Edit  

Methods

method close(self: IOBase) {.base, ...raises: [], tags: [], forbids: [].}
Source   Edit  
method close(self: RawIOBase) {....raises: [], tags: [], forbids: [].}
Source   Edit  
method close(self: TextIOWrapper) {....raises: [Exception], tags: [RootEffect],
                                    forbids: [].}
Source   Edit  
method seek(f: IOBase; cookie: int64; whence = SEEK_SET): int64 {.base,
    discardable, ...raises: [IOError], tags: [], forbids: [].}
Source   Edit  
method seek(self: TextIOWrapper; cookie: int64; whence = SEEK_SET): int64 {.
    discardable, ...raises: [ValueError, UnsupportedOperation, IOError, Exception],
    tags: [WriteIOEffect, RootEffect], forbids: [].}

Example:

var f = open("tempfiletest", 'w')
doAssertRaises UnsupportedOperation:
  f.seek(1, SEEK_CUR)
f.close()
Source   Edit  

Templates

template open(file: int; mode: static[string | char] = "r"; buffering: int = -1;
              encoding: string = DefEncoding; errors: string = DefErrors;
              newline: string | char = DefNewLine): untyped
Source   Edit  
template open[S](file: PathLike[S]; mode: static[string | char] = "r";
                 buffering: int = -1; encoding: string = DefEncoding;
                 errors: string = DefErrors; newline: string | char = DefNewLine): untyped
WARN:
  • line buffering is not support for Win32
  • errors is not just ignored, always 'strict'

Example:

const fn = "tempfiletest"
const nonfn = r"   \:/ $&* "
doAssertRaises LookupError:
  # raise LookupError instead of FileNotFoundError (like Python)
  discard open(nonfn, encoding="this is a invalid enc")
doAssertRaises FileNotFoundError:
  discard io.open(nonfn)  # an invalid filename, never existing
block Write:
  var f = open(fn, "w",  encoding="utf-8")
  let ret = f.write("123\r\n")
  when defined(windows):
    assert ret == 6  # Universal Newline, written "123\r\r\n"
  else:
    assert ret == 5  # written "123\r\n"
  assert not f.closed
  f.close()
  assert f.closed
  assert readFile(fn) == (when defined(windows):"123\r\r\n" else:"123\r\n")
block Read:
  var f = open(fn, 'r')
  let uniLineRes = f.read() # Universal Newline, "123\r\n\n" -> "123\n\n"
  assert uniLineRes == (when defined(windows):"123\n\n" else:"123\n")
  f.close()
Source   Edit