@@ -83,42 +83,68 @@ int PyLong_AsInt(PyObject* obj, int* result) {
8383int igraphmodule_PyObject_to_enum (PyObject * o ,
8484 igraphmodule_enum_translation_table_entry_t * table ,
8585 int * result ) {
86- char * s , * s2 ;
87- int i , best , best_result , best_unique ;
8886
89- if (o == 0 || o == Py_None )
87+ char * s , * s2 ;
88+ int i , best , best_result , best_unique ;
89+
90+ if (o == 0 || o == Py_None )
91+ return 0 ;
92+
93+ if (PyLong_Check (o ))
94+ return PyLong_AsInt (o , result );
95+
96+ s = PyUnicode_CopyAsString (o );
97+ if (s == 0 ) {
98+ PyErr_SetString (PyExc_TypeError , "int, long or string expected" );
99+ return -1 ;
100+ }
101+
102+ /* Convert string to lowercase */
103+ for (s2 = s ; * s2 ; s2 ++ ) {
104+ * s2 = tolower (* s2 );
105+ }
106+
107+ /* Search for matches */
108+ best = 0 ; best_unique = 0 ; best_result = -1 ;
109+ while (table -> name != 0 ) {
110+ if (strcmp (s , table -> name ) == 0 ) {
111+ /* Exact match found */
112+ * result = table -> value ;
113+ free (s );
90114 return 0 ;
91- if (PyLong_Check (o ))
92- return PyLong_AsInt (o , result );
93- s = PyUnicode_CopyAsString (o );
94- if (s == 0 ) {
95- PyErr_SetString (PyExc_TypeError , "int, long or string expected" );
96- return -1 ;
97115 }
98- /* Convert string to lowercase */
99- for (s2 = s ; * s2 ; s2 ++ )
100- * s2 = tolower (* s2 );
101- best = 0 ; best_unique = 0 ; best_result = -1 ;
102- /* Search for matches */
103- while (table -> name != 0 ) {
104- if (strcmp (s , table -> name ) == 0 ) {
105- * result = table -> value ;
106- free (s );
107- return 0 ;
108- }
109- for (i = 0 ; s [i ] == table -> name [i ]; i ++ );
110- if (i > best ) {
111- best = i ; best_unique = 1 ; best_result = table -> value ;
112- } else if (i == best ) best_unique = 0 ;
113- table ++ ;
116+
117+ /* Find length of longest prefix that matches */
118+ for (i = 0 ; s [i ] == table -> name [i ]; i ++ );
119+
120+ if (i > best ) {
121+ /* Found a better match than before */
122+ best = i ; best_unique = 1 ; best_result = table -> value ;
123+ } else if (i == best ) {
124+ /* Best match is not unique */
125+ best_unique = 0 ;
114126 }
115- free (s );
116- if (best_unique ) { * result = best_result ; return 0 ; }
127+
128+ table ++ ;
129+ }
130+
131+ free (s );
132+
133+ if (best_unique ) {
134+ PyErr_Warn (
135+ PyExc_DeprecationWarning ,
136+ "Partial string matches of enum members are deprecated since igraph 0.9.3; "
137+ "use strings that identify an enum member unambiguously."
138+ );
139+
140+ * result = best_result ;
141+ return 0 ;
142+ } else {
117143 PyErr_SetObject (PyExc_ValueError , o );
118144 return -1 ;
145+ }
119146}
120147
121-
122148/**
123149 * \ingroup python_interface_conversion
124150 * \brief Converts a Python object to a corresponding igraph enum, strictly.
0 commit comments