Fixed a few docstring/bracketized-line-continuation issues. (I know, I know...)
Porting Monzur's ea942dcfc8323dd046290636c6cca8a2e563f4c1 from monzum/affix-repo (beta branch) over here.
Merge remote branch 'monzum-affix/beta' into beta
Upped the restrictions for running the Repy NAT forwarder locally. I took some inspiration from repyportability's restrictions (per getresources()).
* Added NTP timestamping instead of plain getruntime(). Makes more sense when trying to (logically) sync logs between machines.
* More verbose logging. Required unless we make the servers (i.e. nodes for which we listen) generate more detailed debugging information.
Removed checking for the existence of a to-be-dylinked Affix. dylink does this automatically now (cf. Seattle tickets #1318, importing modules only once); also, the removed line would sometimes raise "dictionary changed size during iteration" (possibly an artifact of the for loop in the implementation of safe.SafeDict's __contains__ method).
* Sync up to Seattle's r7220 (use cachedadvertise/advertisepipe instead of AdvertiseObject, give more verbose errors, random.random_shuffle instead of random.random_sample)
* Make errors in constructing the stack, contacting the forwarder etc. raise exceptions instead of silently retrying or even falling back to non-NatPunch'ed operation. ``Explicit is better than implicit,''  and in our case implicity resulted in listening on the private IP address (and never getting incoming connections from the public Internet), and lots of DuplicateTupleErrors.
* Syncing up to Seattle's r7259 (no ``import traceback'' in Repy!) and r7338 (NAT_FORWARDER_KEY shouldn't be a list). Also, use cachedadvertise/advertisepipe instead of AdvertiseObject.
* Removed Affixes from the control connection to the forwarder. WARNING, this requires (small) additional changes to nat_forwarder.repy to also not use Affixes.
* Removed the reconnection logic when the forwarder connection breaks down. Retrying only gave us DuplicateTupleErrors (as we didn't change our source port!), and made it impossible to detect for our caller that we weren't listening using the old forwarder anymore.
* Raise lots of exceptions. Not all of them feel totally fitting, but the Repy network API only allows (and programmers consequently expect) only certain exceptions in certain situations. Staying silent is not an option however. We must inform our caller when things go very wrong.
* Replaced the retrieve_random_tcp_port logic by a loop that tries each available connport. See Seattle's r7150/7150 for the blueprint.

TODO: I left a few additional debug statements in the code. These aren't strictly required/interesting and should be removed before a production push.
Completing the previous commit. Also removed a few of the mentioned debug messages.
i* Synced with Seattle's r7319, typecast for RECV_BYTES.
* Removed Affix support on the control connection.
* Consequently changed callargs: You can now specify an override NAT_FORWARDER_KEY to announce (rather than an Affix stack). Handy for testing!
* Works with natpunchaffix@6f8608e3b12cf9fa28e93ee4c34225cd11c2f0e5.
Basic unit test using the static Affix string "(CoordinationAffix)(NatPunchAffix)", plus restrictions file. The test uses the actual advertise servers and NAT forwarders to listen for an incoming connection, and also connect to itself using the chosen forwarder. A test message is sent and checked for correct reception.
Factor out the actual connect-and-send-message test into a RepyV2API test (which it is!); the Affix test just transparently overrides the networking calls, and then imports said RepyV2API test.
This file was missing from my previous commit 3bdd73700964191ce5d983f8414afb2f1a7204db. This is the Affix-enabled unit test that redefines two network calls, then imports the SeattleLib test and runs it with Affixes in place.
Renaming currently relevant files to *.r2py, see Seattle's #1351. Also added file extensions to dylink imports, see Seattle's #1317.
Updated file extension of dylink import (see Seattle's #1351, #1317).
Unit test to verify that the NatPunchAffix raises an exception (rather than hangs) when the NAT forwarder drops the connection. PASSes with my NatPunchAffix of e7898e2cb3ebb7b4e978c92194b54d91f2075eeb.
Moving to .r2py, and also suffixing library names with the extension (now required by dylink).
Added small comments in natpunchaffix.repy
Carrying over changes from Monzur's 4dfb412b697807a2b9726a78ba018230fdc22ced.
Yet another file renamed.