Skip to content

Commit e148184

Browse files
tiranencukou
authored andcommitted
Make bytes mode TypeError more useful
Make bytes mode TypeError more useful It's a bit hard to understand where the TypeError excactly comes from. The exception now contains the argument name. python-ldap#165 Signed-off-by: Christian Heimes <cheimes@redhat.com>
1 parent dfbe523 commit e148184

File tree

6 files changed

+90
-42
lines changed

6 files changed

+90
-42
lines changed

Lib/ldap/ldapobject.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,10 @@ def _bytesify_input(self, arg_name, value):
144144
return value
145145
else:
146146
if self.bytes_mode_hardfail:
147-
raise TypeError("All provided fields *must* be bytes when bytes mode is on; got %r" % (value,))
147+
raise TypeError(
148+
"All provided fields *must* be bytes when bytes mode is on; "
149+
"got type '{}' for '{}'.".format(type(value).__name__, arg_name)
150+
)
148151
else:
149152
_raise_byteswarning(
150153
"Received non-bytes value for '{}' with default (disabled) bytes mode; "
@@ -153,7 +156,10 @@ def _bytesify_input(self, arg_name, value):
153156
return value.encode('utf-8')
154157
else:
155158
if not isinstance(value, text_type):
156-
raise TypeError("All provided fields *must* be text when bytes mode is off; got %r" % (value,))
159+
raise TypeError(
160+
"All provided fields *must* be text when bytes mode is off; "
161+
"got type '{}' for '{}'.".format(type(value).__name__, arg_name)
162+
)
157163
assert not isinstance(value, bytes)
158164
return value.encode('utf-8')
159165

Modules/LDAPObject.c

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -108,16 +108,16 @@ Tuple_to_LDAPMod( PyObject* tup, int no_op )
108108
Py_ssize_t i, len, nstrs;
109109

110110
if (!PyTuple_Check(tup)) {
111-
LDAPerror_TypeError("expected a tuple", tup);
111+
LDAPerror_TypeError("Tuple_to_LDAPMod(): expected a tuple", tup);
112112
return NULL;
113113
}
114114

115115
if (no_op) {
116-
if (!PyArg_ParseTuple( tup, "sO", &type, &list ))
116+
if (!PyArg_ParseTuple( tup, "sO:Tuple_to_LDAPMod", &type, &list ))
117117
return NULL;
118118
op = 0;
119119
} else {
120-
if (!PyArg_ParseTuple( tup, "isO", &op, &type, &list ))
120+
if (!PyArg_ParseTuple( tup, "isO:Tuple_to_LDAPMod", &op, &type, &list ))
121121
return NULL;
122122
}
123123

@@ -161,7 +161,7 @@ Tuple_to_LDAPMod( PyObject* tup, int no_op )
161161
if (item == NULL)
162162
goto error;
163163
if (!PyBytes_Check(item)) {
164-
LDAPerror_TypeError("expected a byte string in the list", item);
164+
LDAPerror_TypeError("Tuple_to_LDAPMod(): expected a byte string in the list", item);
165165
goto error;
166166
}
167167
lm->mod_bvalues[i]->bv_len = PyBytes_Size(item);
@@ -206,14 +206,14 @@ List_to_LDAPMods( PyObject *list, int no_op ) {
206206
PyObject *item;
207207

208208
if (!PySequence_Check(list)) {
209-
LDAPerror_TypeError("expected list of tuples", list);
209+
LDAPerror_TypeError("List_to_LDAPMods(): expected list of tuples", list);
210210
return NULL;
211211
}
212212

213213
len = PySequence_Length(list);
214214

215215
if (len < 0) {
216-
LDAPerror_TypeError("expected list of tuples", list);
216+
LDAPerror_TypeError("List_to_LDAPMods(): expected list of tuples", list);
217217
return NULL;
218218
}
219219

@@ -262,7 +262,7 @@ attrs_from_List( PyObject *attrlist, char***attrsp) {
262262
#endif
263263
/* caught by John Benninghoff <johnb@netscape.com> */
264264
LDAPerror_TypeError(
265-
"expected *list* of strings, not a string", attrlist);
265+
"attrs_from_List(): expected *list* of strings, not a string", attrlist);
266266
goto error;
267267
} else {
268268
PyObject *item = NULL;
@@ -291,15 +291,15 @@ attrs_from_List( PyObject *attrlist, char***attrsp) {
291291
#if PY_MAJOR_VERSION == 2
292292
/* Encoded in Python to UTF-8 */
293293
if (!PyBytes_Check(item)) {
294-
LDAPerror_TypeError("expected bytes in list", item);
294+
LDAPerror_TypeError("attrs_from_List(): expected bytes in list", item);
295295
goto error;
296296
}
297297
if (PyBytes_AsStringAndSize(item, &str, &strlen) == -1) {
298298
goto error;
299299
}
300300
#else
301301
if (!PyUnicode_Check(item)) {
302-
LDAPerror_TypeError("expected string in list", item);
302+
LDAPerror_TypeError("attrs_from_List(): expected string in list", item);
303303
goto error;
304304
}
305305
str = PyUnicode_AsUTF8AndSize(item, &strlen);
@@ -361,7 +361,7 @@ l_ldap_unbind_ext( LDAPObject* self, PyObject* args )
361361

362362
int ldaperror;
363363

364-
if (!PyArg_ParseTuple( args, "|OO", &serverctrls, &clientctrls)) return NULL;
364+
if (!PyArg_ParseTuple( args, "|OO:unbind_ext", &serverctrls, &clientctrls)) return NULL;
365365
if (not_valid(self)) return NULL;
366366

367367
if (!PyNone_Check(serverctrls)) {
@@ -404,7 +404,7 @@ l_ldap_abandon_ext( LDAPObject* self, PyObject* args )
404404

405405
int ldaperror;
406406

407-
if (!PyArg_ParseTuple( args, "i|OO", &msgid, &serverctrls, &clientctrls)) return NULL;
407+
if (!PyArg_ParseTuple( args, "i|OO:abandon_ext", &msgid, &serverctrls, &clientctrls)) return NULL;
408408
if (not_valid(self)) return NULL;
409409

410410
if (!PyNone_Check(serverctrls)) {
@@ -449,7 +449,7 @@ l_ldap_add_ext( LDAPObject* self, PyObject *args )
449449
int ldaperror;
450450
LDAPMod **mods;
451451

452-
if (!PyArg_ParseTuple( args, "sO|OO", &dn, &modlist, &serverctrls, &clientctrls )) return NULL;
452+
if (!PyArg_ParseTuple( args, "sO|OO:add_ext", &dn, &modlist, &serverctrls, &clientctrls )) return NULL;
453453
if (not_valid(self)) return NULL;
454454

455455
mods = List_to_LDAPMods( modlist, 1 );
@@ -499,7 +499,7 @@ l_ldap_simple_bind( LDAPObject* self, PyObject* args )
499499
LDAPControl** client_ldcs = NULL;
500500
struct berval cred;
501501

502-
if (!PyArg_ParseTuple( args, "zz#|OO", &who, &cred.bv_val, &cred_len, &serverctrls, &clientctrls )) return NULL;
502+
if (!PyArg_ParseTuple( args, "zz#|OO:simple_bind", &who, &cred.bv_val, &cred_len, &serverctrls, &clientctrls )) return NULL;
503503
cred.bv_len = (ber_len_t) cred_len;
504504

505505
if (not_valid(self)) return NULL;
@@ -649,7 +649,7 @@ l_ldap_sasl_bind_s( LDAPObject* self, PyObject* args )
649649
struct berval *servercred;
650650
int ldaperror;
651651

652-
if (!PyArg_ParseTuple(args, "zzz#OO", &dn, &mechanism, &cred.bv_val, &cred_len, &serverctrls, &clientctrls ))
652+
if (!PyArg_ParseTuple(args, "zzz#OO:sasl_bind_s", &dn, &mechanism, &cred.bv_val, &cred_len, &serverctrls, &clientctrls ))
653653
return NULL;
654654

655655
if (not_valid(self)) return NULL;
@@ -713,9 +713,9 @@ l_ldap_sasl_interactive_bind_s( LDAPObject* self, PyObject* args )
713713
* "i" otherwise.
714714
*/
715715
#if (PY_MAJOR_VERSION == 2) && (PY_MINOR_VERSION < 3)
716-
if (!PyArg_ParseTuple(args, "sOOOi", &who, &SASLObject, &serverctrls, &clientctrls, &sasl_flags ))
716+
if (!PyArg_ParseTuple(args, "sOOOi:sasl_interactive_bind_s", &who, &SASLObject, &serverctrls, &clientctrls, &sasl_flags ))
717717
#else
718-
if (!PyArg_ParseTuple(args, "sOOOI", &who, &SASLObject, &serverctrls, &clientctrls, &sasl_flags ))
718+
if (!PyArg_ParseTuple(args, "sOOOI:sasl_interactive_bind_s", &who, &SASLObject, &serverctrls, &clientctrls, &sasl_flags ))
719719
#endif
720720
return NULL;
721721

@@ -780,7 +780,7 @@ l_ldap_cancel( LDAPObject* self, PyObject* args )
780780

781781
int ldaperror;
782782

783-
if (!PyArg_ParseTuple( args, "i|OO", &cancelid, &serverctrls, &clientctrls)) return NULL;
783+
if (!PyArg_ParseTuple( args, "i|OO:cancel", &cancelid, &serverctrls, &clientctrls)) return NULL;
784784
if (not_valid(self)) return NULL;
785785

786786
if (!PyNone_Check(serverctrls)) {
@@ -826,7 +826,7 @@ l_ldap_compare_ext( LDAPObject* self, PyObject *args )
826826
Py_ssize_t value_len;
827827
struct berval value;
828828

829-
if (!PyArg_ParseTuple( args, "sss#|OO", &dn, &attr, &value.bv_val, &value_len, &serverctrls, &clientctrls )) return NULL;
829+
if (!PyArg_ParseTuple( args, "sss#|OO:compare_ext", &dn, &attr, &value.bv_val, &value_len, &serverctrls, &clientctrls )) return NULL;
830830
value.bv_len = (ber_len_t) value_len;
831831

832832
if (not_valid(self)) return NULL;
@@ -871,7 +871,7 @@ l_ldap_delete_ext( LDAPObject* self, PyObject *args )
871871
int msgid;
872872
int ldaperror;
873873

874-
if (!PyArg_ParseTuple( args, "s|OO", &dn, &serverctrls, &clientctrls )) return NULL;
874+
if (!PyArg_ParseTuple( args, "s|OO:delete_ext", &dn, &serverctrls, &clientctrls )) return NULL;
875875
if (not_valid(self)) return NULL;
876876

877877
if (!PyNone_Check(serverctrls)) {
@@ -916,7 +916,7 @@ l_ldap_modify_ext( LDAPObject* self, PyObject *args )
916916
int ldaperror;
917917
LDAPMod **mods;
918918

919-
if (!PyArg_ParseTuple( args, "sO|OO", &dn, &modlist, &serverctrls, &clientctrls )) return NULL;
919+
if (!PyArg_ParseTuple( args, "sO|OO:modify_ext", &dn, &modlist, &serverctrls, &clientctrls )) return NULL;
920920
if (not_valid(self)) return NULL;
921921

922922
mods = List_to_LDAPMods( modlist, 0 );
@@ -969,7 +969,7 @@ l_ldap_rename( LDAPObject* self, PyObject *args )
969969
int msgid;
970970
int ldaperror;
971971

972-
if (!PyArg_ParseTuple( args, "ss|ziOO", &dn, &newrdn, &newSuperior, &delold, &serverctrls, &clientctrls ))
972+
if (!PyArg_ParseTuple( args, "ss|ziOO:rename", &dn, &newrdn, &newSuperior, &delold, &serverctrls, &clientctrls ))
973973
return NULL;
974974
if (not_valid(self)) return NULL;
975975

@@ -1022,7 +1022,7 @@ l_ldap_result4( LDAPObject* self, PyObject *args )
10221022
char **refs = NULL;
10231023
LDAPControl **serverctrls = 0;
10241024

1025-
if (!PyArg_ParseTuple( args, "|iidiii", &msgid, &all, &timeout, &add_ctrls, &add_intermediates, &add_extop ))
1025+
if (!PyArg_ParseTuple( args, "|iidiii:result4", &msgid, &all, &timeout, &add_ctrls, &add_intermediates, &add_extop ))
10261026
return NULL;
10271027
if (not_valid(self)) return NULL;
10281028

@@ -1162,7 +1162,7 @@ l_ldap_search_ext( LDAPObject* self, PyObject* args )
11621162
int msgid;
11631163
int ldaperror;
11641164

1165-
if (!PyArg_ParseTuple( args, "sis|OiOOdi",
1165+
if (!PyArg_ParseTuple( args, "sis|OiOOdi:search_ext",
11661166
&base, &scope, &filter, &attrlist, &attrsonly,
11671167
&serverctrls, &clientctrls, &timeout, &sizelimit )) return NULL;
11681168
if (not_valid(self)) return NULL;
@@ -1224,7 +1224,7 @@ l_ldap_whoami_s( LDAPObject* self, PyObject* args )
12241224

12251225
int ldaperror;
12261226

1227-
if (!PyArg_ParseTuple( args, "|OO", &serverctrls, &clientctrls)) return NULL;
1227+
if (!PyArg_ParseTuple( args, "|OO:whoami_s", &serverctrls, &clientctrls)) return NULL;
12281228
if (not_valid(self)) return NULL;
12291229

12301230
if (!PyNone_Check(serverctrls)) {
@@ -1265,7 +1265,7 @@ l_ldap_start_tls_s( LDAPObject* self, PyObject* args )
12651265
{
12661266
int ldaperror;
12671267

1268-
if (!PyArg_ParseTuple( args, "" )) return NULL;
1268+
if (!PyArg_ParseTuple( args, ":start_tls_s" )) return NULL;
12691269
if (not_valid(self)) return NULL;
12701270

12711271
LDAP_BEGIN_ALLOW_THREADS( self );
@@ -1331,7 +1331,7 @@ l_ldap_passwd( LDAPObject* self, PyObject *args )
13311331
int msgid;
13321332
int ldaperror;
13331333

1334-
if (!PyArg_ParseTuple( args, "z#z#z#|OO", &user.bv_val, &user_len, &oldpw.bv_val, &oldpw_len, &newpw.bv_val, &newpw_len, &serverctrls, &clientctrls ))
1334+
if (!PyArg_ParseTuple( args, "z#z#z#|OO:passwd", &user.bv_val, &user_len, &oldpw.bv_val, &oldpw_len, &newpw.bv_val, &newpw_len, &serverctrls, &clientctrls ))
13351335
return NULL;
13361336

13371337
user.bv_len = (ber_len_t) user_len;
@@ -1387,7 +1387,7 @@ l_ldap_extended_operation( LDAPObject* self, PyObject *args )
13871387
int msgid;
13881388
int ldaperror;
13891389

1390-
if (!PyArg_ParseTuple( args, "sz#|OO", &reqoid, &reqvalue.bv_val, &reqvalue.bv_len, &serverctrls, &clientctrls ))
1390+
if (!PyArg_ParseTuple( args, "sz#|OO:extended_operation", &reqoid, &reqvalue.bv_val, &reqvalue.bv_len, &serverctrls, &clientctrls ))
13911391
return NULL;
13921392

13931393
if (not_valid(self)) return NULL;

Modules/functions.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ l_ldap_initialize(PyObject* unused, PyObject *args)
1616
LDAP *ld = NULL;
1717
int ret;
1818

19-
if (!PyArg_ParseTuple(args, "s", &uri))
19+
if (!PyArg_ParseTuple(args, "s:initialize", &uri))
2020
return NULL;
2121

2222
Py_BEGIN_ALLOW_THREADS

Modules/ldapcontrol.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ Tuple_to_LDAPControl( PyObject* tup )
7272
Py_ssize_t len;
7373

7474
if (!PyTuple_Check(tup)) {
75-
LDAPerror_TypeError("expected a tuple", tup);
75+
LDAPerror_TypeError("Tuple_to_LDAPControl(): expected a tuple", tup);
7676
return NULL;
7777
}
7878

79-
if (!PyArg_ParseTuple( tup, "sbO", &oid, &iscritical, &bytes ))
79+
if (!PyArg_ParseTuple( tup, "sbO:Tuple_to_LDAPControl", &oid, &iscritical, &bytes ))
8080
return NULL;
8181

8282
lc = PyMem_NEW(LDAPControl, 1);
@@ -106,7 +106,7 @@ Tuple_to_LDAPControl( PyObject* tup )
106106
berbytes.bv_val = PyBytes_AsString(bytes);
107107
}
108108
else {
109-
LDAPerror_TypeError("expected bytes", bytes);
109+
LDAPerror_TypeError("Tuple_to_LDAPControl(): expected bytes", bytes);
110110
LDAPControl_DEL(lc);
111111
return NULL;
112112
}
@@ -128,7 +128,7 @@ LDAPControls_from_object(PyObject* list, LDAPControl ***controls_ret)
128128
PyObject* item;
129129

130130
if (!PySequence_Check(list)) {
131-
LDAPerror_TypeError("expected a list", list);
131+
LDAPerror_TypeError("LDAPControls_from_object(): expected a list", list);
132132
return 0;
133133
}
134134

Tests/t_cext.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,10 +784,16 @@ def assertInvalidControls(self, func, *args, **kwargs):
784784
# last two args are serverctrls, clientctrls
785785
with self.assertRaises(TypeError) as e:
786786
func(*(args + (object, None) + post))
787-
self.assertEqual(e.exception.args, ('expected a list', object))
787+
self.assertEqual(
788+
e.exception.args,
789+
('LDAPControls_from_object(): expected a list', object)
790+
)
788791
with self.assertRaises(TypeError) as e:
789792
func(*(args + (None, object) + post))
790-
self.assertEqual(e.exception.args, ('expected a list', object))
793+
self.assertEqual(
794+
e.exception.args,
795+
('LDAPControls_from_object(): expected a list', object)
796+
)
791797

792798
def test_invalid_controls(self):
793799
l = self._open_conn()

Tests/t_ldapobject.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,48 @@ def test_reject_bytes_base(self):
106106
base = self.server.suffix
107107
l = self._ldap_conn
108108

109-
with self.assertRaises(TypeError):
110-
l.search_s(base.encode('utf-8'), ldap.SCOPE_SUBTREE, '(cn=Foo*)', ['*'])
111-
with self.assertRaises(TypeError):
112-
l.search_s(base, ldap.SCOPE_SUBTREE, b'(cn=Foo*)', ['*'])
113-
with self.assertRaises(TypeError):
114-
l.search_s(base, ldap.SCOPE_SUBTREE, '(cn=Foo*)', [b'*'])
109+
with self.assertRaises(TypeError) as e:
110+
l.search_s(
111+
base.encode('utf-8'), ldap.SCOPE_SUBTREE, '(cn=Foo*)', ['*']
112+
)
113+
if PY2:
114+
self.assertIn(
115+
u"got type 'str' for 'base'", text_type(e.exception)
116+
)
117+
elif sys.version_info >= (3, 5, 0):
118+
# Python 3.4.x does not include 'search_ext()' in message
119+
self.assertEqual(
120+
"search_ext() argument 1 must be str, not bytes",
121+
text_type(e.exception)
122+
)
123+
124+
with self.assertRaises(TypeError) as e:
125+
l.search_s(
126+
base, ldap.SCOPE_SUBTREE, b'(cn=Foo*)', ['*']
127+
)
128+
if PY2:
129+
self.assertIn(
130+
u"got type 'str' for 'filterstr'", text_type(e.exception)
131+
)
132+
elif sys.version_info >= (3, 5, 0):
133+
self.assertEqual(
134+
"search_ext() argument 3 must be str, not bytes",
135+
text_type(e.exception)
136+
)
137+
138+
with self.assertRaises(TypeError) as e:
139+
l.search_s(
140+
base, ldap.SCOPE_SUBTREE, '(cn=Foo*)', [b'*']
141+
)
142+
if PY2:
143+
self.assertIn(
144+
u"got type 'str' for 'attrlist'", text_type(e.exception)
145+
)
146+
elif sys.version_info >= (3, 5, 0):
147+
self.assertEqual(
148+
('attrs_from_List(): expected string in list', b'*'),
149+
e.exception.args
150+
)
115151

116152
def test_search_keys_are_text(self):
117153
base = self.server.suffix

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy