Skip to content

Commit bcacc61

Browse files
marc-jasper-sonarsourcesonartech
authored andcommitted
SONARPY-3855 Fix typo in the Django Model class stub file (#902)
GitOrigin-RevId: 801fa94069c36f85b167800511af38f63c1946d2
1 parent 772831e commit bcacc61

File tree

10 files changed

+83
-48
lines changed

10 files changed

+83
-48
lines changed

python-checks/src/main/java/org/sonar/python/checks/django/DjangoModelStrMethodCheck.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616
*/
1717
package org.sonar.python.checks.django;
1818

19-
import java.util.List;
2019
import java.util.Objects;
2120
import java.util.Optional;
2221
import org.sonar.check.Rule;
2322
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
23+
import org.sonar.plugins.python.api.SubscriptionContext;
2424
import org.sonar.plugins.python.api.symbols.Symbol;
2525
import org.sonar.plugins.python.api.tree.ClassDef;
26+
import org.sonar.plugins.python.api.tree.RegularArgument;
2627
import org.sonar.plugins.python.api.tree.Tree;
28+
import org.sonar.plugins.python.api.types.v2.matchers.TypeMatcher;
29+
import org.sonar.plugins.python.api.types.v2.matchers.TypeMatchers;
2730
import org.sonar.python.checks.utils.Expressions;
2831
import org.sonar.python.tree.TreeUtils;
2932

@@ -34,14 +37,13 @@
3437
public class DjangoModelStrMethodCheck extends PythonSubscriptionCheck {
3538

3639
public static final String MESSAGE = "Define a \"__str__\" method for this Django model.";
37-
private static final List<String> DJANGO_MODEL_FQN = List.of("django.db.models.Model");
40+
private static final TypeMatcher IS_DJANGO_MODEL = TypeMatchers.isType("django.db.models.base.Model");
3841

3942
@Override
4043
public void initialize(Context context) {
4144
context.registerSyntaxNodeConsumer(Tree.Kind.CLASSDEF, ctx -> {
4245
var classDef = (ClassDef) ctx.syntaxNode();
43-
var parentClassesFQN = TreeUtils.getParentClassesFQN(classDef);
44-
if (DJANGO_MODEL_FQN.equals(parentClassesFQN)) {
46+
if (isDirectDjangoModelSubclass(classDef, ctx)) {
4547
if (isAbstractModel(classDef)) {
4648
return;
4749
}
@@ -54,6 +56,18 @@ public void initialize(Context context) {
5456
});
5557
}
5658

59+
private static boolean isDirectDjangoModelSubclass(ClassDef classDef, SubscriptionContext ctx) {
60+
var args = classDef.args();
61+
if (args == null) {
62+
return false;
63+
}
64+
return args.arguments().stream()
65+
.filter(RegularArgument.class::isInstance)
66+
.map(RegularArgument.class::cast)
67+
.map(RegularArgument::expression)
68+
.anyMatch(expr -> IS_DJANGO_MODEL.isTrueFor(expr, ctx));
69+
}
70+
5771
private static boolean isAbstractModel(ClassDef classDef) {
5872
return getMetaClass(classDef)
5973
.flatMap(metaClass -> getFieldAssignment(metaClass, "abstract"))

python-checks/src/main/java/org/sonar/python/checks/django/DjangoModelStringFieldCheck.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import org.sonar.plugins.python.api.tree.Statement;
3535
import org.sonar.plugins.python.api.tree.StatementList;
3636
import org.sonar.plugins.python.api.tree.Tree;
37+
import org.sonar.plugins.python.api.types.v2.matchers.TypeMatcher;
38+
import org.sonar.plugins.python.api.types.v2.matchers.TypeMatchers;
3739
import org.sonar.python.quickfix.TextEditUtils;
3840
import org.sonar.python.tree.TreeUtils;
3941

@@ -45,7 +47,7 @@ public class DjangoModelStringFieldCheck extends PythonSubscriptionCheck {
4547
private static final String REPLACE_QUICK_FIX_MESSAGE = "Replace with \"blank=True\"";
4648
private static final String REMOVE_QUICK_FIX_MESSAGE = "Remove the \"null=true\" flag";
4749

48-
private static final String DJANGO_MODEL_FQN = "django.db.models.Model";
50+
private static final TypeMatcher IS_DJANGO_MODEL = TypeMatchers.isOrExtendsType("django.db.models.base.Model");
4951
public static final Set<String> FIELD_TYPES_FQN = Set.of(
5052
"django.db.models.CharField",
5153
"django.db.models.TextField"
@@ -55,7 +57,7 @@ public class DjangoModelStringFieldCheck extends PythonSubscriptionCheck {
5557
public void initialize(Context context) {
5658
context.registerSyntaxNodeConsumer(Tree.Kind.CLASSDEF, ctx -> {
5759
var classDef = (ClassDef) ctx.syntaxNode();
58-
if (TreeUtils.getParentClassesFQN(classDef).contains(DJANGO_MODEL_FQN)) {
60+
if (IS_DJANGO_MODEL.isTrueFor(classDef.name(), ctx)) {
5961
var modelClassBodyStatements = classDef.body().statements();
6062

6163
if (isNotManaged(modelClassBodyStatements)) {

python-frontend/src/main/resources/org/sonar/python/types/custom_protobuf/django.apps.config.protobuf

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
django.apps.config�
2+
django.apps.config�
33
AppConfigdjango.apps.config.AppConfig"builtins.object*�
44
__init__%django.apps.config.AppConfig.__init__"
55
None*F
@@ -8,22 +8,22 @@
88
args
99
Any*
1010
kwargs
11-
Any*�
12-
get_model&django.apps.config.AppConfig.get_model"
13-
Type[Any]
14-
Any"type*F
11+
Any*�
12+
get_model&django.apps.config.AppConfig.get_model"g
13+
!Type[django.db.models.base.Model]:
14+
django.db.models.base.Model"django.db.models.base.Model"type*F
1515
self<
1616
django.apps.config.AppConfig"django.apps.config.AppConfig*,
1717

1818
model_name
1919
builtins.str" builtins.str*3
2020
require_ready
21-
builtins.bool"builtins.bool *�
21+
builtins.bool"builtins.bool *�
2222

23-
get_models'django.apps.config.AppConfig.get_models"K
24-
typing.Iterator[Type[Any]]
25-
Type[Any]
26-
Any"type"typing.Iterator*F
23+
get_models'django.apps.config.AppConfig.get_models"�
24+
2typing.Iterator[Type[django.db.models.base.Model]]g
25+
!Type[django.db.models.base.Model]:
26+
django.db.models.base.Model"django.db.models.base.Model"type"typing.Iterator*F
2727
self<
2828
django.apps.config.AppConfig"django.apps.config.AppConfig*:
2929
include_auto_created
@@ -33,6 +33,4 @@ get_models'django.apps.config.AppConfig.get_models"K
3333
__annotations__"django.apps.config.__annotations__W
3434
builtins.dict[builtins.str,Any]
3535
builtins.str" builtins.str
36-
Any"builtins.dict**
37-
Modeldjango.apps.config.Model
38-
Any
36+
Any"builtins.dict

python-frontend/src/main/resources/org/sonar/python/types/custom_protobuf/django.apps.protobuf

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
django.apps�
2+
django.apps�
33
AppConfigdjango.apps.config.AppConfig"builtins.object*�
44
__init__%django.apps.config.AppConfig.__init__"
55
None*F
@@ -8,22 +8,22 @@
88
args
99
Any*
1010
kwargs
11-
Any*�
12-
get_model&django.apps.config.AppConfig.get_model"
13-
Type[Any]
14-
Any"type*F
11+
Any*�
12+
get_model&django.apps.config.AppConfig.get_model"g
13+
!Type[django.db.models.base.Model]:
14+
django.db.models.base.Model"django.db.models.base.Model"type*F
1515
self<
1616
django.apps.config.AppConfig"django.apps.config.AppConfig*,
1717

1818
model_name
1919
builtins.str" builtins.str*3
2020
require_ready
21-
builtins.bool"builtins.bool *�
21+
builtins.bool"builtins.bool *�
2222

23-
get_models'django.apps.config.AppConfig.get_models"K
24-
typing.Iterator[Type[Any]]
25-
Type[Any]
26-
Any"type"typing.Iterator*F
23+
get_models'django.apps.config.AppConfig.get_models"�
24+
2typing.Iterator[Type[django.db.models.base.Model]]g
25+
!Type[django.db.models.base.Model]:
26+
django.db.models.base.Model"django.db.models.base.Model"type"typing.Iterator*F
2727
self<
2828
django.apps.config.AppConfig"django.apps.config.AppConfig*:
2929
include_auto_created

python-frontend/src/main/resources/org/sonar/python/types/custom_protobuf/django.apps.registry.protobuf

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
django.apps.registry�
2+
django.apps.registry�
33
Appsdjango.apps.registry.Apps"builtins.object*�
44
__init__"django.apps.registry.Apps.__init__"
55
None*@
@@ -8,21 +8,21 @@
88
args
99
Any*
1010
kwargs
11-
Any*�
11+
Any*�
1212

13-
get_models$django.apps.registry.Apps.get_models"G
14-
builtins.list[Type[Any]]
15-
Type[Any]
16-
Any"type"builtins.list*@
13+
get_models$django.apps.registry.Apps.get_models"�
14+
0builtins.list[Type[django.db.models.base.Model]]g
15+
!Type[django.db.models.base.Model]:
16+
django.db.models.base.Model"django.db.models.base.Model"type"builtins.list*@
1717
self6
1818
django.apps.registry.Apps"django.apps.registry.Apps*:
1919
include_auto_created
2020
builtins.bool"builtins.bool *5
2121
include_swapped
22-
builtins.bool"builtins.bool *�
23-
get_model#django.apps.registry.Apps.get_model"
24-
Type[Any]
25-
Any"type*@
22+
builtins.bool"builtins.bool *�
23+
get_model#django.apps.registry.Apps.get_model"g
24+
!Type[django.db.models.base.Model]:
25+
django.db.models.base.Model"django.db.models.base.Model"type*@
2626
self6
2727
django.apps.registry.Apps"django.apps.registry.Apps*+
2828
app_label
@@ -37,8 +37,6 @@ model_nameD
3737
__annotations__$django.apps.registry.__annotations__W
3838
builtins.dict[builtins.str,Any]
3939
builtins.str" builtins.str
40-
Any"builtins.dict*,
41-
Modeldjango.apps.registry.Model
42-
Any*Y
40+
Any"builtins.dict*Y
4341
appsdjango.apps.registry.apps6
4442
django.apps.registry.Apps"django.apps.registry.Apps

python-frontend/src/main/resources/org/sonar/python/types/custom_protobuf/django.db.models.base.protobuf

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
django.db.models.base;
3+
ModelBasedjango.db.models.base.ModelBase"builtins.type�
4+
Modeldjango.db.models.base.Model"builtins.object*�
5+
__init__$django.db.models.base.Model.__init__"
6+
None*D
7+
self:
8+
django.db.models.base.Model"django.db.models.base.Model*
9+
args
10+
Any*
11+
kwargs
12+
Any@bdjango.db.models.base.ModelBase*�
13+
__annotations__%django.db.models.base.__annotations__W
14+
builtins.dict[builtins.str,Any]
15+
builtins.str" builtins.str
16+
Any"builtins.dict

python-frontend/src/main/resources/org/sonar/python/types/custom_protobuf/django.db.models.protobuf

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,21 @@
1010
kwargs
1111
Anyrw
1212
object'django.db.models.manager.Manager.objectD
13-
django.db.models.manager.Manager" django.db.models.manager.Manager*q
13+
django.db.models.manager.Manager" django.db.models.manager.Manager�
14+
Modeldjango.db.models.base.Model"builtins.object*�
15+
__init__$django.db.models.base.Model.__init__"
16+
None*D
17+
self:
18+
django.db.models.base.Model"django.db.models.base.Model*
19+
args
20+
Any*
21+
kwargs
22+
Any@bdjango.db.models.base.ModelBase*q
1423
__path__django.db.models.__path__J
1524
builtins.list[builtins.str]
1625
builtins.str" builtins.str"builtins.list*�
1726
__annotations__ django.db.models.__annotations__W
1827
builtins.dict[builtins.str,Any]
1928
builtins.str" builtins.str
2029
Any"builtins.dict*%
21-
managerdjango.db.models.manager *(
22-
Modeldjango.db.models.Model
23-
Any
30+
managerdjango.db.models.manager 
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
ff99a5ab4ee8349e8b21eeb3668e2e4990aa198e31cc27ca31aee9299e0bed67
2-
5ed498acd62426c597e0c2ab3ff0ab186b5cc72f27538e9d7627a996c36f4568
2+
7886ceeda4958304a326174baba1ff7ac6c0298352b3e9699aa7322185d94f69

python-frontend/typeshed_serializer/resources/custom/django/db/models/base.ipy renamed to python-frontend/typeshed_serializer/resources/custom/django/db/models/base.pyi

File renamed without changes.

python-frontend/typeshed_serializer/tests/test_serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def test_custom_stubs_serializer(typeshed_custom_stubs):
7474
custom_stubs_serializer.serialize()
7575
assert custom_stubs_serializer.get_build_result.call_count == 1
7676
# Not every files from "typeshed_custom_stubs" build are serialized, as some are builtins
77-
assert symbols.save_module.call_count == 335
77+
assert symbols.save_module.call_count == 336
7878

7979

8080
def test_importer_serializer():

0 commit comments

Comments
 (0)