1- #!/usr/bin/env python
2-
3- # Copyright (C) 2022-2023 NV Access Limited
1+ # Copyright (C) 2022-2025 NV Access Limited
42# This file may be used under the terms of the GNU General Public License, version 2 or later.
53# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
64
7- import os
8- import sys
9- from typing import (
10- Optional ,
11- TextIO ,
12- Tuple ,
13- )
14- from io import StringIO
5+ from io import StringIO , TextIOBase
6+ from typing import Any , cast
157
168from configobj import ConfigObj
179from configobj .validate import Validator , ValidateError
1810
19- sys .path .append (os .path .dirname (__file__ ))
20- # E402 module level import not at top of file
21- from majorMinorPatch import MajorMinorPatch # noqa:E402
22- del sys .path [- 1 ]
11+ from .majorMinorPatch import MajorMinorPatch
12+
13+ ApiVersionT = tuple [int , int , int ] # major, minor, patch
2314
2415
2516class AddonManifest (ConfigObj ):
2617 """From the NVDA addonHandler module. Should be kept in sync.
27- Add-on manifest file. It contains metadata about an NVDA add-on package. """
28- configspec = ConfigObj (StringIO (
29- """
18+ Add-on manifest file. It contains metadata about an NVDA add-on package."""
19+
20+ configspec = ConfigObj (
21+ StringIO (
22+ """
3023 # NVDA Add-on Manifest configuration specification
3124 # Add-on unique name
3225 # Suggested convention is lowerCamelCase.
@@ -69,29 +62,32 @@ class AddonManifest(ConfigObj):
6962 # "0.0.0" is also valid.
7063 # The final integer can be left out, and in that case will default to 0. E.g. 2019.1
7164
65+ """ ,
66+ ),
67+ )
68+
69+ def __init__ (self , input : str | TextIOBase , translatedInput : str | None = None ):
7270 """
73- ))
71+ Constructs an :class:`AddonManifest` instance from manifest string data.
7472
75- def __init__ (self , input : TextIO , translatedInput : Optional [TextIO ] = None ):
76- """ Constructs an L{AddonManifest} instance from manifest string data
77- @param input: data to read the manifest information
78- @param translatedInput: translated manifest input
73+ :param input: data to read the manifest information. Can be a filename or a file-like object.
74+ :param translatedInput: translated manifest input
7975 """
80- super ().__init__ (
76+ super ().__init__ ( # type: ignore[reportUnknownMemberType]
8177 input ,
8278 configspec = self .configspec ,
83- encoding = ' utf-8' ,
84- default_encoding = ' utf-8' ,
79+ encoding = " utf-8" ,
80+ default_encoding = " utf-8" ,
8581 )
86- self ._errors : Optional [ str ] = None
87- val = Validator ({"apiVersion" : validate_apiVersionString })
88- result = self .validate (val , copy = True , preserve_errors = True )
82+ self ._errors : str | None = None
83+ validator = Validator ({"apiVersion" : validate_apiVersionString })
84+ result = self .validate (validator , copy = True , preserve_errors = True ) # type: ignore[reportUnknownMemberType]
8985 if result is not True :
9086 self ._errors = result
9187 elif self ._validateApiVersionRange () is not True :
9288 self ._errors = "Constraint not met: minimumNVDAVersion ({}) <= lastTestedNVDAVersion ({})" .format (
93- self .get ("minimumNVDAVersion" ),
94- self .get ("lastTestedNVDAVersion" )
89+ cast ( ApiVersionT , self .get ("minimumNVDAVersion" )), # type: ignore[reportUnknownMemberType]
90+ cast ( ApiVersionT , self .get ("lastTestedNVDAVersion" )), # type: ignore[reportUnknownMemberType]
9591 )
9692 self ._translatedConfig = None
9793 if translatedInput is not None :
@@ -102,23 +98,23 @@ def __init__(self, input: TextIO, translatedInput: Optional[TextIO] = None):
10298 self [key ] = val
10399
104100 @property
105- def errors (self ) -> str :
101+ def errors (self ) -> str | None :
106102 return self ._errors
107103
108104 def _validateApiVersionRange (self ) -> bool :
109- lastTested = self .get ("lastTestedNVDAVersion" )
110- minRequiredVersion = self .get ("minimumNVDAVersion" )
105+ lastTested = cast ( ApiVersionT , self .get ("lastTestedNVDAVersion" )) # type: ignore[reportUnknownMemberType]
106+ minRequiredVersion = cast ( ApiVersionT , self .get ("minimumNVDAVersion" )) # type: ignore[reportUnknownMemberType]
111107 return minRequiredVersion <= lastTested
112108
113109
114- def validate_apiVersionString (value : str ) -> Tuple [ int , int , int ] :
110+ def validate_apiVersionString (value : str | Any ) -> ApiVersionT :
115111 """From the NVDA addonHandler module. Should be kept in sync."""
116112 if not value or value == "None" :
117113 return (0 , 0 , 0 )
118114 if not isinstance (value , str ):
119115 raise ValidateError (
120116 "Expected an apiVersion in the form of a string. "
121- f"e.g. '2019.1.0' instead of { value } (type { type (value )} )"
117+ f"e.g. '2019.1.0' instead of { value } (type { type (value )} )" ,
122118 )
123119 try :
124120 versionParsed = MajorMinorPatch .getFromStr (value )
0 commit comments