trouble with cmd.Cmd and prompting
Cameron Simpson
cs at zip.com.au
Mon Jan 2 19:33:15 EST 2017
I'm using cmd.Cmd to write a little FTP-like command line to interface to a
storage system of mine and encountering weird behaviour. When I enter a command
the next prompt appears _before_ the associated operation runs, or so it
appears.
Look at this:
[~/hg/css-venti(hg:venti)]fleet*> dev ./bin/vt -M -C - -S '[archive]' ftp ~/var/mnt/archive.vt
stores = [<cs.venti.store.DataDirStore object at 0x10a564a90>]
S = Store(MappingStore(ConfigWatcher('/Users/cameron/.vtrc')[archive]))
~/var/mnt/archive.vt:/> ls
~/var/mnt/archive.vt:/> precmd: line='ls'
---------- OnyX.dmg
postcmd: stop=None, line='ls'
See how the cmd.Cmd prompt "~/var/mnt/archive.vt:/> " appears again right after
the "ls", and before its output:
precmd: line='ls'
---------- OnyX.dmg
postcmd: stop=None, line='ls'
The precmd and postcmd lines are debugging, emitted from my precmd and postcmd
methods in the subclass.
Has anyone seen this kind of thing before?
The salient parts of my class are shown below. It's not complete and I'm happy
to post the full thing if people need to see it. The behaviour is the same
regardless of the command; even an empty command shows it:
~/var/mnt/archive.vt:/> precmd: line=''
postcmd: stop=None, line=''
~/var/mnt/archive.vt:/> precmd: line=''
postcmd: stop=None, line=''
Any insights or suggestions welcome. Code below.
Cheers,
Cameron Simpson <cs at zip.com.au>
from cmd import Cmd
import readline
class FTP(Cmd):
def __init__(self, D, sep=None, FS=None, prompt=None):
Cmd.__init__(self)
self._prompt = prompt
if sep is None:
sep = '/' # NB: _not_ os.sep
self.root = D
self.cwd = D
self.sep = sep
self.fs = FS
self._set_prompt()
def _set_prompt(self):
prompt = self._prompt
pwd = '/' + self.op_pwd()
self.prompt = ( pwd if prompt is None else ":".join( (prompt, pwd) ) ) + '> '
def precmd(self, line):
X("precmd: line=%r", line)
return line
def postcmd(self, stop, line):
X("postcmd: stop=%s, line=%r", stop, line)
self._set_prompt()
return stop
def emptyline(self):
pass
def do_EOF(self, args):
''' Quit on end of input.
'''
return True
def do_quit(self, args):
''' Usage: quit
'''
return True
def do_ls(self, args):
''' Usage: ls [paths...]
'''
argv = shlex.split(args)
if not argv:
argv = sorted(self.cwd.entries.keys())
for name in argv:
with Pfx(name):
E, P, tail = resolve(self.cwd, name)
if tail:
error("not found: unresolved path elements: %r", tail)
else:
M = E.meta
S = M.stat()
u, g, perms = M.unix_perms
typemode = M.unix_typemode
typechar = ( '-' if typemode == stat.S_IFREG
else 'd' if typemode == stat.S_IFDIR
else 's' if typemode == stat.S_IFLNK
else '?'
)
print("%s%s%s%s %s" % ( typechar,
rwx((typemode>>6)&7),
rwx((typemode>>3)&7),
rwx((typemode)&7),
name
))
More information about the Python-list
mailing list