swansonk14 / typed-argument-parser

Typed argument parser for Python
MIT License
497 stars 40 forks source link

Design Proposal: Separate parser from argument data #78

Open kavinvin opened 2 years ago

kavinvin commented 2 years ago

Currently, parser class and the namespace object are the same type and object.

from tap import Tap

class SimpleArgumentParser(Tap):
    name: str
    language: str = 'Python' 

args: SimpleArgumentParser = SimpleArgumentParser().parse_args()

There're disadvantages doing this:

  1. Types are less intuitive.

SimpleArgumentParser().name will pass mypy checks, but will definitely throw error since argument is not there yet. Meanwhile, in args = SimpleArgumentParser().parse_args(), args will still have irrelevant types information about the parser.

  1. When trying to nest the subparser inside the main parser (#69), it make less sense for an unused subparser to be an accessible data. It will be harder to manipulate when methods mixed with data in the future.

Instead, we can have something like:

import tap

@dataclass
class SimpleArgument:
    name: str
    language: str = 'Python' 

args = tap.parse_args(SimpleArgument)

This is an improvement because:

  1. SimpleArgument is just a built-in dataclass which can be instantiated normally, getting free hash and equal, free structural pattern matching, and can be tested like normal data.
  2. Cleaner types interface.
  3. Nested data types are natural.

An example of subparser:

import tap
from tap import Parser

@dataclass
class Foo:
    foo: str

@dataclass
class Bar:
    bar: str

@dataclass
class SimpleArgument:
    name: str
    language: str = 'Python'
    command: Parser[Foo | Bar]

args = tap.parse_args(SimpleArgument)
martinjm97 commented 2 years ago

Hi @kavinvin,

Since making Tap, we've been hoping to find a way to separate the Namespace and ArgumentParser without making typing extremely unpleasant. We couldn't figure out a way to do it. This seems like a totally sensible proposal. We have to think more about this one, but we'll add it to our options in the design doc and update you with our thoughts.

Thanks again, Kyle and Jesse