diff --git a/.github/instructions/pact-cli.instructions.md b/.github/instructions/pact-cli.instructions.md new file mode 100644 index 000000000..e1b08ca03 --- /dev/null +++ b/.github/instructions/pact-cli.instructions.md @@ -0,0 +1,11 @@ +--- +description: "Pact CLI" +applyTo: "/pact-python-cli/**" +--- + +# Pact CLI + +- This directory contains the source for the `pact-python-cli` package, which provides a thin wrapper around the Pact CLI binaries. +- It allows users to install the Pact CLI tools via PyPI and use them in Python projects without requiring separate installation steps. +- The package includes executable wrappers for all major Pact CLI tools (`pact`, `pact-broker`, `pact-message`, `pact-mock-service`, `pact-provider-verifier`, etc.). +- By default, it uses bundled binaries, but can fall back to system-installed Pact CLI tools when `PACT_USE_SYSTEM_BINS` environment variable is set to `TRUE` or `YES`. diff --git a/.github/instructions/pact-ffi.instructions.md b/.github/instructions/pact-ffi.instructions.md new file mode 100644 index 000000000..da62203b6 --- /dev/null +++ b/.github/instructions/pact-ffi.instructions.md @@ -0,0 +1,15 @@ +--- +description: "Pact FFI" +applyTo: "/pact-python-ffi/**" +--- + +# Pact FFI + +- This directory contains the source for the `pact-python-ffi` package, which provides Python bindings to the Pact FFI library. +- This library only exposes low-level FFI bindings and is not intended for direct use by end users. All user-facing functionality should be provided through the higher-level `pact` package. +- Code in this package should focus exclusively on: + - Providing automatic memory management for FFI objects (implementing `__del__` methods to drop/free objects as needed) + - Converting between Python types and FFI types (input parameter casting and return value conversion) + - Handling errors returned from the FFI and converting them into appropriate Python exceptions + - Wrapping low-level C structs and handles in Python classes with proper lifecycle management +- Avoid implementing high-level business logic or convenience methods - these belong in the main `pact` package. diff --git a/.github/instructions/pact-v2.instructions.md b/.github/instructions/pact-v2.instructions.md new file mode 100644 index 000000000..cac47aea6 --- /dev/null +++ b/.github/instructions/pact-v2.instructions.md @@ -0,0 +1,14 @@ +--- +description: "Pact V2" +applyTo: "/src/pact/v2/**" +--- + +# Pact V2 Legacy Code + +- These files provide backwards compatibility with version 2 of Pact Python. +- They are in maintenance mode with only critical bug fixes being applied - no new features should be added. +- When making changes: + - Preserve existing APIs and behavior to maintain backwards compatibility + - Prioritize minimal, targeted fixes over architectural improvements + - Ensure changes do not break existing user code +- New development should focus on the main V3+ codebase in `/src/pact/` instead. diff --git a/.github/instructions/pact.instructions.md b/.github/instructions/pact.instructions.md new file mode 100644 index 000000000..9a6a35e23 --- /dev/null +++ b/.github/instructions/pact.instructions.md @@ -0,0 +1,21 @@ +--- +description: "Pact Core Library" +applyTo: "/src/pact/**" +--- + +# Pact Core Library + +- The code in `src/pact/` forms the core Pact library that provides the main user-facing APIs. +- This is the primary codebase for Pact Python functionality. +- Key modules include: + - `pact.py` - Main Pact class for consumer testing + - `verifier.py` - Provider verification functionality + - `match/` - Matching rules and matchers + - `generate/` - Value generators + - `interaction/` - Interaction building blocks + +## V2 Legacy Code + +- Files in `v2/` subdirectories implement the legacy version of Pact Python +- This version is in maintenance mode with only critical bug fixes being applied +- New features and active development should focus on the main codebase diff --git a/.github/instructions/python-tests.instructions.md b/.github/instructions/python-tests.instructions.md new file mode 100644 index 000000000..e5461847e --- /dev/null +++ b/.github/instructions/python-tests.instructions.md @@ -0,0 +1,31 @@ +--- +description: "Python testing conventions and guidelines" +applyTo: "**/tests/**/*.py" +--- + +# Python Testing Conventions + +- Use `pytest` as the testing framework, with all tests located in `tests/` directories and files prefixed with `test_`. +- Prefer descriptive function names that clearly indicate the test's purpose. Include docstrings only when additional context is needed beyond the function name. +- Use `@pytest.mark.parametrize` to cover multiple scenarios without code duplication: + + ```python + @pytest.mark.parametrize( + ("param1", "param2", "expected"), + [ + pytest.param(v1, x1, r1, id="description1"), + pytest.param(v2, x2, r2, id="description2"), + ... + ] + ) + def test_function(param1: Type1, param2: Type2, expected: ReturnType) -> None: + ... + ``` + +- Ensure test coverage for: + - Critical application paths and core functionality + - Common edge cases (empty inputs, invalid data types, boundary conditions) + - Error conditions and exception handling +- Include comments explaining complex test logic or edge case rationale. +- Minimize mocking and prefer testing with real data and dependencies when practical. Mock only external services or components that are unreliable or expensive to test against. +- Use pytest fixtures for common test setup and shared data. diff --git a/.github/instructions/python.instructions.md b/.github/instructions/python.instructions.md new file mode 100644 index 000000000..394240630 --- /dev/null +++ b/.github/instructions/python.instructions.md @@ -0,0 +1,52 @@ +--- +description: "Python coding conventions and guidelines" +applyTo: "**/*.py" +--- + +# Python Coding Conventions + +## Documentation + +- MkDocs-Material is used for documentation generation, allowing for Markdown formatting in docstrings. +- All functions must have Google-style, Markdown-compatible docstrings with proper formatting (note whitespace and indentation as shown): + + ```python + def function_name(param1: Type1, param2: Type2) -> ReturnType: + """ + Brief description of the function. + + Optional detailed description of the function. + + Args: + param1: + Description of param1. + + param2: + Description of param2. + + Returns: + Description of the return value. + """ + ``` + +- References to other functions, classes, or modules must be linked, using the fully qualified Python path: + + ```markdown + A link to a [`ClassName.method`][pact.module.ClassName.method] or a + [`function_name`][pact.module.function_name]. + ``` + +## General Instructions + +- Always prioritize readability and clarity. +- All functions must use type annotations for parameters and return types. Prefer generic types (e.g., `Iterable[str]`, `Mapping[str, int]`) over concrete types (`list[str]`, `dict[str, int]`) for better flexibility and reusability. +- Write code with good maintainability practices, including comments on why certain design decisions were made. +- Handle edge cases and write clear exception handling. +- Write concise, efficient, and idiomatic code that is also easily understandable. +- When performing validations, use early returns to reduce nesting and improve readability. + - Prefer built-in exceptions (such as `ValueError` for invalid values, `TypeError` for incorrect types, etc.) for standard Python errors. + - For Pact-specific issues, define and use custom exceptions to provide clear and meaningful error handling. These must all inherit from the `PactError` base class, and may inherit from other exceptions as appropriate. + +## Code Style and Linting + +- Use `ruff` for linting and formatting, preferring automatic fixes where possible.