]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
* Python/bltinmodule.c (builtin_vars): correct typo in error msg
authorGuido van Rossum <guido@python.org>
Mon, 29 Aug 1994 12:52:16 +0000 (12:52 +0000)
committerGuido van Rossum <guido@python.org>
Mon, 29 Aug 1994 12:52:16 +0000 (12:52 +0000)
Python/bltinmodule.c

index c8a8e83c417cac6785d13b6f161288c3a0154b70..d8e0d2692324cc38cbf8c6fcbacb879985f53531 100644 (file)
@@ -1,5 +1,5 @@
 /***********************************************************
-Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
 Amsterdam, The Netherlands.
 
                         All Rights Reserved
@@ -63,9 +63,52 @@ builtin_apply(self, args)
        object *func, *arglist;
        if (!getargs(args, "(OO)", &func, &arglist))
                return NULL;
+       if (!is_tupleobject(arglist)) {
+               err_setstr(TypeError, "apply() 2nd argument must be tuple");
+               return NULL;
+       }
        return call_object(func, arglist);
 }
 
+static int
+callable(x)
+       object *x;
+{
+       if (x == NULL)
+               return 0;
+       if (x->ob_type->tp_call != NULL ||
+           is_funcobject(x) ||
+           is_instancemethodobject(x) ||
+           is_methodobject(x) ||
+           is_classobject(x))
+               return 1;
+       if (is_instanceobject(x)) {
+               object *call = getattr(x, "__call__");
+               if (call == NULL) {
+                       err_clear();
+                       return 0;
+               }
+               /* Could test recursively but don't, for fear of endless
+                  recursion if some joker sets self.__call__ = self */
+               DECREF(call);
+               return 1;
+       }
+       return 0;
+}
+
+static object *
+builtin_callable(self, args)
+       object *self;
+       object *args;
+{
+       if (args == NULL) {
+               err_setstr(TypeError,
+                          "callable requires exactly one argument");
+               return NULL;
+       }
+       return newintobject((long)callable(args));
+}
+
 static object *
 builtin_filter(self, args)
        object *self;
@@ -107,12 +150,19 @@ builtin_filter(self, args)
                        goto Fail_2;
        }
 
-       for (i = j = 0; i < len; ++i) {
+       for (i = j = 0; ; ++i) {
                object *item, *good;
                int ok;
 
-               if ((item = (*sqf->sq_item)(seq, i)) == NULL)
+               if ((item = (*sqf->sq_item)(seq, i)) == NULL) {
+                       if (i < len)
+                               goto Fail_1;
+                       if (err_occurred() == IndexError) {
+                               err_clear();
+                               break;
+                       }
                        goto Fail_1;
+               }
 
                if (func == None) {
                        good = item;
@@ -131,13 +181,20 @@ builtin_filter(self, args)
                DECREF(good);
                if (ok) {
                        INCREF(item);
-                       if (setlistitem(result, j++, item) < 0)
-                               goto Fail_1;
+                       if (j < len) {
+                               if (setlistitem(result, j++, item) < 0)
+                                       goto Fail_1;
+                       }
+                       else {
+                               j++;
+                               if (addlistitem(result, item) < 0)
+                                       goto Fail_1;
+                       }
                }
        }
 
 
-       if (setlistslice(result, j, len, NULL) < 0)
+       if (j < len && setlistslice(result, j, len, NULL) < 0)
                goto Fail_1;
 
        return result;
@@ -453,7 +510,7 @@ builtin_map(self, args)
                goto Fail_2;
        }
 
-       for (len = -1, i = 0, sqp = seqs; i < n; ++i, ++sqp) {
+       for (len = 0, i = 0, sqp = seqs; i < n; ++i, ++sqp) {
                int curlen;
        
                if ((sqp->seq = gettupleitem(args, i + 1)) == NULL)
@@ -480,55 +537,81 @@ builtin_map(self, args)
                goto Fail_2;
 
        /* XXX Special case map(None, single_list) could be more efficient */
-       for (i = 0; i < len; ++i) {
-               object *arglist, *item;
+       for (i = 0; ; ++i) {
+               object *arglist, *item, *value;
+               int any = 0;
 
-               if ((arglist = newtupleobject(n)) == NULL)
-                       goto Fail_1;
+               if (func == None && n == 1)
+                       arglist = NULL;
+               else {
+                       if ((arglist = newtupleobject(n)) == NULL)
+                               goto Fail_1;
+               }
 
                for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
-                       if (i >= sqp->len) {
+                       if (sqp->len < 0) {
                                INCREF(None);
                                item = None;
                        }
                        else {
                                item = (*sqp->sqf->sq_item)(sqp->seq, i);
-                               if (item == NULL)
-                                       goto Fail_0;
+                               if (item == NULL) {
+                                       if (i < sqp->len)
+                                               goto Fail_0;
+                                       if (err_occurred() == IndexError) {
+                                               err_clear();
+                                               INCREF(None);
+                                               item = None;
+                                               sqp->len = -1;
+                                       }
+                                       else {
+                                               goto Fail_0;
+                                       }
+                               }
+                               else
+                                       any = 1;
 
                        }
-                       if (settupleitem(arglist, j, item) < 0)
+                       if (!arglist)
+                               break;
+                       if (settupleitem(arglist, j, item) < 0) {
+                               DECREF(item);
                                goto Fail_0;
+                       }
                        continue;
 
                Fail_0:
-                       DECREF(arglist);
+                       XDECREF(arglist);
                        goto Fail_1;
                }
 
-               if (func == None) {
-                       if (n == 1)     { /* avoid creating singleton */
-                               INCREF(item); /* This is arglist[0] !!! */
-                               DECREF(arglist);
-                               if (setlistitem(result, i, item) < 0)
-                                       goto Fail_1;
-                       }
-                       else {
-                               if (setlistitem(result, i, arglist) < 0)
-                                       goto Fail_1;
-                       }
+               if (!arglist)
+                       arglist = item;
+
+               if (!any) {
+                       DECREF(arglist);
+                       break;
                }
+
+               if (func == None)
+                       value = arglist;
                else {
-                       object *value = call_object(func, arglist);
+                       value = call_object(func, arglist);
                        DECREF(arglist);
                        if (value == NULL)
                                goto Fail_1;
-                       if (setlistitem((object *) result, i, value) < 0)
+               }
+               if (i >= len) {
+                       if (addlistitem(result, value) < 0)
+                               goto Fail_1;
+               }
+               else {
+                       if (setlistitem(result, i, value) < 0)
                                goto Fail_1;
                }
        }
 
-       if (seqs) DEL(seqs);
+       DEL(seqs);
        return result;
 
 Fail_1:
@@ -665,7 +748,7 @@ min_max(v, sign)
        object *v;
        int sign;
 {
-       int i, n, cmp;
+       int i;
        object *w, *x;
        sequence_methods *sq;
        if (v == NULL) {
@@ -677,24 +760,30 @@ min_max(v, sign)
                err_setstr(TypeError, "min() or max() of non-sequence");
                return NULL;
        }
-       n = (*sq->sq_length)(v);
-       if (n < 0)
-               return NULL;
-       if (n == 0) {
-               err_setstr(ValueError, "min() or max() of empty sequence");
-               return NULL;
-       }
-       w = (*sq->sq_item)(v, 0); /* Implies INCREF */
-       for (i = 1; i < n; i++) {
+       w = NULL;
+       for (i = 0; ; i++) {
                x = (*sq->sq_item)(v, i); /* Implies INCREF */
-               cmp = cmpobject(x, w);
-               if (cmp * sign > 0) {
-                       DECREF(w);
+               if (x == NULL) {
+                       if (err_occurred() == IndexError) {
+                               err_clear();
+                               break;
+                       }
+                       XDECREF(w);
+                       return NULL;
+               }
+               if (w == NULL)
                        w = x;
+               else {
+                       if (cmpobject(x, w) * sign > 0) {
+                               DECREF(w);
+                               w = x;
+                       }
+                       else
+                               DECREF(x);
                }
-               else
-                       DECREF(x);
        }
+       if (w == NULL)
+               err_setstr(ValueError, "min() or max() of empty sequence");
        return w;
 }
 
@@ -735,10 +824,18 @@ builtin_open(self, args)
        object *self;
        object *args;
 {
-       char *name, *mode;
-       if (!getargs(args, "(ss)", &name, &mode))
+       char *name;
+       char *mode = "r";
+       int bufsize = -1;
+       object *f;
+       if (!getargs(args, "s", &name) &&
+           (err_clear(), !getargs(args, "(ss)", &name, &mode)) &&
+           (err_clear(), !getargs(args, "(ssi)", &name, &mode, &bufsize)))
                return NULL;
-       return newfileobject(name, mode);
+       f = newfileobject(name, mode);
+       if (f != NULL)
+               setfilebufsize(f, bufsize);
+       return f;
 }
 
 static object *
@@ -920,25 +1017,15 @@ builtin_reduce(self, args)
 {
        object *seq, *func, *result;
        sequence_methods *sqf;
-       static char reduce_err[] = "reduce() requires 2 or 3 args";
        register int i;
-       int start = 0;
-       int len;
-
-       if (args == NULL || !is_tupleobject(args)) {
-               err_setstr(TypeError, reduce_err);
-               return NULL;
-       }
 
-       switch (gettuplesize(args)) {
-       case 2:
-               start = 1;              /* fall through */
-       case 3:
-               func = gettupleitem(args, 0);
-               seq  = gettupleitem(args, 1);
-               break;
-       default:
-               err_setstr(TypeError, reduce_err);
+       if (getargs(args, "(OO)", &func, &seq))
+               result = NULL;
+       else {
+               err_clear();
+               if (!getargs(args, "(OOO)", &func, &seq, &result))
+                       return NULL;
+               INCREF(result);
        }
 
        if ((sqf = seq->ob_type->tp_as_sequence) == NULL) {
@@ -947,55 +1034,47 @@ builtin_reduce(self, args)
                return NULL;
        }
 
-       if ((len = (*sqf->sq_length)(seq)) < 0)
-               goto Fail_2;
-
-       if (start == 1) {
-               if (len == 0) {
-                       err_setstr(TypeError,
-                           "reduce of empty sequence with no initial value");
-                       goto Fail_2;
-               }
-
-               if ((result = (*sqf->sq_item)(seq, 0)) == NULL)
-                       goto Fail_2;
-       }
-       else {
-               result = gettupleitem(args, 2);
-               INCREF(result);
-       }
-
        if ((args = newtupleobject(2)) == NULL)
-               goto Fail_1;
+               goto Fail;
 
-       for (i = start; i < len; ++i) {
+       for (i = 0; ; ++i) {
                object *op2;
 
                if (args->ob_refcnt > 1) {
                        DECREF(args);
                        if ((args = newtupleobject(2)) == NULL)
-                               goto Fail_1;
+                               goto Fail;
                }
 
-               if ((op2 = (*sqf->sq_item)(seq, i)) == NULL)
-                       goto Fail_2;
+               if ((op2 = (*sqf->sq_item)(seq, i)) == NULL) {
+                       if (err_occurred() == IndexError) {
+                               err_clear();
+                               break;
+                       }
+                       goto Fail;
+               }
 
-               settupleitem(args, 0, result);
-               settupleitem(args, 1, op2);
-               if ((result = call_object(func, args)) == NULL)
-                       goto Fail_0;
+               if (result == NULL)
+                       result = op2;
+               else {
+                       settupleitem(args, 0, result);
+                       settupleitem(args, 1, op2);
+                       if ((result = call_object(func, args)) == NULL)
+                               goto Fail;
+               }
        }
 
        DECREF(args);
 
+       if (result == NULL)
+               err_setstr(TypeError,
+                          "reduce of empty sequence with no initial value");
+
        return result;
 
-Fail_0:
-       DECREF(args);
-       goto Fail_2;
-Fail_1:
-       DECREF(result);
-Fail_2:
+Fail:
+       XDECREF(args);
+       XDECREF(result);
        return NULL;
 }
 
@@ -1073,9 +1152,31 @@ builtin_type(self, v)
        return v;
 }
 
+static object *
+builtin_vars(self, v)
+       object *self;
+       object *v;
+{
+       object *d;
+       if (v == NULL) {
+               d = getlocals();
+               INCREF(d);
+       }
+       else {
+               d = getattr(v, "__dict__");
+               if (d == NULL) {
+                       err_setstr(TypeError,
+                           "vars() argument must have __dict__ attribute");
+                       return NULL;
+               }
+       }
+       return d;
+}
+
 static struct methodlist builtin_methods[] = {
        {"abs",         builtin_abs},
        {"apply",       builtin_apply},
+       {"callable",    builtin_callable},
        {"chr",         builtin_chr},
        {"cmp",         builtin_cmp},
        {"coerce",      builtin_coerce},
@@ -1111,6 +1212,7 @@ static struct methodlist builtin_methods[] = {
        {"setattr",     builtin_setattr},
        {"str",         builtin_str},
        {"type",        builtin_type},
+       {"vars",        builtin_vars},
        {"xrange",      builtin_xrange},
        {NULL,          NULL},
 };
@@ -1121,7 +1223,15 @@ object *
 getbuiltin(name)
        object *name;
 {
-       return dict2lookup(builtin_dict, name);
+       return mappinglookup(builtin_dict, name);
+}
+
+int
+setbuiltin(cname, value)
+       char *cname;
+       object *value;
+{
+       return dictinsert(builtin_dict, cname, value);
 }
 
 /* Predefined exceptions */
@@ -1291,8 +1401,8 @@ filterstring(func, strobj)
 
        if (func == None) {
                /* No character is ever false -- share input string */
-               INCREF(result);
-               return result;
+               INCREF(strobj);
+               return strobj;
        }
        if ((result = newsizedstringobject(NULL, len)) == NULL)
                return NULL;