Skip to content

Design Proposal: Separate parser from argument data #78

Open
@kavinvin

Description

@kavinvin

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 (Subparsers are not typed. #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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions