Skip to content

Commit 24437e6

Browse files
committed
Fix Python type errors in existing code
1 parent 2e9078b commit 24437e6

7 files changed

Lines changed: 128 additions & 108 deletions

File tree

server/reportmanager/management/commands/import_reports_from_bigquery.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
# check.
3333
def find_bucket_for_report(report_info: Report) -> int | None:
3434
hostname = report_info.url.hostname
35+
36+
if hostname is None:
37+
return None
38+
3539
if (known_bucket := KNOWN_BUCKET_IDS.get(hostname)) is not None:
3640
return known_bucket
3741

server/reportmanager/migrations/0001_initial.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import django.core.validators
44
import django.db.models.deletion
55
import django.utils.timezone
6-
import enumfields.fields
76
from django.conf import settings
87
from django.db import migrations, models
98

@@ -167,8 +166,8 @@ class Migration(migrations.Migration):
167166
),
168167
(
169168
"mode",
170-
enumfields.fields.EnumField(
171-
enum=reportmanager.models.BugzillaTemplateMode, max_length=30
169+
models.TextField(
170+
choices=reportmanager.models.BugzillaTemplateMode, max_length=30
172171
),
173172
),
174173
("name", models.TextField()),

server/reportmanager/models.py

Lines changed: 94 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from django.db.models.signals import post_delete, post_save
1919
from django.dispatch.dispatcher import receiver
2020
from django.utils import timezone
21-
from enumfields import Enum, EnumField
21+
from django_stubs_ext.db.models import TypedModelMeta
2222

2323
from webcompat.models import Report, Signature
2424
from webcompat.symptoms import URLSymptom, ValueMatcher
@@ -36,11 +36,11 @@
3636

3737

3838
class App(models.Model):
39-
channel = models.CharField(max_length=63, null=True)
40-
name = models.CharField(max_length=63)
41-
version = models.CharField(max_length=127)
39+
channel: models.CharField = models.CharField(max_length=63, null=True)
40+
name: models.CharField = models.CharField(max_length=63)
41+
version: models.CharField = models.CharField(max_length=127)
4242

43-
class Meta:
43+
class Meta(TypedModelMeta):
4444
constraints = (
4545
models.UniqueConstraint(
4646
fields=("channel", "name", "version"), name="unique_app"
@@ -49,29 +49,32 @@ class Meta:
4949

5050

5151
class BreakageCategory(models.Model):
52-
value = models.CharField(max_length=63, unique=True)
52+
value: models.CharField = models.CharField(max_length=63, unique=True)
5353

5454

5555
class Bucket(models.Model):
56-
bug = models.ForeignKey("Bug", null=True, on_delete=models.deletion.CASCADE)
57-
color = models.ForeignKey(
56+
id: models.AutoField = models.AutoField(primary_key=True)
57+
bug: models.ForeignKey = models.ForeignKey(
58+
"Bug", null=True, on_delete=models.deletion.CASCADE
59+
)
60+
color: models.ForeignKey = models.ForeignKey(
5861
"BucketColor", null=True, on_delete=models.deletion.CASCADE
5962
)
60-
description = models.TextField()
63+
description: models.TextField = models.TextField()
6164
# store the domain outside the signature only if the signature includes
6265
# a non-regex domain symptom and no other symptoms (for quick exclusion)
63-
domain = models.CharField(max_length=255, null=True)
66+
domain: models.CharField = models.CharField(max_length=255, null=True)
6467
# bucket can be hidden from view until given date, without being logged
65-
hide_until = models.DateTimeField(blank=True, null=True)
68+
hide_until: models.DateTimeField = models.DateTimeField(blank=True, null=True)
6669
# higher priority = earlier match
67-
priority = models.IntegerField(
70+
priority: models.IntegerField = models.IntegerField(
6871
default=0, validators=(MinValueValidator(-2), MaxValueValidator(2))
6972
)
7073
# Raw signature JSON (see webcompat.models.Signature)
71-
signature = models.TextField()
72-
reassign_in_progress = models.BooleanField(default=False)
74+
signature: models.TextField = models.TextField()
75+
reassign_in_progress: models.BooleanField = models.BooleanField(default=False)
7376

74-
class Meta:
77+
class Meta(TypedModelMeta):
7578
constraints = (
7679
models.CheckConstraint(
7780
condition=models.Q(priority__gte=-2) & models.Q(priority__lte=2),
@@ -295,12 +298,12 @@ def optimize_signature(self, unbucketed_entries):
295298

296299

297300
class BucketColor(models.Model):
298-
name = models.CharField(max_length=255, unique=True)
299-
value = models.IntegerField(
301+
name: models.CharField = models.CharField(max_length=255, unique=True)
302+
value: models.IntegerField = models.IntegerField(
300303
unique=True, validators=(MinValueValidator(0), MaxValueValidator(0xFFFFFF))
301304
)
302305

303-
class Meta:
306+
class Meta(TypedModelMeta):
304307
constraints = (
305308
models.CheckConstraint(
306309
condition=models.Q(value__gte=0) & models.Q(value__lte=0xFFFFFF),
@@ -310,11 +313,11 @@ class Meta:
310313

311314

312315
class BugProvider(models.Model):
313-
classname = models.CharField(max_length=255, blank=False)
314-
hostname = models.CharField(max_length=255, blank=False)
316+
classname: models.CharField = models.CharField(max_length=255, blank=False)
317+
hostname: models.CharField = models.CharField(max_length=255, blank=False)
315318

316319
# This is used to annotate bugs with the URL linking to them
317-
url_template = models.CharField(max_length=1023, blank=False)
320+
url_template: models.CharField = models.CharField(max_length=1023, blank=False)
318321

319322
def get_instance(self):
320323
# Dynamically instantiate the provider as requested
@@ -329,19 +332,25 @@ def __str__(self):
329332

330333

331334
class Bug(models.Model):
332-
external_id = models.CharField(max_length=255, blank=True)
333-
external_type = models.ForeignKey(BugProvider, on_delete=models.deletion.CASCADE)
334-
closed = models.DateTimeField(blank=True, null=True)
335+
external_id: models.CharField = models.CharField(max_length=255, blank=True)
336+
external_type: models.ForeignKey = models.ForeignKey(
337+
BugProvider, on_delete=models.deletion.CASCADE
338+
)
339+
closed: models.DateTimeField = models.DateTimeField(blank=True, null=True)
335340

336341

337342
def buckethit_default_range_begin():
338343
return timezone.now().replace(microsecond=0, second=0, minute=0)
339344

340345

341346
class BucketHit(models.Model):
342-
bucket = models.ForeignKey(Bucket, on_delete=models.deletion.CASCADE)
343-
begin = models.DateTimeField(default=buckethit_default_range_begin)
344-
count = models.IntegerField(default=0)
347+
bucket: models.ForeignKey = models.ForeignKey(
348+
Bucket, on_delete=models.deletion.CASCADE
349+
)
350+
begin: models.DateTimeField = models.DateTimeField(
351+
default=buckethit_default_range_begin
352+
)
353+
count: models.IntegerField = models.IntegerField(default=0)
345354

346355
@classmethod
347356
@transaction.atomic
@@ -369,7 +378,7 @@ def increment_count(cls, bucket_id, begin):
369378
counter.count += 1
370379
counter.save()
371380

372-
class Meta:
381+
class Meta(TypedModelMeta):
373382
constraints = (
374383
models.UniqueConstraint(
375384
fields=["bucket", "begin"],
@@ -379,21 +388,25 @@ class Meta:
379388

380389

381390
class BucketWatch(models.Model):
382-
user = models.ForeignKey("User", on_delete=models.deletion.CASCADE)
383-
bucket = models.ForeignKey(Bucket, on_delete=models.deletion.CASCADE)
391+
user: models.ForeignKey = models.ForeignKey(
392+
"User", on_delete=models.deletion.CASCADE
393+
)
394+
bucket: models.ForeignKey = models.ForeignKey(
395+
Bucket, on_delete=models.deletion.CASCADE
396+
)
384397
# This is the primary key of last crash marked viewed by the user
385398
# Store as an integer to prevent problems if the particular crash
386399
# is deleted later. We only care about its place in the ordering.
387-
last_report = models.IntegerField(default=0)
400+
last_report: models.IntegerField = models.IntegerField(default=0)
388401

389402

390403
class OS(models.Model):
391-
name = models.CharField(max_length=63, unique=True)
404+
name: models.CharField = models.CharField(max_length=63, unique=True)
392405

393406

394407
class ReportHit(models.Model):
395-
last_update = models.DateTimeField(default=timezone.now)
396-
count = models.BigIntegerField(default=0)
408+
last_update: models.DateTimeField = models.DateTimeField(default=timezone.now)
409+
count: models.BigIntegerField = models.BigIntegerField(default=0)
397410

398411
@staticmethod
399412
def get_period(time):
@@ -411,7 +424,7 @@ def get_period(time):
411424
microseconds=-time.microsecond,
412425
)
413426

414-
class Meta:
427+
class Meta(TypedModelMeta):
415428
constraints = (
416429
models.UniqueConstraint(
417430
fields=["last_update"],
@@ -452,20 +465,22 @@ def create_from_report(self, report, bucket_id=None):
452465

453466

454467
class ReportEntry(models.Model):
455-
app = models.ForeignKey(App, on_delete=models.deletion.CASCADE)
456-
breakage_category = models.ForeignKey(
468+
app: models.ForeignKey = models.ForeignKey(App, on_delete=models.deletion.CASCADE)
469+
breakage_category: models.ForeignKey = models.ForeignKey(
457470
BreakageCategory, null=True, on_delete=models.deletion.CASCADE
458471
)
459-
bucket = models.ForeignKey(Bucket, null=True, on_delete=models.deletion.CASCADE)
460-
comments = models.TextField()
461-
comments_translated = models.TextField(null=True)
462-
comments_original_language = models.TextField(null=True)
463-
details = models.JSONField()
464-
os = models.ForeignKey(OS, on_delete=models.deletion.CASCADE)
465-
reported_at = models.DateTimeField()
466-
url = models.URLField(max_length=8192)
467-
uuid = models.UUIDField(unique=True)
468-
ml_valid_probability = models.FloatField(null=True)
472+
bucket: models.ForeignKey = models.ForeignKey(
473+
Bucket, null=True, on_delete=models.deletion.CASCADE
474+
)
475+
comments: models.TextField = models.TextField()
476+
comments_translated: models.TextField = models.TextField(null=True)
477+
comments_original_language: models.TextField = models.TextField(null=True)
478+
details: models.JSONField = models.JSONField()
479+
os: models.ForeignKey = models.ForeignKey(OS, on_delete=models.deletion.CASCADE)
480+
reported_at: models.DateTimeField = models.DateTimeField()
481+
url: models.URLField = models.URLField(max_length=8192)
482+
uuid: models.UUIDField = models.UUIDField(unique=True)
483+
ml_valid_probability: models.FloatField = models.FloatField(null=True)
469484

470485
objects = ReportEntryManager()
471486

@@ -574,43 +589,43 @@ def ReportEntry_save(sender, instance, created, **kwargs):
574589
triage_new_report.apply_async((instance.pk,), countdown=0.1)
575590

576591

577-
class BugzillaTemplateMode(Enum):
592+
class BugzillaTemplateMode(models.TextChoices):
578593
Bug = "bug"
579594
Comment = "comment"
580595

581596

582597
class BugzillaTemplate(models.Model):
583-
mode = EnumField(BugzillaTemplateMode, max_length=30)
584-
name = models.TextField()
585-
product = models.TextField()
586-
component = models.TextField()
587-
summary = models.TextField(blank=True)
588-
version = models.TextField()
589-
description = models.TextField(blank=True)
590-
whiteboard = models.TextField(blank=True)
591-
keywords = models.TextField(blank=True)
592-
op_sys = models.TextField(blank=True)
593-
platform = models.TextField(blank=True)
594-
priority = models.TextField(blank=True)
595-
severity = models.TextField(blank=True)
596-
alias = models.TextField(blank=True)
597-
cc = models.TextField(blank=True)
598-
assigned_to = models.TextField(blank=True)
599-
qa_contact = models.TextField(blank=True)
600-
target_milestone = models.TextField(blank=True)
601-
attrs = models.TextField(blank=True)
602-
security = models.BooleanField(blank=False, default=False)
603-
security_group = models.TextField(blank=True)
604-
comment = models.TextField(blank=True)
605-
blocks = models.TextField(blank=True)
606-
dependson = models.TextField(blank=True)
598+
mode: models.TextField = models.TextField(choices=BugzillaTemplateMode, max_length=30)
599+
name: models.TextField = models.TextField()
600+
product: models.TextField = models.TextField()
601+
component: models.TextField = models.TextField()
602+
summary: models.TextField = models.TextField(blank=True)
603+
version: models.TextField = models.TextField()
604+
description: models.TextField = models.TextField(blank=True)
605+
whiteboard: models.TextField = models.TextField(blank=True)
606+
keywords: models.TextField = models.TextField(blank=True)
607+
op_sys: models.TextField = models.TextField(blank=True)
608+
platform: models.TextField = models.TextField(blank=True)
609+
priority: models.TextField = models.TextField(blank=True)
610+
severity: models.TextField = models.TextField(blank=True)
611+
alias: models.TextField = models.TextField(blank=True)
612+
cc: models.TextField = models.TextField(blank=True)
613+
assigned_to: models.TextField = models.TextField(blank=True)
614+
qa_contact: models.TextField = models.TextField(blank=True)
615+
target_milestone: models.TextField = models.TextField(blank=True)
616+
attrs: models.TextField = models.TextField(blank=True)
617+
security: models.BooleanField = models.BooleanField(blank=False, default=False)
618+
security_group: models.TextField = models.TextField(blank=True)
619+
comment: models.TextField = models.TextField(blank=True)
620+
blocks: models.TextField = models.TextField(blank=True)
621+
dependson: models.TextField = models.TextField(blank=True)
607622

608623
def __str__(self):
609624
return self.name
610625

611626

612627
class User(models.Model):
613-
class Meta:
628+
class Meta(TypedModelMeta):
614629
permissions = (
615630
(
616631
"reportmanager_visible",
@@ -620,16 +635,16 @@ class Meta:
620635
("reportmanager_read", "Read access to ReportManager"),
621636
)
622637

623-
user = models.OneToOneField(DjangoUser, on_delete=models.deletion.CASCADE)
638+
user: models.OneToOneField = models.OneToOneField(DjangoUser, on_delete=models.deletion.CASCADE)
624639
# Explicitly do not store this as a ForeignKey to e.g. BugzillaTemplate
625640
# because the bug provider has to decide how to interpret this ID.
626-
default_template_id = models.IntegerField(default=0)
627-
default_provider_id = models.IntegerField(default=1)
628-
buckets_watching = models.ManyToManyField(Bucket, through="BucketWatch")
641+
default_template_id: models.IntegerField = models.IntegerField(default=0)
642+
default_provider_id: models.IntegerField = models.IntegerField(default=1)
643+
buckets_watching: models.ManyToManyField = models.ManyToManyField(Bucket, through="BucketWatch")
629644

630645
# Notifications
631-
bucket_hit = models.BooleanField(blank=False, default=False)
632-
inaccessible_bug = models.BooleanField(blank=False, default=False)
646+
bucket_hit: models.BooleanField = models.BooleanField(blank=False, default=False)
647+
inaccessible_bug: models.BooleanField = models.BooleanField(blank=False, default=False)
633648

634649

635650
@receiver(post_save, sender=DjangoUser)

0 commit comments

Comments
 (0)