suppression-debt

Many ur-allow comments excuse code of one shape.

Group
Opportunities
Runs
Runs under ur report: ur report --rule suppression-debt
Level
note
Reads
Every file
Fix
None: the shared function's name and home are a design choice

Why

These ur-allow: semantic-clone comments accept clone classes whose normal forms are the same once the globals and methods they call and the numbers they use are holes, so they excuse one shape of code written out in many places. A family of many places is a shared function, or a library, waiting to be written. An advisory rule that ur report runs.

The fix, as Ur suggests it: write one function for the shape, call it at each place, and remove the comments.

For agents

Before accepting a clone with an ur-allow comment, look for other accepted clones of its shape, and share the code instead when there are many.

Example

billing/invoices.py
# ur-allow: semantic-clone invoices may diverge later
def outstanding(invoices):
    total = 0
    for invoice in invoices:
        if not invoice.paid:
            total += invoice.amount - invoice.credit
    return total
billing/refunds.py
# ur-allow: semantic-clone quick fix for the quarter close
def pending_refunds(refunds):
    pending = 0
    for refund in refunds:
        if not refund.paid:
            pending += refund.amount - refund.credit
    return pending
billing/subscriptions.py
# ur-allow: semantic-clone owned by the subscriptions team
def unpaid_renewals(renewals):
    due = 0
    for renewal in renewals:
        if not renewal.paid:
            due += renewal.amount - renewal.credit
    return due
What Ur prints
$ ur report --rule suppression-debt
opportunity[suppression-debt]: 3 `ur-allow` comments excuse one clone class of 3 places: 3 functions have the same behavior (saves about 11 lines)
  --> ./billing/invoices.py:2:1-7 function `outstanding`
  --> ./billing/refunds.py:2:1-7 function `pending_refunds`
  --> ./billing/subscriptions.py:2:1-7 function `unpaid_renewals`
  = hint: write one function for the shape, call it at each place, and remove the comments
1 opportunity saving about 11 lines in all

Try it in the playground →