On Jan 12, 4:49 pm, Chris Nelson <[email protected]> wrote:
>
> He's my use case.  TracPM defines
>
>   class ITaskScheduler(Interface):
>      # Schedule each the ticket in ticketsByID with consideration for
>      # dependencies, estimated work, hours per day, etc.
>      #
>      # ticketsByID is a dictionary, indexed by numeric ticket ID, each
>      # ticket contains at least the fields returned by queryFields()
>      # and the whole list was processed by postQuery().
>      #
>      # On exit, each ticket has t['calc_start'] and t['calc_finish']
>      # set (FIXME - we should probably be able to configure those field
>      # names.) and can be accessed with TracPM.start() and finish().
>      def scheduleTasks(self, options, ticketsByID):
>          """Called to schedule tasks"""
>
> and
>
>      # tickets is an unordered list of tickets.  Each ticket contains
>      # at least the fields returned by queryFields() and the whole list
>      # was processed by postQuery().
>      def computeSchedule(self, options, tickets):
>
> computeSchedule() takes a list of tickets because that's the natural way
> for other code to handle the data (as returned from a query, used to
> display a Gantt, etc.)  ITaskScheduler takes a dictionary because it had
> to create one interinally anyway and I can have computeSchedule() build
> it for all schedulers and use that as an opportunity to isolate the
> caller of computeSchedule() from the vagaries of the scheduler (which
> might want to update tickets in weird ways).
>
> So, my implementation of computeSchedule is:
>
>          # Convert list to dictionary, making copies so schedule can
>          # mess with the tickets.
>          ticketsByID = {}
>          for t in tickets:
>              # FIXME - deepcopy fails here but with only copy, if the
>              # scheduler updates fields, those updates are visible to
>              # the caller.
>              ticketsByID[t['id']] = copy.copy(t)
>
>          # Schedule the tickets
>          self.scheduler.scheduleTasks(options, ticketsByID)
>
>          # Copy back the schedule results
>          for t in tickets:
>              for field in [ 'calc_start', 'calc_finish']:
>                  t[field] = ticketsByID[t['id']][field]
>
> but it doesn't work, the caller still sees the changes to other fields
> that the scheduler makes.
>
> > However, I can elaborate on the original topic of making a copy of the
> > ticket values:
>
> > I left you a clue when I said that t.values will contain all the
> > actual ticket data - the strings, datateime and integers that makes up
> > the ticket data.
>
> I guess my clue detector is on the fritz.  Sorry.
>
>  > As these are all immutable values, there is no need
>
>
>
> > to deepcopy - a straight copy would suffice:
>
> > ticket_values = {}
> > for t in tickets:
> >      ticket_values[t.id] = t.values.copy()
>
> > Or if you don't want to store it in a dict with ID as key but instead
> > need to retain the order in a list, you need to include the ticket id
> > in the values as it is not stored in values. So this should make a
> > simplified copy of the tickets with just the values:
>
> > ticket_values = []
> > for t in tickets:
> >      t_vals = t.values.copy()
> >      t_vals['id'] = t.id
> >      ticket_values.append(t_vals)
>
> So, something like:
>
>      # tickets is an unordered list of tickets.  Each ticket contains
>      # at least the fields returned by queryFields() and the whole list
>      # was processed by postQuery().
>      def computeSchedule(self, options, tickets):
>          # Convert list to dictionary, making copies so schedule can
>          # mess with the tickets.
>          ticketsByID = {}
>          for t in tickets:
>              ticketsByID[t['id']] = t.values.copy()
>
>          # Schedule the tickets
>          self.scheduler.scheduleTasks(options, ticketsByID)
>
>          # Copy back the schedule results
>          for t in tickets:
>              for field in [ 'calc_start', 'calc_finish']:
>                  t[field] = ticketsByID[t['id']][field]
>
> ?

Yes, something like that looks like it should work. But if done like
that, I still don't understand why you wouldn't just pass the tickets
to your scheduler? Your code comments say you pass a copy so that
schedulers can "mess" with the ticket data, but any Trac and plugin
code should really be trusted to do the right thing with objects they
get passed. I don't see the reason for building structures to hide and
protect data when all is available anyway. It is Python after all...
But, your code - you decide :-)


:::simon

-- 
You received this message because you are subscribed to the Google Groups "Trac 
Development" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/trac-dev?hl=en.

Reply via email to