2121import logging
2222import os
2323import os .path
24+ import typing as ty
2425from abc import ABC , abstractmethod
2526from configparser import DEFAULTSECT , ConfigParser , ParsingError
26- from typing import Any , AnyStr , Dict , List , Optional , Tuple , Union
2727
2828from platformdirs import user_config_dir
2929from scenedetect .frame_timecode import FrameTimecode
3030
3131from dvr_scan .scanner import DEFAULT_FFMPEG_INPUT_ARGS , DEFAULT_FFMPEG_OUTPUT_ARGS
3232
3333# Backwards compatibility for config options that were renamed/replaced.
34- MIGRATED_CONFIG_OPTION : Dict [str , str ] = {
34+ MIGRATED_CONFIG_OPTION : ty . Dict [str , str ] = {
3535 "timecode" : "time-code" ,
3636 "timecode-margin" : "text-margin" ,
3737 "timecode-font-scale" : "text-font-scale" ,
4040 "timecode-bg-color" : "text-bg-color" ,
4141}
4242
43- DEPRECATED_CONFIG_OPTION : Dict [str , str ] = {
43+ DEPRECATED_CONFIG_OPTION : ty . Dict [str , str ] = {
4444 "region-of-interest" : "The region-of-interest config option is deprecated and may be removed. "
4545 "Use the load-region option instead, or specify -R/--load-region."
4646}
@@ -51,7 +51,7 @@ class ValidatedValue(ABC):
5151
5252 @property
5353 @abstractmethod
54- def value (self ) -> Any :
54+ def value (self ) -> ty . Any :
5555 """Get the value after validation."""
5656 raise NotImplementedError ()
5757
@@ -79,13 +79,13 @@ class TimecodeValue(ValidatedValue):
7979
8080 Stores value in original representation."""
8181
82- def __init__ (self , value : Union [int , float , str ]):
82+ def __init__ (self , value : ty . Union [int , float , str ]):
8383 # Ensure value is a valid timecode.
8484 FrameTimecode (timecode = value , fps = 100.0 )
8585 self ._value = value
8686
8787 @property
88- def value (self ) -> Union [int , float , str ]:
88+ def value (self ) -> ty . Union [int , float , str ]:
8989 return self ._value
9090
9191 def __repr__ (self ) -> str :
@@ -109,9 +109,9 @@ class RangeValue(ValidatedValue):
109109
110110 def __init__ (
111111 self ,
112- value : Union [int , float ],
113- min_val : Union [int , float ],
114- max_val : Union [int , float ],
112+ value : ty . Union [int , float ],
113+ min_val : ty . Union [int , float ],
114+ max_val : ty . Union [int , float ],
115115 ):
116116 if value < min_val or value > max_val :
117117 # min and max are inclusive.
@@ -121,16 +121,16 @@ def __init__(
121121 self ._max_val = max_val
122122
123123 @property
124- def value (self ) -> Union [int , float ]:
124+ def value (self ) -> ty . Union [int , float ]:
125125 return self ._value
126126
127127 @property
128- def min_val (self ) -> Union [int , float ]:
128+ def min_val (self ) -> ty . Union [int , float ]:
129129 """Minimum value of the range."""
130130 return self ._min_val
131131
132132 @property
133- def max_val (self ) -> Union [int , float ]:
133+ def max_val (self ) -> ty . Union [int , float ]:
134134 """Maximum value of the range."""
135135 return self ._max_val
136136
@@ -193,7 +193,7 @@ class RegionValueDeprecated(ValidatedValue):
193193 _IGNORE_CHARS = ["," , "/" , "(" , ")" ]
194194 """Characters to ignore."""
195195
196- def __init__ (self , value : Optional [str ] = None , allow_size : bool = False ):
196+ def __init__ (self , value : ty . Optional [str ] = None , allow_size : bool = False ):
197197 if value is not None :
198198 translation_table = str .maketrans (
199199 {char : " " for char in RegionValueDeprecated ._IGNORE_CHARS }
@@ -211,7 +211,7 @@ def __init__(self, value: Optional[str] = None, allow_size: bool = False):
211211 self ._value = None
212212
213213 @property
214- def value (self ) -> Optional [List [int ]]:
214+ def value (self ) -> ty . Optional [ty . List [int ]]:
215215 return self ._value
216216
217217 def __repr__ (self ) -> str :
@@ -244,7 +244,7 @@ class RGBValue(ValidatedValue):
244244 _IGNORE_CHARS = ["," , "/" , "(" , ")" ]
245245 """Characters to ignore."""
246246
247- def __init__ (self , value : Union [int , str , "RGBValue" ]):
247+ def __init__ (self , value : ty . Union [int , str , "RGBValue" ]):
248248 if isinstance (value , RGBValue ):
249249 return value
250250 # If not an int, convert to one.
@@ -281,7 +281,7 @@ def __init__(self, value: Union[int, str, "RGBValue"]):
281281 )
282282
283283 @property
284- def value (self ) -> Tuple [int , int , int ]:
284+ def value (self ) -> ty . Tuple [int , int , int ]:
285285 return self ._value
286286
287287 @property
@@ -305,13 +305,13 @@ def from_config(config_value: str, default: "RGBValue") -> "RGBValue":
305305 ) from ex
306306
307307
308- ConfigValue = Union [bool , int , float , str ]
309- ConfigDict = Dict [str , ConfigValue ]
308+ ConfigValue = ty . Union [bool , int , float , str ]
309+ ConfigDict = ty . Dict [str , ConfigValue ]
310310
311- _CONFIG_FILE_NAME : AnyStr = "dvr-scan.cfg"
312- _CONFIG_FILE_DIR : AnyStr = user_config_dir ("DVR-Scan" , False )
311+ _CONFIG_FILE_NAME : ty . AnyStr = "dvr-scan.cfg"
312+ _CONFIG_FILE_DIR : ty . AnyStr = user_config_dir ("DVR-Scan" , False )
313313
314- USER_CONFIG_FILE_PATH : AnyStr = os .path .join (_CONFIG_FILE_DIR , _CONFIG_FILE_NAME )
314+ USER_CONFIG_FILE_PATH : ty . AnyStr = os .path .join (_CONFIG_FILE_DIR , _CONFIG_FILE_NAME )
315315
316316# TODO: Investigate if centralizing user help strings here would be useful.
317317# It might make CLI help and documentation are easier to create, as well as
@@ -382,7 +382,7 @@ def from_config(config_value: str, default: "RGBValue") -> "RGBValue":
382382The types of these values are used when decoding the configuration file. Valid choices for
383383certain string options are stored in `CHOICE_MAP`."""
384384
385- CHOICE_MAP : Dict [str , List [str ]] = {
385+ CHOICE_MAP : ty . Dict [str , ty . List [str ]] = {
386386 "input-mode" : ["opencv" , "pyav" , "moviepy" ],
387387 "opencv-codec" : ["XVID" , "MP4V" , "MP42" , "H264" ],
388388 "output-mode" : ["scan_only" , "opencv" , "copy" , "ffmpeg" ],
@@ -398,7 +398,7 @@ def from_config(config_value: str, default: "RGBValue") -> "RGBValue":
398398class ConfigLoadFailure (Exception ):
399399 """Raised when a user-specified configuration file fails to be loaded or validated."""
400400
401- def __init__ (self , init_log : Tuple [int , str ], reason : Optional [Exception ] = None ):
401+ def __init__ (self , init_log : ty . Tuple [int , str ], reason : ty . Optional [Exception ] = None ):
402402 super ().__init__ ()
403403 self .init_log = init_log
404404 self .reason = reason
@@ -409,7 +409,7 @@ class ConfigRegistry:
409409 default values specified in the global CONFIG_MAP."""
410410
411411 def __init__ (self ):
412- self ._init_log : List [Tuple [int , str ]] = []
412+ self ._init_log : ty . List [ty . Tuple [int , str ]] = []
413413 self ._config : ConfigDict = {}
414414
415415 @property
@@ -482,7 +482,7 @@ def _migrate_deprecated(self, config: ConfigParser):
482482
483483 def _parse_config (
484484 self , config : ConfigParser
485- ) -> Tuple [Optional [ConfigDict ], List [Tuple [int , str ]]]:
485+ ) -> ty . Tuple [ty . Optional [ConfigDict ], ty . List [ty . Tuple [int , str ]]]:
486486 """Process the given configuration into a key-value mapping.
487487
488488 Returns:
@@ -568,7 +568,7 @@ def is_default(self, option: str) -> bool:
568568 def get (
569569 self ,
570570 option : str ,
571- override : Optional [ConfigValue ] = None ,
571+ override : ty . Optional [ConfigValue ] = None ,
572572 ignore_default : bool = False ,
573573 ) -> ConfigValue :
574574 """Get the current setting or default value of the specified option."""
@@ -585,7 +585,7 @@ def get(
585585 return value .value # Extract validated value.
586586 return value
587587
588- def get_help_string (self , option : str , show_default : Optional [bool ] = None ) -> str :
588+ def get_help_string (self , option : str , show_default : ty . Optional [bool ] = None ) -> str :
589589 """Get string for help text including the option's value, if set, otherwise the default.
590590
591591 Arguments:
0 commit comments