[WEB-4805] fix: upgraded psycopgy packages to fix linting and removed unused imports (#7735)

* chore: update psycopg dependencies to version 3.2.9 in base requirements

* refactor: clean up unused imports across multiple files

* chore: update lxml dependency to version 6.0.0 in base requirements

* style: improve code readability by breaking long lines into multiple lines across several files

* style: enhance readability by breaking long lines in ModuleSerializer docstring
This commit is contained in:
Nikhil 2025-09-29 14:33:50 +05:30 committed by GitHub
parent e891482a97
commit 1fb22bd252
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 45 additions and 46 deletions

View File

@ -29,7 +29,8 @@ class BaseSerializer(serializers.ModelSerializer):
""" """
Adjust the serializer's fields based on the provided 'fields' list. Adjust the serializer's fields based on the provided 'fields' list.
:param fields: List or dictionary specifying which fields to include in the serializer. :param fields: List or dictionary specifying which
fields to include in the serializer.
:return: The updated fields for the serializer. :return: The updated fields for the serializer.
""" """
# Check each field_name in the provided fields. # Check each field_name in the provided fields.

View File

@ -43,7 +43,8 @@ class IssueSerializer(BaseSerializer):
Comprehensive work item serializer with full relationship management. Comprehensive work item serializer with full relationship management.
Handles complete work item lifecycle including assignees, labels, validation, Handles complete work item lifecycle including assignees, labels, validation,
and related model updates. Supports dynamic field expansion and HTML content processing. and related model updates. Supports dynamic field expansion and HTML content
processing.
""" """
assignees = serializers.ListField( assignees = serializers.ListField(

View File

@ -17,8 +17,9 @@ class ModuleCreateSerializer(BaseSerializer):
""" """
Serializer for creating modules with member validation and date checking. Serializer for creating modules with member validation and date checking.
Handles module creation including member assignment validation, date range verification, Handles module creation including member assignment validation, date range
and duplicate name prevention for feature-based project organization setup. verification, and duplicate name prevention for feature-based
project organization setup.
""" """
members = serializers.ListField( members = serializers.ListField(
@ -105,8 +106,9 @@ class ModuleUpdateSerializer(ModuleCreateSerializer):
""" """
Serializer for updating modules with enhanced validation and member management. Serializer for updating modules with enhanced validation and member management.
Extends module creation with update-specific validations including member reassignment, Extends module creation with update-specific validations including
name conflict checking, and relationship management for module modifications. member reassignment, name conflict checking,
and relationship management for module modifications.
""" """
class Meta(ModuleCreateSerializer.Meta): class Meta(ModuleCreateSerializer.Meta):
@ -155,8 +157,8 @@ class ModuleSerializer(BaseSerializer):
""" """
Comprehensive module serializer with work item metrics and member management. Comprehensive module serializer with work item metrics and member management.
Provides complete module data including work item counts by status, member relationships, Provides complete module data including work item counts by status, member
and progress tracking for feature-based project organization. relationships, and progress tracking for feature-based project organization.
""" """
members = serializers.ListField( members = serializers.ListField(

View File

@ -8,7 +8,7 @@ from django.conf import settings
# Third party imports # Third party imports
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from drf_spectacular.utils import OpenApiExample, OpenApiRequest, OpenApiTypes from drf_spectacular.utils import OpenApiExample, OpenApiRequest
# Module Imports # Module Imports
from plane.bgtasks.storage_metadata_task import get_asset_object_metadata from plane.bgtasks.storage_metadata_task import get_asset_object_metadata
@ -282,8 +282,9 @@ class UserServerAssetEndpoint(BaseAPIView):
def post(self, request): def post(self, request):
"""Generate presigned URL for user server asset upload. """Generate presigned URL for user server asset upload.
Create a presigned URL for uploading user profile assets (avatar or cover image) using server credentials. Create a presigned URL for uploading user profile assets
This endpoint generates the necessary credentials for direct S3 upload with server-side authentication. (avatar or cover image) using server credentials. This endpoint generates the
necessary credentials for direct S3 upload with server-side authentication.
""" """
# get the asset key # get the asset key
name = request.data.get("name") name = request.data.get("name")

View File

@ -30,12 +30,10 @@ from rest_framework.response import Response
# drf-spectacular imports # drf-spectacular imports
from drf_spectacular.utils import ( from drf_spectacular.utils import (
extend_schema, extend_schema,
OpenApiParameter,
OpenApiResponse, OpenApiResponse,
OpenApiExample, OpenApiExample,
OpenApiRequest, OpenApiRequest,
) )
from drf_spectacular.types import OpenApiTypes
# Module imports # Module imports
from plane.api.serializers import ( from plane.api.serializers import (
@ -99,7 +97,6 @@ from plane.utils.openapi import (
EXTERNAL_ID_PARAMETER, EXTERNAL_ID_PARAMETER,
EXTERNAL_SOURCE_PARAMETER, EXTERNAL_SOURCE_PARAMETER,
ORDER_BY_PARAMETER, ORDER_BY_PARAMETER,
SEARCH_PARAMETER,
SEARCH_PARAMETER_REQUIRED, SEARCH_PARAMETER_REQUIRED,
LIMIT_PARAMETER, LIMIT_PARAMETER,
WORKSPACE_SEARCH_PARAMETER, WORKSPACE_SEARCH_PARAMETER,

View File

@ -10,7 +10,7 @@ from django.core.serializers.json import DjangoJSONEncoder
# Third party imports # Third party imports
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from drf_spectacular.utils import OpenApiResponse, OpenApiExample, OpenApiRequest from drf_spectacular.utils import OpenApiResponse, OpenApiRequest
# Module imports # Module imports
from plane.api.serializers import ( from plane.api.serializers import (
@ -41,8 +41,6 @@ from plane.utils.host import base_host
from plane.utils.openapi import ( from plane.utils.openapi import (
module_docs, module_docs,
module_issue_docs, module_issue_docs,
WORKSPACE_SLUG_PARAMETER,
PROJECT_ID_PARAMETER,
MODULE_ID_PARAMETER, MODULE_ID_PARAMETER,
MODULE_PK_PARAMETER, MODULE_PK_PARAMETER,
ISSUE_ID_PARAMETER, ISSUE_ID_PARAMETER,

View File

@ -11,7 +11,7 @@ from django.core.serializers.json import DjangoJSONEncoder
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
from drf_spectacular.utils import OpenApiResponse, OpenApiExample, OpenApiRequest from drf_spectacular.utils import OpenApiResponse, OpenApiRequest
# Module imports # Module imports

View File

@ -4,7 +4,7 @@ from django.db import IntegrityError
# Third party imports # Third party imports
from rest_framework import status from rest_framework import status
from rest_framework.response import Response from rest_framework.response import Response
from drf_spectacular.utils import OpenApiResponse, OpenApiExample, OpenApiRequest from drf_spectacular.utils import OpenApiResponse, OpenApiRequest
# Module imports # Module imports
from plane.api.serializers import StateSerializer from plane.api.serializers import StateSerializer

View File

@ -1,4 +1,3 @@
from lxml import html
# Django imports # Django imports
from django.utils import timezone from django.utils import timezone

View File

@ -1,4 +1,3 @@
from lxml import html
# Django imports # Django imports
from django.utils import timezone from django.utils import timezone

View File

@ -1,6 +1,5 @@
# Python imports # Python imports
import json import json
import base64
from datetime import datetime from datetime import datetime
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder

View File

@ -39,9 +39,6 @@ from plane.db.models import (
Profile, Profile,
) )
from plane.app.permissions import ROLE, allow_permission from plane.app.permissions import ROLE, allow_permission
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control
from django.views.decorators.vary import vary_on_cookie
from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS from plane.utils.constants import RESTRICTED_WORKSPACE_SLUGS
from plane.license.utils.instance_value import get_configuration_value from plane.license.utils.instance_value import get_configuration_value
from plane.bgtasks.workspace_seed_task import workspace_seed from plane.bgtasks.workspace_seed_task import workspace_seed

View File

@ -1,6 +1,5 @@
import pytest import pytest
from rest_framework import status from rest_framework import status
from django.db import IntegrityError
from uuid import uuid4 from uuid import uuid4
from plane.db.models import Label, Project, ProjectMember from plane.db.models import Label, Project, ProjectMember

View File

@ -27,7 +27,7 @@ class TestCopyS3Objects:
name="Test Issue", name="Test Issue",
workspace=workspace, workspace=workspace,
project_id=project.id, project_id=project.id,
description_html=f'<div><image-component src="35e8b958-6ee5-43ce-ae56-fb0e776f421e"></image-component><image-component src="97988198-274f-4dfe-aa7a-4c0ffc684214"></image-component></div>', description_html='<div><image-component src="35e8b958-6ee5-43ce-ae56-fb0e776f421e"></image-component><image-component src="97988198-274f-4dfe-aa7a-4c0ffc684214"></image-component></div>',
) )
@pytest.fixture @pytest.fixture

View File

@ -2,7 +2,6 @@ import pytest
from plane.utils.url import ( from plane.utils.url import (
contains_url, contains_url,
is_valid_url, is_valid_url,
get_url_components,
normalize_url_path, normalize_url_path,
) )

View File

@ -499,7 +499,7 @@ ISSUE_COMMENT_EXAMPLE = OpenApiExample(
name="IssueComment", name="IssueComment",
value={ value={
"id": "550e8400-e29b-41d4-a716-446655440000", "id": "550e8400-e29b-41d4-a716-446655440000",
"comment_html": "<p>This issue has been resolved by implementing OAuth 2.0 flow.</p>", "comment_html": "<p>This issue has been resolved by implementing OAuth 2.0 flow.</p>", # noqa: E501
"comment_json": { "comment_json": {
"type": "doc", "type": "doc",
"content": [ "content": [
@ -508,7 +508,7 @@ ISSUE_COMMENT_EXAMPLE = OpenApiExample(
"content": [ "content": [
{ {
"type": "text", "type": "text",
"text": "This issue has been resolved by implementing OAuth 2.0 flow.", "text": "This issue has been resolved by implementing OAuth 2.0 flow.", # noqa: E501
} }
], ],
} }
@ -551,7 +551,7 @@ ISSUE_ATTACHMENT_NOT_UPLOADED_EXAMPLE = OpenApiExample(
"error": "The asset is not uploaded.", "error": "The asset is not uploaded.",
"status": False, "status": False,
}, },
description="Error when trying to download an attachment that hasn't been uploaded yet", description="Error when trying to download an attachment that hasn't been uploaded yet", # noqa: E501
) )
# Intake Issue Response Examples # Intake Issue Response Examples
@ -733,7 +733,7 @@ SAMPLE_STATE = {
SAMPLE_COMMENT = { SAMPLE_COMMENT = {
"id": "550e8400-e29b-41d4-a716-446655440000", "id": "550e8400-e29b-41d4-a716-446655440000",
"comment_html": "<p>This issue needs more investigation. I'll look into the database connection timeout.</p>", "comment_html": "<p>This issue needs more investigation. I'll look into the database connection timeout.</p>", # noqa: E501
"created_at": "2024-01-15T14:20:00Z", "created_at": "2024-01-15T14:20:00Z",
"actor": {"id": "550e8400-e29b-41d4-a716-446655440002", "display_name": "John Doe"}, "actor": {"id": "550e8400-e29b-41d4-a716-446655440002", "display_name": "John Doe"},
} }

View File

@ -336,7 +336,7 @@ ORDER_BY_PARAMETER = OpenApiParameter(
OpenApiExample( OpenApiExample(
name="State group", name="State group",
value="state__group", value="state__group",
description="Order by state group (backlog, unstarted, started, completed, cancelled)", description="Order by state group (backlog, unstarted, started, completed, cancelled)", # noqa: E501
), ),
OpenApiExample( OpenApiExample(
name="Assignee name", name="Assignee name",

View File

@ -221,7 +221,7 @@ EXTERNAL_ID_EXISTS_RESPONSE = OpenApiResponse(
OpenApiExample( OpenApiExample(
name="External ID Exists", name="External ID Exists",
value={ value={
"error": "Resource with the same external id and external source already exists", "error": "Resource with the same external id and external source already exists", # noqa: E501
"id": "550e8400-e29b-41d4-a716-446655440000", "id": "550e8400-e29b-41d4-a716-446655440000",
}, },
) )

View File

@ -221,7 +221,8 @@ class GroupedOffsetPaginator(OffsetPaginator):
self.group_by_field_name = group_by_field_name self.group_by_field_name = group_by_field_name
# Set the group by fields # Set the group by fields
self.group_by_fields = group_by_fields self.group_by_fields = group_by_fields
# Set the count filter - this are extra filters that need to be passed to calculate the counts with the filters # Set the count filter - this are extra filters that need to be passed
# to calculate the counts with the filters
self.count_filter = count_filter self.count_filter = count_filter
def get_result(self, limit=50, cursor=None): def get_result(self, limit=50, cursor=None):
@ -434,7 +435,8 @@ class SubGroupedOffsetPaginator(OffsetPaginator):
self.sub_group_by_field_name = sub_group_by_field_name self.sub_group_by_field_name = sub_group_by_field_name
self.sub_group_by_fields = sub_group_by_fields self.sub_group_by_fields = sub_group_by_fields
# Set the count filter - this are extra filters that need to be passed to calculate the counts with the filters # Set the count filter - this are extra filters that need
# to be passed to calculate the counts with the filters
self.count_filter = count_filter self.count_filter = count_filter
def get_result(self, limit=30, cursor=None): def get_result(self, limit=30, cursor=None):

View File

@ -10,11 +10,11 @@ URL_PATTERN = re.compile(
r"(?:" # Non-capturing group for alternatives r"(?:" # Non-capturing group for alternatives
r"https?://[^\s]+" # http:// or https:// followed by non-whitespace r"https?://[^\s]+" # http:// or https:// followed by non-whitespace
r"|" r"|"
r"www\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*" # www.domain with proper length limits r"www\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*" # noqa: E501
r"|" r"|"
r"(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}" # domain.tld with length limits r"(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}" # noqa: E501
r"|" r"|"
r"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" # IP address with proper validation r"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" # noqa: E501
r")" r")"
) )
@ -85,7 +85,10 @@ def get_url_components(url: str) -> Optional[dict]:
Example: Example:
>>> get_url_components("https://example.com/path?query=1") >>> get_url_components("https://example.com/path?query=1")
{'scheme': 'https', 'netloc': 'example.com', 'path': '/path', 'params': '', 'query': 'query=1', 'fragment': ''} {
'scheme': 'https', 'netloc': 'example.com',
'path': '/path', 'params': '',
'query': 'query=1', 'fragment': ''}
""" """
if not is_valid_url(url): if not is_valid_url(url):
return None return None
@ -102,9 +105,11 @@ def get_url_components(url: str) -> Optional[dict]:
def normalize_url_path(url: str) -> str: def normalize_url_path(url: str) -> str:
""" """
Normalize the path component of a URL by replacing multiple consecutive slashes with a single slash. Normalize the path component of a URL by
replacing multiple consecutive slashes with a single slash.
This function preserves the protocol, domain, query parameters, and fragments of the URL, This function preserves the protocol, domain,
query parameters, and fragments of the URL,
only modifying the path portion to ensure there are no duplicate slashes. only modifying the path portion to ensure there are no duplicate slashes.
Args: Args:

View File

@ -5,9 +5,9 @@ Django==4.2.24
# rest framework # rest framework
djangorestframework==3.15.2 djangorestframework==3.15.2
# postgres # postgres
psycopg==3.1.18 psycopg==3.2.9
psycopg-binary==3.1.18 psycopg-binary==3.2.9
psycopg-c==3.1.18 psycopg-c==3.2.9
dj-database-url==2.1.0 dj-database-url==2.1.0
# mongo # mongo
pymongo==4.6.3 pymongo==4.6.3
@ -53,7 +53,7 @@ posthog==3.5.0
# crypto # crypto
cryptography==44.0.1 cryptography==44.0.1
# html validator # html validator
lxml==5.2.1 lxml==6.0.0
# s3 # s3
boto3==1.34.96 boto3==1.34.96
# password validator # password validator