Merge lp:~jameinel/bzr/2.1-st-from-iterable into lp:bzr

Proposed by John A Meinel
Status: Merged
Merged at revision: not available
Proposed branch: lp:~jameinel/bzr/2.1-st-from-iterable
Merge into: lp:bzr
Diff against target: 86 lines
2 files modified
bzrlib/_static_tuple_c.c (+14/-8)
bzrlib/tests/test__static_tuple.py (+15/-0)
To merge this branch: bzr merge lp:~jameinel/bzr/2.1-st-from-iterable
Reviewer Review Type Date Requested Status
Vincent Ladeuil Approve
Review via email: mp+14027@code.launchpad.net
To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

This is a small cleanup of Matt Nordhoff's update for 'from_sequence'. Basically, it changes the internals such that if an object isn't a simple sequence, we cast it to a tuple and then use that instead.

It means you can do "StaticTuple.from_sequence(generator)" which is what they had been doing in loggerhead. (using tuple(generator).)

I don't think we *need* this, but if it helps someone, I'm ok with it.

Revision history for this message
Vincent Ladeuil (vila) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/_static_tuple_c.c'
2--- bzrlib/_static_tuple_c.c 2009-10-26 15:59:54 +0000
3+++ bzrlib/_static_tuple_c.c 2009-10-27 14:10:22 +0000
4@@ -183,7 +183,8 @@
5 static StaticTuple *
6 StaticTuple_FromSequence(PyObject *sequence)
7 {
8- StaticTuple *new;
9+ StaticTuple *new = NULL;
10+ PyObject *as_tuple = NULL;
11 PyObject *item;
12 Py_ssize_t i, size;
13
14@@ -192,16 +193,18 @@
15 return (StaticTuple *)sequence;
16 }
17 if (!PySequence_Check(sequence)) {
18- PyErr_Format(PyExc_TypeError, "Type %s is not a sequence type",
19- Py_TYPE(sequence)->tp_name);
20- return NULL;
21+ as_tuple = PySequence_Tuple(sequence);
22+ if (as_tuple == NULL)
23+ goto done;
24+ sequence = as_tuple;
25 }
26 size = PySequence_Size(sequence);
27- if (size == -1)
28- return NULL;
29+ if (size == -1) {
30+ goto done;
31+ }
32 new = StaticTuple_New(size);
33 if (new == NULL) {
34- return NULL;
35+ goto done;
36 }
37 for (i = 0; i < size; ++i) {
38 // This returns a new reference, which we then 'steal' with
39@@ -209,10 +212,13 @@
40 item = PySequence_GetItem(sequence, i);
41 if (item == NULL) {
42 Py_DECREF(new);
43- return NULL;
44+ new = NULL;
45+ goto done;
46 }
47 StaticTuple_SET_ITEM(new, i, item);
48 }
49+done:
50+ Py_XDECREF(as_tuple);
51 return (StaticTuple *)new;
52 }
53
54
55=== modified file 'bzrlib/tests/test__static_tuple.py'
56--- bzrlib/tests/test__static_tuple.py 2009-10-21 17:54:33 +0000
57+++ bzrlib/tests/test__static_tuple.py 2009-10-27 14:10:22 +0000
58@@ -571,6 +571,8 @@
59 def test_from_sequence_not_sequence(self):
60 self.assertRaises(TypeError,
61 self.module.StaticTuple.from_sequence, object())
62+ self.assertRaises(TypeError,
63+ self.module.StaticTuple.from_sequence, 10)
64
65 def test_from_sequence_incorrect_args(self):
66 self.assertRaises(TypeError,
67@@ -578,6 +580,19 @@
68 self.assertRaises(TypeError,
69 self.module.StaticTuple.from_sequence, foo='a')
70
71+ def test_from_sequence_iterable(self):
72+ st = self.module.StaticTuple.from_sequence(iter(['foo', 'bar']))
73+ self.assertIsInstance(st, self.module.StaticTuple)
74+ self.assertEqual(('foo', 'bar'), st)
75+
76+ def test_from_sequence_generator(self):
77+ def generate_tuple():
78+ yield 'foo'
79+ yield 'bar'
80+ st = self.module.StaticTuple.from_sequence(generate_tuple())
81+ self.assertIsInstance(st, self.module.StaticTuple)
82+ self.assertEqual(('foo', 'bar'), st)
83+
84 def test_pickle(self):
85 st = self.module.StaticTuple('foo', 'bar')
86 pickled = cPickle.dumps(st)