#168 residual: two CORRECT py-django binds lost — views.serve and storage.request.COOKIES #250
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#250
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by a bind-for-bind census of the tier-3 drift, run against the
1d3228ebinary(which predates lanes A–E) and
bd1c4e2. py-django movedresolved108545 → 108401 withthe ref universe byte-identical at 480167 refs, so this is resolution only.
The −144 adjudicates as 150 phantoms removed, 6 correct binds net gained, 2 correct
binds LOST. That is a large precision win and the trade is clearly right. This issue is
only about the two, so they are not forgotten.
The two losses
1.
tests/staticfiles_tests/urls/default.py:5Target was
django/contrib/staticfiles/views.py:16 def serve— correct, and thequalifier
viewsis bound by an import that names exactly that package. It now resolvesto nothing.
2.
tests/messages_tests/test_cookie.py:30—storage.request.COOKIESreachingdjango/http/request.py#COOKIES.storage.requestis a realHttpRequest, so the bindwas right.
Why they were refused
qual_root_scope_sqlscopes the file-stem/file-key anchor arms so a stem anchor cannotleave the package the qualifier's first segment names. Case 1 has the qualifier naming a
real package whose own
views.pyis the target, so it looks like it should be ADMITTEDby the rule's own logic rather than refused — worth checking whether the root-reach or
containment clause is too tight here, not whether the gate should exist.
For contrast, the 79 lost
typebinds in the same repo are unambiguously right to lose:django/db/models/expressions.pydoesfrom django.db.models import fieldsand itsfields.DateTimeFieldwas bindingdjango/forms/fields.py:532(the FORMS class) insteadof
django/db/models/fields/__init__.py:1600(the MODEL class). Wrong class, phantom,and now correctly unresolved.
Reproduction
then join
refson(path, start_line, start_col, name)and take rows resolved inbeforeand unresolved inafterwithkind NOT IN ('type','method_call'). Seven rows;five are
storage.location/storage.base_locationphantoms on a localFileSystemStoragebinding
contrib/staticfiles/storage.py, and these two are the correct ones.Recorded in
tier3-baseline.json's bless reason so the number is not silently carried.Loss 1 and all of #251 are the same missing distinction, in opposite directions
Worth linking these before either is worked, because a fix aimed at one
alone will very likely move the other — and they pull opposite ways.
from django.contrib.staticfiles import viewsimport inspectdjango.contrib.staticfiles.viewsinspectdjango/utils/inspect.pyBoth sites are
qualifier.name(...)where the qualifier was bound by animport. In neither case is the current rule consulting what the import
form actually says about the module's location — it is matching on
file stem and then applying a containment gate as a separate,
after-the-fact scope test.
Python states the location precisely in the syntax:
import X— absolute, top-level (PEP 328). It can never mean asibling file. #251's 13 phantoms are all anchors on non-top-level
files.
from A.B import X—Xis exactlyA.B.XwhenXis a module.Loss 1's target is
django/contrib/staticfiles/views.py, i.e.precisely the module the import names — which is why the issue text
above says it "looks like it should be ADMITTED by the rule's own
logic".
So the general mechanism is one thing rather than two: resolve the
qualifier through the import that bound it into a full module path, then
require the anchor file to BE that module — not to merely share its
stem, and not to pass a separate containment test afterwards.
That admits loss 1 (the module path matches exactly) and refuses all 13
of #251 (
django.utils.inspect≠inspect), with the same clause. Apatch that only loosens the gate here risks re-admitting #251's
phantoms; a patch that only tightens #251 risks losing more binds of
this shape.
Loss 2 is NOT this shape
storage.request.COOKIESis a receiver chain —storage.requestis anHttpRequestinstance, not a module — so it is tier-1R/receiverterritory and no import-form rule reaches it. It should be tracked
separately rather than folded in, or it will be the case that quietly
fails to be fixed while the issue is closed.
The constraint on doing it
Language-scoped, and measured bind-for-bind before anything is blessed.
tier1q_root_scope.rs:19already records an unscoped variant of aneighbouring clause at −1244 on rust-analyzer, which is what an
import-semantics rule applied outside Python would look like. Details in
the analysis on #251.
Verified against the actual published v0.28.1 CLI (
340a75a) and pinned Django corpus:tests/staticfiles_tests/urls/default.py:5:44now resolvesviews.servetodjango/contrib/staticfiles/views.py:16 serve.tests/messages_tests/test_cookie.py:30:21remains an unresolved write throughstorage.request.COOKIES.The remaining case needs evidence across an untyped helper argument, inherited storage/request factories, constructor argument-to-field assignment, and the fallback storage list path. The current receiver-origin rule does not establish those flows. A basename or unique-field fallback would recreate the false-binding class this work removed. Keeping this issue open for that remaining implementation; PR #266 addresses #246 and #263 separately.
Rechecked both reported occurrences with the actual published v0.28.2 CLI (
76e8967) on the pinned Django corpus.tests/staticfiles_tests/urls/default.py:5:44still resolvesviews.servetodjango/contrib/staticfiles/views.py:16.tests/messages_tests/test_cookie.py:30:21(storage.request.COOKIES) remains unresolved.This issue stays open. The remaining chain requires caller-argument flow, inherited factory results, constructor-to-field flow, and the fallback caller's backend collection path. Existing local constructor/annotation facts do not prove that chain. No global same-name field fallback was added to manufacture a target. The v0.28.2 notes disclose this remaining gap.