|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +# you may not use this file except in compliance with the License. |
| 5 | +# You may obtain a copy of the License at |
| 6 | +# |
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +# |
| 9 | +# Unless required by applicable law or agreed to in writing, software |
| 10 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +# See the License for the specific language governing permissions and |
| 13 | +# limitations under the License. |
| 14 | + |
| 15 | +# SPDX-FileCopyrightText: 2024 Dmitriy Kovalev |
| 16 | + |
| 17 | +# SPDX-License-Identifier: Apache-2.0 |
| 18 | + |
| 19 | +# https://gist.github.com/dmitriykovalev/2ab1aa33a8099ef2d514925d84aa89e7 |
| 20 | + |
| 21 | +from argparse import Action |
| 22 | +from argparse import ArgumentError |
| 23 | +from operator import gt |
| 24 | +from operator import ge |
| 25 | +from operator import lt |
| 26 | +from operator import le |
| 27 | + |
| 28 | + |
| 29 | +class CheckRange(Action): |
| 30 | + ops = {'inf': gt, |
| 31 | + 'min': ge, |
| 32 | + 'sup': lt, |
| 33 | + 'max': le} |
| 34 | + |
| 35 | + def __init__(self, *args, **kwargs): |
| 36 | + if 'min' in kwargs and 'inf' in kwargs: |
| 37 | + raise ValueError('either min or inf, but not both') |
| 38 | + if 'max' in kwargs and 'sup' in kwargs: |
| 39 | + raise ValueError('either max or sup, but not both') |
| 40 | + |
| 41 | + for name in self.ops: |
| 42 | + if name in kwargs: |
| 43 | + setattr(self, name, kwargs.pop(name)) |
| 44 | + |
| 45 | + super().__init__(*args, **kwargs) |
| 46 | + |
| 47 | + def interval(self): |
| 48 | + if hasattr(self, 'min'): |
| 49 | + l = f'[{self.min}' |
| 50 | + elif hasattr(self, 'inf'): |
| 51 | + l = f'({self.inf}' |
| 52 | + else: |
| 53 | + l = '(-infinity' |
| 54 | + |
| 55 | + if hasattr(self, 'max'): |
| 56 | + u = f'{self.max}]' |
| 57 | + elif hasattr(self, 'sup'): |
| 58 | + u = f'{self.sup})' |
| 59 | + else: |
| 60 | + u = '+infinity)' |
| 61 | + |
| 62 | + return f'valid range: {l}, {u}' |
| 63 | + |
| 64 | + def __call__(self, parser, namespace, values, option_string=None): |
| 65 | + for name, op in self.ops.items(): |
| 66 | + if hasattr(self, name) and not op(values, getattr(self, name)): |
| 67 | + raise ArgumentError(self, self.interval()) |
| 68 | + setattr(namespace, self.dest, values) |
0 commit comments