Opened 17 years ago

Closed 14 years ago

#3508 closed (fixed)

MergeDict needs more descriptive return values from __str__ and __repr__

Reported by: thebanana Owned by:
Component: Core (Other) Version: dev
Severity: Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Since MergeDict is a subclass of object, it inherits the default str and repr methods. The default methods are very generic and not as useful as they could be, especially when you're trying to inspect objects.

I'm submitting a patch that gives a detailed representation of the instance data when you run str(myMergeDict) and returns an "eval-able" value when you run repr(myMergeDict).

Attachments (2)

doc_MergeDict.diff (1.0 KB ) - added by thebanana 17 years ago.
patch to add str and repr to MergeDict
doc_MergeDict_py23.diff (1008 bytes ) - added by thebanana 17 years ago.
MergeDict patch that works with Python 2.3

Download all attachments as: .zip

Change History (15)

by thebanana, 17 years ago

Attachment: doc_MergeDict.diff added

patch to add str and repr to MergeDict

comment:1 by (removed), 17 years ago

Offhand, django is still targeting python 2.3; you're using a genexp in the repr which is py2.4. Bit of a no go.

Also, use iteritems. No point in having the interp. build the intermediate list...

comment:2 by Malcolm Tredinnick, 17 years ago

Patch needs improvement: set
Triage Stage: UnreviewedAccepted

Brian's comment is correct: the patch needs to work with Python 2.3.

comment:3 by thebanana, 17 years ago

OK, I am attaching another patch that I tested in Python 2.3. It uses a list expression in place of the genexp in the repr.

However, I'm not sure where I could use iteritems. MergeDict isn't like a normal dict. The data isn't stored the same, and MergeDict itself doesn't have an iteritems method. Could you be more specific about where you would use iteritems?

by thebanana, 17 years ago

Attachment: doc_MergeDict_py23.diff added

MergeDict patch that works with Python 2.3

comment:4 by thebanana, 17 years ago

An example of how this patch might be used:

> python2.3
Python 2.3.6 (#1, Feb 15 2007, 22:57:09)
[GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from django.utils.datastructures import MergeDict
>>> a = MergeDict({'a': 1, 'b': 2}, {'id': 'asdf', 'user': 'joe', 'color': 'blue'})
>>> str(a)
"{'a': 1, 'color': 'blue', 'b': 2, 'id': 'asdf', 'user': 'joe'}"
>>> repr(a)
"MergeDict({'a': 1, 'b': 2}, {'color': 'blue', 'id': 'asdf', 'user': 'joe'})"
>>>

comment:5 by (removed), 17 years ago

No iteritems on MergeDict? Bah. Simple solution, add one ;)
Bit curious why MergeDict doesn't support the full dict protocol though; iteritems specifically would be useful compared to the current implementation.

Would use a map personally, but list comp seems preferred in the src.

Meanwhile, back to the patch- str output won't be valid;

>>> print MergeDict({1:2}, {1:3})
{1:3}
>>> print MergeDict({1:2}, {1:3})[1]
2

Fault lies with MergeDict diverting from the dict protocol; its items is a list built via L->R walk of the internal dicts, concating the list on the end as it goes. Dict instantiation works via just walking the args, adding them- meaning the rightmost key wins.

you want-

def __str__(self):
  l = self.items()
  l.reverse()
  return str(dict(l))

Although personally, I'd look at making MergeDict into a proper dict, and just using return str(dict(self.iteritems())) # till someone gets bored and implements it efficiently.

comment:6 by thebanana, 17 years ago

Brian,

I would also have implemented MergeDict differently. However, my intent for this patch was not to change how MergeDict behaved - just to add the "documenter" methods to make debugging and interactive inspection of request.REQUEST easier.

Grepping the code yielded the following example as the only way that MergeDict is used:

self._request = datastructures.MergeDict(self.POST, self.GET)

I'm happy to re-work the request.REQUEST and MergeDict implementations if that is what the community desires. Again, my initial goals were to minimize API impact while enhancing the inspection-related properties of the class.

comment:7 by thebanana <john@…>, 17 years ago

Also see the REQUEST docs: http://www.djangoproject.com/documentation/request_response/

They say the REQUEST searches POST first, then GET.

All-in-all, very low impact. I don't care if this gets merged in - I've even stopped using REQUEST myself. I just thought it might be useful to others. <shrug>

comment:8 by anonymous, 17 years ago

Needs tests: set
Patch needs improvement: unset

comment:9 by Matt Boersma, 17 years ago

Owner: changed from nobody to Matt Boersma
Status: newassigned

comment:10 by Matt Boersma, 17 years ago

Owner: Matt Boersma removed
Status: assignednew

comment:11 by Adam Nelson, 14 years ago

Triage Stage: AcceptedReady for checkin

Aside from Brian Harring's comment, this patch is low impact and just does what it says, adds better str and repr and nothing else. The 2.4 version is sufficient now that 2.3 is no longer supported.

comment:12 by Mike Lissner, 14 years ago

Can we get this checked in? contrib.auth.views has several uses of request.REQUEST, and I just had the occasion to need to inspect them. Having this patch would have made life easier, for sure.

comment:13 by Malcolm Tredinnick, 14 years ago

Resolution: fixed
Status: newclosed

(In [13721]) Added more readable str and repr methods to MergeDict.
Thanks, john@…. Fixed #3508.

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