NEW_OBJECTmodule.c

Steven D. Majewski (sdm7g@elvis.med.virginia.edu)
Sat, 9 Apr 1994 01:42:31 -0400

Tommy Burnette wrote this module, and handed it over to me to
test before he went out of town. After making one minor mod,
I haven't been able to crash it, so I think it's type-safe
enough to release.

This module gives a Python interface to the internal routines
to create a new code/function/method/module object.

For example:

elvis: /usr/local/src/Python/Python $ ./python
Python 1.0.1 (Apr 5 1994)
Copyright 1991-1994 Stichting Mathematisch Centrum, Amsterdam
>>> import NEW_OBJECT
>>> new = NEW_OBJECT
>>> dir(new)
['__name__', 'code', 'function', 'instancemethod', 'module']
>>> def fa( x ): return a + x
...
>>> fa( 2 )
Traceback (innermost last):
File "<stdin>", line 1
File "<stdin>", line 1
NameError: a
>>> a = 1
>>> fa( 2 )
3
>>> fb = new.function( fa.func_code, { 'a':'Hello World' }, 'fb' )
>>> fb
<function fb at 20074db8>
>>> fb( '!'*20 )
'Hello World!!!!!!!!!!!!!!!!!!!!'
>>>

Now I can remove the R/W attribute hacks from my Python and
do it the RIGHT way! Other than a shorter, easier to type
module name than NEW_OBJECT, I couldn't ask for more!

NEW_OBJECT.module replaces by newmodule hack.
NEW_OBJECT.function can provide a better implementation than
my bind() that relied on hacking RO object attributes to R/W.
I'm working on a Python byte-code assembler that will use
NEW_OBJECT.code and NEW_OBJECT.function. ( although you can
use marshal.loads to create a code object if you don't need
it bound into a function.)

I'm still meditating on the utility of NEW_OBJECT.instancemethod,
but I think Tommy had something in mind, as that was the reason
he started this.

-- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> --
-- UVA Department of Molecular Physiology and Biological Physics --
"Cognitive Science is where Philosophy goes when it dies, if it
hasn't been good." - Jerry Fodor.

----- cut here, copy into Modules/NEW_OBJECTmodule.c, and put -----
----- the line NEW_OBJECT NEW_OBJECTmodule.o into file: Setup -----

#include "allobjects.h"
#include "compile.h"
#include "modsupport.h"

/* extern "C" { */
/* void initNEW_OBJECT(void); */
/* } */

object*
NEW_OBJECT_instancemethod(unused, args)
object* unused;
object* args;
{
object* func;
object* self;
object* classObj;

if (!getargs(args, "(OOO)", &func, &self, &classObj)) {
return NULL;
} else if (!is_funcobject(func) || !is_instanceobject(self) || !is_classobject(classObj)) {
err_setstr(TypeError, "expected a function, instance and classobject as args");
return NULL;
}
return newinstancemethodobject(func, self, classObj);
}

object*
NEW_OBJECT_function(unused, args)
object* unused;
object* args;
{
object* code;
object* globals;
object* name;
object* newfunc;

if (getargs(args, "(OO)", &code, &globals)) {
name = NULL;
} else {
err_clear();
if (getargs(args, "(OOO)", &code, &globals, &name)) {
} else {
return NULL;
}
}
if (!is_codeobject(code) || !is_mappingobject(globals)) {
err_setstr(TypeError, "expected a code object, a dict for globals and an \
(optional) string name");
return NULL;
} else if (!is_stringobject(name) && name !=NULL) {
err_setstr(TypeError, "expected a code object, a dict for globals and an \
(optional) string name");
return NULL;
}

newfunc = newfuncobject(code, globals);
if (name != NULL) {
((funcobject *)newfunc)->func_name = name;
XINCREF( name );
XDECREF( ((codeobject*)(((funcobject *)(newfunc))->func_code))->co_name );
}
return newfunc;
}

object*
NEW_OBJECT_code(unused, args)
object* unused;
object* args;
{
object* code;
object* consts;
object* names;
object* filename;
object* name;

if (!getargs(args, "(OOOOO)", &code, &consts, &names, &filename, &name)) {
return NULL;
} else if (!is_stringobject(code) || !is_listobject(consts) || \
!is_listobject(names) || !is_stringobject(filename) || \
!is_stringobject(name)) {
err_setstr(TypeError, "expected a string of compiled code, a list of constants, \
a list of names used, a string filename, and a string name \
as args");
return NULL;
}
return (object *)newcodeobject(code, consts, names, filename, name);
}

object*
NEW_OBJECT_module(unused, args)
object* unused;
object* args;
{
object* name;

if (!getargs(args, "S", &name)) {
err_setstr(TypeError, "expected a string name as args");
return NULL;
}
return newmoduleobject(getstringvalue(name));
}

static struct methodlist NEW_OBJECT_methods[] = {
{ "instancemethod", NEW_OBJECT_instancemethod },
{ "function", NEW_OBJECT_function },
{ "code", NEW_OBJECT_code },
{ "module", NEW_OBJECT_module },
{NULL, NULL} /* sentinel */
};

void
initNEW_OBJECT()
{
initmodule("NEW_OBJECT", NEW_OBJECT_methods);
}