Metadata-Version: 2.4
Name: LineDance
Version: 1.0.0
Summary: Synchronous line-oriented IPC with command-line utilities
Author: Jeremy Hill
Author-email: jezhill@gmail.com
License: CC0-1.0
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Description-Content-Type: text/x-rst
License-File: LICENSE.txt
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: license
Dynamic: license-file
Dynamic: summary

.. default-role:: code


LineDance
=========

LineDance provides a small, dependency-free interface for conducting synchronous,
line-oriented exchanges with a command-line utility.  It supports Python 2.7 and
Python 3.

A `Partner` instance owns one subprocess.  Each call writes one line to its stdin
and waits for stdout, stderr, or process termination::

	from linedance import Partner

	partner = Partner( "perl -ple '$|=1; tr/a-z/A-Z/'" )
	partner( 'hello world' )
	# 'HELLO WORLD'
	partner.Close()

Consecutive reply lines that arrive close together are returned in one newline-
joined string.  Output on stderr raises `PartnerError`, while failure to produce
the first reply before an optional timeout raises `PartnerTimeout`::

	partner = Partner( command, timeout=10.0, interLineTimeout=0.010 )
	reply = partner.Communicate( 'one request' )

The defaults are mutable attributes and may also be overridden for one call.
`timeout=None`, the default, permits an arbitrarily long computation before the
first reply.  Once the first line arrives, only the resetting `interLineTimeout`
applies, allowing any number of promptly consecutive lines to be collected.

Transcript
----------

Every sent or received line is retained in one chronological transcript::

    partner.transcript
    # [(timestamp, 'stdin',  'hello again'),
    #  (timestamp, 'stdout', 'HELLO AGAIN')]

The `stdin`, `stdout`, and `stderr` properties provide filtered views of the same
history.  `History()` provides optional stream and ignored-output filters.  Empty
lines are preserved.  A received LF and one optional preceding CR are stripped
from each line.

Ignored output
--------------

Optional regex filters may be supplied with `ignore` at initialization time, or
by assigning or mutating the `ignore` list later.  A single string replaces the
list with one filter; an iterable replaces it with multiple filters.  Prefix a
string with `stdout:`, `stderr:`, or `all:` to choose its stream scope; unprefixed
filters apply to stdout::

    partner = Partner( command, ignore=r'^progress: ' )
    partner.ignore.append( r'stderr:^warning: transient ' )
    partner.ignore = [ r'all:^debug: ', r'stdout:^progress: ' ]
    partner.ignore.clear()
    
Matching decoded lines are omitted from replies and errors, but are retained in
`transcript` as `stdout-ignored` or `stderr-ignored` events.  The `stdout` and
`stderr` properties include ignored lines by default.

Use `History()` for narrower views::

    partner.History( 'stdout', ignored=False )  # non-ignored stdout lines
    partner.History( 'stdout', ignored=True )   # ignored stdout lines
    partner.History( 'stdout-ignored' )         # exact event-type filter

An ignored line does not count as a reply or an error, but if a multi-line reply
or error is already being collected, it resets the `interLineTimeout` clock.

Text and bytes
--------------

Native strings are encoded using the configurable `encoding` and receive the
configurable `terminator` (default `\n`) unless already terminated.  On Python 3,
explicit `bytes` input is written exactly as supplied, without encoding or an
added terminator.

Protocol boundaries
-------------------

LineDance deliberately assumes a request/reply protocol.  The child must flush
its output and terminate reply lines with `\n`.  A command that remains alive but
produces no output has no observable reply boundary and therefore waits until its
timeout, if any.  A timeout leaves the exchange desynchronized, so the `Partner`
refuses subsequent requests rather than risk attributing a late reply to the
wrong request.

Unsolicited output is retained but is not mistaken for a reply if it arrived
before the request.  Protocols with prompts lacking line terminators, request IDs,
or explicit completion sentinels need a protocol-specific adapter.

LineDance is public-domain software released under CC0.
