[Python-Dev] Re: [Patches] [1.6] dictionary objects: new method 'supplement'
Greg Stein
gstein@lyra.org
Mon, 3 Apr 2000 03:18:30 -0700 (PDT)
I don't recall the termination of the discussion, but I don't know that
consensus was ever reached.
Personally, I find this of little value over the similar (not exact) code:
def supplement(dict, extra):
d = extra.copy()
d.update(dict)
return d
If the dictionary needs to be modified in place, then the loop from your
UserDict.supplement would be used.
Another view: why keep adding methods to service all possible needs?
Cheers,
-g
On Mon, 3 Apr 2000, Peter Funk wrote:
> Dear Python patcher!
>
> Please consider to apply the patch appended below and commit into the CVS tree.
> It applies to: Python 1.6a1 as released on april 1st.
> --=-- argument: --=--=--=--=--=--=--=--=--=--=-->8--=-
> This patch adds a new method to dictionary and UserDict objects:
> '.supplement()' is a "sibling" of '.update()', but it add only
> those items that are not already there instead of replacing them.
>
> This idea has been discussed on python-dev last month.
> --=-- obligatory disclaimer: -=--=--=--=--=--=-->8--=-
> I confirm that, to the best of my knowledge and belief, this
> contribution is free of any claims of third parties under
> copyright, patent or other rights or interests ("claims"). To
> the extent that I have any such claims, I hereby grant to CNRI a
> nonexclusive, irrevocable, royalty-free, worldwide license to
> reproduce, distribute, perform and/or display publicly, prepare
> derivative versions, and otherwise use this contribution as part
> of the Python software and its related documentation, or any
> derivative versions thereof, at no cost to CNRI or its licensed
> users, and to authorize others to do so.
>
> I acknowledge that CNRI may, at its sole discretion, decide
> whether or not to incorporate this contribution in the Python
> software and its related documentation. I further grant CNRI
> permission to use my name and other identifying information
> provided to CNRI by me for use in connection with the Python
> software and its related documentation.
> --=-- dry signature: =--=--=--=--=--=--=--=--=-->8--=-
> Regards, Peter
> --
> Peter Funk, Oldenburger Str.86, D-27777 Ganderkesee, Germany, Fax:+49 4222950260
> office: +49 421 20419-0 (ArtCom GmbH, Grazer Str.8, D-28359 Bremen)
> --=-- patch: --=--=--=--=--=--=--=--=--=--=--=-->8--=-
> *** ../../cvs_01_04_00_orig/dist/src/Objects/dictobject.c Fri Mar 31 11:45:02 2000
> --- src/Objects/dictobject.c Mon Apr 3 10:30:11 2000
> ***************
> *** 734,739 ****
> --- 734,781 ----
> }
>
> static PyObject *
> + dict_supplement(mp, args)
> + register dictobject *mp;
> + PyObject *args;
> + {
> + register int i;
> + dictobject *other;
> + dictentry *entry, *oldentry;
> + if (!PyArg_Parse(args, "O!", &PyDict_Type, &other))
> + return NULL;
> + if (other == mp)
> + goto done; /* a.supplement(a); nothing to do */
> + /* Do one big resize at the start, rather than incrementally
> + resizing as we insert new items. Expect that there will be
> + no (or few) overlapping keys. */
> + if ((mp->ma_fill + other->ma_used)*3 >= mp->ma_size*2) {
> + if (dictresize(mp, (mp->ma_used + other->ma_used)*3/2) != 0)
> + return NULL;
> + }
> + for (i = 0; i < other->ma_size; i++) {
> + entry = &other->ma_table[i];
> + if (entry->me_value != NULL) {
> + oldentry = lookdict(mp, entry->me_key, entry->me_hash);
> + if (oldentry->me_value == NULL) {
> + /* TODO: optimize:
> + 'insertdict' does another call to 'lookdict'.
> + But for sake of readability and symmetry with
> + 'dict_update' I didn't tried to avoid this.
> + At least not now as we go into 1.6 alpha. */
> + Py_INCREF(entry->me_key);
> + Py_INCREF(entry->me_value);
> + insertdict(mp, entry->me_key, entry->me_hash,
> + entry->me_value);
> + }
> + }
> + }
> + done:
> + Py_INCREF(Py_None);
> + return Py_None;
> + }
> +
> +
> + static PyObject *
> dict_copy(mp, args)
> register dictobject *mp;
> PyObject *args;
> ***************
> *** 1045,1050 ****
> --- 1087,1093 ----
> {"clear", (PyCFunction)dict_clear},
> {"copy", (PyCFunction)dict_copy},
> {"get", (PyCFunction)dict_get, METH_VARARGS},
> + {"supplement", (PyCFunction)dict_supplement},
> {NULL, NULL} /* sentinel */
> };
>
> *** ../../cvs_01_04_00_orig/dist/src/Lib/test/test_types.py Wed Feb 23 23:23:17 2000
> --- src/Lib/test/test_types.py Mon Apr 3 10:41:53 2000
> ***************
> *** 242,247 ****
> --- 242,250 ----
> d.update({2:20})
> d.update({1:1, 2:2, 3:3})
> if d != {1:1, 2:2, 3:3}: raise TestFailed, 'dict update'
> + d.supplement({1:"not", 2:"neither", 4:4})
> + if d != {1:1, 2:2, 3:3, 4:4}: raise TestFailed, 'dict supplement'
> + del d[4]
> if d.copy() != {1:1, 2:2, 3:3}: raise TestFailed, 'dict copy'
> if {}.copy() != {}: raise TestFailed, 'empty dict copy'
> # dict.get()
> *** ../../cvs_01_04_00_orig/dist/src/Lib/UserDict.py Wed Feb 2 16:10:14 2000
> --- src/Lib/UserDict.py Mon Apr 3 10:45:17 2000
> ***************
> *** 32,36 ****
> --- 32,45 ----
> else:
> for k, v in dict.items():
> self.data[k] = v
> + def supplement(self, dict):
> + if isinstance(dict, UserDict):
> + self.data.supplement(dict.data)
> + elif isinstance(dict, type(self.data)):
> + self.data.supplement(dict)
> + else:
> + for k, v in dict.items():
> + if not self.data.has_key(k):
> + self.data[k] = v
> def get(self, key, failobj=None):
> return self.data.get(key, failobj)
> *** ../../cvs_01_04_00_orig/dist/src/Lib/test/test_userdict.py Fri Mar 26 16:32:02 1999
> --- src/Lib/test/test_userdict.py Mon Apr 3 10:50:29 2000
> ***************
> *** 93,101 ****
> --- 93,109 ----
> t.update(u2)
> assert t == u2
>
> + # Test supplement
> +
> + t = UserDict(d1)
> + t.supplement(u2)
> + assert t == u2
> +
> # Test get
>
> for i in u2.keys():
> assert u2.get(i) == u2[i]
> assert u1.get(i) == d1.get(i)
> assert u0.get(i) == d0.get(i)
> +
> + # TODO: Add a test using dir({}) to test for unimplemented methods
>
> _______________________________________________
> Patches mailing list
> Patches@python.org
> http://www.python.org/mailman/listinfo/patches
>
--
Greg Stein, http://www.lyra.org/