Merge lp:~gz/brz/py3_static_tuple_start into lp:brz
- py3_static_tuple_start
- Merge into trunk
Proposed by
Martin Packman
Status: | Merged |
---|---|
Approved by: | Martin Packman |
Approved revision: | no longer in the source branch. |
Merge reported by: | The Breezy Bot |
Merged at revision: | not available |
Proposed branch: | lp:~gz/brz/py3_static_tuple_start |
Merge into: | lp:brz |
Diff against target: |
432 lines (+118/-103) 4 files modified
breezy/_export_c_api.h (+3/-5) breezy/_static_tuple_c.c (+61/-76) breezy/python-compat.h (+31/-0) breezy/tests/test__static_tuple.py (+23/-22) |
To merge this branch: | bzr merge lp:~gz/brz/py3_static_tuple_start |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jelmer Vernooij | Approve | ||
Review via email: mp+326117@code.launchpad.net |
Commit message
Start of making _static_tuple_c compatible with Python 3
Description of the change
This is not everything done to make StaticTuple work on Python 3, but is a reasonable checkpoint. The code compiles, runs tests, and fails in a few relevant ways. The C API level import is also broken.
To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) : | # |
review:
Approve
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Revision history for this message
The Breezy Bot (the-breezy-bot) wrote : | # |
Running landing tests failed
http://
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'breezy/_export_c_api.h' | |||
2 | --- breezy/_export_c_api.h 2009-10-12 21:44:27 +0000 | |||
3 | +++ breezy/_export_c_api.h 2017-06-25 23:38:37 +0000 | |||
4 | @@ -15,6 +15,7 @@ | |||
5 | 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
6 | 16 | */ | 16 | */ |
7 | 17 | 17 | ||
8 | 18 | /* GZ 2017-06-22: This header needs updating to use Capsules over CObjects */ | ||
9 | 18 | 19 | ||
10 | 19 | /* This file contains helper functions for exporting a C API for a CPython | 20 | /* This file contains helper functions for exporting a C API for a CPython |
11 | 20 | * extension module. | 21 | * extension module. |
12 | @@ -45,17 +46,14 @@ | |||
13 | 45 | PyObject *d = NULL; | 46 | PyObject *d = NULL; |
14 | 46 | PyObject *c_obj = NULL; | 47 | PyObject *c_obj = NULL; |
15 | 47 | 48 | ||
20 | 48 | /* (char *) is because python2.4 declares this api as 'char *' rather than | 49 | d = PyObject_GetAttrString(module, _C_API_NAME); |
17 | 49 | * const char* which it really is. | ||
18 | 50 | */ | ||
19 | 51 | d = PyObject_GetAttrString(module, (char *)_C_API_NAME); | ||
21 | 52 | if (!d) { | 50 | if (!d) { |
22 | 53 | PyErr_Clear(); | 51 | PyErr_Clear(); |
23 | 54 | d = PyDict_New(); | 52 | d = PyDict_New(); |
24 | 55 | if (!d) | 53 | if (!d) |
25 | 56 | goto bad; | 54 | goto bad; |
26 | 57 | Py_INCREF(d); | 55 | Py_INCREF(d); |
28 | 58 | if (PyModule_AddObject(module, (char *)_C_API_NAME, d) < 0) | 56 | if (PyModule_AddObject(module, _C_API_NAME, d) < 0) |
29 | 59 | goto bad; | 57 | goto bad; |
30 | 60 | } | 58 | } |
31 | 61 | c_obj = PyCObject_FromVoidPtrAndDesc(func, signature, 0); | 59 | c_obj = PyCObject_FromVoidPtrAndDesc(func, signature, 0); |
32 | 62 | 60 | ||
33 | === modified file 'breezy/_static_tuple_c.c' | |||
34 | --- breezy/_static_tuple_c.c 2017-05-21 18:10:28 +0000 | |||
35 | +++ breezy/_static_tuple_c.c 2017-06-25 23:38:37 +0000 | |||
36 | @@ -26,12 +26,6 @@ | |||
37 | 26 | #include "_static_tuple_c.h" | 26 | #include "_static_tuple_c.h" |
38 | 27 | #include "_export_c_api.h" | 27 | #include "_export_c_api.h" |
39 | 28 | 28 | ||
40 | 29 | /* Pyrex 0.9.6.4 exports _simple_set_pyx_api as | ||
41 | 30 | * import__simple_set_pyx(), while Pyrex 0.9.8.5 and Cython 0.11.3 export them | ||
42 | 31 | * as import_breezy___simple_set_pyx(). As such, we just #define one to be | ||
43 | 32 | * equivalent to the other in our internal code. | ||
44 | 33 | */ | ||
45 | 34 | #define import__simple_set_pyx import_breezy___simple_set_pyx | ||
46 | 35 | #include "_simple_set_pyx_api.h" | 29 | #include "_simple_set_pyx_api.h" |
47 | 36 | 30 | ||
48 | 37 | #if defined(__GNUC__) | 31 | #if defined(__GNUC__) |
49 | @@ -242,11 +236,14 @@ | |||
50 | 242 | " should not have a NULL entry."); | 236 | " should not have a NULL entry."); |
51 | 243 | return 0; | 237 | return 0; |
52 | 244 | } | 238 | } |
54 | 245 | if (PyString_CheckExact(obj) | 239 | if (PyBytes_CheckExact(obj) |
55 | 246 | || StaticTuple_CheckExact(obj) | 240 | || StaticTuple_CheckExact(obj) |
56 | 247 | || obj == Py_None | 241 | || obj == Py_None |
57 | 248 | || PyBool_Check(obj) | 242 | || PyBool_Check(obj) |
58 | 243 | #if PY_MAJOR_VERSION >= 3 | ||
59 | 244 | #else | ||
60 | 249 | || PyInt_CheckExact(obj) | 245 | || PyInt_CheckExact(obj) |
61 | 246 | #endif | ||
62 | 250 | || PyLong_CheckExact(obj) | 247 | || PyLong_CheckExact(obj) |
63 | 251 | || PyFloat_CheckExact(obj) | 248 | || PyFloat_CheckExact(obj) |
64 | 252 | || PyUnicode_CheckExact(obj) | 249 | || PyUnicode_CheckExact(obj) |
65 | @@ -314,8 +311,12 @@ | |||
66 | 314 | if (tuple_repr == NULL) { | 311 | if (tuple_repr == NULL) { |
67 | 315 | return NULL; | 312 | return NULL; |
68 | 316 | } | 313 | } |
69 | 314 | #if PY_MAJOR_VERSION >= 3 | ||
70 | 315 | result = PyUnicode_FromFormat("StaticTuple%U", tuple_repr); | ||
71 | 316 | #else | ||
72 | 317 | result = PyString_FromFormat("StaticTuple%s", | 317 | result = PyString_FromFormat("StaticTuple%s", |
73 | 318 | PyString_AsString(tuple_repr)); | 318 | PyString_AsString(tuple_repr)); |
74 | 319 | #endif | ||
75 | 319 | return result; | 320 | return result; |
76 | 320 | } | 321 | } |
77 | 321 | 322 | ||
78 | @@ -362,7 +363,7 @@ | |||
79 | 362 | { | 363 | { |
80 | 363 | PyObject *vt; | 364 | PyObject *vt; |
81 | 364 | PyObject *result = NULL; | 365 | PyObject *result = NULL; |
83 | 365 | 366 | ||
84 | 366 | vt = StaticTuple_as_tuple((StaticTuple *)v); | 367 | vt = StaticTuple_as_tuple((StaticTuple *)v); |
85 | 367 | if (vt == NULL) { | 368 | if (vt == NULL) { |
86 | 368 | goto done; | 369 | goto done; |
87 | @@ -478,7 +479,7 @@ | |||
88 | 478 | vlen = v_st->size; | 479 | vlen = v_st->size; |
89 | 479 | wlen = w_st->size; | 480 | wlen = w_st->size; |
90 | 480 | min_len = (vlen < wlen) ? vlen : wlen; | 481 | min_len = (vlen < wlen) ? vlen : wlen; |
92 | 481 | string_richcompare = PyString_Type.tp_richcompare; | 482 | string_richcompare = PyBytes_Type.tp_richcompare; |
93 | 482 | for (i = 0; i < min_len; i++) { | 483 | for (i = 0; i < min_len; i++) { |
94 | 483 | PyObject *result = NULL; | 484 | PyObject *result = NULL; |
95 | 484 | v_obj = StaticTuple_GET_ITEM(v_st, i); | 485 | v_obj = StaticTuple_GET_ITEM(v_st, i); |
96 | @@ -487,7 +488,7 @@ | |||
97 | 487 | /* Shortcut case, these must be identical */ | 488 | /* Shortcut case, these must be identical */ |
98 | 488 | continue; | 489 | continue; |
99 | 489 | } | 490 | } |
101 | 490 | if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj)) { | 491 | if (PyBytes_CheckExact(v_obj) && PyBytes_CheckExact(w_obj)) { |
102 | 491 | result = string_richcompare(v_obj, w_obj, Py_EQ); | 492 | result = string_richcompare(v_obj, w_obj, Py_EQ); |
103 | 492 | } else if (StaticTuple_CheckExact(v_obj) && | 493 | } else if (StaticTuple_CheckExact(v_obj) && |
104 | 493 | StaticTuple_CheckExact(w_obj)) | 494 | StaticTuple_CheckExact(w_obj)) |
105 | @@ -547,7 +548,7 @@ | |||
106 | 547 | return Py_True; | 548 | return Py_True; |
107 | 548 | } | 549 | } |
108 | 549 | /* It is some other comparison, go ahead and do the real check. */ | 550 | /* It is some other comparison, go ahead and do the real check. */ |
110 | 550 | if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj)) | 551 | if (PyBytes_CheckExact(v_obj) && PyBytes_CheckExact(w_obj)) |
111 | 551 | { | 552 | { |
112 | 552 | return string_richcompare(v_obj, w_obj, op); | 553 | return string_richcompare(v_obj, w_obj, op); |
113 | 553 | } else if (StaticTuple_CheckExact(v_obj) && | 554 | } else if (StaticTuple_CheckExact(v_obj) && |
114 | @@ -679,6 +680,8 @@ | |||
115 | 679 | return obj; | 680 | return obj; |
116 | 680 | } | 681 | } |
117 | 681 | 682 | ||
118 | 683 | #if PY_MAJOR_VERSION >= 3 | ||
119 | 684 | #else | ||
120 | 682 | static PyObject * | 685 | static PyObject * |
121 | 683 | StaticTuple_slice(StaticTuple *self, Py_ssize_t ilow, Py_ssize_t ihigh) | 686 | StaticTuple_slice(StaticTuple *self, Py_ssize_t ilow, Py_ssize_t ihigh) |
122 | 684 | { | 687 | { |
123 | @@ -692,6 +695,21 @@ | |||
124 | 692 | Py_DECREF(as_tuple); | 695 | Py_DECREF(as_tuple); |
125 | 693 | return result; | 696 | return result; |
126 | 694 | } | 697 | } |
127 | 698 | #endif | ||
128 | 699 | |||
129 | 700 | static PyObject * | ||
130 | 701 | StaticTuple_subscript(StaticTuple *self, PyObject *key) | ||
131 | 702 | { | ||
132 | 703 | PyObject *as_tuple, *result; | ||
133 | 704 | |||
134 | 705 | as_tuple = StaticTuple_as_tuple(self); | ||
135 | 706 | if (as_tuple == NULL) { | ||
136 | 707 | return NULL; | ||
137 | 708 | } | ||
138 | 709 | result = PyTuple_Type.tp_as_mapping->mp_subscript(as_tuple, key); | ||
139 | 710 | Py_DECREF(as_tuple); | ||
140 | 711 | return result; | ||
141 | 712 | } | ||
142 | 695 | 713 | ||
143 | 696 | static int | 714 | static int |
144 | 697 | StaticTuple_traverse(StaticTuple *self, visitproc visit, void *arg) | 715 | StaticTuple_traverse(StaticTuple *self, visitproc visit, void *arg) |
145 | @@ -759,29 +777,36 @@ | |||
146 | 759 | 0, /* nb_or */ | 777 | 0, /* nb_or */ |
147 | 760 | 0, /* nb_coerce */ | 778 | 0, /* nb_coerce */ |
148 | 761 | }; | 779 | }; |
150 | 762 | 780 | ||
151 | 763 | 781 | ||
152 | 764 | static PySequenceMethods StaticTuple_as_sequence = { | 782 | static PySequenceMethods StaticTuple_as_sequence = { |
153 | 765 | (lenfunc)StaticTuple_length, /* sq_length */ | 783 | (lenfunc)StaticTuple_length, /* sq_length */ |
154 | 766 | 0, /* sq_concat */ | 784 | 0, /* sq_concat */ |
155 | 767 | 0, /* sq_repeat */ | 785 | 0, /* sq_repeat */ |
156 | 768 | (ssizeargfunc)StaticTuple_item, /* sq_item */ | 786 | (ssizeargfunc)StaticTuple_item, /* sq_item */ |
157 | 787 | #if PY_MAJOR_VERSION >= 3 | ||
158 | 788 | #else | ||
159 | 769 | (ssizessizeargfunc)StaticTuple_slice, /* sq_slice */ | 789 | (ssizessizeargfunc)StaticTuple_slice, /* sq_slice */ |
160 | 790 | #endif | ||
161 | 770 | 0, /* sq_ass_item */ | 791 | 0, /* sq_ass_item */ |
162 | 771 | 0, /* sq_ass_slice */ | 792 | 0, /* sq_ass_slice */ |
163 | 772 | 0, /* sq_contains */ | 793 | 0, /* sq_contains */ |
171 | 773 | }; | 794 | #if PY_MAJOR_VERSION >= 3 |
172 | 774 | 795 | 0, /* sq_inplace_concat */ | |
173 | 775 | /* TODO: Implement StaticTuple_as_mapping. | 796 | 0, /* sq_inplace_repeat */ |
174 | 776 | * The only thing we really want to support from there is mp_subscript, | 797 | #endif |
175 | 777 | * so that we could support extended slicing (foo[::2]). Not worth it | 798 | }; |
176 | 778 | * yet, though. | 799 | |
177 | 779 | */ | 800 | |
178 | 801 | static PyMappingMethods StaticTuple_as_mapping = { | ||
179 | 802 | (lenfunc)StaticTuple_length, /* mp_length */ | ||
180 | 803 | (binaryfunc)StaticTuple_subscript, /* mp_subscript */ | ||
181 | 804 | 0, /* mp_ass_subscript */ | ||
182 | 805 | }; | ||
183 | 780 | 806 | ||
184 | 781 | 807 | ||
185 | 782 | PyTypeObject StaticTuple_Type = { | 808 | PyTypeObject StaticTuple_Type = { |
188 | 783 | PyObject_HEAD_INIT(NULL) | 809 | PyVarObject_HEAD_INIT(NULL, 0) |
187 | 784 | 0, /* ob_size */ | ||
189 | 785 | "breezy._static_tuple_c.StaticTuple", /* tp_name */ | 810 | "breezy._static_tuple_c.StaticTuple", /* tp_name */ |
190 | 786 | sizeof(StaticTuple), /* tp_basicsize */ | 811 | sizeof(StaticTuple), /* tp_basicsize */ |
191 | 787 | sizeof(PyObject *), /* tp_itemsize */ | 812 | sizeof(PyObject *), /* tp_itemsize */ |
192 | @@ -793,7 +818,7 @@ | |||
193 | 793 | (reprfunc)StaticTuple_repr, /* tp_repr */ | 818 | (reprfunc)StaticTuple_repr, /* tp_repr */ |
194 | 794 | &StaticTuple_as_number, /* tp_as_number */ | 819 | &StaticTuple_as_number, /* tp_as_number */ |
195 | 795 | &StaticTuple_as_sequence, /* tp_as_sequence */ | 820 | &StaticTuple_as_sequence, /* tp_as_sequence */ |
197 | 796 | 0, /* tp_as_mapping */ | 821 | &StaticTuple_as_mapping, /* tp_as_mapping */ |
198 | 797 | (hashfunc)StaticTuple_hash, /* tp_hash */ | 822 | (hashfunc)StaticTuple_hash, /* tp_hash */ |
199 | 798 | 0, /* tp_call */ | 823 | 0, /* tp_call */ |
200 | 799 | 0, /* tp_str */ | 824 | 0, /* tp_str */ |
201 | @@ -887,72 +912,32 @@ | |||
202 | 887 | } | 912 | } |
203 | 888 | 913 | ||
204 | 889 | 914 | ||
249 | 890 | static int | 915 | PYMOD_INIT_FUNC(_static_tuple_c) |
206 | 891 | _workaround_pyrex_096(void) | ||
207 | 892 | { | ||
208 | 893 | /* Work around an incompatibility in how pyrex 0.9.6 exports a module, | ||
209 | 894 | * versus how pyrex 0.9.8 and cython 0.11 export it. | ||
210 | 895 | * Namely 0.9.6 exports import__simple_set_pyx and tries to | ||
211 | 896 | * "import _simple_set_pyx" but it is available only as | ||
212 | 897 | * "import breezy._simple_set_pyx" | ||
213 | 898 | * It is a shame to hack up sys.modules, but that is what we've got to do. | ||
214 | 899 | */ | ||
215 | 900 | PyObject *sys_module = NULL, *modules = NULL, *set_module = NULL; | ||
216 | 901 | int retval = -1; | ||
217 | 902 | |||
218 | 903 | /* Clear out the current ImportError exception, and try again. */ | ||
219 | 904 | PyErr_Clear(); | ||
220 | 905 | /* Note that this only seems to work if somewhere else imports | ||
221 | 906 | * breezy._simple_set_pyx before importing breezy._static_tuple_c | ||
222 | 907 | */ | ||
223 | 908 | set_module = PyImport_ImportModule("breezy._simple_set_pyx"); | ||
224 | 909 | if (set_module == NULL) { | ||
225 | 910 | goto end; | ||
226 | 911 | } | ||
227 | 912 | /* Add the _simple_set_pyx into sys.modules at the appropriate location. */ | ||
228 | 913 | sys_module = PyImport_ImportModule("sys"); | ||
229 | 914 | if (sys_module == NULL) { | ||
230 | 915 | goto end; | ||
231 | 916 | } | ||
232 | 917 | modules = PyObject_GetAttrString(sys_module, "modules"); | ||
233 | 918 | if (modules == NULL || !PyDict_Check(modules)) { | ||
234 | 919 | goto end; | ||
235 | 920 | } | ||
236 | 921 | PyDict_SetItemString(modules, "_simple_set_pyx", set_module); | ||
237 | 922 | /* Now that we have hacked it in, try the import again. */ | ||
238 | 923 | retval = import_breezy___simple_set_pyx(); | ||
239 | 924 | end: | ||
240 | 925 | Py_XDECREF(set_module); | ||
241 | 926 | Py_XDECREF(sys_module); | ||
242 | 927 | Py_XDECREF(modules); | ||
243 | 928 | return retval; | ||
244 | 929 | } | ||
245 | 930 | |||
246 | 931 | |||
247 | 932 | PyMODINIT_FUNC | ||
248 | 933 | init_static_tuple_c(void) | ||
250 | 934 | { | 916 | { |
251 | 935 | PyObject* m; | 917 | PyObject* m; |
252 | 936 | 918 | ||
253 | 937 | StaticTuple_Type.tp_getattro = PyObject_GenericGetAttr; | 919 | StaticTuple_Type.tp_getattro = PyObject_GenericGetAttr; |
256 | 938 | if (PyType_Ready(&StaticTuple_Type) < 0) | 920 | if (PyType_Ready(&StaticTuple_Type) < 0) { |
257 | 939 | return; | 921 | return PYMOD_ERROR; |
258 | 922 | } | ||
259 | 940 | 923 | ||
264 | 941 | m = Py_InitModule3("_static_tuple_c", static_tuple_c_methods, | 924 | PYMOD_CREATE(m, "_static_tuple_c", |
265 | 942 | "C implementation of a StaticTuple structure"); | 925 | "C implementation of a StaticTuple structure", |
266 | 943 | if (m == NULL) | 926 | static_tuple_c_methods); |
267 | 944 | return; | 927 | if (m == NULL) { |
268 | 928 | return PYMOD_ERROR; | ||
269 | 929 | } | ||
270 | 945 | 930 | ||
271 | 946 | Py_INCREF(&StaticTuple_Type); | 931 | Py_INCREF(&StaticTuple_Type); |
272 | 947 | PyModule_AddObject(m, "StaticTuple", (PyObject *)&StaticTuple_Type); | 932 | PyModule_AddObject(m, "StaticTuple", (PyObject *)&StaticTuple_Type); |
277 | 948 | if (import_breezy___simple_set_pyx() == -1 | 933 | if (import_breezy___simple_set_pyx() == -1) { |
278 | 949 | && _workaround_pyrex_096() == -1) | 934 | return PYMOD_ERROR; |
275 | 950 | { | ||
276 | 951 | return; | ||
279 | 952 | } | 935 | } |
280 | 953 | setup_interned_tuples(m); | 936 | setup_interned_tuples(m); |
281 | 954 | setup_empty_tuple(m); | 937 | setup_empty_tuple(m); |
282 | 955 | setup_c_api(m); | 938 | setup_c_api(m); |
283 | 939 | |||
284 | 940 | return PYMOD_SUCCESS(m); | ||
285 | 956 | } | 941 | } |
286 | 957 | 942 | ||
287 | 958 | // vim: tabstop=4 sw=4 expandtab | 943 | // vim: tabstop=4 sw=4 expandtab |
288 | 959 | 944 | ||
289 | === modified file 'breezy/python-compat.h' | |||
290 | --- breezy/python-compat.h 2017-06-05 23:59:08 +0000 | |||
291 | +++ breezy/python-compat.h 2017-06-25 23:38:37 +0000 | |||
292 | @@ -25,6 +25,37 @@ | |||
293 | 25 | #ifndef _BZR_PYTHON_COMPAT_H | 25 | #ifndef _BZR_PYTHON_COMPAT_H |
294 | 26 | #define _BZR_PYTHON_COMPAT_H | 26 | #define _BZR_PYTHON_COMPAT_H |
295 | 27 | 27 | ||
296 | 28 | #if PY_MAJOR_VERSION >= 3 | ||
297 | 29 | |||
298 | 30 | #define PyInt_FromSsize_t PyLong_FromSsize_t | ||
299 | 31 | |||
300 | 32 | /* In Python 3 the Py_TPFLAGS_CHECKTYPES behaviour is on by default */ | ||
301 | 33 | #define Py_TPFLAGS_CHECKTYPES 0 | ||
302 | 34 | |||
303 | 35 | #define PYMOD_ERROR NULL | ||
304 | 36 | #define PYMOD_SUCCESS(val) val | ||
305 | 37 | #define PYMOD_INIT_FUNC(name) PyMODINIT_FUNC PyInit_##name(void) | ||
306 | 38 | #define PYMOD_CREATE(ob, name, doc, methods) do { \ | ||
307 | 39 | static struct PyModuleDef moduledef = { \ | ||
308 | 40 | PyModuleDef_HEAD_INIT, name, doc, -1, methods \ | ||
309 | 41 | }; \ | ||
310 | 42 | ob = PyModule_Create(&moduledef); \ | ||
311 | 43 | } while(0) | ||
312 | 44 | |||
313 | 45 | #else | ||
314 | 46 | |||
315 | 47 | #define PyBytes_Type PyString_Type | ||
316 | 48 | #define PyBytes_CheckExact PyString_CheckExact | ||
317 | 49 | |||
318 | 50 | #define PYMOD_ERROR | ||
319 | 51 | #define PYMOD_SUCCESS(val) | ||
320 | 52 | #define PYMOD_INIT_FUNC(name) void init##name(void) | ||
321 | 53 | #define PYMOD_CREATE(ob, name, doc, methods) do { \ | ||
322 | 54 | ob = Py_InitModule3(name, methods, doc); \ | ||
323 | 55 | } while(0) | ||
324 | 56 | |||
325 | 57 | #endif | ||
326 | 58 | |||
327 | 28 | #if defined(_WIN32) || defined(WIN32) | 59 | #if defined(_WIN32) || defined(WIN32) |
328 | 29 | /* Defining WIN32_LEAN_AND_MEAN makes including windows quite a bit | 60 | /* Defining WIN32_LEAN_AND_MEAN makes including windows quite a bit |
329 | 30 | * lighter weight. | 61 | * lighter weight. |
330 | 31 | 62 | ||
331 | === modified file 'breezy/tests/test__static_tuple.py' | |||
332 | --- breezy/tests/test__static_tuple.py 2017-05-23 14:08:03 +0000 | |||
333 | +++ breezy/tests/test__static_tuple.py 2017-06-25 23:38:37 +0000 | |||
334 | @@ -16,7 +16,10 @@ | |||
335 | 16 | 16 | ||
336 | 17 | """Tests for the StaticTuple type.""" | 17 | """Tests for the StaticTuple type.""" |
337 | 18 | 18 | ||
339 | 19 | import cPickle | 19 | try: |
340 | 20 | import cPickle as pickle | ||
341 | 21 | except ImportError: | ||
342 | 22 | import pickle | ||
343 | 20 | import sys | 23 | import sys |
344 | 21 | 24 | ||
345 | 22 | from breezy import ( | 25 | from breezy import ( |
346 | @@ -26,6 +29,10 @@ | |||
347 | 26 | static_tuple, | 29 | static_tuple, |
348 | 27 | tests, | 30 | tests, |
349 | 28 | ) | 31 | ) |
350 | 32 | from breezy.sixish import ( | ||
351 | 33 | PY3, | ||
352 | 34 | text_type, | ||
353 | 35 | ) | ||
354 | 29 | from breezy.tests import ( | 36 | from breezy.tests import ( |
355 | 30 | features, | 37 | features, |
356 | 31 | ) | 38 | ) |
357 | @@ -213,6 +220,8 @@ | |||
358 | 213 | self.assertRaises(TypeError, self.module.StaticTuple, subint(2)) | 220 | self.assertRaises(TypeError, self.module.StaticTuple, subint(2)) |
359 | 214 | 221 | ||
360 | 215 | def test_holds_long(self): | 222 | def test_holds_long(self): |
361 | 223 | if PY3: | ||
362 | 224 | self.skipTest("No long type on Python 3") | ||
363 | 216 | k1 = self.module.StaticTuple(2**65) | 225 | k1 = self.module.StaticTuple(2**65) |
364 | 217 | class sublong(long): | 226 | class sublong(long): |
365 | 218 | pass | 227 | pass |
366 | @@ -225,15 +234,15 @@ | |||
367 | 225 | pass | 234 | pass |
368 | 226 | self.assertRaises(TypeError, self.module.StaticTuple, subfloat(1.5)) | 235 | self.assertRaises(TypeError, self.module.StaticTuple, subfloat(1.5)) |
369 | 227 | 236 | ||
373 | 228 | def test_holds_str(self): | 237 | def test_holds_bytes(self): |
374 | 229 | k1 = self.module.StaticTuple('astring') | 238 | k1 = self.module.StaticTuple(b'astring') |
375 | 230 | class substr(str): | 239 | class substr(bytes): |
376 | 231 | pass | 240 | pass |
378 | 232 | self.assertRaises(TypeError, self.module.StaticTuple, substr('a')) | 241 | self.assertRaises(TypeError, self.module.StaticTuple, substr(b'a')) |
379 | 233 | 242 | ||
380 | 234 | def test_holds_unicode(self): | 243 | def test_holds_unicode(self): |
381 | 235 | k1 = self.module.StaticTuple(u'\xb5') | 244 | k1 = self.module.StaticTuple(u'\xb5') |
383 | 236 | class subunicode(unicode): | 245 | class subunicode(text_type): |
384 | 237 | pass | 246 | pass |
385 | 238 | self.assertRaises(TypeError, self.module.StaticTuple, | 247 | self.assertRaises(TypeError, self.module.StaticTuple, |
386 | 239 | subunicode(u'\xb5')) | 248 | subunicode(u'\xb5')) |
387 | @@ -416,16 +425,8 @@ | |||
388 | 416 | k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing') | 425 | k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing') |
389 | 417 | self.assertEqual(('foo', 'bar'), k[:2]) | 426 | self.assertEqual(('foo', 'bar'), k[:2]) |
390 | 418 | self.assertEqual(('baz',), k[2:-1]) | 427 | self.assertEqual(('baz',), k[2:-1]) |
401 | 419 | try: | 428 | self.assertEqual(('foo', 'baz',), k[::2]) |
402 | 420 | val = k[::2] | 429 | self.assertRaises(TypeError, k.__getitem__, 'not_slice') |
393 | 421 | except TypeError: | ||
394 | 422 | # C implementation raises a TypeError, we don't need the | ||
395 | 423 | # implementation yet, so allow this to pass | ||
396 | 424 | pass | ||
397 | 425 | else: | ||
398 | 426 | # Python implementation uses a regular Tuple, so make sure it gives | ||
399 | 427 | # the right result | ||
400 | 428 | self.assertEqual(('foo', 'baz'), val) | ||
403 | 429 | 430 | ||
404 | 430 | def test_referents(self): | 431 | def test_referents(self): |
405 | 431 | # We implement tp_traverse so that things like 'meliae' can measure the | 432 | # We implement tp_traverse so that things like 'meliae' can measure the |
406 | @@ -582,20 +583,20 @@ | |||
407 | 582 | 583 | ||
408 | 583 | def test_pickle(self): | 584 | def test_pickle(self): |
409 | 584 | st = self.module.StaticTuple('foo', 'bar') | 585 | st = self.module.StaticTuple('foo', 'bar') |
412 | 585 | pickled = cPickle.dumps(st) | 586 | pickled = pickle.dumps(st) |
413 | 586 | unpickled = cPickle.loads(pickled) | 587 | unpickled = pickle.loads(pickled) |
414 | 587 | self.assertEqual(unpickled, st) | 588 | self.assertEqual(unpickled, st) |
415 | 588 | 589 | ||
416 | 589 | def test_pickle_empty(self): | 590 | def test_pickle_empty(self): |
417 | 590 | st = self.module.StaticTuple() | 591 | st = self.module.StaticTuple() |
420 | 591 | pickled = cPickle.dumps(st) | 592 | pickled = pickle.dumps(st) |
421 | 592 | unpickled = cPickle.loads(pickled) | 593 | unpickled = pickle.loads(pickled) |
422 | 593 | self.assertIs(st, unpickled) | 594 | self.assertIs(st, unpickled) |
423 | 594 | 595 | ||
424 | 595 | def test_pickle_nested(self): | 596 | def test_pickle_nested(self): |
425 | 596 | st = self.module.StaticTuple('foo', self.module.StaticTuple('bar')) | 597 | st = self.module.StaticTuple('foo', self.module.StaticTuple('bar')) |
428 | 597 | pickled = cPickle.dumps(st) | 598 | pickled = pickle.dumps(st) |
429 | 598 | unpickled = cPickle.loads(pickled) | 599 | unpickled = pickle.loads(pickled) |
430 | 599 | self.assertEqual(unpickled, st) | 600 | self.assertEqual(unpickled, st) |
431 | 600 | 601 | ||
432 | 601 | def test_static_tuple_thunk(self): | 602 | def test_static_tuple_thunk(self): |
Running landing tests failed 10.242. 247.184: 8080/job/ brz-dev/ 168/
http://