/breezy/unstable

To get this branch, use:
bzr branch https://code.breezy-vcs.org/breezy/unstable

« back to all changes in this revision

Viewing changes to breezy/_static_tuple_c.c

Merge trunk, address review comments.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include "_static_tuple_c.h"
27
27
#include "_export_c_api.h"
28
28
 
29
 
/* Pyrex 0.9.6.4 exports _simple_set_pyx_api as
30
 
 * import__simple_set_pyx(), while Pyrex 0.9.8.5 and Cython 0.11.3 export them
31
 
 * as import_breezy___simple_set_pyx(). As such, we just #define one to be
32
 
 * equivalent to the other in our internal code.
33
 
 */
34
 
#define import__simple_set_pyx import_breezy___simple_set_pyx
35
29
#include "_simple_set_pyx_api.h"
36
30
 
37
31
#if defined(__GNUC__)
242
236
                " should not have a NULL entry.");
243
237
            return 0;
244
238
        }
245
 
        if (PyString_CheckExact(obj)
 
239
        if (PyBytes_CheckExact(obj)
246
240
            || StaticTuple_CheckExact(obj)
247
241
            || obj == Py_None
248
242
            || PyBool_Check(obj)
 
243
#if PY_MAJOR_VERSION >= 3
 
244
#else
249
245
            || PyInt_CheckExact(obj)
 
246
#endif
250
247
            || PyLong_CheckExact(obj)
251
248
            || PyFloat_CheckExact(obj)
252
249
            || PyUnicode_CheckExact(obj)
314
311
    if (tuple_repr == NULL) {
315
312
        return NULL;
316
313
    }
 
314
#if PY_MAJOR_VERSION >= 3
 
315
    result = PyUnicode_FromFormat("StaticTuple%U", tuple_repr);
 
316
#else
317
317
    result = PyString_FromFormat("StaticTuple%s",
318
318
                                 PyString_AsString(tuple_repr));
 
319
#endif
319
320
    return result;
320
321
}
321
322
 
362
363
{
363
364
    PyObject *vt;
364
365
    PyObject *result = NULL;
365
 
    
 
366
 
366
367
    vt = StaticTuple_as_tuple((StaticTuple *)v);
367
368
    if (vt == NULL) {
368
369
        goto done;
427
428
    } else if (w == Py_None) {
428
429
        // None is always less than the object
429
430
        switch (op) {
430
 
        case Py_NE:case Py_GT:case Py_GE:
 
431
        case Py_NE:
 
432
#if PY_MAJOR_VERSION >= 3
 
433
#else
 
434
        case Py_GT:case Py_GE:
 
435
#endif
431
436
            Py_INCREF(Py_True);
432
437
            return Py_True;
433
 
        case Py_EQ:case Py_LT:case Py_LE:
 
438
        case Py_EQ:
 
439
#if PY_MAJOR_VERSION >= 3
 
440
#else
 
441
        case Py_LT:case Py_LE:
 
442
#endif
434
443
            Py_INCREF(Py_False);
435
444
            return Py_False;
436
 
    default: // Should never happen
437
 
        return Py_NotImplemented;
 
445
        default: // Should only happen on Python 3
 
446
            return Py_NotImplemented;
438
447
        }
439
448
    } else {
440
449
        /* We don't special case this comparison, we just let python handle
478
487
    vlen = v_st->size;
479
488
    wlen = w_st->size;
480
489
    min_len = (vlen < wlen) ? vlen : wlen;
481
 
    string_richcompare = PyString_Type.tp_richcompare;
 
490
    string_richcompare = PyBytes_Type.tp_richcompare;
482
491
    for (i = 0; i < min_len; i++) {
483
492
        PyObject *result = NULL;
484
493
        v_obj = StaticTuple_GET_ITEM(v_st, i);
487
496
            /* Shortcut case, these must be identical */
488
497
            continue;
489
498
        }
490
 
        if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj)) {
 
499
        if (PyBytes_CheckExact(v_obj) && PyBytes_CheckExact(w_obj)) {
491
500
            result = string_richcompare(v_obj, w_obj, Py_EQ);
492
501
        } else if (StaticTuple_CheckExact(v_obj) &&
493
502
                   StaticTuple_CheckExact(w_obj))
547
556
        return Py_True;
548
557
    }
549
558
    /* It is some other comparison, go ahead and do the real check. */
550
 
    if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj))
 
559
    if (PyBytes_CheckExact(v_obj) && PyBytes_CheckExact(w_obj))
551
560
    {
552
561
        return string_richcompare(v_obj, w_obj, op);
553
562
    } else if (StaticTuple_CheckExact(v_obj) &&
679
688
    return obj;
680
689
}
681
690
 
 
691
#if PY_MAJOR_VERSION >= 3
 
692
#else
682
693
static PyObject *
683
694
StaticTuple_slice(StaticTuple *self, Py_ssize_t ilow, Py_ssize_t ihigh)
684
695
{
692
703
    Py_DECREF(as_tuple);
693
704
    return result;
694
705
}
 
706
#endif
 
707
 
 
708
static PyObject *
 
709
StaticTuple_subscript(StaticTuple *self, PyObject *key)
 
710
{
 
711
    PyObject *as_tuple, *result;
 
712
 
 
713
    as_tuple = StaticTuple_as_tuple(self);
 
714
    if (as_tuple == NULL) {
 
715
        return NULL;
 
716
    }
 
717
    result = PyTuple_Type.tp_as_mapping->mp_subscript(as_tuple, key);
 
718
    Py_DECREF(as_tuple);
 
719
    return result;
 
720
}
695
721
 
696
722
static int
697
723
StaticTuple_traverse(StaticTuple *self, visitproc visit, void *arg)
707
733
static PyObject *
708
734
StaticTuple_sizeof(StaticTuple *self)
709
735
{
710
 
        Py_ssize_t res;
 
736
    Py_ssize_t res;
711
737
 
712
 
        res = _PyObject_SIZE(&StaticTuple_Type) + (int)self->size * sizeof(void*);
713
 
        return PyInt_FromSsize_t(res);
 
738
    res = _PyObject_SIZE(&StaticTuple_Type) + (int)self->size * sizeof(void*);
 
739
    return PyInt_FromSsize_t(res);
714
740
}
715
741
 
716
742
 
759
785
    0,                              /* nb_or */
760
786
    0,                              /* nb_coerce */
761
787
};
762
 
    
 
788
 
763
789
 
764
790
static PySequenceMethods StaticTuple_as_sequence = {
765
791
    (lenfunc)StaticTuple_length,            /* sq_length */
766
792
    0,                              /* sq_concat */
767
793
    0,                              /* sq_repeat */
768
794
    (ssizeargfunc)StaticTuple_item,         /* sq_item */
 
795
#if PY_MAJOR_VERSION >= 3
 
796
#else
769
797
    (ssizessizeargfunc)StaticTuple_slice,   /* sq_slice */
 
798
#endif
770
799
    0,                              /* sq_ass_item */
771
800
    0,                              /* sq_ass_slice */
772
801
    0,                              /* sq_contains */
773
 
};
774
 
 
775
 
/* TODO: Implement StaticTuple_as_mapping.
776
 
 *       The only thing we really want to support from there is mp_subscript,
777
 
 *       so that we could support extended slicing (foo[::2]). Not worth it
778
 
 *       yet, though.
779
 
 */
 
802
#if PY_MAJOR_VERSION >= 3
 
803
    0,                              /* sq_inplace_concat */
 
804
    0,                              /* sq_inplace_repeat */
 
805
#endif
 
806
};
 
807
 
 
808
 
 
809
static PyMappingMethods StaticTuple_as_mapping = {
 
810
    (lenfunc)StaticTuple_length,            /* mp_length */
 
811
    (binaryfunc)StaticTuple_subscript,      /* mp_subscript */
 
812
    0,                                      /* mp_ass_subscript */
 
813
};
780
814
 
781
815
 
782
816
PyTypeObject StaticTuple_Type = {
783
 
    PyObject_HEAD_INIT(NULL)
784
 
    0,                                           /* ob_size */
 
817
    PyVarObject_HEAD_INIT(NULL, 0)
785
818
    "breezy._static_tuple_c.StaticTuple",        /* tp_name */
786
819
    sizeof(StaticTuple),                         /* tp_basicsize */
787
820
    sizeof(PyObject *),                          /* tp_itemsize */
793
826
    (reprfunc)StaticTuple_repr,                  /* tp_repr */
794
827
    &StaticTuple_as_number,                      /* tp_as_number */
795
828
    &StaticTuple_as_sequence,                    /* tp_as_sequence */
796
 
    0,                                           /* tp_as_mapping */
 
829
    &StaticTuple_as_mapping,                     /* tp_as_mapping */
797
830
    (hashfunc)StaticTuple_hash,                  /* tp_hash */
798
831
    0,                                           /* tp_call */
799
832
    0,                                           /* tp_str */
887
920
}
888
921
 
889
922
 
890
 
static int
891
 
_workaround_pyrex_096(void)
892
 
{
893
 
    /* Work around an incompatibility in how pyrex 0.9.6 exports a module,
894
 
     * versus how pyrex 0.9.8 and cython 0.11 export it.
895
 
     * Namely 0.9.6 exports import__simple_set_pyx and tries to
896
 
     * "import _simple_set_pyx" but it is available only as
897
 
     * "import breezy._simple_set_pyx"
898
 
     * It is a shame to hack up sys.modules, but that is what we've got to do.
899
 
     */
900
 
    PyObject *sys_module = NULL, *modules = NULL, *set_module = NULL;
901
 
    int retval = -1;
902
 
 
903
 
    /* Clear out the current ImportError exception, and try again. */
904
 
    PyErr_Clear();
905
 
    /* Note that this only seems to work if somewhere else imports
906
 
     * breezy._simple_set_pyx before importing breezy._static_tuple_c
907
 
     */
908
 
    set_module = PyImport_ImportModule("breezy._simple_set_pyx");
909
 
    if (set_module == NULL) {
910
 
        goto end;
911
 
    }
912
 
    /* Add the _simple_set_pyx into sys.modules at the appropriate location. */
913
 
    sys_module = PyImport_ImportModule("sys");
914
 
    if (sys_module == NULL) {
915
 
        goto end;
916
 
    }
917
 
    modules = PyObject_GetAttrString(sys_module, "modules");
918
 
    if (modules == NULL || !PyDict_Check(modules)) {
919
 
        goto end;
920
 
    }
921
 
    PyDict_SetItemString(modules, "_simple_set_pyx", set_module);
922
 
    /* Now that we have hacked it in, try the import again. */
923
 
    retval = import_breezy___simple_set_pyx();
924
 
end:
925
 
    Py_XDECREF(set_module);
926
 
    Py_XDECREF(sys_module);
927
 
    Py_XDECREF(modules);
928
 
    return retval;
929
 
}
930
 
 
931
 
 
932
 
PyMODINIT_FUNC
933
 
init_static_tuple_c(void)
 
923
PYMOD_INIT_FUNC(_static_tuple_c)
934
924
{
935
925
    PyObject* m;
936
926
 
937
927
    StaticTuple_Type.tp_getattro = PyObject_GenericGetAttr;
938
 
    if (PyType_Ready(&StaticTuple_Type) < 0)
939
 
        return;
 
928
    if (PyType_Ready(&StaticTuple_Type) < 0) {
 
929
        return PYMOD_ERROR;
 
930
    }
940
931
 
941
 
    m = Py_InitModule3("_static_tuple_c", static_tuple_c_methods,
942
 
                       "C implementation of a StaticTuple structure");
943
 
    if (m == NULL)
944
 
      return;
 
932
    PYMOD_CREATE(m, "_static_tuple_c",
 
933
                 "C implementation of a StaticTuple structure",
 
934
                 static_tuple_c_methods);
 
935
    if (m == NULL) {
 
936
      return PYMOD_ERROR;
 
937
    }
945
938
 
946
939
    Py_INCREF(&StaticTuple_Type);
947
940
    PyModule_AddObject(m, "StaticTuple", (PyObject *)&StaticTuple_Type);
948
 
    if (import_breezy___simple_set_pyx() == -1
949
 
        && _workaround_pyrex_096() == -1)
950
 
    {
951
 
        return;
 
941
    if (import_breezy___simple_set_pyx() == -1) {
 
942
        return PYMOD_ERROR;
952
943
    }
953
944
    setup_interned_tuples(m);
954
945
    setup_empty_tuple(m);
955
946
    setup_c_api(m);
 
947
 
 
948
    return PYMOD_SUCCESS(m);
956
949
}
957
950
 
958
951
// vim: tabstop=4 sw=4 expandtab