python/cpython · error · TypeError

{size!r} is not an integer

Error message

{size!r} is not an integer

What it means

Raised by IOBase.readline (Lib/_pyio.py:542) when the size argument does not implement __index__ (i.e. cannot be interpreted as an integer). The pure-Python io layer is strict: it converts size via size.__index__ and raises TypeError if that attribute is missing. This rejects floats, strings, or arbitrary objects passed as readline's size limit.

Source

Thrown at Lib/_pyio.py:542

        if hasattr(self, "peek"):
            def nreadahead():
                readahead = self.peek(1)
                if not readahead:
                    return 1
                n = (readahead.find(b"\n") + 1) or len(readahead)
                if size >= 0:
                    n = min(n, size)
                return n
        else:
            def nreadahead():
                return 1
        if size is None:
            size = -1
        else:
            try:
                size_index = size.__index__
            except AttributeError:
                raise TypeError(f"{size!r} is not an integer")
            else:
                size = size_index()
        res = bytearray()
        while size < 0 or len(res) < size:
            b = self.read(nreadahead())
            if not b:
                break
            res += b
            if res.endswith(b"\n"):
                break
        return res.take_bytes()

    def __iter__(self):
        self._checkClosed()
        return self

    def __next__(self):
        line = self.readline()

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Convert the value before the call: `f.readline(int(size))`.
  2. Use operator.index(size) if you want non-int integer-like types (numpy ints, enum IntEnum) to pass through unchanged.
  3. Validate at the API boundary that size is an int (isinstance check) and reject or coerce early.

Example fix

# before
line = f.readline(max_len / 2)  # float -> TypeError

# after
line = f.readline(max_len // 2)  # int
Defensive patterns

Strategy: validation

Validate before calling

from operator import index
size = index(user_size)  # raises TypeError early with clear context
line = f.readline(size)

Type guard

def is_indexable(v) -> bool:
    return hasattr(v, '__index__')

Try / catch

try:
    line = f.readline(size)
except TypeError:
    line = f.readline(int(size))  # coerce and retry

Prevention

When it happens

Trigger: f.readline(1024.0) or f.readline('16'); passing a size computed by len()/division that yielded a float; forwarding an unvalidated user-supplied size parameter to readline.

Common situations: Computing a size with true division (`total / 2` instead of `total // 2`); API wrappers that accept a size hint from JSON or query strings and pass it through unconverted; numpy integer scalars (these do work via __index__, but numpy floats do not).

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/872ae88fdbd663a9. Report an issue: GitHub.