#30179: Merging 3 or more media objects can throw unnecessary
MediaOrderConflictWarnings
-------------------------------+------------------------------------
     Reporter:  Matt Westcott  |                    Owner:  nobody
         Type:  Bug            |                   Status:  new
    Component:  Forms          |                  Version:  master
     Severity:  Normal         |               Resolution:
     Keywords:                 |             Triage Stage:  Accepted
    Has patch:  0              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  0
Easy pickings:  0              |                    UI/UX:  0
-------------------------------+------------------------------------

Comment (by Matt Westcott):

 To summarise: Even with the new strategy in #30153 of holding on to the
 un-merged lists as long as possible, the final merging is still done by
 adding one list at a time. The intermediate results are lists, which are
 assumed to be order-critical; this means the intermediate results have
 additional constraints that are not present in the original lists, causing
 it to see conflicts where there aren't any. Additionally, we should try to
 preserve the original sequence of files as much as possible, to avoid
 unnecessarily breaking user code that hasn't fully specified its
 dependencies and is relying on the 1.x behaviour.

 I think we need to approach this as a graph problem (which I realise might
 sound like overkill, but I'd rather start with something formally correct
 and optimise later as necessary): a conflict occurs whenever the
 dependency graph is cyclic. #30153 is a useful step towards this, as it
 ensures we have the accurate dependency graph up until the point where we
 need to assemble the final list.

 I suggest we replace `Media.merge` with a new method that accepts any
 number of lists (using `*args` if we want to preserve the existing method
 signature for backwards compatibility). This would work as follows:

 * Iterate over all items in all sub-lists, building a dependency graph
 (where a dependency is any item that immediately precedes it within a sub-
 list) and a de-duplicated list containing all items indexed in the order
 they are first encountered
 * Starting from the first item in the de-duplicated list, backtrack
 through the dependency graph, following the lowest-indexed dependency each
 time until we reach an item with no dependencies. While backtracking,
 maintain a stack of visited items. If we encounter an item already on the
 stack, this is a dependency loop; throw a `MediaOrderConflictWarning` and
 break out of the backtracking loop
 * Output the resulting item, then remove it from the dependency graph and
 the de-duplicated list
 * If the 'visited items' stack is non-empty, pop the last item off it and
 repeat the backtracking step from there. Otherwise, repeat the
 backtracking step starting from the next item in the de-duplicated list
 * Repeat until no items remain

-- 
Ticket URL: <https://code.djangoproject.com/ticket/30179#comment:11>
Django <https://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 unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/064.4f56f9d497c842bfe7acf86d258b4d56%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to