TireSwingSoftware/openassign-server — Issue #94: AssignmentManager().session_view() can't handle duplicate assignments
Author: mhrivnak
Created: 2012-02-01 06:23:54+00:00
State: open

If a user has two assignments to the same session, this view will barf like so:

```
2012-02-01 06:07:38,038 ERROR pr_services.rpc PID 2511 TID -1241416848: INTERNAL ERROR: [pr[/var/www/oadev.hrivnak.org/lib/pr_services/rpc/service.pyc]: 2012-02-01 06:07:38.037261 [0:00:00.145518 elapsed]: .session_view[, {}, []] = {'status': 'error', 'error': [46, "internal error: unhashable type: 'dict'", {}]}
] stack trace [Traceback (most recent call last):
File "/var/www/oadev.hrivnak.org/lib/pr_services/rpc/service.py", line 223, in _run
ret = self._run_transaction_protected_method(self.method, *parameters)
res = func(*args, **kwargs)
File "/var/www/oadev.hrivnak.org/lib/pr_services/rpc/service.py", line 312, in _run_transaction_protected_method
return method(*parameters)
File "/var/www/oadev.hrivnak.org/lib/pr_services/credential_system/assignment_manager.py", line 366, in session_view
assignment['task']['session'] = session_dict[assignment['task']['session']]
TypeError: unhashable type: 'dict'
]
```

The reason is interesting. Suppose there are two assignments to a given task. The results start with {task:1, ...}. That '1' gets replaced with a dictionary representing the task. In fact, BOTH assignments will get a reference to the SAME dictionary.

So assignments[0]['task'] == assignments[1]['task']

Now comes the code referenced above. It replaces assignments[0]['task']['session'] with a dict. But then it tries to do the same to assignments[1], but since it's the same exact task dictionary, the work has already been done. So assignments[1]['task']['session'] is already a dict, and not the int the method expects.

Perhaps a fix for this is that merge_queries always replaces a PK with a copy of its corresponding object, instead of a direct reference.