Opened 4 years ago

Closed 3 years ago

#23548 closed Bug (fixed)

Transform.relabeled_clone calls own constructor with wrong number of arguments

Reported by: ris Owned by: nobody
Component: Database layer (models, ORM) Version: 1.7
Severity: Normal Keywords: lookup transform orm subquery
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


In :

    def relabeled_clone(self, relabels):
        return self.__class__(self.lhs.relabeled_clone(relabels))

relabeled_clone here calls Transform's own constructor with one argument (ignoring bound self), but (

    def __init__(self, lhs, lookups):
        self.lhs = lhs
        self.init_lookups = lookups[:]

init takes two (non-bound) arguments, so this screws up when you try and use a QuerySet employing a custom Transform as a subquery.

Change History (3)

comment:1 Changed 4 years ago by Akis Kesoglou

Triage Stage: UnreviewedAccepted

I'm marking the ticket as accepted based on the discussion with @akaariai in #django-dev.

comment:2 Changed 3 years ago by ris

Updating this with example for creating this failure:

from django.db import models
from django.db.models import Transform

class Sqrt ( Transform ):
	lookup_name = "sqrt"

	def as_sql ( self , qn , connection ):
		lhs , params = qn.compile ( self.lhs )
		return "sqrt(%s)" % lhs , params
models.FloatField.register_lookup ( Sqrt )

class ModelA ( models.Model ):
	x = models.FloatField ()

class ModelB ( models.Model ):
	a = models.ForeignKey ( ModelA )

Issuing the query:

ModelB.objects.filter ( a__pk__in = ModelA.objects.filter ( x__sqrt__lt = 5 ) )

raises the above exception.

I've used this test case to verify that this bug is still present in django 1.8.2.

comment:3 Changed 3 years ago by ris

Resolution: fixed
Status: newclosed

This appears to be fixed in commit 08232ef84d4959826ad5136f183c9fc5bedf0599 (also backported to 1.8.x @ b4b13759f82e9e09951bb72875b1c6e384dca6a9). Closing.

Note: See TracTickets for help on using tickets.
Back to Top