Metadata-Version: 2.4
Name: lazy-inspect-offline
Version: 0.1.1
Summary: Search locally installed Python modules for functions and classes.
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# lazy-inspect-offline

`lazy-inspect-offline` searches functions and classes in Python modules installed in the current environment.
It does not make network requests or require third-party runtime dependencies.

The distribution name uses hyphens; its Python import name is
`lazy_inspect_offline`.

## Python compatibility

Version 0.1.1 supports Python 3.8 and newer. Unit tests, docstring examples,
and CLI execution were checked on Python 3.8.20, 3.9.20, 3.10.15, 3.11.5,
3.12.3, and 3.13.15. Python 3.7 was not runtime-tested and is not declared
supported; Python 3.6 cannot import the future annotations used by this package.
Python 3.8 and 3.9 are upstream end-of-life versions; compatibility is provided
for existing internal environments.

There are no third-party runtime dependencies. `setuptools>=68` is a build-time
requirement only, supporting the current `pyproject.toml` configuration and
editable installs. Pip selects a setuptools release compatible with the build
interpreter. Installing the prebuilt wheel offline does not require setuptools.
Search results depend on the version of the library being inspected.

## Install

Install from a wheel or source archive available on the offline machine:

```bash
python -m pip install --no-index lazy_inspect_offline-0.1.1-py3-none-any.whl
```

From this directory (the one containing `pyproject.toml`), build a wheel and
source archive on a connected build machine:

```bash
python -m pip install --upgrade build
python -m build
```

Copy the wheel to the offline machine and install it there. 
The modules being searched must also be installed locally.

## Python API

```python
from lazy_inspect_offline import (
    find_location,
    search_class,
    search_function,
)

search_function("os", "join")
# ['os.path.join']

search_class("datetime", "timezone")
# ['datetime.timezone']

find_location("datetime.timezone")
# path to the file backing the defining module (e.g. /home/user/anaconda3/lib/python3.11/datetime.py)

search_function('pandas', ['dataframe', 'fill'], exclude_keywords='na')
# ['pandas.DataFrame.bfill',
#  'pandas.DataFrame.ffill',
#  'pandas.api.typing.DataFrameGroupBy.bfill',
#  'pandas.api.typing.DataFrameGroupBy.ffill']

import pydoc
pydoc.help("os.path.join")
```

Pass a fully qualified search result to `pydoc.help()` to inspect the function's
documentation without an internet connection. For example, after finding
`os.path.join`, simply call `pydoc.help("os.path.join")` to view its description
and usage. For the pandas example, pass one of the returned names in the same way;
pandas must be installed in the current environment.

`keywords` and `exclude_keywords` each accept one string or a sequence of
strings. All search keywords must appear in the qualified name. A match is
excluded if its name contains any excluded keyword. Matching is
case-insensitive by default; set `lower=False` to make it case-sensitive.
Names beginning with `_` are skipped.

`find_location("datetime.timezone")` returns the absolute path of the file backing
that object's defining module. This may be a Python file, extension binary, or
bytecode file; it does not locate the implementation or a source line. It raises `LookupError` for an unresolved qualified
name and `OSError` if the defining module has no existing local file (for example,
`builtins.str`).

The search imports the requested module, so use trusted, locally installed
modules. It searches public attributes exposed after import, descending into module-tree
submodules and classes; unexposed submodules are not automatically imported.
Each module/class is traversed once, so descendant aliases may be omitted; it does
not build a persistent documentation index or search source code that is not
importable in the current environment.

## Command line

```bash
lazy-inspect-offline functions os join
lazy-inspect-offline classes datetime timezone
lazy-inspect-offline functions pandas dataframe fill --exclude na
lazy-inspect-offline location pandas.DataFrame.bfill
```

Repeated `--exclude` options are supported. Searches are case-insensitive by
default; for case-sensitive matching, use
`lazy-inspect-offline functions pandas DataFrame fill --exclude na --case-sensitive`.

`location` prints the absolute path of the defining module file, using the same
behavior as `find_location()`. It exits with status 1 if the name cannot be
resolved or its module file is unavailable. Pandas must be installed to run
the pandas examples.

## Package layout and development

This directory is the standalone packaging project, following the
[PyPA packaging tutorial](https://packaging.python.org/en/latest/tutorials/packaging-projects/).
Notebooks and comparison materials in the parent directory are not part of it.

```text
lazy-inspect-offline/
├── pyproject.toml
├── README.md
├── src/
│   └── lazy_inspect_offline/
│       ├── __init__.py
│       ├── __main__.py
│       ├── cli.py
│       └── search.py
└── tests/
    ├── test_cli.py
    └── test_search.py
```

```bash
python -m pip install -e .
python -m unittest discover -s tests -v
python -m pydoc lazy_inspect_offline.search_function
python -m pydoc lazy_inspect_offline.search_class
python -m pydoc lazy_inspect_offline.find_location
```

After building, `dist/` contains the wheel (`.whl`) and source archive
(`.tar.gz`). These are the files to distribute or upload to your package index.
To validate their package metadata and README rendering:

```bash
python -m pip install --upgrade twine
python -m twine check dist/*
```

No license has been selected for this project. Once the owner chooses terms,
add `LICENSE` here and the corresponding `project.license` and
`project.license-files` metadata to `pyproject.toml` before release.
