`conflicting_migration_leaves` fires when `dependencies` is built by a function

Đang mở
#247 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
Nửa ngày
Mức phù hợp với người mới
74/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
django, python
Lĩnh vực
cli, databases

Hướng nghiên cứu

Start with _extract_dependency_pairs() and _parse_migration_file() in cli/orm_lens/migrations_parser.py, then the leaf rule in analyze_migration_risks(), to see how a non-literal dependencies value is currently treated as empty. Add the tests in cli/tests/test_migration_conflicts.py, beginning with the repro, which should yield no conflicting_migration_leaves finding. Done means that test passes, the existing two-branches-on-the-same-parent test still fires, and pytest, ruff and mypy pass.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug good first issue python

Source: weblate — weblate/trans/migrations/0084_consolidate_inherited_settings.py

What happens

Some migrations compute their dependencies, usually to depend on an optional app only when it's installed:

def get_dependencies():
    dependencies = [("trans", "0083_...")]
    if "weblate.billing" in settings.INSTALLED_APPS:
        dependencies.append(("billing", "0011_workspace"))
    return dependencies


class Migration(migrations.Migration):
    dependencies = get_dependencies()

_extract_dependency_pairs() only reads a literal list, so this migration gets []. Its parent (0083) now has no child, and migration-risk reports a critical conflict between 0083_... and the real leaf 0122_.... Exit code 1 on a perfectly linear history.

The comment above the rule already says the right thing: "a false 'your migrations conflict' is worse than a missed one". We just don't know when we're guessing.

Found on weblate: trans gets two critical findings (0083_alter_contributoragreement_unique_together_and_more vs 0122_backupauthorclaim_...).

Repro

trans/migrations/

# 0001_initial.py — creates Project, dependencies = []

# 0002_backfill.py
from django.conf import settings
from django.db import migrations


def get_dependencies():
    dependencies = [("trans", "0001_initial")]
    if "billing" in settings.INSTALLED_APPS:
        dependencies.append(("billing", "0001_initial"))
    return dependencies


class Migration(migrations.Migration):
    dependencies = get_dependencies()
    operations = [migrations.RunPython(migrations.RunPython.noop)]

# 0003_noop.py
class Migration(migrations.Migration):
    dependencies = [("trans", "0002_backfill")]
    operations = []
$ orm-lens migration-risk
trans/migrations/0001_initial.py:1  [critical/high]  (migration graph) trans.None
  rule:      conflicting_migration_leaves
  risk:      App 'trans' has 2 leaf migrations (0001_initial, 0003_noop). ...
$ echo $?
1

Expected: no finding.

Where

cli/orm_lens/migrations_parser.py

  • line 125, _extract_dependency_pairs() returns [] for anything that isn't a list/tuple;
  • line 145, _parse_migration_file() can't tell "no dependencies" from "couldn't read them";
  • around line 1310–1385, the leaf rule in analyze_migration_risks() (line 1254).
Suggested fix

In _parse_migration_file(), set a flag such as "dependencies_unknown": True when the dependencies = ... value is not a list/tuple literal. In the leaf rule, skip the app (stay silent) if any of its migrations has that flag. Same spirit as the effective_label fallback a few lines above.

Optional, only if it stays small: resolve dependencies = some_func() when some_func is a module-level function whose first statement is dependencies = [ ...literal... ]. Not needed to close the issue.

How to test
  • cli/tests/test_migration_conflicts.py: the repro gives no conflicting_migration_leaves.
  • The existing "two branches on the same parent" test still fires.
  • cd cli && python -m pytest -q, ruff and mypy pass.

Difficulty: good first issue.

Ngôn ngữ chính
Python
Star
84
Fork
13
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của FROWNINGdev/django-orm-lens

Tất cả issue của FROWNINGdev/django-orm-lens

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.