From addc0c3760b565ead630bd67cc038b31954b9284 Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Sat, 29 Jul 2017 00:57:03 +0100 Subject: [PATCH] *.pyx: Add some rather laconic docstrings. Organization: Straylight/Edgeware From: Mark Wooding --- atom.pyx | 1 + bres.pyx | 24 ++++++++++++++++ codec.pyx | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++ codec.pyx.in | 18 ++++++++++++ conn.pyx | 17 +++++++++++ crc32.pyx | 4 +++ fdutils.pyx | 19 +++++++++++++ fwatch.pyx | 6 ++++ ident.pyx | 17 +++++++++++ lbuf.pyx | 19 +++++++++++++ mapping.pyx | 16 +++++++++++ mdup.pyx | 8 ++++++ pkbuf.pyx | 18 ++++++++++++ report.pyx | 3 ++ sel-base.pyx | 1 + sel-file.pyx | 14 +++++++++ sel-timer.pyx | 10 +++++++ selbuf.pyx | 17 +++++++++++ selpk.pyx | 16 +++++++++++ sig.pyx | 12 ++++++++ str.pyx | 5 ++++ stuff.pyx | 2 ++ sym.pyx | 5 ++++ unihash.pyx | 6 ++++ url.pyx | 8 ++++++ 25 files changed, 344 insertions(+) diff --git a/atom.pyx b/atom.pyx index cee88b9..5c63722 100644 --- a/atom.pyx +++ b/atom.pyx @@ -37,6 +37,7 @@ cdef class AtomIter: return me def atoms(): + """atoms() -> ITER: return iterator over known atoms""" return AtomIter() ###----- That's all, folks -------------------------------------------------- diff --git a/bres.pyx b/bres.pyx index cd2d16c..8097855 100644 --- a/bres.pyx +++ b/bres.pyx @@ -24,6 +24,7 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class SelResolve: + """Abstract superclass for background name resolution.""" cdef bres_client r cdef int _activep cdef _resolved @@ -35,9 +36,11 @@ cdef class SelResolve: me._dead() bres_abort(&me.r) property activep: + """BR.activep: is lookup still waiting?""" def __get__(me): return _tobool(me._activep) def kill(me): + """BR.kill(): cancel in-progress lookup""" if not me._activep: raise ValueError, 'already dead' me._dead() @@ -47,8 +50,10 @@ cdef class SelResolve: me._activep = 0 me.dead() def dead(me): + """BR.dead(): called when lookup completes or is cancelled""" pass property resolvedproc: + """BR.resolvedproc -> FUNC: call FUNC(NAME, ALIASES, ADDRS) when ok""" def __get__(me): return me._resolved def __set__(me, proc): @@ -56,6 +61,7 @@ cdef class SelResolve: def __del__(me): me._resolved = None property failedproc: + """BR.failedproc -> FUNC: call FUNC() when lookup fails""" def __get__(me): return me._failed def __set__(me, proc): @@ -63,11 +69,21 @@ cdef class SelResolve: def __del__(me): me._failed = None def resolved(me, name, aliases, addrs): + """BR.resolved(NAME, ALIASES, ADDRS): called when lookup completes""" return _maybecall(me._resolved, (name, aliases, addrs)) def failed(me): + """BR.failed(): called when lookup fails""" return _maybecall(me._failed, ()) cdef class SelResolveByName (SelResolve): + """ + Resolve a hostname to an IP address, asynchronously. + + SelResolveByName(NAME, [resolvedproc = None], [failedproc = None]) + + Calls RESOLVEDPROC(NAME, ALIASES, ADDRS) on success, or FAILEDPROC() on + failure. + """ def __cinit__(me, char *name, resolvedproc = None, failedproc = None, *hunoz, **hukairz): me._resolved = _checkcallable(resolvedproc, 'resolved proc') @@ -78,6 +94,14 @@ cdef class SelResolveByName (SelResolve): pass cdef class SelResolveByAddr (SelResolve): + """ + Resolve an IPv4 address to a hostname, asynchronously. + + SelResolveByAddr(ADDR, [resolvedproc = None], [failedproc = None]) + + Calls RESOLVEDPROC(NAME, ALIASES, ADDRS) on success, or FAILEDPROC() on + failure. + """ def __cinit__(me, char *addr, resolvedproc = None, failedproc = None, *hunoz, **hukairz): cdef in_addr ia diff --git a/codec.pyx b/codec.pyx index b9f910f..1274afd 100644 --- a/codec.pyx +++ b/codec.pyx @@ -81,6 +81,11 @@ class CDCERR: INVZPAD = CDCERR_INVZPAD class CodecError (Exception): + """ + Exception from decoding operation. + + Attributes: err = CDCERR.* code, msg = message string + """ def __init__(me, err): me.err = err me.msg = _codec_strerror(err) @@ -88,6 +93,7 @@ class CodecError (Exception): return me.msg def codec_strerror(err): + """codec_strerror(ERR) -> STR: message for CDCERR.* code""" return _codec_strerror(err) cdef int code(codec *c, void *p, size_t len, dstr *d) except -1: @@ -98,6 +104,7 @@ cdef int code(codec *c, void *p, size_t len, dstr *d) except -1: return 0 cdef class _BaseCodec: + """Abstract superclass for codecs.""" cdef codec *c def __cinit__(me, *hunoz, **hukairz): me.c = NULL @@ -125,14 +132,17 @@ cdef class _BaseCodec: finally: dstr_destroy(&d) def done(me): + """C.done() -> OUT: final output""" me.code('', True) cdef class _BaseEncoder (_BaseCodec): def encode(me, text, finishp = False): + """C.encode(IN, [finishp = False]) -> OUT: continue/finish encoding""" return me.code(text, finishp) cdef class _BaseDecoder (_BaseCodec): def decode(me, text, finishp = False): + """C.decode(IN, [finishp = False]) -> OUT: continue/finish decoding""" return me.code(text, finishp) ###-------------------------------------------------------------------------- @@ -144,26 +154,60 @@ cdef extern from 'mLib/base64.h': codec_class base64url_class cdef class Base64Encoder (_BaseEncoder): + """ + Base64Encoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base64 encoder. + """ def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK): me.c = base64_class.encoder(flags, indent, maxline) cdef class Base64Decoder (_BaseDecoder): + """ + Base64Decoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base64 decoder. + """ def __init__(me, flags = CDCF_IGNJUNK): me.c = base64_class.decoder(flags) cdef class File64Encoder (_BaseEncoder): + """ + File64Encoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base64 encoder, using `%' instead of `/', so encoded strings are safe as + filenames. + """ def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK): me.c = file64_class.encoder(flags, indent, maxline) cdef class File64Decoder (_BaseDecoder): + """ + File64Decoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base64 encoder, using `%' instead of `/', so encoded strings are safe as + filenames. + """ def __init__(me, flags = CDCF_IGNJUNK): me.c = file64_class.decoder(flags) cdef class Base64URLEncoder (_BaseEncoder): + """ + Base64URLEncoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base64 encoder, using `-' and `_' instead of `+' and `/', so encoded + strings are safe as URL components. + """ def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK): me.c = base64url_class.encoder(flags, indent, maxline) cdef class Base64URLDecoder (_BaseDecoder): + """ + Base64URLDecoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base64 decoder, using `-' and `_' instead of `+' and `/', so encoded + strings are safe as URL components. + """ def __init__(me, flags = CDCF_IGNJUNK): me.c = base64url_class.decoder(flags) @@ -175,18 +219,40 @@ cdef extern from 'mLib/base32.h': codec_class base32hex_class cdef class Base32Encoder (_BaseEncoder): + """ + Base32Encoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base32 encoder. + """ def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK): me.c = base32_class.encoder(flags, indent, maxline) cdef class Base32Decoder (_BaseDecoder): + """ + Base32Decoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base32 decoder. + """ def __init__(me, flags = CDCF_IGNJUNK): me.c = base32_class.decoder(flags) cdef class Base32HexEncoder (_BaseEncoder): + """ + Base32Encoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base32 encoder, using digits and letters in ascending order, rather than + avoiding digits which visually resemble letters. + """ def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK): me.c = base32hex_class.encoder(flags, indent, maxline) cdef class Base32HexDecoder (_BaseDecoder): + """ + Base32Decoder([indent = '\\n'], [maxline = 72], [flags = CDCF.IGNJUNK]) + + Base32 decoder, using digits and letters in ascending order, rather than + avoiding digits which visually resemble letters. + """ def __init__(me, flags = CDCF_IGNJUNK): me.c = base32hex_class.decoder(flags) @@ -197,11 +263,23 @@ cdef extern from 'mLib/hex.h': codec_class hex_class cdef class HexEncoder (_BaseEncoder): + """ + HexEncoder([indent = '\\n'], [maxline = 72], + [flags = CDCF.IGNJUNK | CDCF.LOWERC]) + + Hexadecimal encoder. + """ def __init__(me, indent = '\n', maxline = 72, flags = CDCF_IGNJUNK | CDCF_LOWERC): me.c = hex_class.encoder(flags, indent, maxline) cdef class HexDecoder (_BaseDecoder): + """ + HexDecoder([indent = '\\n'], [maxline = 72], + [flags = CDCF.IGNJUNK | CDCF.LOWERC]) + + Hexadecimal decoder. + """ def __init__(me, flags = CDCF_IGNJUNK | CDCF_LOWERC): me.c = hex_class.decoder(flags) diff --git a/codec.pyx.in b/codec.pyx.in index 2ea5255..3da1b83 100644 --- a/codec.pyx.in +++ b/codec.pyx.in @@ -34,6 +34,11 @@ cdef extern from 'mLib/%PREFIX%.h': void *p, size_t sz, dstr *d) cdef class %CLASS%Encode: + """ + %CLASS%([indent = '\\n'], [maxline = 72]) + + Obsolete %CLASS% encoder. + """ cdef %PREFIX%_ctx ctx def __cinit__(me, *hunoz, **hukairz): _%PREFIX%_init(&me.ctx) @@ -47,6 +52,7 @@ cdef class %CLASS%Encode: if me.ctx.indent: xfree(me.ctx.indent) property indent: + """E.indent -> INT: indent level for new lines""" def __get__(me): return me.ctx.indent def __set__(me, indent): @@ -54,11 +60,13 @@ cdef class %CLASS%Encode: xfree(me.ctx.indent) me.ctx.indent = xstrdup(indent) property maxline: + """E.maxline -> INT: maximum length of line, or 0 to prevent splitting""" def __get__(me): return me.ctx.maxline def __set__(me, maxline): me.ctx.maxline = maxline def encode(me, text): + """E.encode(IN) -> OUT: continue encoding""" cdef void *p cdef Py_ssize_t len cdef dstr d @@ -71,6 +79,7 @@ cdef class %CLASS%Encode: dstr_destroy(&d) return rc def done(me): + """E.done() -> OUT: finish encoding, returning final output""" cdef dstr d DCREATE(&d) try: @@ -81,15 +90,22 @@ cdef class %CLASS%Encode: return rc def %PREFIX%_encode(text, *arg, **kw): + """%PREFIX%_encode(IN, [ARGS...]) -> OUT: %CLASS%-encode the string IN""" e = %CLASS%Encode(*arg, **kw) return e.encode(text) + e.done() cdef class %CLASS%Decode: + """ + %CLASS%() + + Obsolete %CLASS% decoder. + """ cdef %PREFIX%_ctx ctx def __cinit__(me, *hunoz, **hukairz): _%PREFIX%_init(&me.ctx) me.ctx.indent = NULL def decode(me, text): + """D.encode(IN) -> OUT: continue decoding""" cdef void *p cdef Py_ssize_t len cdef dstr d @@ -102,6 +118,7 @@ cdef class %CLASS%Decode: dstr_destroy(&d) return rc def done(me): + """D.done() -> OUT: finish decoding, returning final output""" cdef dstr d DCREATE(&d) try: @@ -112,6 +129,7 @@ cdef class %CLASS%Decode: return rc def %PREFIX%_decode(text, *arg, **kw): + """%PREFIX%_decode(IN) -> OUT: %CLASS%-decode the string IN""" d = %CLASS%Decode(*arg, **kw) return d.decode(text) + d.done() diff --git a/conn.pyx b/conn.pyx index 2b3e0bc..2f5d493 100644 --- a/conn.pyx +++ b/conn.pyx @@ -24,6 +24,14 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class SelConnect: + """ + SelConnect(SK, [connectedproc = FUNC], [errorproc = FUNC]) + + When socket SK connects, call CONNECTEDPROC(); if connection fails, call + ERRORPROC(ERRNO, MESSAGE). + + Attributes: C.socket, C.activep, C.connectedproc, C.errorproc. + """ cdef conn c cdef int _activep cdef readonly object socket @@ -40,9 +48,11 @@ cdef class SelConnect: if me._activep: conn_kill(&me.c) property activep: + """C.activep -> BOOL: is connection still in progress?""" def __get__(me): return _tobool(me._activep) property connectedproc: + """C.connectedproc -> FUNC: call FUNC() when connection completes""" def __get__(me): return me._connected def __set__(me, proc): @@ -50,6 +60,9 @@ cdef class SelConnect: def __del__(me): me._connected = None property errorproc: + """ + C.errorproc -> FUNC: call FUNC(ERRNO, MSG) if connection fails + """ def __get__(me): return me._error def __set__(me, proc): @@ -57,6 +70,7 @@ cdef class SelConnect: def __del__(me): me._error = None def kill(me): + """C.kill(): give up on connection""" if not me._activep: raise ValueError, 'already dead' conn_kill(&me.c); @@ -66,10 +80,13 @@ cdef class SelConnect: me._activep = 0 me.dead() def dead(me): + """C.dead(): called when connection completes or fails""" pass def connected(me): + """C.connected(): called when connection completes successfully""" return _maybecall(me._connected, ()) def error(me, errno, strerror): + """C.error(ERRNO, MSG): called when connection fails""" return _maybecall(me._error, ()) cdef void _connfunc(int fd, void *arg): diff --git a/crc32.pyx b/crc32.pyx index c1f3b82..f4072a0 100644 --- a/crc32.pyx +++ b/crc32.pyx @@ -24,21 +24,25 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class CRC32: + """CRC32(): calculate CRC32 of a stream""" cdef uint32 _a def __cinit__(me, *hunoz, **hukairz): me._a = 0 def __init__(me): pass def chunk(me, data): + """C.chunk(STR): process another chunk of input""" cdef void *p cdef Py_ssize_t n PyObject_AsReadBuffer(data, &p, &n) me._a = c_crc32(me._a, p, n) return me def done(me): + """C.done() -> INT: return CRC of data""" return _u32(me._a) def crc32(data): + """crc32(STR) -> INT""" cdef void *p cdef Py_ssize_t n cdef uint32 c diff --git a/fdutils.pyx b/fdutils.pyx index bb28188..55c8ca1 100644 --- a/fdutils.pyx +++ b/fdutils.pyx @@ -26,6 +26,17 @@ def fdflags(file, unsigned fbic = 0, unsigned fxor = 0, unsigned fdbic = 0, unsigned fdxor = 0): + """ + fdflags(FILE, [fbic = 0], [fxor = 0], [fdbic = 0], [fdxor = 0]) + + Set fcntl(2) file and descriptor flags. If these are FL and FD, then + update: + + * FL = (FL & ~FBIC) ^ FXOR + * FD = (FD & ~FDBIC) ^ FDXOR + + FILE may be integer file descriptor or an object with `fileno' method. + """ cdef int rc rc = _fdflags(_getfd(fd), fbix, fxor, fdbic, fdxor) if rc < 0: @@ -33,6 +44,10 @@ def fdflags(file, return rc def fdsend(sock, file, buffer): + """ + fdsend(SOCK, FILE, BUFFER) -> RC: + send FILE over Unix-domain socket SOCK, along with BUFFER + """ cdef void *p cdef Py_ssize_t len cdef int rc @@ -43,6 +58,10 @@ def fdsend(sock, file, buffer): return rc def fdrecv(sock, unsigned size): + """ + fdrecv(SOCK, SIZE) -> FD, BUFFER + receive file FD and BUFFER of length up to SIZE from Unix-domain SOCK + """ cdef void *p cdef buf cdef Py_ssize_t len diff --git a/fwatch.pyx b/fwatch.pyx index 2e484cd..eedb872 100644 --- a/fwatch.pyx +++ b/fwatch.pyx @@ -24,6 +24,11 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class FWatch: + """ + FWatch(FILE): watch FILE for changes + + FILE may be a string, file descriptor, or an object with a `fileno' method. + """ cdef fwatch fw cdef public file def __cinit__(me, file): @@ -37,6 +42,7 @@ cdef class FWatch: fwatch_initfd(&me.fw, _getfd(file)) me.file = file def update(me): + """FW.update() -> RC: nonzero if the file has changed state""" cdef int rc if isinstance(me.file, str): rc = fwatch_update(&me.fw, me.file) diff --git a/ident.pyx b/ident.pyx index 1c2789e..9a522bd 100644 --- a/ident.pyx +++ b/ident.pyx @@ -41,6 +41,12 @@ cdef _inaddr_topy(sockaddr_in *sin): return inet_ntoa(sin.sin_addr), ntohs(sin.sin_port) cdef class SelIdentify: + """ + SelIdentify(SK, [userproc = None], [bogusproc = None], + [badproc = None], [errorproc = None],) + + Asynchronously enquire about remote user of socket SK. + """ cdef ident_request irq cdef int _activep cdef readonly localaddr @@ -80,9 +86,11 @@ cdef class SelIdentify: if me._activep: ident_abort(&me.irq) property activep: + """I.activep -> BOOL: query still in progress?""" def __get__(me): return _tobool(me._activep) property userproc: + """I.userproc -> FUNC: call FUNC(OS, USER) if server replied""" def __get__(me): return me._user def __set__(me, proc): @@ -90,6 +98,7 @@ cdef class SelIdentify: def __del__(me): me._user = None property badproc: + """I.badproc -> FUNC: call FUNC() if server's reply was broken""" def __get__(me): return me._bad def __set__(me, proc): @@ -97,6 +106,7 @@ cdef class SelIdentify: def __del__(me): me._bad = None property errorproc: + """I.errorproc -> FUNC: call FUNC(ERR) if server reported error""" def __get__(me): return me._error def __set__(me, proc): @@ -104,6 +114,7 @@ cdef class SelIdentify: def __del__(me): me._error = None property bogusproc: + """I.bogusproc -> FUNC: call FUNC() on failure if no specific handler""" def __get__(me): return me._bogus def __set__(me, proc): @@ -111,6 +122,7 @@ cdef class SelIdentify: def __del__(me): me._bogus = None def kill(me): + """I.kill(): cancel ident query""" if not me._activep: raise ValueError, 'already disabled' ident_abort(&me.irq) @@ -119,18 +131,23 @@ cdef class SelIdentify: me._activep = 0 me.dead() def dead(me): + """I.dead(): called when operation completes or fails""" pass def user(me, os, user): + """I.user(OS, USER): called if server returns user name""" return _maybecall(me._user, (os, user)) def bad(me): + """I.bad(): called if server's reply is invalid""" if me._bad is not None: return me._bad() return me.bogus() def error(me, error): + """I.error(ERR): called if server returns an error""" if me._error is not None: return me._error(error) return me.bogus() def bogus(me): + """I.bogus(): called on failure if there's no more specific handler""" return _maybecall(me._bogus, ()) cdef void _identfunc(ident_reply *i, void *arg): diff --git a/lbuf.pyx b/lbuf.pyx index 2793e47..c5f2688 100644 --- a/lbuf.pyx +++ b/lbuf.pyx @@ -27,6 +27,11 @@ LBUF_CRLF = _LBUF_CRLF LBUF_STRICTCRLF = _LBUF_STRICTCRLF cdef class LineBuffer: + """ + LineBuffer([lineproc = None], [eofproc = None]) + + Split an incoming stream into lines. + """ cdef lbuf b cdef _line cdef _eof @@ -37,9 +42,11 @@ cdef class LineBuffer: def __dealloc__(me): lbuf_destroy(&me.b) property activep: + """LB.activep -> BOOL: is the buffer still active?""" def __get__(me): return _tobool(me.b.f & LBUF_ENABLE) property delim: + """LB.delim -> CHAR | LBUF_...: line-end delimiter""" def __get__(me): if me.b.delim == _LBUF_CRLF or me.b.delim == _LBUF_STRICTCRLF: return me.b.delim @@ -51,6 +58,7 @@ cdef class LineBuffer: else: me.b.delim = ord(d) property size: + """LB.size -> INT: buffer size limit""" def __get__(me): return me.b.sz def __set__(me, sz): @@ -58,6 +66,7 @@ cdef class LineBuffer: raise TypeError, 'size must be positive' lbuf_setsize(&me.b, sz) property lineproc: + """LB.lineproc -> FUNC: call FUNC(LINE) on each line""" def __get__(me): return me._line def __set__(me, proc): @@ -65,6 +74,7 @@ cdef class LineBuffer: def __del__(me): me._line = None property eofproc: + """LB.eofproc -> FUNC: call FUNC() at end-of-file""" def __get__(me): return me._eof def __set__(me, proc): @@ -72,27 +82,32 @@ cdef class LineBuffer: def __del__(me): me._eof = None def enable(me): + """LB.enable(): enable the buffer, allowing lines to be emitted""" if me.b.f & LBUF_ENABLE: raise ValueError, 'already enabled' me.b.f = me.b.f | LBUF_ENABLE me.enabled() return me def disable(me): + """LB.disable(): disable the buffer, suspending line emission""" if not (me.b.f & LBUF_ENABLE): raise ValueError, 'already disabled' me.b.f = me.b.f & ~LBUF_ENABLE me.disabled() return me def close(me): + """LB.close(): report the end of the input stream""" if not (me.b.f & LBUF_ENABLE): raise ValueError, 'buffer disabled' lbuf_close(&me.b) return me property free: + """LB.free -> INT: amount of space remaining in buffer""" def __get__(me): cdef char *p return lbuf_free(&me.b, &p) def flush(me, str): + """LB.flush(STR) -> insert STR into the buffer and emit lines""" cdef Py_ssize_t len cdef char *p cdef char *q @@ -110,12 +125,16 @@ cdef class LineBuffer: lbuf_flush(&me.b, q, n) return PyString_FromStringAndSize(p, len) def enabled(me): + """LB.enabled(): called when buffer is enabled""" pass def disabled(me): + """LB.disabled(): called when buffer is disabled""" pass def line(me, line): + """LB.line(LINE): called for each completed line""" return _maybecall(me._line, (line,)) def eof(me): + """LB.eof(): called at end-of-file""" return _maybecall(me._eof, ()) cdef void _lbfunc(char *s, size_t n, void *arg): diff --git a/mapping.pyx b/mapping.pyx index f99de34..b044ed6 100644 --- a/mapping.pyx +++ b/mapping.pyx @@ -55,6 +55,7 @@ cdef class Mapping: ## Bulk update def update(me, stuff = None, **kw): + """D.update([MAP], **KW): insert mappings from MAP and KW""" cdef unsigned f if stuff is None: pass @@ -89,12 +90,16 @@ cdef class Mapping: raise KeyError, key me._del(e) def get(me, key, default = None): + """D.get(KEY, [default = None]) -> VALUE: value at KEY, or DEFAULT""" cdef void *e e = me._find(key, NULL) if not e: return default return me._value(e) def setdefault(me, key, default = None): + """ + D.setdefault(KEY, [default = None]) -> VALUE: + return value at key, or store DEFAULT at key and return that""" cdef void *e cdef unsigned f e = me._find(key, &f) @@ -104,6 +109,9 @@ cdef class Mapping: me._setval(e, default) return default def pop(me, key, default = None): + """ + D.pop(KEY, [default = None]) -> VALUE: + return value at key or DEFAULT, and remove KEY""" cdef void *e e = me._find(key, NULL) if not e: @@ -112,6 +120,7 @@ cdef class Mapping: me._del(e) return rc def popitem(me): + """D.popitem() -> KEY, VALUE: return and remove an association pair""" cdef _MapIterator i cdef void *e i = me._iter() @@ -134,13 +143,17 @@ cdef class Mapping: return l def keys(me): + """D.keys() -> LIST: return a list of known keys""" return me._list(_map_key) def values(me): + """D.values() -> LIST: return a list of known values""" return me._list(_map_value) def items(me): + """D.values() -> LIST: return a list of known (KEY, VALUE) pairs""" return me._list(_map_item) def clear(me): + """D.clear(): remove all mappings""" cdef _MapIterator i cdef void *e i = me._iter() @@ -155,10 +168,13 @@ cdef class Mapping: def __iter__(me): return MapKeyIter(me) def iterkeys(me): + """D.iterkeys() -> ITER: return iterator over keys""" return MapKeyIter(me) def itervalues(me): + """D.itervalues() -> ITER: return iterator over values""" return MapValueIter(me) def iteritems(me): + """D.iteritems() -> ITER: return iterator over (KEY, VALUE) pairs""" return MapItemIter(me) cdef class MapIterBase: diff --git a/mdup.pyx b/mdup.pyx index cf3a3c0..7256211 100644 --- a/mdup.pyx +++ b/mdup.pyx @@ -24,6 +24,14 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. def mdup(v): + """ + mdup(LIST) -> LIST: + LIST is a list (mutable sequence) of pairs (CUR, WANT). Duplicate each + CUR file descriptor as WANT (may be -1 to mean `don't care'), closing + original CUR. Works even if there are cycles. LIST is updated in place + with CUR reflecting the new file descriptors even on error. Returns the + same LIST on success. + """ cdef mdup_fd *vv cdef size_t n cdef int i diff --git a/pkbuf.pyx b/pkbuf.pyx index 2544aaa..fe296f3 100644 --- a/pkbuf.pyx +++ b/pkbuf.pyx @@ -24,6 +24,11 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class PacketBuffer: + """ + PacketBuffer([packetproc = None], [eofproc = None]) + + Split an incoming stream into packets. + """ cdef pkbuf pk cdef _packet cdef _eof @@ -34,9 +39,11 @@ cdef class PacketBuffer: def __dealloc__(me): pkbuf_destroy(&me.pk) property activep: + """PK.activep -> BOOL: is the buffer still active?""" def __get__(me): return _tobool(me.pk.f & PKBUF_ENABLE) property want: + """PK.want -> INT: size of next packet to return""" def __get__(me): return me.pk.want def __set__(me, want): @@ -44,6 +51,7 @@ cdef class PacketBuffer: raise TypeError, 'want must be positive' pkbuf_want(&me.pk, pk) property packetproc: + """PK.packetproc -> FUNC: call FUNC(PACKET) on each packet""" def __get__(me): return me._packet def __set__(me, proc): @@ -51,6 +59,7 @@ cdef class PacketBuffer: def __del__(me): me._line = None property eofproc: + """PK.eofproc -> FUNC: call FUNC() at end-of-file""" def __get__(me): return me._eof def __set__(me, proc): @@ -58,27 +67,32 @@ cdef class PacketBuffer: def __del__(me): me._eof = None def enable(me): + """PK.enable(): enable the buffer, allowing packets to be emitted""" if me.pk.f & PKBUF_ENABLE: raise ValueError, 'already enabled' me.pk.f = me.pk.f | PKBUF_ENABLE me.enabled() return me def disable(me): + """PK.disable(): disable the buffer, suspending packet emission""" if not (me.pk.f & PKBUF_ENABLE): raise ValueError, 'already disabled' me.pk.f = me.pk.f & ~PKBUF_ENABLE me.disabled() return me def close(me): + """PK.close(): report the end of the input stream""" if not (me.pk.f & PKBUF_ENABLE): raise ValueError, 'buffer disabled' pkbuf_close(&me.pk) return me property free: + """PK.free -> INT: amount of space remaining in buffer""" def __get__(me): cdef unsigned char *p return pkbuf_free(&me.pk, &p) def flush(me, str): + """PK.flush(STR) -> insert STR into the buffer and emit packets""" cdef Py_ssize_t len cdef unsigned char *p cdef unsigned char *q @@ -96,12 +110,16 @@ cdef class PacketBuffer: pkbuf_flush(&me.pk, q, n) return PyString_FromStringAndSize(p, len) def enabled(me): + """PK.enabled(): called when buffer is enabled""" pass def disabled(me): + """PK.disabled(): called when buffer is disabled""" pass def packet(me, pk): + """PK.packet(PACKET): called for each completed packet""" return _maybecall(me._packet, (pk,)) def eof(me): + """PK.eof(): called at end-of-file""" return _maybecall(me._eof, ()) cdef void _pkfunc(unsigned char *p, size_t n, pkbuf *pk, diff --git a/report.pyx b/report.pyx index 523dbe0..9d19ed2 100644 --- a/report.pyx +++ b/report.pyx @@ -28,6 +28,7 @@ cdef char *_progstring _progstring = NULL def ego(char *prog): + """ego(PROG): set program name""" global quis, _progstring if _progstring: xfree(_progstring) @@ -36,8 +37,10 @@ def ego(char *prog): quis = _quis() def moan(char *msg): + """moan(MSG): report a warning""" _moan('%s', msg) def die(char *msg, rc = 126): + """die(MSG, [rc = 126]): report a fatal error and exit""" _moan('%s', msg) raise SystemExit, rc diff --git a/sel-base.pyx b/sel-base.pyx index ca1f365..64e8d08 100644 --- a/sel-base.pyx +++ b/sel-base.pyx @@ -26,6 +26,7 @@ cdef sel_state _sel def select(): + """select(): wait for I/O and/or timeouts""" if sel_select(&_sel) and errno != EINTR and errno != EAGAIN: _oserror() diff --git a/sel-file.pyx b/sel-file.pyx index f077e7c..9ff1029 100644 --- a/sel-file.pyx +++ b/sel-file.pyx @@ -28,6 +28,11 @@ SEL_WRITE = _SEL_WRITE SEL_EXCEPT = _SEL_EXC cdef class SelFile: + """ + SelFile(FILE, [mode = SEL_READ], [readyproc = None]) + + Register a file (or socket, or, ...) with the select loop. + """ cdef sel_file f cdef int _activep cdef readonly unsigned mode @@ -46,12 +51,15 @@ cdef class SelFile: if me._activep: sel_rmfile(&me.f) property fd: + """SF.fd -> INT: the file descriptor""" def __get__(me): return me.f.fd property activep: + """SF.activep -> BOOL: is the descriptor active?""" def __get__(me): return _tobool(me._activep) property readyproc: + """SF.readyproc -> FUNC: call FUNC() when file is ready for I/O""" def __get__(me): return me._readyfunc def __set__(me, proc): @@ -59,18 +67,21 @@ cdef class SelFile: def __del__(me): me._readyfunc = None def enable(me): + """SF.enable(): enable waiting on file""" if me._activep: raise ValueError, 'already enabled' sel_addfile(&me.f) me._enabled() return me def disable(me): + """SF.disable(): disable waiting on file""" if not me._activep: raise ValueError, 'already disabled' sel_rmfile(&me.f) me._disabled() return me def force(me): + """SF.force(): artificially mark file as ready""" sel_force(&me.f) return me cdef _enabled(me): @@ -80,10 +91,13 @@ cdef class SelFile: me._activep = 0 me.disabled() def enabled(me): + """SF.enabled(): called when file is enabled""" pass def disabled(me): + """SF.disabled(): called when file is disabled""" pass def ready(me): + """SF.ready(): called when file is ready for I/O""" return _maybecall(me._readyfunc, ()) cdef void _filefunc(int fd, unsigned mode, void *arg): diff --git a/sel-timer.pyx b/sel-timer.pyx index ba59a7c..ebdd433 100644 --- a/sel-timer.pyx +++ b/sel-timer.pyx @@ -32,6 +32,11 @@ cdef void _floattotv(timeval *tv, double t): tv.tv_usec = (us * 1000000) cdef class SelTimer: + """ + SelTimer(WHEN, [timerproc = None]) + + Arrange to perform some action at time WHEN. + """ cdef sel_timer t cdef int _activep cdef readonly double time @@ -47,9 +52,11 @@ cdef class SelTimer: if me._activep: sel_rmtimer(&me.t) property activep: + """ST.activep -> BOOL: is the timer active?""" def __get__(me): return _tobool(me._activep) property timerproc: + """ST.timerproc -> FUNC: call FUNC() when the timer pops""" def __get__(me): return me._timer def __set__(me, proc): @@ -57,6 +64,7 @@ cdef class SelTimer: def __del__(me): me._timer = None def kill(me): + """ST.kill(): deactivate timer permanently""" if not me._activep: raise ValueError, 'already dead' sel_rmtimer(&me.t) @@ -66,8 +74,10 @@ cdef class SelTimer: me._activep = 0 me.dead() def dead(me): + """ST.dead(): called when timer is deactivated""" pass def timer(me, now): + """ST.timer(NOW): called when the timer pops""" return _maybecall(me._timer, ()) cdef void _timerfunc(timeval *now, void *arg): diff --git a/selbuf.pyx b/selbuf.pyx index 35b7cf6..53964c7 100644 --- a/selbuf.pyx +++ b/selbuf.pyx @@ -24,6 +24,11 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class SelLineBuffer: + """ + SelLineBuffer(FILE, [lineproc = None], [eofproc = None]) + + Split an asynchronous stream into lines. + """ cdef selbuf b cdef _line cdef _eof @@ -35,12 +40,15 @@ cdef class SelLineBuffer: def __dealloc__(me): selbuf_destroy(&me.b) property activep: + """SLB.activep -> BOOL: is the buffer still active?""" def __get__(me): return _tobool(me.b.b.f & LBUF_ENABLE) property fd: + """SLB.fd -> INT: the file descriptor""" def __get__(me): return me.b.reader.fd property delim: + """SLB.delim -> CHAR | LBUF_...: line-end delimiter""" def __get__(me): if me.b.b.delim == _LBUF_CRLF or me.b.b.delim == _LBUF_STRICTCRLF: return me.b.b.delim @@ -52,6 +60,7 @@ cdef class SelLineBuffer: else: me.b.b.delim = ord(d) property size: + """SLB.size -> INT: buffer size limit""" def __get__(me): return me.b.b.sz def __set__(me, sz): @@ -59,6 +68,7 @@ cdef class SelLineBuffer: raise TypeError, 'size must be positive' selbuf_setsize(&me.b, sz) property lineproc: + """SLB.lineproc -> FUNC: call FUNC(LINE) on each line""" def __get__(me): return me._line def __set__(me, proc): @@ -66,6 +76,7 @@ cdef class SelLineBuffer: def __del__(me): me._line = None property eofproc: + """SLB.eofproc -> FUNC: call FUNC() at end-of-file""" def __get__(me): return me._eof def __set__(me, proc): @@ -73,24 +84,30 @@ cdef class SelLineBuffer: def __del__(me): me._eof = None def enable(me): + """SLB.enable(): enable the buffer, allowing lines to be emitted""" if me.b.b.f & LBUF_ENABLE: raise ValueError, 'already enabled' selbuf_enable(&me.b) me.enabled() return me def disable(me): + """SLB.disable(): disable the buffer, suspending line emission""" if not (me.b.b.f & LBUF_ENABLE): raise ValueError, 'already disabled' selbuf_disable(&me.b) me.disabled() return me def enabled(me): + """SLB.enabled(): called when buffer is enabled""" pass def disabled(me): + """SLB.disabled(): called when buffer is disabled""" pass def line(me, line): + """SLB.line(LINE): called for each completed line""" return _maybecall(me._line, (line,)) def eof(me): + """SLB.eof(): called at end-of-file""" return _maybecall(me._eof, ()) cdef void _selbfunc(char *s, size_t n, void *arg): diff --git a/selpk.pyx b/selpk.pyx index ee27302..a54ce95 100644 --- a/selpk.pyx +++ b/selpk.pyx @@ -24,6 +24,11 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class SelPacketBuffer: + """ + SelPacketBuffer(FILE, [packetproc = None], [eofproc = None]) + + Split an incoming stream into packets. + """ cdef selpk p cdef _packet cdef _eof @@ -35,12 +40,15 @@ cdef class SelPacketBuffer: def __dealloc__(me): selpk_destroy(&me.p) property activep: + """SPK.activep -> BOOL: is the buffer still active?""" def __get__(me): return _to_bool(me.p.pk.f & PKBUF_ENABLE) property fd: + """SPK.fd -> INT: the file descriptor""" def __get__(me): return me.p.reader.fd property want: + """SPK.want -> INT: size of next packet to return""" def __get__(me): return me.p.pk.want def __set__(me, n): @@ -48,6 +56,7 @@ cdef class SelPacketBuffer: raise TypeError, 'size must be positive' selpk_want(&me.p, n) property packetproc: + """SPK.packetproc -> FUNC: call FUNC(PACKET) on each packet""" def __get__(me): return me._packet def __set__(me, proc): @@ -55,6 +64,7 @@ cdef class SelPacketBuffer: def __del__(me): me._packet = None property eofproc: + """SPK.eofproc -> FUNC: call FUNC() at end-of-file""" def __get__(me): return me._eof def __set__(me, proc): @@ -62,24 +72,30 @@ cdef class SelPacketBuffer: def __del__(me): me._eof = None def enable(me): + """SPK.enable(): enable the buffer, allowing packets to be emitted""" if me.p.pk.f & PKBUF_ENABLE: raise ValueError, 'already enabled' selpk_enable(&me.p) me.enabled() return me def disable(me): + """SPK.disable(): disable the buffer, suspending packet emission""" if not (me.p.pk.f & PKBUF_ENABLE): raise ValueError, 'already disabled' selpk_disable(&me.p) me.disabled() return me def enabled(me): + """SPK.enabled(): called when buffer is enabled""" pass def disabled(me): + """SPK.disabled(): called when buffer is disabled""" pass def packet(me, pk): + """SPK.packet(PACKET): called for each completed packet""" return _maybecall(me._packet, (pk,)) def eof(me): + """SPK.eof(): called at end-of-file""" return _maybecall(me._eof, ()) cdef void _selpkfunc(unsigned char *p, size_t n, pkbuf *pk, diff --git a/sig.pyx b/sig.pyx index 17d52fe..aafa050 100644 --- a/sig.pyx +++ b/sig.pyx @@ -26,6 +26,11 @@ import signal cdef class SelSignal: + """ + SelSignal(SIG, [signalledproc = None]) + + Collect signals from the event loop. + """ cdef sig s cdef int _activep cdef readonly int signal @@ -40,9 +45,11 @@ cdef class SelSignal: if me._activep: sig_remove(&me.s) property activep: + """SS.activep -> BOOL: is the handler still active?""" def __get__(me): return _tobool(me._activep) property signalledproc: + """SS.signalledproc -> FUNC: call FUNC() when the signal is received""" def __get__(me): return me._signalled def __set__(me, proc): @@ -50,12 +57,14 @@ cdef class SelSignal: def __del__(me): me._signalled = None def enable(me): + """SS.enable(): enable the handler""" if me._activep: raise ValueError, 'already enabled' sig_add(&me.s, me.signal, _sigfunc, me) me._enabled() return me def disable(me): + """SS.disable(): disable the handler""" if not me._activep: raise ValueError, 'already disabled' sig_remove(&me.s) @@ -68,10 +77,13 @@ cdef class SelSignal: me._activep = 0 me.disabled() def enabled(me): + """SS.enabled(): called when handler is enabled""" pass def disabled(me): + """SS.disabled(): called when handler is disabled""" pass def signalled(me): + """SS.signalled(): called when the signal is received""" return _maybecall(me._signalled, ()) cdef void _sigfunc(int sig, void *arg): diff --git a/str.pyx b/str.pyx index 676b0ee..f1a2ee5 100644 --- a/str.pyx +++ b/str.pyx @@ -24,6 +24,7 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. def word(char *p, quotep = False): + """word(STR, [quotep = False]) -> WORD, REST""" cdef unsigned f cdef char *op cdef char *pp @@ -48,6 +49,7 @@ def word(char *p, quotep = False): return w, r def split(char *p, int n = -1, quotep = False): + """split(STR, [n = -1], [quotep = False]) -> WORDS, REST""" cdef unsigned f cdef char *op cdef char *pp @@ -75,6 +77,7 @@ def split(char *p, int n = -1, quotep = False): return l, r def match(char *p, char *s, prefixp = False): + """match(PAT, STR, [prefixp = False]) -> BOOL""" cdef unsigned f f = 0 @@ -83,6 +86,7 @@ def match(char *p, char *s, prefixp = False): return _tobool(str_matchx(p, s, f)) def sanitize(char *p, int n = -1): + """sanitize(STR, [n = -1]) -> STR""" cdef char *buf cdef object d @@ -95,6 +99,7 @@ def sanitize(char *p, int n = -1): return d def versioncmp(char *va, char *vb): + """versioncmp(V0, V1) -> -1 | 0 | +1""" return _versioncmp(va, vb) ###----- That's all, folks -------------------------------------------------- diff --git a/stuff.pyx b/stuff.pyx index e18e367..dcb8a9c 100644 --- a/stuff.pyx +++ b/stuff.pyx @@ -24,9 +24,11 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. def detachtty(): + """detachtty(): detach from terminal and fork""" _detachtty() def daemonize(): + """daemonize(): become a daemon""" if _daemonize(): _oserror() diff --git a/sym.pyx b/sym.pyx index eab6984..f456db8 100644 --- a/sym.pyx +++ b/sym.pyx @@ -28,6 +28,11 @@ cdef struct _sym_entry: PyObject *v cdef class SymTable (Mapping): + """ + SymTable([DICT], **KW) + + A mapping keyed by strings. + """ cdef sym_table _t cdef int _init(me) except -1: sym_create(&me._t) diff --git a/unihash.pyx b/unihash.pyx index de6f3d4..8ededb0 100644 --- a/unihash.pyx +++ b/unihash.pyx @@ -24,19 +24,23 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. def setglobalkey(uint32 k): + """setglobalkey(K): set global hash key""" unihash_setkey(&unihash_global, k) cdef class Key: + """Key(K): universal hashing key""" cdef unihash_info _i cdef uint32 _k def __cinit__(me, uint32 k): unihash_setkey(&me._i, k) me._k = k property k: + """K.k -> INT: the key value""" def __get__(me): return _u32(me._k) cdef class Unihash: + """Unihash([key = None]): universal hashing context""" cdef uint32 _a cdef readonly Key key cdef unihash_info *_i @@ -50,11 +54,13 @@ cdef class Unihash: me._i = &k._i me._a = UNIHASH_INIT(me._i) def chunk(me, data): + """U.chunk(STR): hash the STR""" cdef void *p cdef Py_ssize_t n PyObject_AsReadBuffer(data, &p, &n) me._a = unihash_hash(me._i, me._a, p, n) def done(me): + """U.done() -> INT: the hash of the data""" return _u32(me._a) ###----- That's all, folks -------------------------------------------------- diff --git a/url.pyx b/url.pyx index ef7e36c..72467f1 100644 --- a/url.pyx +++ b/url.pyx @@ -24,6 +24,7 @@ ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cdef class URLEncode: + """URLEncode([strictp = False], [laxp = False], [semip = False])""" cdef url_ectx ctx cdef dstr d @@ -41,12 +42,15 @@ cdef class URLEncode: f = f | URLF_SEMI me.ctx.f = f def encode(me, char *name, char *value): + """UE.encode(NAME, VALUE): encode a key/value pair""" url_enc(&me.ctx, &me.d, name, value) return me property result: + """UE.result -> STR: the encoded string""" def __get__(me): return PyString_FromStringAndSize(me.d.buf, me.d.len) property strictp: + """UE.strictp -> BOOL: strictly escape non-alphanumerics?""" def __get__(me): return _tobool(me.ctx.f & URLF_STRICT) def __set__(me, val): @@ -55,6 +59,7 @@ cdef class URLEncode: else: me.ctx.f = me.ctx.f & ~URLF_STRICT property laxp: + """UE.laxp -> BOOL: only escape obviously unsafe characters?""" def __get__(me): return _tobool(me.ctx.f & URLF_LAX) def __set__(me, val): @@ -63,6 +68,7 @@ cdef class URLEncode: else: me.ctx.f = me.ctx.f & ~URLF_LAX property semip: + """UE.semip -> BOOL: separate key/value pairs with semicolons?""" def __get__(me): return _tobool(me.ctx.f & URLF_SEMI) def __set__(me, val): @@ -74,6 +80,7 @@ cdef class URLEncode: dstr_destroy(&me.d) cdef class URLDecode: + """URLDecode(STR, [semip = False]): iterator over (KEY, VALUE) pairs""" cdef url_dctx ctx cdef char *p @@ -109,6 +116,7 @@ cdef class URLDecode: raise StopIteration return nn, vv property semip: + """UD.semip -> BOOL: key/value pairs separated with semicolons?""" def __get__(me): return _tobool(me.ctx.f & URLF_SEMI) def __set__(me, val): -- [mdw]