Skip to content

Latest commit

 

History

History
177 lines (152 loc) · 6.1 KB

File metadata and controls

177 lines (152 loc) · 6.1 KB

I can do this, but I can’t fetch or browse that URL from here. If you paste the source tree (or upload a zip / paste the contents of the src/parallel package), I’ll generate a single consolidated parallel.pyi that mirrors the public API and copies docstrings 1:1.

In the meantime, here are two ways to get me the code with minimal effort, and a ready-to-run script you can use to produce a one-file stub on your side.

Option A (best): Upload a zip

  1. Download the repo (or just the src/parallel folder).
  2. Zip it.
  3. Upload here.
  4. Tell me whether you want only public API (recommended) or everything including private _ stuff.

Option B: Paste key files

At minimum, paste:

  • src/parallel/__init__.py
  • any client.py, types.py, resources/*.py, etc.
  • anything that defines user-facing classes/functions

Option C: Generate a single stub locally and paste it

Run this script locally pointing at your src/parallel directory. It will:

  • import the package
  • walk modules
  • emit a single .pyi containing signatures
  • include docstrings where retrievable (runtime docstrings; if you want 1:1 from source even when not loaded, I can do that too once I have the files)
# save as: make_parallel_stub.py
import ast
import os
import sys
import pkgutil
import importlib
import inspect
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple

def iter_modules(pkg):
    prefix = pkg.__name__ + "."
    yield pkg.__name__
    for m in pkgutil.walk_packages(pkg.__path__, prefix=prefix):
        yield m.name

def safe_import(name: str):
    try:
        return importlib.import_module(name)
    except Exception as e:
        return e

def format_signature(obj) -> str:
    try:
        sig = inspect.signature(obj)
        return str(sig)
    except Exception:
        return "( *args, **kwargs )"

def indent(s: str, n: int = 4) -> str:
    pad = " " * n
    return "\n".join(pad + line if line else line for line in s.splitlines())

def stub_for_module(mod) -> str:
    out: List[str] = []
    name = getattr(mod, "__name__", "<unknown>")
    out.append(f"# --- module: {name} ---")
    doc = inspect.getdoc(mod) or None
    if doc:
        out.append('"""' + doc + '"""')

    members = inspect.getmembers(mod)
    # Prefer explicit __all__ when present
    export = getattr(mod, "__all__", None)
    if isinstance(export, (list, tuple)):
        export_set = set(export)
        members = [m for m in members if m[0] in export_set]

    for k, v in members:
        if k.startswith("_"):
            continue
        if inspect.isclass(v) and getattr(v, "__module__", None) == name:
            out.append(stub_for_class(k, v))
        elif inspect.isfunction(v) and getattr(v, "__module__", None) == name:
            out.append(stub_for_function(k, v))
        elif not inspect.ismodule(v):
            # constants / aliases: best-effort annotation
            out.append(f"{k}: Any")
    return "\n".join(out).rstrip() + "\n"

def stub_for_function(name: str, fn) -> str:
    doc = inspect.getdoc(fn)
    sig = format_signature(fn)
    lines = []
    if doc:
        lines.append('"""' + doc + '"""')
    lines.append(f"def {name}{sig}: ...")
    return "\n".join(lines) + "\n"

def stub_for_class(name: str, cls) -> str:
    lines: List[str] = []
    doc = inspect.getdoc(cls)
    bases = []
    for b in getattr(cls, "__bases__", ()):
        if b is object:
            continue
        bases.append(getattr(b, "__name__", "object"))
    base_str = f"({', '.join(bases)})" if bases else ""
    if doc:
        lines.append('"""' + doc + '"""')
    lines.append(f"class {name}{base_str}:")
    body: List[str] = []

    # class attributes
    for k, v in inspect.getmembers(cls):
        if k.startswith("_"):
            continue
        if inspect.isfunction(v) or inspect.ismethoddescriptor(v):
            # Methods
            try:
                fn = getattr(cls, k)
            except Exception:
                continue
            docm = inspect.getdoc(fn)
            sig = format_signature(fn)
            if docm:
                body.append('"""' + docm + '"""')
            body.append(f"def {k}{sig}: ...")
        elif isinstance(v, property):
            body.append(f"@property\ndef {k}(self) -> Any: ...")
        elif not inspect.isclass(v) and not inspect.ismodule(v):
            body.append(f"{k}: Any")

    if not body:
        body.append("pass")
    lines.append(indent("\n".join(body)))
    return "\n".join(lines) + "\n"

def main():
    if len(sys.argv) != 3:
        print("usage: python make_parallel_stub.py <path-to-src> <output.pyi>")
        raise SystemExit(2)

    src = Path(sys.argv[1]).resolve()
    sys.path.insert(0, str(src))
    import parallel  # type: ignore

    chunks = []
    chunks.append("# Consolidated stub for parallel\n")
    chunks.append("from __future__ import annotations\n")
    chunks.append("from typing import *\n")
    chunks.append("import typing\n\n")
    for modname in sorted(set(iter_modules(parallel))):
        mod = safe_import(modname)
        if isinstance(mod, Exception):
            chunks.append(f"# (failed import) {modname}: {mod}\n")
            continue
        chunks.append(stub_for_module(mod))
        chunks.append("\n")

    Path(sys.argv[2]).write_text("\n".join(chunks), encoding="utf-8")
    print("wrote", sys.argv[2])

if __name__ == "__main__":
    main()

Run:

python make_parallel_stub.py path/to/repo/src parallel.pyi

Then paste parallel.pyi here and I can:

  • clean it up (add missing imports/types),
  • ensure class nesting/exports align with __all__,
  • and (if you provide sources) replace docstrings with exact 1:1 source docstrings (runtime inspect.getdoc can normalize whitespace).

What I need from you to finish properly

  1. The code (zip or paste).
  2. Whether to include private members (_foo) or only public.
  3. Whether you want the stub to be “LLM-friendly” (single file, grouped by module, with comments indicating module boundaries) — I’ll do that by default.

Send the src/parallel folder (or the generated parallel.pyi) and I’ll produce the final single consolidated .pyi with doc-comments copied 1:1 from source.