@@ -6206,6 +6206,74 @@ def __setattr__(self, name, value):
62066206 object.__setattr__(self, name, value); return
62076207 object.__setattr__(self, name, value)
62086208
6209+ # ========= shared utilities =========
6210+
6211+ def _maybe_make_mmap(fp_like, mode, use_mmap=False, mmap_size=None):
6212+ """
6213+ If use_mmap is True and fp_like ultimately has a real fileno(),
6214+ return (fp_like, mm) where mm is an mmap.mmap for the whole file (read)
6215+ or a pre-sized mapping (write). Otherwise return (fp_like, None).
6216+ """
6217+ if not use_mmap:
6218+ return fp_like, None
6219+
6220+ base = _extract_base_fp(fp_like)
6221+ if base is None:
6222+ return fp_like, None # BytesIO / compressed stream etc.
6223+
6224+ import mmap
6225+ # READ mapping: map entire file (size 0 means "whole file")
6226+ if "r" in mode and "w" not in mode and "a" not in mode and "x" not in mode:
6227+ try:
6228+ mm = mmap.mmap(base.fileno(), 0, access=mmap.ACCESS_READ)
6229+ return fp_like, mm
6230+ except Exception:
6231+ return fp_like, None
6232+
6233+ # WRITE mapping: must pre-size
6234+ if any(ch in mode for ch in "wax+"):
6235+ if not mmap_size or mmap_size <= 0:
6236+ # caller must provide a mapping length for writes
6237+ return fp_like, None
6238+ try:
6239+ # Ensure the underlying file is opened read+write
6240+ # (re-open if needed)
6241+ try:
6242+ fd = base.fileno()
6243+ except Exception:
6244+ return fp_like, None
6245+
6246+ # Make sure file is large enough
6247+ try:
6248+ base.truncate(mmap_size)
6249+ except Exception:
6250+ return fp_like, None
6251+
6252+ mm = mmap.mmap(fd, mmap_size, access=mmap.ACCESS_WRITE)
6253+ return fp_like, mm
6254+ except Exception:
6255+ return fp_like, None
6256+
6257+ return fp_like, None
6258+
6259+
6260+ def open_adapter(obj_or_path, mode="rb", use_mmap=False, mmap_size=None):
6261+ """
6262+ Universal opener:
6263+ - If given a path (str/bytes), open it with built-in open().
6264+ - If given a file-like, use it as-is.
6265+ Returns a FileLikeAdapter, optionally mmap-backed (only when possible).
6266+ """
6267+ is_path = isinstance(obj_or_path, (str, bytes))
6268+ if is_path:
6269+ fp = open(obj_or_path, mode)
6270+ fp, mm = _maybe_make_mmap(fp, mode, use_mmap=use_mmap, mmap_size=mmap_size)
6271+ return FileLikeAdapter(fp, mode=mode, mm=mm)
6272+
6273+ # file-like object
6274+ fp_like = obj_or_path
6275+ fp_like, mm = _maybe_make_mmap(fp_like, mode, use_mmap=use_mmap, mmap_size=mmap_size)
6276+ return FileLikeAdapter(fp_like, mode=mode, mm=mm)
62096277
62106278# Assumes you already have: compressionsupport, outextlistwd, MkTempFile, etc.
62116279
0 commit comments