Metadata-Version: 2.4
Name: lazy-inspect-offline
Version: 0.1.2
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.2 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 PyPI:

```bash
pip install lazy-inspect-offline
```

For offline installation, copy the wheel to the target machine and run:

```bash
python -m pip install --no-index lazy_inspect_offline-0.1.2-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(module_name, keywords, ...)`

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

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

- **Purpose:** Find public functions and methods in a locally installed module.
- **Result:** A sorted list of unique dotted names; `[]` if nothing matches.
- **Search scope:** Skip names starting with `_`; inspect exposed submodules and classes in the module tree. Unexposed submodules are not automatically imported. Each module/class is traversed once, so some descendant aliases may be omitted.
- **Options:**
    - `keywords`: A string or sequence of strings. Every keyword must occur in the full dotted name.
    - `exclude_keywords=()`: A string or sequence of strings. Exclude names containing any of these keywords.
    - `lower=True`: Match without case sensitivity. Use `lower=False` for case-sensitive matching.
    - `suppress_warnings=True`: Hide Python warnings during the call and restore warning settings afterward, even on exceptions. Use `False` to retain the caller's warning policy during the search. 
- **Imports:** Use trusted modules; importing and inspecting them may execute code. No persistent index is created.


- **[TIP] Read documentation with `pydoc`**. Pass a returned name to `pydoc.help()` to view its description and usage offline. This also works for class names returned by `search_class()`.

    ```python
    import pydoc

    pydoc.help("os.path.join")
    pydoc.help("datetime.timezone")  # Class documentation works the same way.
    ```

### `search_class(module_name, keywords, ...)`

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

- **Purpose:** Find public classes, including nested classes encountered during traversal.
- **Result:** A sorted list of unique dotted names; `[]` if nothing matches. Instances are not included.
- **Options:** Uses the same `keywords`, `exclude_keywords`, `lower`, and `suppress_warnings` options as `search_function()`.
- **Behavior:** Shares the search scope, import and warning behavior, as described for `search_function()`.

### `find_location(qualified_name)`

```python
find_location("datetime.timezone")
# e.g. /home/user/anaconda3/lib/python3.11/datetime.py
```
- **Purpose:** Find the file location of the module defining the specified object in current environment.
- **Result:** The absolute path of the file backing the object's defining module.
- **Behavior:** 
    - **Input:** A dotted object name, usually returned by either search function.
    - **File type:** May be Python source, an extension binary, or bytecode. It does not identify an implementation or source line.
    - **Errors:** Raises `LookupError` for an unresolved name and `OSError` if no local module file exists, as with `builtins.str`. Import failures may also propagate.
    - **Warnings:** Has no `suppress_warnings` option; uses the caller's warning settings.

## 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

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
    └── test_warnings.py
```
