Documentation for (built-in) Python support

EPIC supports bi-directional support with Python.
1. EPIC calling to Python
2. Python calling to EPIC
3. Python foundation script for calling to EPIC


1. EPIC calling to Python
==========================
a. Executing a Python Statement
	/PYTHON { <python code> }
   The <python code> is passed to PyRun_SimpleString()
   The <python code> must not be an expression!

b. Executing a Python Expression
	$python(<python code>)
   The <python code> is passed to PyRun_String()
   The return code of <python code> Is repr()d as UTF-8 string

c. Calling a Python function (Low level)
	$pydirect(module.method arguments)
	/PYDIRECT module.method arguments
   The module.method function is called with a single string argument "arguments"
   The module.method function is passed to PyObject_CallObject().
   If called as $pydirect()...
      ... The return value of module.method is repr()d as a UTF-8 String.


2. Python calling to EPIC
=========================
First,
    /python import _epic
Then, you can use any of these python functions:

---- NOTE ---- 
    All of these functions will throw an exception if you don't pass in the required params 
---- NOTE ---- 

(Higher level ircII interfaces)
    _epic.echo(string)
	Argument: 	string -- text to be output to the epic window, literally
	What it does:	yell(string) -- which is an /echo.  Not suppressed by ^

    _epic.say(string)
	Argument:	string -- text to be output to theh epic window preceded by $BANNER
	What it does:	say(string) -- output stuff like builtin features.  Suppressed by ^

    _epic.cmd(string)
	Argument:	string -- ircII code to be run without $-expansion
	What it does:	runcmds("$*", string) -- like typing at the input line

    _epic.eval(string)
	Argument:	string - ircII code to be run with $-expansion
	What it does:	runcmds(string, "") -- like running an alias ($* is "")

    _epic.expr(string)
	Argument:	string - an ircII expression to be evaluated with $-expansion
	What it does:	parse_inline(string, "") -- evaluating an expression ($* is "")
	Return val:	a utf8-encoded string (even if the result is a number -- everything in ircII is a string)

    _epic.call(string, string)
	Arguments:	string -- the name of a function (either an alias or a builtin) to be called directly
			string -- the arguments to pass to the function -- will be $-expanded ($* is "")
	Return val:	A utf8-encoded string (even if the result is a number -- everything in ircII is a string)

    _epic.expand(string)
	Argument:	string -- a string to be expanded with $-expansion
	Internal Op:	expand_alias -- ($* is "")
        Return val:	A utf8-encoded string

(Lower level direct interfaces)
    _epic.run_command(string, string)
	Argument:	string -- The name of an alias or builtin command
			string -- The argument list to pass to the command, with no $-expansion
	Internal Op:	Directly call the alias (preferentially) or builtin command with the literal argument list.
			You must pass in a single space-separated string as the argument list.
	Return val:	The None object
	Exception:	NameError - If the name of the command is not found

    _epic.call_function(string, string)
	Argument:	string -- The name of an alias or builtin function
			string -- The argument list to pass to the function, with no $-expansion
	Internal Op:	Directly call the alias (preferentially) or builtin function with the literal argument list.
			You must pass in a single space-separated string as the argument list.
	Return val:	A utf8-encoded string of the return value of the function (even if the result is a number)
	Exception:	NameError - If the name of the function is not found

    _epic.get_set(string)
	Argument:	string -- The name of a /SET
	Internal Op:	Return the value of a /SET variable
	Return val:	A utf8-encoded string
	Exception:	NameError - If the name of the /SET is not found

    _epic.get_assign(string)
	Argument:	string -- The name of an /ASSIGN
	Internal Op:	Return the value of a /ASSIGN variable
	Return val:	A utf8-encoded string
	Exception:	NameError - If the name of the /ASSIGN is not found

    _epic.get_var(string)
	Argument:	string -- The name of simple $-expando (ie, to get the value of $foo, pass in 'foo')
	Internal Op:	Return the value of a variable (either an assign, set, or inline expando)
	Return val:	A utf8-encoded string
	Exception:	No -- if name is not found, you get zero-length string back.

    _epic.set_set(string, string)
	Argument:	string - The name of a /SET (must exist)
			string - The new value to give the /SET
	Internal Op:	Nothing - just a stub for now - does not do anything
	Exception:	NotImplementedError (for now)

    _epic.set_assign(string, string)
	Argument:	string - The name of an /ASSIGN (does not need to exist)
			string - The new value to give the /ASSIGN
	Internal Op:	Nothing - just a stub for now - does not do anything
	Exception:	NotImplementedError (for now)

   _epic.builtin_command(string)
	Argument:	string - The name of a python "module.method".
	Internal Op:	/MODULE.METHOD becomes a builtin command that calls python
	Return Val:	The None object

(Low-level IO operations -- I haven't implemented these yet.)
    _epic.callback_when_readable(int, CallableObject, CallableObject, int)
	Argument:	int - a file descriptor to watch
			CallableObject - A python method that takes one integer argument.
					 It will be called each time the fd is readable
					 You must "handle" the fd, or it will busy-loop.
					 If you block while handling the fd, epic will block
			CallableObject - A python method that takes one integer argument.
					 It will be called if the fd is found to be invalid.
					 (ie, select(2) returns EBADF).  This would be 
					 caused by something close()ing the fd, but 
					 _epic.cancel_callback() [see below] didn't get called.
			int - Flags -- None have been defined yet; pass in a 0.
	Internal Op:	Cause Python to be called when a read from an fd would not block
			listen() sockets are readable when someone connects to them.
			sockets are readable when they have an error
			files are readable until you reach EOF.

    _epic.callback_when_writable(int, CallableObject, CallableObject, int)
	Argument:	int - a file descriptor to watch
			CallableObject - A python method that takes one integer argument.
					 It will be called each time the fd is writable.
					 You must "handle" the fd, or it will busy-loop.
					 This is a particular risk with writable callbacks.
					 (most sockets are writable at all times, unless 
					 their buffers are saturated).  If you block while
					 handling the fd, epic will block.
			CallableObject - A python method that takes one integer argument.
					 It will be called if the fd is found to be invalid.
					 (ie, select(2) returns EBADF).  This would be 
					 caused by something close()ing the fd, but 
					 _epic.cancel_callback() [see below] didn't get called.
			int - Flags -- None have been defined yet; pass in a 0.
	Internal Op:	Cause Python to be called when a write to an fd would not block
			nonblocking connect()s are writable when the connection completes

    _epic.cancel_callback(int)
	Argument:	int - a file descriptor to watch
	Internal Op:	Cancel any callbacks registered with the file descriptor.
			Call this when you close a fd, or you'll be sorry!

3. Python foundation script for calling to EPIC
==================================================
TBD with skully


