Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔧 Update pre-commit config #47

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading