Python Ext‐Packages - LogeshVel/learning_resources GitHub Wiki
Python Packaging — pyproject.toml
References:
Mypy is a static type checker for Python. It allows developers to add type annotations to their Python code, making the codebase easier to understand, maintain, and debug. Mypy checks the types at compile time, not at runtime, ensuring that potential type errors are caught early.
How to Use Mypy
-
Install Mypy:
pip install mypy
-
Add Type Annotations:
def greet(name: str) -> str: return f"Hello, {name}"
-
Run Mypy:
mypy script.py
Type Annotations Syntax:
-
Variables:
age: int = 25 name: str = "Alice" is_active: bool = True
-
Function Annotations:
def add(a: int, b: int) -> int: return a + b
-
Optional Types:
from typing import Optional def get_user(user_id: int) -> Optional[str]: if user_id == 1: return "Alice" return None
-
Lists, Tuples, and Dicts:
from typing import List, Tuple, Dict names: List[str] = ["Alice", "Bob"] point: Tuple[int, int] = (10, 20) user_data: Dict[str, int] = {"age": 30}
Why Use Mypy?
- Early Error Detection: Catches potential bugs before runtime.
- Code Clarity: Type annotations serve as documentation.
- Refactoring Safety: Easier to maintain and refactor codebases.
When you run mypy script.py
, Mypy checks your Python file (script.py
) for type correctness based on the type annotations you provided. Here's what the output might look like, depending on the state of your code:
1. No Type Errors (Success Case)
Success: no issues found in 1 source file
Explanation:
This means Mypy found no type-related issues in your file. The code complies with all the type hints and annotations provided.
2. Type Errors Found
Example Code (script.py
):
def add(a: int, b: int) -> int:
return a + b
result = add(10, "20") # Incorrect argument type
Running Mypy:
mypy script.py
Output:
script.py:4: error: Argument 2 to "add" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)
Explanation:
-
script.py:4
- The file and line number where the issue occurred. -
Argument 2 to "add"
- Describes the problematic argument. -
incompatible type "str"; expected "int"
- Indicates that astr
was passed, while anint
was expected based on the function signature.
3. Multiple Errors If multiple issues exist, Mypy lists them one by one:
script.py:3: error: Argument 1 to "add" has incompatible type "str"; expected "int"
script.py:4: error: Incompatible return value type (got "str", expected "int")
Found 2 errors in 1 file (checked 1 source file)
4. Warnings and Additional Info
If you enable more strict options like --strict
, Mypy provides detailed warnings such as:
- Missing type hints (
--disallow-untyped-defs
) - Return types not matching
- Incompatible operations
Common Command-Line Options
-
--strict
: Enables strict type checking. -
--ignore-missing-imports
: Ignores errors related to missing module type hints. -
--check-untyped-defs
: Checks code even when functions lack type annotations.
Pylint is a popular static code analysis tool for Python that checks your code against the PEP 8 style guide and best practices. It helps identify potential issues such as code smells, logical errors, and violations of coding standards.
How to Install Pylint
pip install pylint
Running Pylint
pylint script.py
Pylint Output Breakdown When you run Pylint, it generates a detailed report, assigning scores and showing errors, warnings, and suggestions.
Example: Basic Python Script (script.py
)
# script.py
def greet(name):
print(f"Hello, {name}")
greet("Alice")
Running Pylint:
pylint script.py
Sample Output:
************* Module script
script.py:1:0: C0114: Missing module docstring (missing-module-docstring)
script.py:3:0: C0116: Missing function or method docstring (missing-function-docstring)
script.py:3:16: W0613: Unused argument 'name' (unused-argument)
--------------------------------------------------------------------
Your code has been rated at 7.50/10 (previous run: 8.33/10, -0.83)
Understanding the Output:
-
C0114 - Missing module docstring:
No top-level documentation provided for the module (script.py
). -
C0116 - Missing function docstring:
The functiongreet
lacks a docstring explaining what it does. -
W0613 - Unused argument:
The argumentname
is not used in the function. -
Code Rating:
The rating (e.g., 7.50/10) reflects code quality. A perfect score is 10/10.
Pylint Message Categories:
Code | Category | Description |
---|---|---|
C | Convention | Coding standard violations |
R | Refactor | Code that could be improved |
W | Warning | Likely coding problems |
E | Error | Errors that prevent running the code |
F | Fatal | Fatal errors that block analysis |
Fixing the Example:
"""
This module demonstrates a simple greeting function.
"""
def greet(name: str) -> None:
"""Greets the user by name."""
print(f"Hello, {name}")
greet("Alice")
Re-running Pylint:
pylint script.py
New Output:
--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 7.50/10, +2.50)
Commonly Used Pylint Options:
-
Run with a specific message category:
pylint --disable=C script.py # Disable convention messages
-
Generate a detailed report:
pylint --reports=y script.py
-
Ignore specific errors:
pylint --disable=missing-docstring script.py
-
Configure Pylint using a config file:
pylint --generate-rcfile > .pylintrc
Why Use Pylint?
- Code Consistency: Ensures adherence to PEP 8 standards.
- Early Error Detection: Finds logical errors before execution.
- Improved Maintainability: Helps keep the code clean and readable.
Running pylint --reports=y script.py
generates a more detailed report with a summary of various metrics about your code. This includes statistics like the number of code lines, comments, classes, functions, and more.
Example: script.py
"""
This module demonstrates a simple greeting function.
"""
def greet(name: str) -> None:
"""Greets the user by name."""
print(f"Hello, {name}")
def add(a: int, b: int) -> int:
"""Adds two numbers."""
return a + b
greet("Alice")
result = add(2, 3)
print(result)
Running Pylint with Reports:
pylint --reports=y script.py
Sample Output:
************* Module script
script.py:1:0: C0114: Missing module docstring (missing-module-docstring)
-------------------------------------------------------------------
Your code has been rated at 9.00/10 (previous run: 8.00/10, +1.00)
-------------------------------------------------------------------
Statistics by type
-------------------------------------------------------------------
+---------+-------+-----------+-----------+-----------+----------------+
| Type | Total | Missed | Covered | % Good | Average |
+---------+-------+-----------+-----------+-----------+----------------+
| Classes | 0 | 0 | 0 | 100% | 0 |
| Methods | 0 | 0 | 0 | 100% | 0 |
| Functions | 2 | 0 | 2 | 100% | 2 |
| Statements| 6 | 0 | 6 | 100% | 6 |
| Comments | 2 | 0 | 2 | 100% | 2 |
| Docstrings| 2 | 0 | 2 | 100% | 2 |
+---------+-------+-----------+-----------+-----------+----------------+
-------------------------------------------------------------------
Messages
-------------------------------------------------------------------
+----------------------------+------------+
| Message Type | Occurrences|
+----------------------------+------------+
| convention (C) | 1 |
| refactor (R) | 0 |
| warning (W) | 0 |
| error (E) | 0 |
| fatal (F) | 0 |
+----------------------------+------------+
-------------------------------------------------------------------
Global evaluation
-------------------------------------------------------------------
Your code has been rated at 9.00/10 (previous run: 8.00/10, +1.00)
Report Breakdown:
-
Statistics by Type:
- Classes: Number of classes defined.
- Methods: Number of methods in the classes.
- Functions: Number of standalone functions.
- Statements: Total executable lines of code.
- Comments: Total number of comments.
- Docstrings: Number of docstrings for functions/classes/modules.
-
Messages Summary:
- Convention (C): Minor issues like missing docstrings or naming style violations.
- Refactor (R): Code that can be improved for clarity or performance.
- Warning (W): Potential problems or questionable code.
- Error (E): Definite errors that would cause the program to fail.
- Fatal (F): Serious issues that prevent Pylint from proceeding.
-
Global Evaluation:
- Displays the overall score out of 10/10, reflecting the code quality and adherence to best practices.
Why Use --reports=y
?
- Detailed Metrics: Helps analyze code structure and maintainability.
- Team Collaboration: Useful for team code reviews and continuous integration (CI).
- Historical Tracking: Tracks improvements by comparing code quality scores.
Poetry is a tool for dependency management and packaging in Python. It simplifies the process of creating and managing Python projects by handling dependencies, virtual environments, and packaging in an efficient and user-friendly way.
Features of Poetry:
- Dependency Management: Poetry ensures you have all dependencies for your project and resolves version conflicts automatically.
- Virtual Environments: Poetry automatically creates and manages virtual environments for your project.
- Version Management: Supports semantic versioning and can automatically update versions based on changes.
- Publishing: Easily publish your projects to package repositories like PyPI.
Installation
curl -sSL https://install.python-poetry.org | python3 -
After installation, ensure poetry
is available in your PATH by checking its version:
poetry --version
Basic Commands
-
Create a New Project
poetry new <project_name>
This creates a project structure like:
project_name/ ├── pyproject.toml ├── README.rst ├── project_name/ │ └── __init__.py └── tests/ └── __init__.py
-
Initialize Poetry in an Existing Project
poetry init
Interactive prompt to set up
pyproject.toml
. -
Add Dependencies
poetry add <package_name> poetry add <package_name>@<version> poetry add <package_name> --dev # Development dependency
-
Remove Dependencies
poetry remove <package_name>
-
Install All Dependencies
poetry install
-
Update Dependencies
poetry update
-
Run Scripts or Commands
poetry run <command>
-
Activate the Virtual Environment
poetry shell
-
Check Dependency Status
poetry check
-
Publish a Package
poetry publish --build
-
Version Management
poetry version <major|minor|patch>
Sample Project: Versioning Automatically
Here, we’ll create a simple project that demonstrates automatic versioning with Poetry.
Step 1: Create a Project
poetry new poetry_version_demo
cd poetry_version_demo
Step 2: Add a Sample Script
Edit poetry_version_demo/__init__.py
:
def main():
print("Hello from Poetry Version Demo!")
Step 3: Manage Dependencies
Add semver
(Semantic Versioning library):
poetry add semver
Step 4: Automatic Versioning Script
Create a script to manage version updates in scripts/update_version.py
:
import semver
import toml
def update_version(part):
pyproject_file = "pyproject.toml"
with open(pyproject_file, "r") as f:
data = toml.load(f)
current_version = data["tool"]["poetry"]["version"]
new_version = str(semver.VersionInfo.parse(current_version).next_version(part))
data["tool"]["poetry"]["version"] = new_version
with open(pyproject_file, "w") as f:
toml.dump(data, f)
print(f"Updated version from {current_version} to {new_version}")
if __name__ == "__main__":
import sys
if len(sys.argv) != 2 or sys.argv[1] not in ["major", "minor", "patch"]:
print("Usage: python update_version.py <major|minor|patch>")
sys.exit(1)
update_version(sys.argv[1])
Step 5: Test Automatic Versioning Run the script to update the version:
python scripts/update_version.py patch
This updates the version
in pyproject.toml
automatically.
Step 6: Run the Project
poetry run python -m poetry_version_demo
Summary of Commands Used
-
Project Creation:
poetry new poetry_version_demo
-
Add Dependency:
poetry add semver
-
Version Update:
python scripts/update_version.py patch
-
Run Script:
poetry run python -m poetry_version_demo
Detailed Explanation of Poetry Commands
poetry install
Description:
This command installs all the dependencies listed in your pyproject.toml
file, including their specific versions as locked in poetry.lock
.
Key Options:
-
--no-root
: Skip installing the current project as a package. Useful when you don't need the project itself installed. -
--only <group>
: Install dependencies only for a specific group, such asdev
ortest
. -
--without <group>
: Skip installing dependencies for a specific group. -
--with <group>
: Include optional groups not installed by default.
Usage:
- Install all dependencies:
poetry install
- Install only development dependencies:
poetry install --only dev
- Skip development dependencies:
poetry install --without dev
poetry update
Description:
This command updates all dependencies to their latest versions allowed by the constraints in pyproject.toml
. It also regenerates the poetry.lock
file.
Key Options:
-
--with <group>
: Include optional groups during the update. -
--without <group>
: Skip specific groups during the update. -
--dry-run
: Simulate the update without applying changes. -
--lock
: Update the lock file only, without installing the updated dependencies.
Usage:
- Update all dependencies:
poetry update
- Update specific dependency:
poetry update <package_name>
- Preview updates without applying:
poetry update --dry-run
poetry run <command>
Description:
Run a command within the context of the project's virtual environment. This ensures that all dependencies are correctly configured.
Usage Examples:
- Run a Python script:
poetry run python script.py
- Run a shell command:
poetry run ls
- Execute a specific module:
poetry run python -m http.server
Tips:
- Use
poetry run
when you want to execute commands with dependencies installed in the Poetry-managed virtual environment.
poetry shell
Description:
Spawns a new shell with the virtual environment activated. This allows you to run commands directly without prefixing them with poetry run
.
Usage:
- Activate the virtual environment:
poetry shell
- Exit the virtual environment:
exit
Key Features:
- You can directly run Python scripts or commands within the activated environment without using
poetry run
. - Useful for interactive work in the virtual environment.
poetry check
Description:
Validates the pyproject.toml
file and checks for issues with the project setup.
Key Use Cases:
- Ensures the
pyproject.toml
file is well-formed. - Verifies that the project dependencies are consistent and correctly specified.
Usage:
- Run a check:
poetry check
Output:
- If there are issues, Poetry will list them, such as missing fields or invalid syntax in
pyproject.toml
.
Summary Table
Command | Purpose | Example Usage |
---|---|---|
poetry install |
Installs all dependencies defined in pyproject.toml . |
poetry install --without dev |
poetry update |
Updates dependencies to their latest compatible versions and regenerates the lock file. | poetry update <package_name> |
poetry run <cmd> |
Runs a specified command within the Poetry virtual environment. | poetry run python -m http.server |
poetry shell |
Activates the virtual environment for running commands interactively. | poetry shell |
poetry check |
Checks for errors or inconsistencies in the pyproject.toml file and project setup. |
poetry check |
This detailed explanation and usage guide should help you master these Poetry commands for managing Python projects effectively.