Python Style Guide🔗
This document outlines the coding style, conventions, and common patterns for the python-json-logger
project. Adhering to this guide will help maintain code consistency, readability, and quality.
General Principles🔗
- Readability Counts: Write code that is easy for others (and your future self) to understand. This aligns with PEP 20 (The Zen of Python).
- Consistency: Strive for consistency in naming, formatting, and structure throughout the codebase.
- Simplicity: Prefer simple, straightforward solutions over overly complex ones.
- PEP 8: Follow PEP 8 (Style Guide for Python Code) for all Python code. The automated tools mentioned below will enforce many of these rules. This guide highlights project-specific conventions or particularly important PEP 8 aspects.
Formatting and Linting🔗
We use automated tools to enforce a consistent code style and catch potential errors. These include:
- Black: For opinionated code formatting.
- Pylint: For static code analysis and error detection.
- MyPy: For static type checking.
Ensure these tools are run before committing code. Configuration for these tools can be found in pyproject.toml
, pylintrc
, and mypy.ini
respectively. This guide primarily focuses on conventions not automatically verifiable by these tools.
Imports🔗
Imports should be structured into the following groups, separated by a blank line, and generally alphabetized within each group:
- Future Imports: e.g.,
from __future__ import annotations
- Standard Library Imports: e.g.,
import sys
,from datetime import datetime
- Installed (Third-Party) Library Imports: e.g.,
import pytest
- Application (Local) Imports: e.g.,
from .core import BaseJsonFormatter
(This project-specific pattern is crucial for internal organization).
Naming Conventions🔗
While PEP 8 covers most naming, we emphasize:
- Modules:
lowercase_with_underscores.py
- Packages:
lowercase
- Classes & Type Aliases:
CapWords
(e.g.,BaseJsonFormatter
,OptionalCallableOrStr
). This is standard, but explicitly stated for clarity. - Constants:
UPPERCASE_WITH_UNDERSCORES
(e.g.,RESERVED_ATTRS
). This is a project convention for module-level constants.
(Functions, methods, and variables follow standard PEP 8 lowercase_with_underscores
).
Comments🔗
- Use comments to explain non-obvious code, complex logic, or important design decisions. Avoid comments that merely restate what the code does.
- For internal code organization within files, especially in longer modules or classes, use comments like
## Section Title ##
or### Subsection Title ###
to delineate logical blocks of code (e.g.,## Parent Methods ##
as seen insrc/pythonjsonlogger/core.py
). This is distinct from Markdown headings used in this document.
Docstrings🔗
- All public modules, classes, functions, and methods must have docstrings.
- We use
mkdocstrings
for generating API documentation, which defaults to the Google Python Style Guide for docstrings. Please adhere to this style. You can find the guide here. - Docstrings should clearly explain the purpose, arguments, return values, and any exceptions raised.
- Project Convention: Use the following markers to indicate changes over time:
*
*New in version_number*
: For features added in a specific version. **Changed in version_number*
: For changes made in a specific version. **Deprecated in version_number*
: For features deprecated in a specific version.Example:
def my_function(param1: str, param2: int) -> bool: """Does something interesting. Args: param1: The first parameter, a string. param2: The second parameter, an integer. Returns: True if successful, False otherwise. Raises: ValueError: If param2 is negative. *New in 3.1* """ # ... function logic ... return True # See 'Return Statements'
Type Hinting🔗
- All new code must include type hints for function arguments, return types, and variables where appropriate, as per PEP 484.
- Use standard types from the
typing
module. - Project Convention: For Python versions older than 3.10, use
typing_extensions.TypeAlias
for creating type aliases. For Python 3.10+, usetyping.TypeAlias
(e.g.,OptionalCallableOrStr: TypeAlias = ...
).
Return Statements🔗
- Project Convention: All functions and methods must have an explicit
return
statement. - If a function does not logically return a value, it should end with
return None
or simplyreturn
. This makes the intent clear and consistent across the codebase.Example:
Class Structure🔗
- Group methods logically within a class (e.g., initialization, public, protected/private, special methods).
- The use of internal code comments like
## Parent Methods ##
(as seen insrc/pythonjsonlogger/core.py
) is encouraged for readability in complex classes.
Project-Specific Code Patterns and Idioms🔗
Familiarize yourself with these patterns commonly used in this project:
- Version-Specific Logic: Using
sys.version_info
for compatibility: - Type Aliases for Clarity: As mentioned in Type Hinting, using
TypeAlias
for complex type combinations improves readability. - Custom Exceptions: Defining custom exception classes for application-specific error conditions (e.g.,
MissingPackageError
insrc/pythonjsonlogger/exception.py
). - Helper/Utility Functions: Encapsulating reusable logic in utility modules (e.g., functions in
src/pythonjsonlogger/utils.py
). - Conditional Imports for Optional Dependencies: The pattern in
src/pythonjsonlogger/__init__.py
for checking optional dependencies likeorjson
andmsgspec
usingpackage_is_available
fromutils.py
.
Testing🔗
This project uses pytest
for testing. Adherence to good testing practices is crucial.
- Test Location: Tests are located in the
tests/
directory. - Test Naming: Test files
test_*.py
; test functionstest_*
. - Fixtures: Utilize
pytest
fixtures (@pytest.fixture
) for setup. * Project Pattern: TheLoggingEnvironment
dataclass andenv
fixture intests/test_formatters.py
is a key pattern for testing logger behavior. Adapt this for similar scenarios. - Parametrization: Use
@pytest.mark.parametrize
extensively to cover multiple scenarios efficiently. - Clarity and Focus: Each test should be focused and its name descriptive.
- Assertions: Use clear, specific
pytest
assertions.
By following these guidelines, we can ensure that python-json-logger
remains a high-quality, maintainable, and developer-friendly library.