Skip to content

Commit

Permalink
🔧 chore: Update pre-commit config
Browse files Browse the repository at this point in the history
- Add sphinx hook
- Add doc formatter hook
- Add ruff hook
- Update codebase
  • Loading branch information
ARYAN-NIKNEZHAD committed Aug 30, 2024
1 parent bdf77c9 commit 1883202
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 61 deletions.
22 changes: 22 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ repos:
- id: check-docstring-first
exclude: (migrations/|tests/|docs/|static/|media/).*

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.5.5
hooks:
- id: ruff
args: ["--config=pyproject.toml"]
exclude: (migrations/|tests/|docs/|static/|media/|apps.py).*

- repo: https://github.com/pre-commit/mirrors-isort
rev: v5.10.1
hooks:
Expand Down Expand Up @@ -42,6 +49,21 @@ repos:
additional_dependencies: [ "bandit[toml]" ]
exclude: (migrations/|tests/|docs/|static/|media/).*

- repo: https://github.com/PyCQA/docformatter
rev: v1.7.5
hooks:
- id: docformatter
args: ["--in-place", "--recursive", "--blank"]
exclude: (migrations/|tests/|docs/|static/|media/).*

- repo: https://github.com/rstcheck/rstcheck
rev: "v6.2.4"
hooks:
- id: rstcheck
args: ["--report-level=warning"]
files: ^(docs/(.*/)*.*\.rst)
additional_dependencies: [Sphinx==6.2.1]

- repo: local
hooks:
- id: pytest
Expand Down
14 changes: 7 additions & 7 deletions docs/pytest_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Each test file should follow a structured format:
- **Imports:** Group imports logically, starting with standard library imports, followed by third-party imports, and finally local application imports.

Example File Structure
--------------
----------------------------------------

.. code-block:: python
Expand Down Expand Up @@ -57,7 +57,7 @@ Example File Structure
pass
Class and Function Naming Conventions
-------------------------------------
---------------------------------------

- **Class Names:** Use the `Test` prefix followed by the name of the class or module being tested. For example, if you're testing the `MyModelAdmin` class, name your test class `TestMyModelAdmin`.

Expand All @@ -69,7 +69,7 @@ Markers
Each test file should include a `pytestmark` variable at the top, which is a list of markers. These markers help categorize tests and can include Django-specific markers (e.g., `django_db`), custom markers (e.g., `admin`, `settings_checks`), and conditional markers (e.g., `skipif`).

Example of pytestmark
--------------
----------------------------------------

.. code-block:: python
Expand All @@ -85,7 +85,7 @@ Docstrings
Every test function should include a docstring that describes the purpose of the test. The docstring should explain what the test is verifying, why it's important, and any relevant details about the setup or expected outcome.

Example of a Docstring
--------------
---------------------------------------

.. code-block:: python
Expand All @@ -103,7 +103,7 @@ Type Annotations
All test functions and methods should include type annotations. This improves code clarity and helps with static analysis tools.

Example of Type Annotations
--------------
---------------------------------------

.. code-block:: python
Expand All @@ -116,7 +116,7 @@ Using Fixtures
Fixtures in Pytest are a powerful way to manage test dependencies. Use fixtures to set up the state your tests need, such as database records, user authentication, or Django settings.

Example of Using a Fixture
--------------
---------------------------------------

.. code-block:: python
Expand Down Expand Up @@ -177,7 +177,7 @@ Admin Model Test Example
assert list(formfield.queryset) == [MyModel.objects.get(name="Test")]
Settings Check Test Example
--------------
---------------------------------------

.. code-block:: python
Expand Down
12 changes: 6 additions & 6 deletions docs/quick_start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ Quick Start
2. **Add `iranian_cities` to `INSTALLED_APPS` in your Django settings**:

.. code-block:: python
.. code-block:: python
INSTALLED_APPS = [
...
'iranian_cities',
...
]
INSTALLED_APPS = [
...
'iranian_cities',
...
]
3. **Run migrations to apply model changes**:

Expand Down
6 changes: 4 additions & 2 deletions iranian_cities/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@


class IranianCitiesAdmin(admin.ModelAdmin):
"""Custom admin model for Iranian cities with a custom form field for foreign key."""
"""Custom admin model for Iranian cities with a custom form field for
foreign key."""

def formfield_for_foreignkey(
self, db_field: ForeignKey, request: HttpRequest, **kwargs: Any
) -> Any:
"""Override the default form field for foreign keys to use ForeignKeyRawIdWidget."""
"""Override the default form field for foreign keys to use
ForeignKeyRawIdWidget."""
db: Optional[str] = kwargs.get("using")
kwargs["widget"] = widgets.ForeignKeyRawIdWidget(
db_field.remote_field, self.admin_site, using=db
Expand Down
4 changes: 2 additions & 2 deletions iranian_cities/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
def check_iranian_cities_config(
app_configs: Dict[str, Any], **kwargs: Any
) -> List[Error]:
"""
Check the Iranian Cities configuration for the application.
"""Check the Iranian Cities configuration for the application.
This function verifies that all required Iranian Cities settings are present and ensure the settings are correct.
Any errors encountered during these checks are returned.
Expand Down Expand Up @@ -39,6 +38,7 @@ def check_iranian_cities_config(
>>> if errors:
... for error in errors:
... print(error)
"""
errors: List[Error] = []

Expand Down
3 changes: 3 additions & 0 deletions iranian_cities/exc.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class SageError(Exception):
__init__(detail: Optional[str] = None, code: Optional[str] = None, section_code: Optional[str] = None):
Initializes the error with specific details.
__str__() -> str: Returns a formatted string representation of the error.
"""

status_code: int = 500
Expand Down Expand Up @@ -54,6 +55,7 @@ class IranianCitiesError(SageError):
default_detail (str): Default error message for Iranian Cities errors.
default_code (str): Default error code for Iranian Cities errors.
section_code (str): Section code for Iranian Cities errors.
"""

status_code: int = 500
Expand All @@ -73,6 +75,7 @@ class IranianCitiesConfigurationError(IranianCitiesError):
default_detail (str): Default error message for configuration errors.
default_code (str): Default error code for configuration errors.
section_code (str): Section code for configuration errors.
"""

status_code: int = 400
Expand Down
39 changes: 20 additions & 19 deletions iranian_cities/management/commands/generate_city.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@


class Command(BaseCommand):
"""Management command to generate and populate database tables for Iranian cities."""
"""Management command to generate and populate database tables for Iranian
cities."""

help = "Generate all data"

def read_csv(self, path: str) -> List[Dict[str, str]]:
"""
Read a CSV file and return a list of dictionaries.
"""Read a CSV file and return a list of dictionaries.
Args:
path (str): The path to the CSV file.
Returns:
List[Dict[str, str]]: A list of dictionaries representing CSV rows.
"""
with open(path, encoding="utf-8") as f:
logger.debug("Reading CSV file")
Expand All @@ -41,11 +42,11 @@ def read_csv(self, path: str) -> List[Dict[str, str]]:
return csv_reader

def prompt_user(self) -> Tuple[bool, str]:
"""
Prompt the user to decide whether to flush the tables.
"""Prompt the user to decide whether to flush the tables.
Returns:
bool: True if the tables should be flushed, False otherwise.
"""
response: Union[None, str] = None
logger.debug("Checking if the database is has data in the database")
Expand Down Expand Up @@ -115,11 +116,11 @@ def flush_tables(self) -> None:
print("All tables have been flushed.")

def generate_province(self, path: str) -> None:
"""
Generate and populate the Province table.
"""Generate and populate the Province table.
Args:
path (str): The path to the CSV file containing province data.
"""
with open(path, encoding="utf-8") as f:
data = csv.DictReader(f)
Expand All @@ -133,11 +134,11 @@ def generate_province(self, path: str) -> None:
print("Province Objects Created Successfully")

def generate_county(self, path: str) -> None:
"""
Generate and populate the County table.
"""Generate and populate the County table.
Args:
path (str): The path to the CSV file containing county data.
"""
with open(path, encoding="utf-8") as f:
data = csv.DictReader(f)
Expand All @@ -154,11 +155,11 @@ def generate_county(self, path: str) -> None:
print("County Objects Created Successfully")

def generate_district(self, path: str) -> None:
"""
Generate and populate the District table.
"""Generate and populate the District table.
Args:
path (str): The path to the CSV file containing district data.
"""
with open(path, encoding="utf-8") as f:
data = csv.DictReader(f)
Expand All @@ -176,11 +177,11 @@ def generate_district(self, path: str) -> None:
print("District Objects Created Successfully")

def generate_city(self, path: str) -> None:
"""
Generate and populate the City table.
"""Generate and populate the City table.
Args:
path (str): The path to the CSV file containing city data.
"""
with open(path, encoding="utf-8") as f:
data = csv.DictReader(f)
Expand All @@ -200,11 +201,11 @@ def generate_city(self, path: str) -> None:
print("City Objects Created Successfully")

def generate_rural_district(self, path: str) -> None:
"""
Generate and populate the RuralDistrict table.
"""Generate and populate the RuralDistrict table.
Args:
path (str): The path to the CSV file containing rural district data.
"""
with open(path, encoding="utf-8") as f:
data = csv.DictReader(f)
Expand All @@ -223,11 +224,11 @@ def generate_rural_district(self, path: str) -> None:
print("RuralDistrict Objects Created Successfully")

def generate_village(self, path: str) -> None:
"""
Generate and populate the Village table.
"""Generate and populate the Village table.
Args:
path (str): The path to the CSV file containing village data.
"""
with open(path, encoding="utf-8") as f:
data = csv.DictReader(f)
Expand All @@ -248,12 +249,12 @@ def generate_village(self, path: str) -> None:
print("Village Objects Created Successfully")

def handle(self, *args, **options) -> None:
"""
Handle the command execution, prompting user and generating data.
"""Handle the command execution, prompting user and generating data.
Args:
*args: Variable length argument list.
**options: Arbitrary keyword arguments.
"""
result, response = self.prompt_user()
if not result and response == "cancel":
Expand Down
4 changes: 1 addition & 3 deletions iranian_cities/mixins/base_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@


class BaseLocation(Model):
"""
Abstract base model for location entities.
"""
"""Abstract base model for location entities."""

name = CharField(
verbose_name=_("Name"),
Expand Down
4 changes: 1 addition & 3 deletions iranian_cities/mixins/dynamic_permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ def has_change_permission(self, request, obj=None):

class DynamicInlineAdmin:
def get_dynamic_inlines(self, model):
"""
Returns the list of inlines based on the settings.
"""
"""Returns the list of inlines based on the settings."""
from iranian_cities.admin import (
CityInline,
County,
Expand Down
Loading

0 comments on commit 1883202

Please sign in to comment.