refactor(name_validator): improve name validation logic for clarity and maintainability

This commit is contained in:
sankalp committed 2025-10-28 21:16:48 +05:45
1 parent 32a9b6a47f
commit 9263f97ee1
1 file changed
+28 -28
+28 -28
View File
@@ -6,47 +6,47 @@ Handles validation of project names, app names, and other user inputs.
import keyword import keyword
import re import re
import sys import sys
from typing import Tuple from typing import Any, Callable, Tuple
# Names that conflict with Django's strcuture # Names that conflict with Django's structure
DJANGO_RESERVED = {"django", "test", "site-packages", "admin"} DJANGO_RESERVED = {"django", "test", "site-packages", "admin"}
# Common Python builtin modules # Common Python builtin modules
PYTHON_BUILTINS = set(sys.builtin_module_names) PYTHON_BUILTINS = set(sys.builtin_module_names)
NAME_PATTERYN = re.compile(r"^[a-zA-Z][a-zA-Z0-9_]*$") NAME_PATTERN = re.compile(r"^[a-zA-Z][a-zA-Z0-9_]*$")
def _validate_name(name:str, name_type: str = "name") -> Tuple[bool, str]:
if not name or not name.strip()
return False, f"{name_type.capitalize()} cannot be empty"
name = name.strip() def _validate_name(name: str, name_type: str = "name") -> Tuple[bool, str]:
validation_rules: list[Tuple[Callable[[str], Any], str]] = [
(lambda n: bool(n and n.strip()), f"{name_type.capitalize()} cannot be empty"),
(lambda n: len(n.strip()) >= 2, f"{name_type.capitalize()} must be at least 2 characters long"),
(lambda n: len(n.strip()) <= 50, f"{name_type.capitalize()} must be less than 50 characters"),
(
lambda n: NAME_PATTERN.match(n.strip()),
f"{name_type.capitalize()} must start with a letter and contain only letters, numbers, and underscores",
),
(
lambda n: not keyword.iskeyword(n.strip()),
f"'{n.strip()}' is a Python keyword. Please choose a different name",
),
(
lambda n: n.strip().lower() not in PYTHON_BUILTINS,
f"'{n.strip()}' conflicts with Python builtin module. Choose a different name",
),
(lambda n: not n.strip().startswith("_"), f"{name_type.capitalize()} should not start with underscore"),
]
if len(name) < 2: for rule, error_message in validation_rules:
return False, f"{name_type.capitalize()} must be at least 2 characters long" if not rule(name):
return False, error_message
if len(name) > 50:
return False, f"{name_type.capitalize()} must be less than 50 characters"
if not NAME_PATTERYN.match(name):
return(
False,
f"{name_type.capitalize()} must start with a letter and contain only letters, numbers, and underscores"
)
if keyword.iskeyword(name):
return False, f"'{name}' is a Python keyword, Please choose a different name."
if name.lower() in PYTHON_BUILTINS:
return False, f"'{name}', conflicts with Python builtin module. Chooose a different name."
if name.startswith("_"):
return False, f"{name_type.capitalize()} should not start with underscore"
return True, "" return True, ""
def validate_project_name(name: str) -> Tuple[bool, str]: def validate_project_name(name: str) -> Tuple[bool, str]:
return _validate_name(name, "project_name") return _validate_name(name, "project name")
def validate_app_name(name: str) -> Tuple[bool, str]: def validate_app_name(name: str) -> Tuple[bool, str]:
return _validate_name(name, "app name") return _validate_name(name, "app name")