python/cpython · error · TypeError

{pos!r} is not an integer

Error message

{pos!r} is not an integer

What it means

BytesIO.seek (Lib/_pyio.py:981) converts its pos argument via pos.__index__ and raises TypeError('{pos!r} is not an integer') when the attribute is absent. Only true integers or index-implementing types (numpy ints, IntEnum) are accepted; floats and strings are not.

Source

Thrown at Lib/_pyio.py:981

            if n == 0:
                return 0

            with self._lock:
                pos = self._pos
                if pos > len(self._buffer):
                    # Pad buffer to pos with null bytes.
                    self._buffer.resize(pos)
                self._buffer[pos:pos + n] = view
                self._pos += n
            return n

    def seek(self, pos, whence=0):
        if self.closed:
            raise ValueError("seek on closed file")
        try:
            pos_index = pos.__index__
        except AttributeError:
            raise TypeError(f"{pos!r} is not an integer")
        else:
            pos = pos_index()
        if whence == 0:
            if pos < 0:
                raise ValueError("negative seek position %r" % (pos,))
            self._pos = pos
        elif whence == 1:
            with self._lock:
                self._pos = max(0, self._pos + pos)
        elif whence == 2:
            with self._lock:
                self._pos = max(0, len(self._buffer) + pos)
        else:
            raise ValueError("unsupported whence value")
        return self._pos

    def tell(self):
        if self.closed:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Coerce to int: `buf.seek(int(pos))`.
  2. Use `//` for offset arithmetic.
  3. Normalize numeric config/protocol fields to int at parse time.

Example fix

# before
offset = len(prefix) / 2
buf.seek(offset)  # TypeError: 5.0 is not an integer

# after
offset = len(prefix) // 2
buf.seek(offset)
Defensive patterns

Strategy: validation

Validate before calling

from operator import index
pos = index(pos)  # or int(pos)
buf.seek(pos)

Type guard

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

Try / catch

try:
    buf.seek(pos)
except TypeError:
    buf.seek(int(pos))  # coerce and retry

Prevention

When it happens

Trigger: buf.seek(offset / 2) with true division; buf.seek('0') from a parsed string header; passing a float default (0.0) or Decimal position.

Common situations: Offset arithmetic using '/'; offsets decoded from text protocols; config values loaded from YAML/JSON as floats (e.g. 0.0) and passed to seek.

Related errors


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