8000 Add mypy.ini and type annotations · robotframework/robotframework@a023b88 · GitHub
[go: up one dir, main page]

Skip to content

Commit a023b88

Browse files
committed
Add mypy.ini and type annotations
1 parent 9f779cf commit a023b88

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+382
-276
lines changed

mypy.ini

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[mypy]
2+
allow_redefinition = True
3+
show_error_codes = True
4+
strict_equality = True
5+
warn_redundant_casts = True
6+
warn_unused_ignores = True

src/robot/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# Allows running as a script. __name__ check needed with multiprocessing:
2121
# https://github.com/robotframework/robotframework/issues/1137
2222
if 'robot' not in sys.modules and __name__ == '__main__':
23-
import pythonpathsetter
23+
import pythonpathsetter # type: ignore[import]
2424

2525
from robot import run_cli
2626

src/robot/api/deco.py

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,21 @@
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
1515

16+
from __future__ import annotations
17+
1618
import inspect
1719

20+
from typing import TYPE_CHECKING, overload, cast, Any
21+
22+
if TYPE_CHECKING:
23+
try:
24+
from typing import Callable, Literal, TypeVar
25+
except ImportError:
26+
from typing_extensions import Literal # type: ignore[misc]
27+
Fn = TypeVar("Fn", bound=Callable[..., Any])
28+
Cls = TypeVar("Cls", bound=type)
1829

19-
def not_keyword(func):
30+
def not_keyword(func: Fn) -> Fn:
2031
"""Decorator to disable exposing functions or methods as keywords.
2132
2233
Examples::
@@ -34,15 +45,20 @@ def exposed_as_keyword():
3445
3546
New in Robot Framework 3.2.
3647
"""
37-
func.robot_not_keyword = True
48+
func.robot_not_keyword = True# type: ignore[attr-defined]
3849
return func
3950

4051

41-
not_keyword.robot_not_keyword = True
52+
not_keyword.robot_not_keyword = True # type: ignore[attr-defined]
4253

54+
@overload
55+
def keyword(name: Fn) -> Fn: ...
56+
57+
@overload
58+
def keyword(name: str = None, tags: list[str] = ..., types: dict[str, type] | list[type] | None = ...) -> Callable[[Fn], Fn]: ...
4359

4460
@not_keyword
45-
def keyword(name=None, tags=(), types=()):
61+
def keyword(name: Fn | str | None = None, tags: list[str] | tuple[None, ...] = (), types: dict[str, type] | list[type] | tuple[None, ...] | None =()) -> Callable[[Fn], Fn] | Fn:
4662
"""Decorator to set custom name, tags and argument types to keywords.
4763
4864
This decorator creates ``robot_name``, ``robot_tags`` and ``robot_types``
@@ -85,20 +101,26 @@ def no_conversion(length, case_insensitive=False):
85101
# ...
86102
"""
87103
if inspect.isroutine(name):
88-
return keyword()(name)
104+
return keyword()(cast(Callable, name))
89105

90-
def decorator(func):
91-
func.robot_name = name
92-
func.robot_tags = tags
93-
func.robot_types = types
106+
def decorator(func: Fn) -> Fn:
107+
func.robot_name = name# type:ignore[attr-defined]
108+
func.robot_tags = tags# type:ignore[attr-defined]
109+
func.robot_types = types# type:ignore[attr-defined]
94110
return func
95111

96112
return decorator
97113

114+
@overload
115+
def library(scope: Cls) -> Cls: ...
116+
117+
@overload
118+
def library(scope: Literal["GLOBAL", "SUITE", "TEST", None] = None, version: str =None, doc_format: str =None, listener: str=None,
119+
auto_keywords: bool=False) -> Callable[[Cls], Cls]: ...
98120

99121
@not_keyword
100-
def library(scope=None, version=None, doc_format=None, listener=None,
101-
auto_keywords=False):
122+
def library(scope: Literal["GLOBAL", "SUITE", "TEST", None] | Cls = None, version: str =None, doc_format: str =None, listener: str=None,
123+
auto_keywords: bool=False) -> Cls | Callable[[Cls], Cls]:
102124
"""Class decorator to control keyword discovery and other library settings.
103125
104126
By default disables automatic keyword detection by setting class attribute
@@ -134,18 +156,18 @@ class LibraryConfiguration:
134156
The ``@library`` decorator is new in Robot Framework 3.2.
135157
"""
136158
if inspect.isclass(scope):
137-
return library()(scope)
159+
return library()(cast(type, scope))
138160

139-
def decorator(cls):
161+
def decorator(cls: Cls) -> Cls:
140162
if scope is not None:
141-
cls.ROBOT_LIBRARY_SCOPE = scope
163+
cls.ROBOT_LIBRARY_SCOPE = scope # type:ignore[attr-defined]
142164
if version is not None:
143< 10000 /code>-
cls.ROBOT_LIBRARY_VERSION = version
165+
cls.ROBOT_LIBRARY_VERSION = version# type:ignore[attr-defined]
144166
if doc_format is not None:
145-
cls.ROBOT_LIBRARY_DOC_FORMAT = doc_format
167+
cls.ROBOT_LIBRARY_DOC_FORMAT = doc_format# type:ignore[attr-defined]
146168
if listener is not None:
147-
cls.ROBOT_LIBRARY_LISTENER = listener
148-
cls.ROBOT_AUTO_KEYWORDS = auto_keywords
169+
cls.ROBOT_LIBRARY_LISTENER = listener# type:ignore[attr-defined]
170+
cls.ROBOT_AUTO_KEYWORDS = auto_keywords# type:ignore[attr-defined]
149171
return cls
150172

151173
return decorator

src/robot/api/exceptions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Failure(AssertionError):
3131
"""
3232
ROBOT_SUPPRESS_NAME = True
3333

34-
def __init__(self, message, html=False):
34+
def __init__(self, message: str, html: bool=False) -> None:
3535
"""
3636
:param message: Exception message.
3737
:param html: When ``True``, message is considered to be HTML and not escaped.
@@ -57,7 +57,7 @@ class Error(RuntimeError):
5757
"""
5858
ROBOT_SUPPRESS_NAME = True
5959

60-
def __init__(self, message, html=False):
60+
def __init__(self, message: str, html: bool=False) -> None:
6161
"""
6262
:param message: Exception message.
6363
:param html: When ``True``, message is considered to be HTML and not escaped.
@@ -76,7 +76,7 @@ class SkipExecution(Exception):
7676
ROBOT_SKIP_EXECUTION = True
7777
ROBOT_SUPPRESS_NAME = True
7878

79-
def __init__(self, message, html=False):
79+
def __init__(self, message: str, html: bool=False) -> None:
8080
"""
8181
:param message: Exception message.
8282
:param html: When ``True``, message is considered to be HTML and not escaped.

src/robot/api/logger.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,12 @@ def my_keyword(arg):
7070
from robot.output import librarylogger
7171
from robot.running.context import EXECUTION_CONTEXTS
7272

73+
try:
74+
from typing import Literal
75+
except ImportError:
76+
from typing_extensions import Literal # type: ignore[misc]
7377

74-
def write(msg, level='INFO', html=False):
78+
def write(msg: str, level: Literal["TRACE", "DEBUG", "INFO", "WARN", "ERROR"]='INFO', html:bool=False) -> None:
7579
"""Writes the message to the log file using the given level.
7680
7781
Valid log levels are ``TRACE``, ``DEBUG``, ``INFO`` (default), ``WARN``, and
@@ -86,26 +90,28 @@ def write(msg, level='INFO', html=False):
8690
librarylogger.write(msg, level, html)
8791
else:
8892
logger = logging.getLogger("RobotFramework")
89-
level = {'TRACE': logging.DEBUG // 2,
93+
level = {'TRACE': logging.DEBUG // 2, # type: ignore[assignment]
9094
'DEBUG': logging.DEBUG,
9195
'INFO': logging.INFO,
9296
'HTML': logging.INFO,
9397
'WARN': logging.WARN,
9498
'ERROR': logging.ERROR}[level]
95-
logger.log(level, msg)
99+
logger.log(level, msg) # type: ignore[arg-type]
96100

97101

98-
def trace(msg, html=False):
102+
103+
104+
def trace(msg: str, html: bool=False) -> None:
99105
"""Writes the message to the log file using the ``TRACE`` level."""
100106
write(msg, 'TRACE', html)
101107

102108

103-
def debug(msg, html=False):
109+
def debug(msg: str, html: bool=False) -> None:
104110
"""Writes the message to the log file using the ``DEBUG`` level."""
105111
write(msg, 'DEBUG', html)
106112

107113

108-
def info(msg, html=False, also_console=False):
114+
def info(msg: str, html: bool=False, also_console: bool=False) -> None:
109115
"""Writes the message to the log file using the ``INFO`` level.
110116
111117
If ``also_console`` argument is set to ``True``, the message is
@@ -116,18 +122,18 @@ def info(msg, html=False, also_console=False):
116122
console(msg)
117123

118124

119-
def warn(msg, html=False):
125+
def warn(msg: str, html: bool=False) -> None:
120126
"""Writes the message to the log file using the ``WARN`` level."""
121127
write(msg, 'WARN', html)
122128

123129

124-
def error(msg, html=False):
130+
def error(msg: str, html: bool=False) -> None:
125131
"""Writes the message to the log file using the ``ERROR`` level.
126132
"""
127133
write(msg, 'ERROR', html)
128134

129135

130-
def console(msg, newline=True, stream='stdout'):
136+
def console(msg: str, newline: bool=True, stream: str='stdout') -> None:
131137
"""Writes the message to the console.
132138
133139
If the ``newline`` argument is ``True``, a newline character is

src/robot/conf/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
@py3to2
3333
class _BaseSettings(object):
34-
_cli_opts = {'RPA' : ('rpa', None),
34+
_cli_opts = {'RPA' : ('rpa', None), # type: ignore[var-annotated]
3535
'Name' : ('name', None),
3636
'Doc' : ('doc', None),
3737
'Metadata' : ('metadata', []),

src/robot/htmldata/htmlfilewriter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
15-
15+
from __future__ import annotations
1616
import os.path
1717
import re
1818

@@ -46,7 +46,7 @@ def _get_writers(self, base_dir):
4646

4747

4848
class _Writer(object):
49-
_handles_line = None
49+
_handles_line: str | None = None
5050

5151
def handles(self, line):
5252
return line.startswith(self._handles_line)

src/robot/htmldata/jartemplate.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
import os
1717
from posixpath import normpath, join
1818
from contextlib import contextmanager
19-
from java.io import BufferedReader, InputStreamReader
19+
from java.io import BufferedReader, InputStreamReader # type: ignore[import]
2020

2121
# Works only when running from jar
22-
from org.robotframework.RobotRunner import getResourceAsStream
22+
from org.robotframework.RobotRunner import getResourceAsStream # type: ignore[import]
2323

2424

2525
class HtmlTemplate(object):
@@ -35,7 +35,7 @@ def __iter__(self):
3535
yield line.rstrip()
3636
line = reader.readLine()
3737

38-
@property
38+
@property # type: ignore[misc]
3939
@contextmanager
4040
def _reader(self):
4141
stream = getResourceAsStream(self._path)

src/robot/htmldata/jsonwriter.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
15-
15+
from __future__ import annotations
1616
from robot.utils import PY2
1717

1818

@@ -61,7 +61,7 @@ def write(self, data):
6161

6262

6363
class _Dumper(object):
64-
_handled_types = None
64+
_handled_types: type | tuple[type, ...] | None = None
6565

6666
def __init__(self, jsondumper):
6767
self._dump = jsondumper.dump
@@ -75,7 +75,7 @@ def dump(self, data, mapping):
7575

7676

7777
class StringDumper(_Dumper):
78-
_handled_types = (str, unicode) if PY2 else str
78+
_handled_types = (str, unicode) if PY2 else str # type: ignore[name-defined]
7979
_search_and_replace = [('\\', '\\\\'), ('"', '\\"'), ('\t', '\\t'),
8080
('\n', '\\n'), ('\r', '\\r'), ('</', '\\x3c/')]
8181

@@ -91,7 +91,7 @@ def _escape(self, string):
9191

9292
class IntegerDumper(_Dumper):
9393
# Handles also bool
94-
_handled_types = (int, long) if PY2 else int
94+
_handled_types = (int, long) if PY2 else int # type: ignore[assignment,name-defined]
9595

9696
def dump(self, data, mapping):
9797
self._write(str(data).lower())

src/robot/htmldata/template.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
try:
1717
from .jartemplate import HtmlTemplate
1818
except ImportError:
19-
from .normaltemplate import HtmlTemplate
19+
from .normaltemplate import HtmlTemplate # type: ignore[misc]

src/robot/htmldata/testdata/create_libdoc_data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@
1818

1919
with open(OUTPUT, 'w') as output:
2020
libdoc = LibraryDocumentation(INPUT)
21-
LibdocModelWriter(output, libdoc).write_data()
21+
LibdocModelWriter(output, libdoc).write_data() # type: ignore[attr-defined]
2222

2323
print(OUTPUT)

src/robot/jarrunner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import os
1717
import sys
1818

19-
from org.robotframework import RobotPythonRunner
19+
from org.robotframework import RobotPythonRunner # type: ignore[import]
2020

2121
from robot.errors import INFO_PRINTED
2222
from robot.libdoc import libdoc_cli

src/robot/libdoc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
# Allows running as a script. __name__ check needed with multiprocessing:
3838
# https://github.com/robotframework/robotframework/issues/1137
3939
if 'robot' not in sys.modules and __name__ == '__main__':
40-
import pythonpathsetter
40+
import pythonpathsetter # type: ignore[import]
4141

4242
from robot.utils import Application, seq2str
4343
from robot.errors import DataError

src/robot/libdocpkg/builder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
if JAVA_VERSION < (1, 9):
2626
from .javabuilder import JavaDocBuilder
2727
else:
28-
from .java9builder import JavaDocBuilder
28+
from .java9builder import JavaDocBuilder # type: ignore[misc]
2929
else:
30-
def JavaDocBuilder():
30+
def JavaDocBuilder(): # type: ignore[no-redef]
3131
raise DataError('Documenting Java test libraries requires Jython.')
3232

3333

src/robot/libdocpkg/datatypes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
EnumType = type(Enum)
2222
except ImportError: # Standard in Py 3.4+ but can be separately installed
23-
class EnumType(object):
23+
class EnumType(object): # type: ignore[no-redef]
2424
pass
2525

2626

src/robot/libdocpkg/htmlutils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
import re
1717
try:
18-
from urllib import quote
18+
from urllib import quote # type: ignore[attr-defined]
1919
except ImportError:
2020
from urllib.parse import quote
2121

src/robot/libdocpkg/java9builder.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515

1616
from inspect import cleandoc
1717

18-
from java.nio.charset import StandardCharsets
19-
from java.util import Locale
20-
from javax.lang.model.element.Modifier import PUBLIC
21-
from javax.lang.model.util import ElementFilter
22-
from javax.lang.model.type import TypeKind
23-
from javax.tools import DocumentationTool, ToolProvider
18+
from java.nio.charset import StandardCharsets # type: ignore[import]
19+
from java.util import Locale # type: ignore[import]
20+
from javax.lang.model.element.Modifier import PUBLIC # type: ignore[import]
21+
from javax.lang.model.util import ElementFilter # type: ignore[import]
22+
from javax.lang.model.type import TypeKind # type: ignore[import]
23+
from javax.tools import DocumentationTool, ToolProvider # type: ignore[import]
2424

2525
from robot.running import ArgumentSpec
2626
from robot.utils import normalize, printable_name, split_tags_from_doc

src/robot/libdocpkg/javabuilder.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ def ClassDoc(path):
112112
http://docs.oracle.com/javase/7/docs/jdk/api/javadoc/doclet/
113113
"""
114114
try:
115-
from com.sun.tools.javadoc import JavadocTool, Messager, ModifierFilter
116-
from com.sun.tools.javac.util import List, Context
117-
from com.sun.tools.javac.code.Flags import PUBLIC
115+
from com.sun.tools.javadoc import JavadocTool, Messager, ModifierFilter # type: ignore[import]
116+
from com.sun.tools.javac.util import List, Context # type: ignore[import]
117+
from com.sun.tools.javac.code.Flags import PUBLIC # type: ignore[import]
118118
except ImportError:
119119
raise DataError("Creating documentation from Java source files "
120120
"requires 'tools.jar' to be in CLASSPATH.")

0 commit comments

Comments
 (0)
0