# Io Wrapper

> Wrap file-like objects with read/write counters. Use when implementing IO wrappers, tracking file access, or counting bytes read/written through a proxy.

- Skill: `knoopx/io-wrapper` (Agent Skill)
- Install (CLI): `npx skillmds@latest add knoopx/io-wrapper`
- Raw SKILL.md: https://api.skillmd.com/api/skills/knoopx/io-wrapper/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: knoopx (https://skillmd.com/u/knoopx)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/knoopx/io-wrapper

---


## When to use

To wrap a file-like object and count reads/writes.

## Rules

- Store the wrapped object as self.\_wrapped
- Implement read(size=-1) by delegating to self.\_wrapped.read(size)
- Increment counters by the length of the RETURNED bytes, NOT the requested size
- For write: increment nwrites by the RETURN VALUE, or by len(data) if the wrapped write returns None
- Expose read_bytes/nreads and write_bytes/nwrites as properties or attributes
- **enter** returns self; **exit** calls self.\_wrapped.**exit** (or close()) and forwards the exception info
- ALWAYS implement close() as a plain method for non-context-manager use
- NEVER count requested bytes — only count what was actually returned/written

## Edge cases

Thread safety: if the test uses threads, wrap counter updates in a threading.Lock.

## Example

```python
class MetaRead:
    def __init__(self, wrapped): self._wrapped = wrapped; self.nreads = 0
    def read(self, size=-1):
        data = self._wrapped.read(size)
        self.nreads += len(data)  # count returned bytes, not requested
        return data
```

