#10249: Cannot create a consistent method resolution order (MRO) for bases FieldFile, File -------------------------------------------+-------------------------------- Reporter: kmtracey | Owner: nobody Status: new | Milestone: Component: File uploads/storage | Version: 1.0 Resolution: | Keywords: Stage: Unreviewed | Has_patch: 0 Needs_docs: 0 | Needs_tests: 0 Needs_better_patch: 0 | -------------------------------------------+-------------------------------- Comment (by kmtracey):
The problem is with this code in source:django/trunk/django/db/models/fields/files.py in the !FileDescriptor class (around line 130): {{{ #!python elif isinstance(file, File) and not isinstance(file, FieldFile): # Other types of files may be assigned as well, but they need to # have the FieldFile interface added to them file_copy = copy.copy(file) file_copy.__class__ = type(file.__class__.__name__, (file.__class__, self.field.attr_class), {}) }}} `self.field.attr_class` is going to be !FieldFile in the specific case noted here (it can also be !ImageFieldFile). But !FieldFile is based on File, so that code is essentially trying to do: {{{ >>> class File(object): pass ... >>> class FieldFile(File): pass ... >>> class X(File, FieldFile): pass ... Traceback (most recent call last): File "<console>", line 1, in <module> TypeError: Error when calling the metaclass bases Cannot create a consistent method resolution order (MRO) for bases FieldFile, File }}} Specifying File first contradicts the lookup order specified by the fact that !FieldFile derives from File, and Python complains. Reversing the order works: {{{ >>> class X(FieldFile, File): pass ... >>> }}} But I'm questioning whether this code is really the right approach to 'add the !FieldFile interface' to something. Based on what's being seen in #10300 it is also having the effect of causing the !FieldFile methods to be called for routines that used to get resolved via inheritance in the class being copied here, with unexpected results. That is, it isn't just adding some missing methods, but changing how some existing ones are resolved. Perhaps there is some cleaner way to just add methods, which seems to be what the comment (and possibly the order in which the bases are currently listed) implies is the intent of the code? Mucking with an object's `__class__` is messing with a level of Python I'm not really comfortable with, so feedback from someone with more Python depth would be useful here. -- Ticket URL: <http://code.djangoproject.com/ticket/10249#comment:2> Django <http://code.djangoproject.com/> The Web framework for perfectionists with deadlines. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-updates@googlegroups.com To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/django-updates?hl=en -~----------~----~----~----~------~----~------~--~---