diff --git a/pylint_django/tests/input/func_noerror_model_enum.py b/pylint_django/tests/input/func_noerror_model_enum.py new file mode 100644 index 00000000..91b38a74 --- /dev/null +++ b/pylint_django/tests/input/func_noerror_model_enum.py @@ -0,0 +1,23 @@ +""" +Test that django TextChoices does not raise a warning due to .label and .value methods +""" +# pylint: disable=missing-docstring,too-few-public-methods + +from django.db import models + + +class SomeTextChoices(models.TextChoices): + CHOICE_A = ("choice_a", "Choice A") + CHOICE_B = ("choice_b", "Choice B") + CHOICE_C = ("choice_c", "Choice C") + + +class SomeClass(): + choice_values = [ + SomeTextChoices.CHOICE_A.value, + SomeTextChoices.CHOICE_B.value, + ] + choice_labels = [ + SomeTextChoices.CHOICE_B.label, + SomeTextChoices.CHOICE_C.label, + ] diff --git a/pylint_django/transforms/__init__.py b/pylint_django/transforms/__init__.py index 03930d3d..2154c47f 100644 --- a/pylint_django/transforms/__init__.py +++ b/pylint_django/transforms/__init__.py @@ -13,10 +13,10 @@ import astroid -from pylint_django.transforms import fields +from pylint_django.transforms import fields, text_choices fields.add_transforms(astroid.MANAGER) - +text_choices.add_transforms(astroid.MANAGER) def _add_transform(package_name): def fake_module_builder(): diff --git a/pylint_django/transforms/text_choices.py b/pylint_django/transforms/text_choices.py new file mode 100644 index 00000000..d923e656 --- /dev/null +++ b/pylint_django/transforms/text_choices.py @@ -0,0 +1,70 @@ +from astroid import MANAGER, scoped_nodes, nodes, inference_tip + +from pylint_django import utils + +class_names = set() + +def is_tuple_in_text_choices(node): + # file_name = node.root().file + # if file_name not in file_names: + # file_names.update({file_name}) + # import ipdb; ipdb.set_trace() + # else: + # return False + + if not (isinstance(node.parent, nodes.Assign) + or isinstance(node.parent, nodes.FunctionDef)) : + return False + if not isinstance(node.parent.parent, nodes.ClassDef): + return False + if "TextChoices" in [i.name for i in node.parent.parent.bases]: + import ipdb; ipdb.set_trace() + + class_name = node.parent.parent.name + if class_name not in class_names: + class_names.update({class_name}) + # import ipdb; ipdb.set_trace() + else: + return False + + # if node.parent.parent.name == "SomeTextChoices": + # import ipdb; ipdb.set_trace() + # else: + # return False + + # if node.parent.parent.parent.name in ["TextChoices", "SomeClass", "ChoicesMeta", "TextChoices"]: + # import ipdb; ipdb.set_trace() + # else: + # return False + + # if node.root().file.endswith("enums.py"): + # import ipdb; ipdb.set_trace() + # else: + # return False + + # try: + # if node.root().file.endswith("model_enum.py"): + # import ipdb; ipdb.set_trace() + # except: + # import ipdb; ipdb.set_trace() + # if (node.parent.parent.name != "LazyObject" + # and node.parent.parent.parent.name != "django.db.models.expressions" + # and node.parent.parent.parent.name != "django.db.models.fields"): + # import ipdb; ipdb.set_trace() + + if isinstance(node.func, nodes.Attribute): + attr = node.func.attrname + elif isinstance(node.func, nodes.Name): + attr = node.func.name + else: + return False + return True + + +def infer_key_classes(node, context=None): + pass + + +def add_transforms(manager): + manager.register_transform(nodes.Call, inference_tip(infer_key_classes), + is_tuple_in_text_choices)