| 527 | |
| 528 | |
| 529 | class _Option(object): |
| 530 | # This class could almost be made generic, but the way the types |
| 531 | # interact with the multiple argument makes this tricky. (default |
| 532 | # and the callback use List[T], but type is still Type[T]). |
| 533 | UNSET = object() |
| 534 | |
| 535 | def __init__( |
| 536 | self, |
| 537 | name: str, |
| 538 | default: Any = None, |
| 539 | type: Optional[type] = None, |
| 540 | help: Optional[str] = None, |
| 541 | metavar: Optional[str] = None, |
| 542 | multiple: bool = False, |
| 543 | file_name: Optional[str] = None, |
| 544 | group_name: Optional[str] = None, |
| 545 | callback: Optional[Callable[[Any], None]] = None, |
| 546 | ) -> None: |
| 547 | if default is None and multiple: |
| 548 | default = [] |
| 549 | self.name = name |
| 550 | if type is None: |
| 551 | raise ValueError("type must not be None") |
| 552 | self.type = type |
| 553 | self.help = help |
| 554 | self.metavar = metavar |
| 555 | self.multiple = multiple |
| 556 | self.file_name = file_name |
| 557 | self.group_name = group_name |
| 558 | self.callback = callback |
| 559 | self.default = default |
| 560 | self._value = _Option.UNSET # type: Any |
| 561 | |
| 562 | def value(self) -> Any: |
| 563 | return self.default if self._value is _Option.UNSET else self._value |
| 564 | |
| 565 | def parse(self, value: str) -> Any: |
| 566 | _parse = { |
| 567 | datetime.datetime: self._parse_datetime, |
| 568 | datetime.timedelta: self._parse_timedelta, |
| 569 | bool: self._parse_bool, |
| 570 | basestring_type: self._parse_string, |
| 571 | }.get( |
| 572 | self.type, self.type |
| 573 | ) # type: Callable[[str], Any] |
| 574 | if self.multiple: |
| 575 | self._value = [] |
| 576 | for part in value.split(","): |
| 577 | if issubclass(self.type, numbers.Integral): |
| 578 | # allow ranges of the form X:Y (inclusive at both ends) |
| 579 | lo_str, _, hi_str = part.partition(":") |
| 580 | lo = _parse(lo_str) |
| 581 | hi = _parse(hi_str) if hi_str else lo |
| 582 | self._value.extend(range(lo, hi + 1)) |
| 583 | else: |
| 584 | self._value.append(_parse(part)) |
| 585 | else: |
| 586 | self._value = _parse(value) |