[Python-Dev] Adding doc-strings to attributes [with patch]

M.-A. Lemburg mal@lemburg.com
Tue, 22 Aug 2000 20:14:56 +0200


This is a multi-part message in MIME format.
--------------04B8F46BE4C7B93B2B5D8B87
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Here's a patch which roughly implements the proposed attribute
doc-string syntax and semantics:

class C:
        " class C doc-string "

        a = 1
        " attribute C.a doc-string "

        b = 2
        " attribute C.b doc-string "

The compiler would handle these cases as follows:

" class C doc-string " -> C.__doc__
" attribute C.a doc-string " -> C.__doc__a__
" attribute C.b doc-string " -> C.__doc__b__

The name mangling assures that attribute doc-strings

a) participate in class inheritence and
b) are treated as special attributes (following the __xxx__
   convention)

Also, the look&feel of this convention is similar to that
of the other existing conventions: the doc string follows
the definition of the object.

The patch is a little rough in the sense that binding the
doc-string to the attribute name is done using a helper
variable that is not reset by non-expressions during the
compile. Shouldn't be too hard to fix though... at least
not for one of you compiler wizards ;-)

What do you think ?

[I will probably have to write a PEP for this...]

-- 
Marc-Andre Lemburg
______________________________________________________________________
Business:                                      http://www.lemburg.com/
Python Pages:                           http://www.lemburg.com/python/
--------------04B8F46BE4C7B93B2B5D8B87
Content-Type: text/plain; charset=us-ascii;
 name="attrdocstrings.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="attrdocstrings.patch"

--- CVS-Python/Python/compile.c	Tue Aug 22 10:31:06 2000
+++ Python+Unicode/Python/compile.c	Tue Aug 22 19:59:30 2000
@@ -293,10 +293,11 @@ struct compiling {
 	int c_last_addr, c_last_line, c_lnotab_next;
 #ifdef PRIVATE_NAME_MANGLING
 	char *c_private;	/* for private name mangling */
 #endif
 	int c_tmpname;		/* temporary local name counter */
+        char *c_last_name;       /* last assigned name */
 };
 
 
 /* Error message including line number */
 
@@ -435,12 +436,13 @@ com_init(struct compiling *c, char *file
 	c->c_stacklevel = 0;
 	c->c_maxstacklevel = 0;
 	c->c_firstlineno = 0;
 	c->c_last_addr = 0;
 	c->c_last_line = 0;
-	c-> c_lnotab_next = 0;
+	c->c_lnotab_next = 0;
 	c->c_tmpname = 0;
+	c->c_last_name = 0;
 	return 1;
 	
   fail:
 	com_free(c);
  	return 0;
@@ -1866,10 +1868,11 @@ com_assign_name(struct compiling *c, nod
 {
 	REQ(n, NAME);
 	com_addopname(c, assigning ? STORE_NAME : DELETE_NAME, n);
 	if (assigning)
 		com_pop(c, 1);
+	c->c_last_name = STR(n);
 }
 
 static void
 com_assign(struct compiling *c, node *n, int assigning)
 {
@@ -1974,18 +1977,40 @@ com_assign(struct compiling *c, node *n,
 		}
 	}
 }
 
 /* Forward */ static node *get_rawdocstring(node *);
+/* Forward */ static PyObject *get_docstring(node *);
 
 static void
 com_expr_stmt(struct compiling *c, node *n)
 {
 	REQ(n, expr_stmt); /* testlist ('=' testlist)* */
-	/* Forget it if we have just a doc string here */
-	if (!c->c_interactive && NCH(n) == 1 && get_rawdocstring(n) != NULL)
+	/* Handle attribute doc-strings here */
+	if (!c->c_interactive && NCH(n) == 1) {
+	    node *docnode = get_rawdocstring(n);
+	    if (docnode != NULL) {
+		if (c->c_last_name) {
+		    PyObject *doc = get_docstring(docnode);
+		    int i = com_addconst(c, doc);
+		    char docname[420];
+#if 0
+		    printf("found doc-string '%s' for '%s'\n", 
+			   PyString_AsString(doc),
+			   c->c_last_name);
+#endif
+		    sprintf(docname, "__doc__%.400s__", c->c_last_name);
+		    com_addoparg(c, LOAD_CONST, i);
+		    com_push(c, 1);
+		    com_addopnamestr(c, STORE_NAME, docname);
+		    com_pop(c, 1);
+		    c->c_last_name = NULL;
+		    Py_DECREF(doc);
+		}
 		return;
+	    }
+	}
 	com_node(c, CHILD(n, NCH(n)-1));
 	if (NCH(n) == 1) {
 		if (c->c_interactive)
 			com_addbyte(c, PRINT_EXPR);
 		else

--------------04B8F46BE4C7B93B2B5D8B87--