Skip to content

Commit 13e7676

Browse files
Bump Prospector 1.18.0 (#334)
* Bump prospector 1.18.0 * refactor configuration during tool run
1 parent 58cb9f3 commit 13e7676

10 files changed

Lines changed: 51 additions & 156 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ target
1111
__pycache__
1212
.mypy_cache
1313
default.profraw
14+
15+
16+
#Ignore vscode AI rules
17+
.github/instructions/codacy.instructions.md

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.11-alpine3.22
1+
FROM python:3.14-alpine3.23
22
COPY requirements.txt requirements.txt
33
RUN pip3 install --no-cache-dir -r requirements.txt
44
COPY src/codacy_prospector.py codacy_prospector.py

docs/multiple-tests/capitalized/results.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,11 @@
33
<file name="example.py">
44
<error source="vulture" line="1" message="Unused function 'non_capitalized' (unused-function)" severity="info" />
55
<error source="vulture" line="6" message="Unused function 'capitalized' (unused-function)" severity="info" />
6+
<error source="pydocstyle" line="2" message="First word of the first line should be properly capitalized ('Compute', not 'compute') (D403)" severity="info" />
7+
<error source="pydocstyle" line="2" message="Multi-line docstring summary should start at the first line (D212)" severity="info" />
8+
<error source="pydocstyle" line="7" message="Multi-line docstring summary should start at the first line (D212)" severity="info" />
9+
<error source="pydocstyle" line="2" message="One-line docstring should fit on one line with quotes (found 3) (D200)" severity="info" />
10+
<error source="pydocstyle" line="7" message="One-line docstring should fit on one line with quotes (found 3) (D200)" severity="info" />
11+
612
</file>
713
</checkstyle>

docs/multiple-tests/no-crash/results.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<checkstyle version="1.5">
33
<file name="example.py">
44
<error source="pycodestyle" line="1" message="block comment should start with '# ' (E265)" severity="info" />
5-
<error source="pylint" line="2" message="Comparison between constants: '1 == 2' has a constant value (comparison-of-constants)" severity="info" />
5+
<error source="pylint" line="2" message="Undefined variable 'a' (undefined-variable)" severity="info" />
66
<error source="pycodestyle" line="3" message="block comment should start with '# ' (E265)" severity="info" />
77
</file>
88
</checkstyle>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
##Patterns: W0311
2-
if 1 == 2:
2+
if a == b:
33
##Info: W0311
44
pass
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?xml version="1.0" encoding="utf-8" ?>
22
<checkstyle version="1.5">
33
<file name="example.py">
4-
<error source="pydocstyle" line="1" message="Multi-line docstring summary should start at the first line (D212)" severity="info" />
5-
<error source="pylint" line="99" message="No value for argument 'on_delete' in constructor call (no-value-for-parameter)" severity="info" />
6-
<error source="pylint" line="100" message="No value for argument 'on_delete' in constructor call (no-value-for-parameter)" severity="info" />
7-
<error source="pylint" line="114" message="No value for argument 'on_delete' in constructor call (no-value-for-parameter)" severity="info" />
8-
<error source="pylint" line="125" message="No value for argument 'on_delete' in constructor call (no-value-for-parameter)" severity="info" />
4+
<error source="pylint" line="1" message="Unused import os (unused-import)" severity="info" />
5+
<error source="pylint" line="4" message="Line too long (127/120) (line-too-long)" severity="info" />
6+
<error source="pycodestyle" line="6" message="expected 2 blank lines, found 1 (E302)" severity="info" />
7+
<error source="pylint" line="14" message="Trailing whitespace (trailing-whitespace)" severity="info" />
8+
<error source="pylint" line="16" message="Trailing whitespace (trailing-whitespace)" severity="info" />
9+
<error source="pylint" line="17" message="Final newline missing (missing-final-newline)" severity="info" />
910
</file>
1011
</checkstyle>
Lines changed: 17 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,136 +1,17 @@
1-
"""
2-
Checks that Pylint does not complain about various
3-
methods on Django model fields.
4-
"""
5-
# pylint: disable=C0111
6-
from __future__ import print_function
7-
from datetime import datetime, date
8-
from decimal import Decimal
9-
from django.db import models
10-
from django.db.models import ForeignKey, OneToOneField
11-
12-
13-
class LotsOfFieldsModel(models.Model):
14-
15-
bigintegerfield = models.BigIntegerField()
16-
booleanfield = models.BooleanField(default=True)
17-
charfield = models.CharField(max_length=40, null=True)
18-
commaseparatedintegerfield = models.CommaSeparatedIntegerField()
19-
datetimefield = models.DateTimeField(auto_now_add=True)
20-
datefield = models.DateField(auto_now_add=True)
21-
decimalfield = models.DecimalField(max_digits=5, decimal_places=2)
22-
emailfield = models.EmailField()
23-
filefield = models.FileField(name='test_file', upload_to='test')
24-
filepathfield = models.FilePathField()
25-
floatfield = models.FloatField()
26-
genericipaddressfield = models.GenericIPAddressField()
27-
imagefield = models.ImageField(name='test_image', upload_to='test')
28-
ipaddressfield = models.IPAddressField()
29-
intfield = models.IntegerField(null=True)
30-
nullbooleanfield = models.NullBooleanField()
31-
positiveintegerfield = models.PositiveIntegerField()
32-
positivesmallintegerfield = models.PositiveSmallIntegerField()
33-
slugfield = models.SlugField()
34-
smallintegerfield = models.SmallIntegerField()
35-
textfield = models.TextField()
36-
timefield = models.TimeField()
37-
urlfield = models.URLField()
38-
39-
def boolean_field_tests(self):
40-
print(self.booleanfield | True)
41-
print(self.nullbooleanfield | True)
42-
43-
def string_field_tests(self):
44-
print(self.charfield.strip())
45-
print(self.charfield.upper())
46-
print(self.charfield.replace('x', 'y'))
47-
48-
print(self.filepathfield.strip())
49-
print(self.filepathfield.upper())
50-
print(self.filepathfield.replace('x', 'y'))
51-
52-
print(self.emailfield.strip())
53-
print(self.emailfield.upper())
54-
print(self.emailfield.replace('x', 'y'))
55-
56-
print(self.textfield.strip())
57-
print(self.textfield.upper())
58-
print(self.textfield.replace('x', 'y'))
59-
60-
def datetimefield_tests(self):
61-
now = datetime.now()
62-
print(now - self.datetimefield)
63-
print(self.datetimefield.ctime())
64-
65-
def datefield_tests(self):
66-
now = date.today()
67-
print(now - self.datefield)
68-
print(self.datefield.isoformat())
69-
70-
def decimalfield_tests(self):
71-
print(self.decimalfield.compare(Decimal('1.4')))
72-
73-
def filefield_tests(self):
74-
print(self.filefield.file)
75-
print(self.imagefield.file)
76-
77-
def numberfield_tests(self):
78-
print(self.intfield + 5)
79-
print(self.bigintegerfield + 4)
80-
print(self.smallintegerfield + 3)
81-
print(self.positiveintegerfield + 2)
82-
print(self.positivesmallintegerfield + 1)
83-
84-
85-
class SomeModel(models.Model):
86-
pass
87-
88-
89-
class Author(models.Model):
90-
author_name = models.CharField(max_length=100)
91-
92-
93-
class ISBN(models.Model):
94-
value = models.CharField(max_length=100)
95-
96-
97-
class Book(models.Model):
98-
book_name = models.CharField(max_length=100)
99-
author = models.ForeignKey(Author)
100-
isbn = models.OneToOneField(ISBN)
101-
102-
def get_isbn(self):
103-
return self.isbn.value
104-
105-
def get_author_name(self):
106-
return self.author.author_name
107-
108-
109-
class Fruit(models.Model):
110-
fruit_name = models.CharField(max_length=20)
111-
112-
113-
class Seed(models.Model):
114-
fruit = ForeignKey(Fruit)
115-
116-
def get_fruit_name(self):
117-
return self.fruit.fruit_name
118-
119-
120-
class User(models.Model):
121-
username = models.CharField(max_length=32)
122-
123-
124-
class UserProfile(models.Model):
125-
user = OneToOneField(User)
126-
127-
def get_username(self):
128-
return self.user.username
129-
130-
131-
if __name__ == '__main__':
132-
MODEL = SomeModel()
133-
MODEL.save()
134-
MODEL.delete()
135-
136-
COUNT = SomeModel.objects.count()
1+
import os
2+
3+
# 1. RULE: Line length (this line is intentionally way too long for standard 79/88 char limits)
4+
# This is a very long comment that will definitely trigger a warning if we set the max-line-length rule strictly in our config.
5+
6+
def complex_function(a):
7+
# 2. RULE: McCabe Complexity (nested loops/ifs increase the 'score')
8+
if a > 0:
9+
for i in range(a):
10+
if i % 2 == 0:
11+
for j in range(i):
12+
if j == 5:
13+
print("Complexity!")
14+
15+
# 3. RULE: Pylint Naming (v is a poor variable name)
16+
v = 10
17+
return v

requirements.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
mypy==1.17.0
2-
prospector[with_everything]==1.17.2
3-
jsonpickle==4.0.2
4-
Django==5.2.6
5-
pylint==3.3.7
6-
Flask==3.1.1
1+
prospector[with_everything]==1.18.0
2+
jsonpickle==4.1.1
3+
Django==6.0.4
4+
pylint==4.0.5
5+
Flask==3.1.3
6+
mypy==1.20.0

src/codacy_prospector.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import signal
99
from contextlib import contextmanager
1010
import traceback
11-
import django
1211
import re
1312

1413
@contextmanager
@@ -89,20 +88,19 @@ def generate():
8988
yield res
9089
return list(generate())
9190

92-
default_tools = {'pylint', 'pyflakes', 'mccabe', 'dodgy', 'pydocstyle', 'profile-validator','pycodestyle'}
93-
extra_tools = {'vulture', 'pyroma', 'mypy','bandit','pyright'}
91+
all_tools = {'pylint', 'pyflakes', 'mccabe', 'dodgy', 'pydocstyle', 'profile-validator','pycodestyle','vulture', 'pyroma', 'mypy','bandit','pyright'}
9492

9593
def readConfiguration(configFile, srcDir):
9694
def allFiles(): return walkDirectory(srcDir)
9795
try:
9896
configuration = readJsonFile(configFile)
9997
files = configuration.get('files') or allFiles()
10098
tools = [t for t in configuration['tools'] if t['name'] == 'prospector']
101-
if tools and 'patterns' in tools[0]:
99+
if tools and tools[0].get('patterns'):
102100
prospector = tools[0]
103101
tools = set([p['patternId'] for p in prospector.get('patterns') or []])
104-
tools_to_disable = default_tools.difference(tools)
105-
tools_to_enable = extra_tools.intersection(tools)
102+
tools_to_disable = all_tools.difference(tools)
103+
tools_to_enable = all_tools.intersection(tools)
106104
options = [f"--without-tool={t}" for t in tools_to_disable] + [f"--with-tool={t}" for t in tools_to_enable]
107105
else:
108106
options = []

src/codacy_prospector_test.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ def test_readConfiguration(self):
7272
'--without-tool=mccabe',
7373
'--without-tool=pyflakes',
7474
'--without-tool=profile-validator',
75+
'--without-tool=vulture',
76+
'--without-tool=mypy',
77+
'--without-tool=bandit',
78+
'--without-tool=pyright',
79+
'--without-tool=profile-validator',
7580
'--with-tool=pyroma'}
7681
expectedFiles = ['C0111.py']
7782

0 commit comments

Comments
 (0)