Problem argparse positional argument, das mit '-' beginnt
Verfasst: Freitag 21. September 2012, 10:16
Hallo,
das folgende simple Beispiel funktioniert, sofern das positional argument als Zahl interpretiert werden kann:
Wenn ich die Doku richtig verstehe, ist das ein Problem mit der Magie...
Alle folgenden Argumente werden also schlichtweg dem positional argument untergeschoben. Auch nicht das, was ich möchte. Zudem behagt mir das Manipulieren an der 'sys.argv' auch nicht wirklich...
Vorläufig habe ich die Sache so gelöst:
Was mir daran nicht gefällt ist, dass ich quasi außerhalb von argparse die Gültigkeit eines Argumentes prüfen muss, sprich: Wenn es sich bei positional arguments z. B. um Datumsargumente handelt *grins*, dann werden nicht nur die vom Nutzer auch so gemeinten Argumente sondern auch alle ungültigen Argumente an einen Datumsparser weitergereicht. Dort muss also erstmal entschieden werden, ob es sich um ungültige Datumsargumente oder um grundsätzlich ungültige Argumente handelt. IMHO fast nicht möglich. Die Fehlermeldung müsste also lauten:
Was meint ihr?
mutetella
das folgende simple Beispiel funktioniert, sofern das positional argument als Zahl interpretiert werden kann:
Code: Alles auswählen
#!/usr/bin/python
import argparse
def action(values):
return values
class MyAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, action(values))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('positional', nargs='*', action=MyAction)
parser.add_argument('-f', '--foo', action='store_true')
print parser.parse_args()
Code: Alles auswählen
$ test +3
Namespace(positional=['+3'], foo=False)
$ test -1.3
Namespace(positional=['-1.3'], foo=False)
$ test +3.b
Namespace(positional=['+3.b'], foo=False)
$ test -3.b
usage: test [-h] [-f] [positional [positional ...]]
test: error: unrecognized arguments: -3.b
Zur Umgehung des beschriebenen Verhaltens liefert die Doku folgendes:Python Doku hat geschrieben:The parse_args() method attempts to give errors whenever the user has clearly made a mistake, but some situations are inherently ambiguous. For example, the command-line argument -1 could either be an attempt to specify an option or an attempt to provide a positional argument. The parse_args() method is cautious here: positional arguments may only begin with - if they look like negative numbers and there are no options in the parser that look like negative numbers.
Wenn ich mein kleines Beispiel allerdings dahingehend ändere, geschieht folgendes:Python Doku hat geschrieben:If you have positional arguments that must begin with - and don’t look like negative numbers, you can insert the pseudo-argument '--' which tells parse_args() that everything after that is a positional argument.
Code: Alles auswählen
#!/usr/bin/python
import argparse
import sys
...
...
if __name__ == '__main__':
sys.argv.insert(1, '--')
...
...
Code: Alles auswählen
$ test -3.b -f
Namespace(foo=False, positional=['-3.b', '-f'])
Vorläufig habe ich die Sache so gelöst:
Code: Alles auswählen
#!/usr/bin/python
import argparse
def action(values):
return values
class MyAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, action(values))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('positional', nargs='*', action=MyAction)
parser.add_argument('-f', '--foo', action='store_true')
known, unknown = parser.parse_known_args()
if unknown:
known.positional = action(unknown)
print known
Code: Alles auswählen
$ test -3.b -f
Namespace(foo=True, positional=['-3.b'])
Code: Alles auswählen
UnknownError: Wenn ich gekonnt hätte, hätte ich ein Datum gebildet.
Konnte ich aber nicht, vielleicht wollten Sie ja etwas ganz anderes?
Aber das konnte ich auch nicht.

Was meint ihr?
mutetella