@@ -6259,6 +6259,74 @@ def __setattr__(self, name, value):
62596259 object.__setattr__(self, name, value); return
62606260 object.__setattr__(self, name, value)
62616261
6262+ # ========= shared utilities =========
6263+
6264+ def _maybe_make_mmap(fp_like, mode, use_mmap=False, mmap_size=None):
6265+ """
6266+ If use_mmap is True and fp_like ultimately has a real fileno(),
6267+ return (fp_like, mm) where mm is an mmap.mmap for the whole file (read)
6268+ or a pre-sized mapping (write). Otherwise return (fp_like, None).
6269+ """
6270+ if not use_mmap:
6271+ return fp_like, None
6272+
6273+ base = _extract_base_fp(fp_like)
6274+ if base is None:
6275+ return fp_like, None # BytesIO / compressed stream etc.
6276+
6277+ import mmap
6278+ # READ mapping: map entire file (size 0 means "whole file")
6279+ if "r" in mode and "w" not in mode and "a" not in mode and "x" not in mode:
6280+ try:
6281+ mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ)
6282+ return fp_like, mm
6283+ except Exception:
6284+ return fp_like, None
6285+
6286+ # WRITE mapping: must pre-size
6287+ if any(ch in mode for ch in "wax+"):
6288+ if not mmap_size or mmap_size <= 0:
6289+ # caller must provide a mapping length for writes
6290+ return fp_like, None
6291+ try:
6292+ # Ensure the underlying file is opened read+write
6293+ # (re-open if needed)
6294+ try:
6295+ fd = base.fileno()
6296+ except Exception:
6297+ return fp_like, None
6298+
6299+ # Make sure file is large enough
6300+ try:
6301+ base.truncate(mmap_size)
6302+ except Exception:
6303+ return fp_like, None
6304+
6305+ mm = mmap.mmap(fd, mmap_size, access=mmap.ACCESS_WRITE)
6306+ return fp_like, mm
6307+ except Exception:
6308+ return fp_like, None
6309+
6310+ return fp_like, None
6311+
6312+
6313+ def open_adapter(obj_or_path, mode="rb", use_mmap=False, mmap_size=None):
6314+ """
6315+ Universal opener:
6316+ - If given a path (str/bytes), open it with built-in open().
6317+ - If given a file-like, use it as-is.
6318+ Returns a FileLikeAdapter, optionally mmap-backed (only when possible).
6319+ """
6320+ is_path = isinstance(obj_or_path, (str, bytes))
6321+ if is_path:
6322+ fp = open(obj_or_path, mode)
6323+ fp, mm = _maybe_make_mmap(fp, mode, use_mmap=use_mmap, mmap_size=mmap_size)
6324+ return FileLikeAdapter(fp, mode=mode, mm=mm)
6325+
6326+ # file-like object
6327+ fp_like = obj_or_path
6328+ fp_like, mm = _maybe_make_mmap(fp_like, mode, use_mmap=use_mmap, mmap_size=mmap_size)
6329+ return FileLikeAdapter(fp_like, mode=mode, mm=mm)
62626330
62636331# Assumes you already have: compressionsupport, outextlistwd, MkTempFile, etc.
62646332
0 commit comments