namespace/dictionary quandry

Jack Carter jcarter at johmar.engr.sgi.com
Mon Sep 20 14:21:40 EDT 2004


Peter,

I guess I just don't understand.

Basically this is to go into a tool that accepts
commandline arguments, one at a time, but will also
allow scripting for testing purposes. Thus the desire
to leverage off python for the commandline interface,
but not for the whole program.

The input from the user will be either from the console or
read from a command file. A simple example of what could
be entered is:

bosco=5
if 1:
  print bosco
  attach bosco 9
  bosco=7
  print bosco
  attach bosco 9

The result I would expect would be for my DoAttach()
routine to receive the python evaluated value of each
of the arguments leaving the ones that it doesn't understand
alone. Whether this happens automagically or by hand I don't
care as long as I get what right value.

In the above trying to follow your advice, remembering that
at this stage of the game I am probably missing the point, this
is the result I expect:

johmar % demo.py
>>> bosco=5
>>> if 1:
...   print bosco
...   attach bosco 9
...   bosco=7
...   print bosco
...   attach bosco 9
...
5
DoAttach: [5, 9]
7
DoAttach: [7, 9]

This is what I get:

johmar % demo.py
>>> bosco=5
>>> if 1:
...   print bosco
...   attach bosco 9
...   bosco=7
...   print bosco
...   attach bosco 9
...
5
DoAttach: ['bosco', '9']
7
DoAttach: ['bosco', '9']

Now I realize that this is probably due to the fact that
I have the lines:

                if white_spaces:
                    line = front_padding + "myparse." + function + "(" +
str(args) + ")"
                else :
                    line = "myparse." + function + "(" + str(args) + ")"

which put make the arguments strings, but that is because I don't
know how to appropriately pack the "line" for later parsing. Maybe
that is the crux of my problem. Remember, there will be many commands
for my tool and the arguments will be variable length and this code
will not know what variables the gentle use would use.

Here is the simplified code with hopefully the tabs expanded
base on your earlier input. Hopefully you'll see the obvious
error of my way and point it out.

Thanks ever so much,

Jack

**********************************
demo.py
**********************************
#!/usr/bin/env python

import myparse

cli = myparse.CLI(globals())
cli.interact()

**********************************
myparse.py
**********************************
import code
import re
import string
import sys

################################################################################
#
# DoAttach
#
# Dummy function that I will eventually use to do
# real stuff.
#
################################################################################
def DoAttach(args):

    print "DoAttach:", args
    pass


class CLI(code.InteractiveConsole):
    """Simple test of a Python interpreter augmented with custom commands."""

    commands = { \
        "attach" : "DoAttach"
        }

    def __init__(self, locals = None):

        # Call super-class initializer
        code.InteractiveConsole.__init__(self, locals, "<console>")

        # Compile regular expression for finding commmands
        self.regexp = re.compile('[a-z]*')


    ##################################################################
    #
    # interact
    #
    # This will read and process input lines from within
    # my main application as though on a python commandline.
    #
    ##################################################################
    def interact(self):

        # Set the primary and secondary prompts
        sys.ps1 = ">>> "
        sys.ps2 = "... "

        # Input Loop
        is_more = 0
        bosco = 0
        while 1:
            try :
                # Display the appropriate prompt
                if not sys.stdin.isatty():
                    prompt = ""
                elif is_more:
                    prompt = sys.ps2
                else:
                    prompt = sys.ps1

                # Read the next line of input
                #self.write("interact 1\n")
                line = self.raw_input(prompt)

                # TODO: add logging of input line here...

                # Process complete lines
                if 1:
                   line = self.process(line)

                # Push incomplete lines onto input stack
                if line or is_more:
                    is_more = self.push(line)

            # Handle CTRL-C
            except KeyboardInterrupt:
                self.write("\nKeyboardInterrupt\n")
                is_more = 0
                self.resetbuffer()

            # Handle CTRL-D
            except EOFError:
                self.write("\n")
                is_more = 0
                self.resetbuffer()
                raise SystemExit

    ##################################################################
    #
    # process
    #
    # This will determine if the input command is either
    # from my application's command language or a python
    # construct.
    #
    ##################################################################
    def process(parent, line):

        # Attempt to match line against our command regular expression

        temp_line = string.lstrip(line)
        len_1 = len(line)
        len_2 = len(temp_line)

        white_spaces = len_1-len_2
        if white_spaces:
            front_padding = line[0:white_spaces]

        match = parent.regexp.match(temp_line)
        if match is not None:

            #parent.write("process 1\n")
            # Extract the command and argument strings
            cmd_string = match.group()
            arg_string = string.lstrip(temp_line[match.end():])

            # Find the function for this command in the command dictionary
            function = parent.commands.get(cmd_string)

            if function is not None:

                # Split argument string into individual arguments
                args = string.split(arg_string)

                # Convert to Python function-call syntax for this command
                if white_spaces:
                    line = front_padding + "myparse." + function + "(" +
str(args) + ")"
                else :
                    line = "myparse." + function + "(" + str(args) + ")"

        # Return the line to be processed by Python
        return line




More information about the Python-list mailing list