Skip to content

Instantly share code, notes, and snippets.

@VigneshChennai
Created January 28, 2015 12:35
Show Gist options
  • Save VigneshChennai/a79e84df57505d88c5b9 to your computer and use it in GitHub Desktop.
Save VigneshChennai/a79e84df57505d88c5b9 to your computer and use it in GitHub Desktop.
A python argument parser
#!/usr/bin/env python
# This file is part of PyArgumentParser.
# PyArgumentParser is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# PyArgumentParser is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with PyArgumentParser. If not, see <http://www.gnu.org/licenses/>.
class ArgumentParserRules:
def __init__(self, with_arguments, without_arguments,
should_not_be_with={}, should_be_with={},
with_repetitions={}, mandatory=[]):
self.with_arguments = with_arguments
self.without_arguments = without_arguments
self.should_not_be_with = should_not_be_with
self.should_be_with = should_be_with
self.with_repetitions = with_repetitions
self.mandatory = mandatory
class ArgumentParserError(Exception):
pass
class ArgumentParser:
def __init__(self, rules, arguments):
self.rules = rules
self.arguments = arguments
def parse(self):
args = {}
i = 0
arg_len = len(self.arguments)
while i < arg_len:
if self.arguments[i] in self.rules.with_arguments:
try:
if self.arguments[i] in self.rules.with_repetitions:
try:
args[self.arguments[i]].append(self.arguments[i + 1])
except KeyError:
args[self.arguments[i]] = [(self.arguments[i + 1])]
else:
if self.arguments[i] in args:
raise ArgumentParserError("Option <%s> specified more than once." % self.arguments[i])
else:
args[self.arguments[i]] = self.arguments[i + 1]
i += 2
continue
except IndexError:
raise ArgumentParserError("Option <%s> requires an argument."
" but none specified." % self.arguments[i]) from None
elif self.arguments[i] in self.rules.without_arguments:
if self.arguments[i] in args:
raise ArgumentParserError("Option <%s> specified more than once." % self.arguments[i])
else:
args[self.arguments[i]] = None
else:
raise ArgumentParserError("Invalid Option <%s>." % self.arguments[i])
i += 1
for arg in args.keys():
try:
options = self.rules.should_not_be_with[arg]
except KeyError:
pass
else:
if isinstance(options, str):
options = [options]
for option in options:
if option in args:
raise ArgumentParserError("Option <%s> should not be used "
"along with <%s> options" % (arg, str(options)))
try:
options = self.rules.should_be_with[arg]
except KeyError:
pass
else:
if isinstance(options, str):
options = [options]
for option in options:
if option not in args:
raise ArgumentParserError("Option <%s> should be used along "
"with <%s> options" % (arg, str(options)))
for arg in self.rules.mandatory:
if isinstance(arg, str):
if arg not in args:
raise ArgumentParserError("Option <%s> should be specified." % arg)
else:
not_found = True
for opt in arg:
if opt in args:
not_found = False
break
if not_found:
raise ArgumentParserError("One of the options <%s> should be specified." % str(arg))
return args
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment