Skip to main content

Structural-honesty checks for Python, powered by Furqan

Project description

furqan-lint

Structural-honesty checks for Python, powered by Furqan.

furqan-lint translates Python source into the Furqan AST and runs the subset of Furqan checkers whose semantics carry across language boundaries into idiomatic Python. Phase 1 ships two checks:

  • D24 (all-paths-return) every control-flow path through a typed function reaches a return statement.
  • D11 (status-coverage) when a function returns Optional[X], every caller either propagates the optionality or explicitly handles None. A caller that silently collapses Optional[X] into a non-optional return type is the structural equivalent of dropping the Incomplete arm of Furqan's Integrity | Incomplete union.

Install

pip install furqan-lint

Requires Python 3.10+ and furqan>=0.10.1.

Usage

furqan-lint check path/to/file.py
furqan-lint check path/to/directory/
furqan-lint version

Example

# example.py
from typing import Optional

def find_record(id: int) -> Optional[dict]:
    if id <= 0:
        return None
    return {"id": id}

def get_name(id: int) -> str:
    record = find_record(id)
    if record is not None:
        return record["name"]
    # Missing else: falls through with no return
$ furqan-lint check example.py

MARAD  example.py
  2 violation(s):
    [all_paths_return] Function 'get_name' at line 8 declares
    -> str but not every control-flow path reaches a return
    statement.
      fix: Add a return statement to the else branch or after
      the if block.

    [status_coverage] Function 'get_name' at line 8 calls
    'find_record' (returns Optional[dict]) but declares -> str.
    The Optional is silently collapsed.
      fix: Change return type to Optional[str].

Phase 1 scope and known gaps

Phase 1 wires two of Furqan's ten checkers to Python. The remaining eight require Python-specific conventions (scope declarations, layer annotations, calibration bounds, dependency mapping) that do not exist in standard Python. Documented gaps in Section 8 of the implementation prompt:

  1. return None with a non-Optional declared return type is treated as a satisfied path by D24. Phase 2 adds D22 (return-type match) which closes this gap.
  2. The D11 producer detection uses a scoped monkey-patch on status_coverage._is_integrity_incomplete_union. Phase 2 adds a producer_predicate parameter to check_status_coverage upstream.
  3. Class methods are extracted as top-level functions; calls written as self.validate() are matched on the attribute name validate only.
  4. Only D24 and D11 run. The other eight checkers require language-level constructs Python does not have.
  5. Calls inside nested functions are attributed to the enclosing function.

License

Apache-2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

furqan_lint-0.1.0.tar.gz (16.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

furqan_lint-0.1.0-py3-none-any.whl (13.7 kB view details)

Uploaded Python 3

File details

Details for the file furqan_lint-0.1.0.tar.gz.

File metadata

  • Download URL: furqan_lint-0.1.0.tar.gz
  • Upload date:
  • Size: 16.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for furqan_lint-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5e7cd02fd288627d802fd16f1a1fd1c6920c87fbda6bcecaeb8d48f15abb3a8e
MD5 7e774450e275dfa92cdaa7bc37c3ad06
BLAKE2b-256 c8f3f22ab1b7320c268f3c79073c4119ba539d74daf3d5d8e63470a9d2803c9b

See more details on using hashes here.

File details

Details for the file furqan_lint-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: furqan_lint-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 13.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.0

File hashes

Hashes for furqan_lint-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4ff9ee0d6b52b3e594d28f6cd33c88821907705f83091a9c3983de8bb830b38b
MD5 4d3105051a38f24262154c97137746bc
BLAKE2b-256 128d781ecd0ef050dca0cfd7579505a57ee1e2d3f5b055dc237f1176b1f3e55e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page