robotcode-robot 0.68.0__py3-none-any.whl → 0.68.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- __version__ = "0.68.0"
1
+ __version__ = "0.68.2"
@@ -79,7 +79,10 @@ def load_config_from_pyproject_toml_str(config_type: Type[_ConfigType], tool_nam
79
79
 
80
80
 
81
81
  def _load_config_data_from_path(
82
- config_type: Type[_ConfigType], tool_name: str, robot_toml_tool_name: Optional[str], __path: Path
82
+ config_type: Type[_ConfigType],
83
+ tool_name: str,
84
+ robot_toml_tool_name: Optional[str],
85
+ __path: Path,
83
86
  ) -> _ConfigType:
84
87
  try:
85
88
  if __path.name == PYPROJECT_TOML:
@@ -87,7 +90,9 @@ def _load_config_data_from_path(
87
90
 
88
91
  if __path.name == ROBOT_TOML or __path.name == LOCAL_ROBOT_TOML or __path.suffix == ".toml":
89
92
  return load_config_from_robot_toml_str(
90
- config_type, __path.read_text("utf-8"), tool_name=robot_toml_tool_name
93
+ config_type,
94
+ __path.read_text("utf-8"),
95
+ tool_name=robot_toml_tool_name,
91
96
  )
92
97
  raise TypeError("Unknown config file type.")
93
98
 
@@ -115,18 +120,25 @@ def load_config_from_path(
115
120
  for __path in __paths:
116
121
  result.add_options(
117
122
  _load_config_data_from_path(
118
- config_type, tool_name, robot_toml_tool_name, __path if isinstance(__path, Path) else __path[0]
123
+ config_type,
124
+ tool_name,
125
+ robot_toml_tool_name,
126
+ __path if isinstance(__path, Path) else __path[0],
119
127
  )
120
128
  )
121
129
 
122
130
  return result
123
131
 
124
132
 
125
- def load_robot_config_from_path(*__paths: Union[Path, Tuple[Path, ConfigType]]) -> RobotConfig:
133
+ def load_robot_config_from_path(
134
+ *__paths: Union[Path, Tuple[Path, ConfigType]],
135
+ ) -> RobotConfig:
126
136
  return load_config_from_path(RobotConfig, *__paths, tool_name="robot")
127
137
 
128
138
 
129
- def find_project_root(*sources: Union[str, Path]) -> Tuple[Optional[Path], DiscoverdBy]:
139
+ def find_project_root(
140
+ *sources: Union[str, Path],
141
+ ) -> Tuple[Optional[Path], DiscoverdBy]:
130
142
  if not sources:
131
143
  sources = (str(Path.cwd().absolute()),)
132
144
 
@@ -158,7 +170,9 @@ def find_project_root(*sources: Union[str, Path]) -> Tuple[Optional[Path], Disco
158
170
  return None, DiscoverdBy.NOT_FOUND
159
171
 
160
172
 
161
- def get_config_files_from_folder(folder: Path) -> Sequence[Tuple[Path, ConfigType]]:
173
+ def get_config_files_from_folder(
174
+ folder: Path,
175
+ ) -> Sequence[Tuple[Path, ConfigType]]:
162
176
  result = []
163
177
 
164
178
  pyproject_toml = folder / PYPROJECT_TOML
@@ -22,10 +22,16 @@ from typing import (
22
22
  )
23
23
 
24
24
  import tomli_w
25
- from robotcode.core.utils.dataclasses import TypeValidationError, ValidateMixin, as_dict, validate_types
26
- from robotcode.core.utils.safe_eval import safe_eval
27
25
  from typing_extensions import Self
28
26
 
27
+ from robotcode.core.utils.dataclasses import (
28
+ TypeValidationError,
29
+ ValidateMixin,
30
+ as_dict,
31
+ validate_types,
32
+ )
33
+ from robotcode.core.utils.safe_eval import safe_eval
34
+
29
35
  EXTEND_PREFIX_LEN = len("extend_")
30
36
 
31
37
 
@@ -260,7 +266,10 @@ class BaseOptions(ValidateMixin):
260
266
  if value is None or value == Flag.DEFAULT:
261
267
  continue
262
268
 
263
- append_name(field, bool(value) != field.metadata.get("robot_flag_default", True))
269
+ append_name(
270
+ field,
271
+ bool(value) != field.metadata.get("robot_flag_default", True),
272
+ )
264
273
 
265
274
  continue
266
275
 
@@ -292,7 +301,11 @@ class BaseOptions(ValidateMixin):
292
301
  def _verified_value(name: str, value: Any, types: Union[type, Tuple[type, ...]], target: Any) -> Any:
293
302
  errors = validate_types(types, value)
294
303
  if errors:
295
- raise TypeValidationError("Dataclass Type Validation Error", target=target, errors={name: errors})
304
+ raise TypeValidationError(
305
+ "Dataclass Type Validation Error",
306
+ target=target,
307
+ errors={name: errors},
308
+ )
296
309
  return value
297
310
 
298
311
  def add_options(self, config: "BaseOptions", combine_extras: bool = False) -> None:
@@ -305,7 +318,10 @@ class BaseOptions(ValidateMixin):
305
318
  continue
306
319
 
307
320
  new = self._verified_value(
308
- f.name, getattr(config, f.name), type_hints[f.name[EXTEND_PREFIX_LEN:]], config
321
+ f.name,
322
+ getattr(config, f.name),
323
+ type_hints[f.name[EXTEND_PREFIX_LEN:]],
324
+ config,
309
325
  )
310
326
  if new is None:
311
327
  continue
@@ -447,7 +463,16 @@ class CommonOptions(BaseOptions):
447
463
  robot_name="expandkeywords",
448
464
  robot_priority=500,
449
465
  )
450
- flatten_keywords: Optional[List[Union[str, Literal["for", "while", "iteration"], NamePattern, TagPattern]]] = field(
466
+ flatten_keywords: Optional[
467
+ List[
468
+ Union[
469
+ str,
470
+ Literal["for", "while", "iteration"],
471
+ NamePattern,
472
+ TagPattern,
473
+ ]
474
+ ]
475
+ ] = field(
451
476
  description="""\
452
477
  Flattens matching keywords in the generated log file.
453
478
  Matching keywords get all log messages from their
@@ -613,7 +638,14 @@ class CommonOptions(BaseOptions):
613
638
  robot_short_name="P",
614
639
  )
615
640
  remove_keywords: Optional[
616
- List[Union[str, Literal["all", "passed", "for", "wuks"], NamePattern, TagPattern]]
641
+ List[
642
+ Union[
643
+ str,
644
+ Literal["all", "passed", "for", "wuks"],
645
+ NamePattern,
646
+ TagPattern,
647
+ ]
648
+ ]
617
649
  ] = field(
618
650
  description="""\
619
651
  Remove keyword data from the generated log file.
@@ -909,7 +941,7 @@ class CommonExtraOptions(BaseOptions):
909
941
  matched using same rules as with --include.
910
942
 
911
943
  corresponds to the `-e --exclude tag *` option of _robot_
912
- """,
944
+ """
913
945
  )
914
946
  extend_expand_keywords: Optional[List[Union[str, NamePattern, TagPattern]]] = field(
915
947
  description="""\
@@ -927,10 +959,17 @@ class CommonExtraOptions(BaseOptions):
927
959
  ```
928
960
 
929
961
  corresponds to the `--expandkeywords name:<pattern>|tag:<pattern> *` option of _robot_
930
- """,
962
+ """
931
963
  )
932
964
  extend_flatten_keywords: Optional[
933
- List[Union[str, Literal["for", "while", "iteration"], NamePattern, TagPattern]]
965
+ List[
966
+ Union[
967
+ str,
968
+ Literal["for", "while", "iteration"],
969
+ NamePattern,
970
+ TagPattern,
971
+ ]
972
+ ]
934
973
  ] = field(
935
974
  description="""\
936
975
  Appends entries to the --flattenkeywords option.
@@ -950,7 +989,7 @@ class CommonExtraOptions(BaseOptions):
950
989
  `--removekeywords tag:<pattern>`
951
990
 
952
991
  corresponds to the `--flattenkeywords for|while|iteration|name:<pattern>|tag:<pattern> *` option of _robot_
953
- """,
992
+ """
954
993
  )
955
994
  extend_includes: Optional[List[Union[str, StringExpression]]] = field(
956
995
  description="""\
@@ -970,7 +1009,7 @@ class CommonExtraOptions(BaseOptions):
970
1009
  ```
971
1010
 
972
1011
  corresponds to the `-i --include tag *` option of _robot_
973
- """,
1012
+ """
974
1013
  )
975
1014
  extend_metadata: Optional[Dict[str, Union[str, StringExpression]]] = field(
976
1015
  description="""\
@@ -981,7 +1020,7 @@ class CommonExtraOptions(BaseOptions):
981
1020
  as --doc. Example: --metadata Version:1.2
982
1021
 
983
1022
  corresponds to the `-M --metadata name:value *` option of _robot_
984
- """,
1023
+ """
985
1024
  )
986
1025
  extend_parse_include: Optional[List[Union[str, StringExpression]]] = field(
987
1026
  description="""\
@@ -995,7 +1034,7 @@ class CommonExtraOptions(BaseOptions):
995
1034
  all files in that directory, recursively.
996
1035
 
997
1036
  corresponds to the `-I --parseinclude pattern *` option of _robot_
998
- """,
1037
+ """
999
1038
  )
1000
1039
  extend_pre_rebot_modifiers: Optional[Dict[str, List[Union[str, StringExpression]]]] = field(
1001
1040
  description="""\
@@ -1006,7 +1045,7 @@ class CommonExtraOptions(BaseOptions):
1006
1045
  arguments the same way as with --listener.
1007
1046
 
1008
1047
  corresponds to the `--prerebotmodifier modifier *` option of _robot_
1009
- """,
1048
+ """
1010
1049
  )
1011
1050
  extend_python_path: Optional[List[Union[str, StringExpression]]] = field(
1012
1051
  description="""\
@@ -1027,10 +1066,17 @@ class CommonExtraOptions(BaseOptions):
1027
1066
  ```
1028
1067
 
1029
1068
  corresponds to the `-P --pythonpath path *` option of _robot_
1030
- """,
1069
+ """
1031
1070
  )
1032
1071
  extend_remove_keywords: Optional[
1033
- List[Union[str, Literal["all", "passed", "for", "wuks"], NamePattern, TagPattern]]
1072
+ List[
1073
+ Union[
1074
+ str,
1075
+ Literal["all", "passed", "for", "wuks"],
1076
+ NamePattern,
1077
+ TagPattern,
1078
+ ]
1079
+ ]
1034
1080
  ] = field(
1035
1081
  description="""\
1036
1082
  Appends entries to the --removekeywords option.
@@ -1075,7 +1121,7 @@ class CommonExtraOptions(BaseOptions):
1075
1121
  ```
1076
1122
 
1077
1123
  corresponds to the `--removekeywords all|passed|for|wuks|name:<pattern>|tag:<pattern> *` option of _robot_
1078
- """,
1124
+ """
1079
1125
  )
1080
1126
  extend_set_tag: Optional[List[Union[str, StringExpression]]] = field(
1081
1127
  description="""\
@@ -1084,7 +1130,7 @@ class CommonExtraOptions(BaseOptions):
1084
1130
  Sets given tag(s) to all executed tests.
1085
1131
 
1086
1132
  corresponds to the `-G --settag tag *` option of _robot_
1087
- """,
1133
+ """
1088
1134
  )
1089
1135
  extend_suites: Optional[List[Union[str, StringExpression]]] = field(
1090
1136
  description="""\
@@ -1099,7 +1145,7 @@ class CommonExtraOptions(BaseOptions):
1099
1145
  selects suite `Y` only if its parent is `X`.
1100
1146
 
1101
1147
  corresponds to the `-s --suite name *` option of _robot_
1102
- """,
1148
+ """
1103
1149
  )
1104
1150
  extend_tag_doc: Optional[Dict[str, Union[str, StringExpression]]] = field(
1105
1151
  description="""\
@@ -1119,7 +1165,7 @@ class CommonExtraOptions(BaseOptions):
1119
1165
  ```
1120
1166
 
1121
1167
  corresponds to the `--tagdoc pattern:doc *` option of _robot_
1122
- """,
1168
+ """
1123
1169
  )
1124
1170
  extend_tag_stat_combine: Optional[List[Union[str, Dict[str, str]]]] = field(
1125
1171
  description="""\
@@ -1139,7 +1185,7 @@ class CommonExtraOptions(BaseOptions):
1139
1185
  ```
1140
1186
 
1141
1187
  corresponds to the `--tagstatcombine tags:name *` option of _robot_
1142
- """,
1188
+ """
1143
1189
  )
1144
1190
  extend_tag_stat_exclude: Optional[List[Union[str, StringExpression]]] = field(
1145
1191
  description="""\
@@ -1150,7 +1196,7 @@ class CommonExtraOptions(BaseOptions):
1150
1196
  similarly as --exclude is used with --include.
1151
1197
 
1152
1198
  corresponds to the `--tagstatexclude tag *` option of _robot_
1153
- """,
1199
+ """
1154
1200
  )
1155
1201
  extend_tag_stat_include: Optional[List[Union[str, StringExpression]]] = field(
1156
1202
  description="""\
@@ -1161,7 +1207,7 @@ class CommonExtraOptions(BaseOptions):
1161
1207
  Given tag can be a pattern like with --include.
1162
1208
 
1163
1209
  corresponds to the `--tagstatinclude tag *` option of _robot_
1164
- """,
1210
+ """
1165
1211
  )
1166
1212
  extend_tag_stat_link: Optional[Dict[str, Union[str, StringExpression]]] = field(
1167
1213
  description="""\
@@ -1181,7 +1227,7 @@ class CommonExtraOptions(BaseOptions):
1181
1227
  ```
1182
1228
 
1183
1229
  corresponds to the `--tagstatlink pattern:link:title *` option of _robot_
1184
- """,
1230
+ """
1185
1231
  )
1186
1232
  extend_tasks: Optional[List[Union[str, StringExpression]]] = field(
1187
1233
  description="""\
@@ -1190,7 +1236,7 @@ class CommonExtraOptions(BaseOptions):
1190
1236
  Alias to --test. Especially applicable with --rpa.
1191
1237
 
1192
1238
  corresponds to the `--task name *` option of _robot_
1193
- """,
1239
+ """
1194
1240
  )
1195
1241
  extend_tests: Optional[List[Union[str, StringExpression]]] = field(
1196
1242
  description="""\
@@ -1204,7 +1250,7 @@ class CommonExtraOptions(BaseOptions):
1204
1250
  in brackets.
1205
1251
 
1206
1252
  corresponds to the `-t --test name *` option of _robot_
1207
- """,
1253
+ """
1208
1254
  )
1209
1255
 
1210
1256
 
@@ -1589,7 +1635,7 @@ class RobotExtraOptions(BaseOptions):
1589
1635
  a custom language file.
1590
1636
 
1591
1637
  corresponds to the `--language lang *` option of _rebot_
1592
- """,
1638
+ """
1593
1639
  )
1594
1640
  extend_listeners: Optional[Dict[str, List[Union[str, StringExpression]]]] = field(
1595
1641
  description="""\
@@ -1608,7 +1654,7 @@ class RobotExtraOptions(BaseOptions):
1608
1654
  ```
1609
1655
 
1610
1656
  corresponds to the `--listener listener *` option of _rebot_
1611
- """,
1657
+ """
1612
1658
  )
1613
1659
  extend_parsers: Optional[Dict[str, List[Union[str, StringExpression]]]] = field(
1614
1660
  description="""\
@@ -1618,7 +1664,7 @@ class RobotExtraOptions(BaseOptions):
1618
1664
  arguments the same way as with --listener.
1619
1665
 
1620
1666
  corresponds to the `--parser parser *` option of _rebot_
1621
- """,
1667
+ """
1622
1668
  )
1623
1669
  extend_pre_run_modifiers: Optional[Dict[str, List[Union[str, StringExpression]]]] = field(
1624
1670
  description="""\
@@ -1629,7 +1675,7 @@ class RobotExtraOptions(BaseOptions):
1629
1675
  same way as with --listener.
1630
1676
 
1631
1677
  corresponds to the `--prerunmodifier modifier *` option of _rebot_
1632
- """,
1678
+ """
1633
1679
  )
1634
1680
  extend_skip: Optional[List[Union[str, StringExpression]]] = field(
1635
1681
  description="""\
@@ -1639,7 +1685,7 @@ class RobotExtraOptions(BaseOptions):
1639
1685
  a pattern.
1640
1686
 
1641
1687
  corresponds to the `--skip tag *` option of _rebot_
1642
- """,
1688
+ """
1643
1689
  )
1644
1690
  extend_skip_on_failure: Optional[List[Union[str, StringExpression]]] = field(
1645
1691
  description="""\
@@ -1649,7 +1695,7 @@ class RobotExtraOptions(BaseOptions):
1649
1695
  Tag can be a pattern
1650
1696
 
1651
1697
  corresponds to the `--skiponfailure tag *` option of _rebot_
1652
- """,
1698
+ """
1653
1699
  )
1654
1700
  extend_variables: Optional[Dict[str, Union[str, StringExpression]]] = field(
1655
1701
  description="""\
@@ -1669,7 +1715,7 @@ class RobotExtraOptions(BaseOptions):
1669
1715
  ```
1670
1716
 
1671
1717
  corresponds to the `-v --variable name:value *` option of _rebot_
1672
- """,
1718
+ """
1673
1719
  )
1674
1720
  extend_variable_files: Optional[List[Union[str, StringExpression]]] = field(
1675
1721
  description="""\
@@ -1687,7 +1733,7 @@ class RobotExtraOptions(BaseOptions):
1687
1733
  ```
1688
1734
 
1689
1735
  corresponds to the `-V --variablefile path *` option of _rebot_
1690
- """,
1736
+ """
1691
1737
  )
1692
1738
 
1693
1739
 
@@ -1889,7 +1935,7 @@ class LibDocExtraOptions(BaseOptions):
1889
1935
  and resources.
1890
1936
 
1891
1937
  corresponds to the `-P --pythonpath path *` option of _libdoc_
1892
- """,
1938
+ """
1893
1939
  )
1894
1940
 
1895
1941
 
@@ -2002,7 +2048,7 @@ class TestDocExtraOptions(BaseOptions):
2002
2048
  Exclude tests by tags.
2003
2049
 
2004
2050
  corresponds to the `-e --exclude tag *` option of _testdoc_
2005
- """,
2051
+ """
2006
2052
  )
2007
2053
  extend_includes: Optional[List[Union[str, StringExpression]]] = field(
2008
2054
  description="""\
@@ -2011,7 +2057,7 @@ class TestDocExtraOptions(BaseOptions):
2011
2057
  Include tests by tags.
2012
2058
 
2013
2059
  corresponds to the `-i --include tag *` option of _testdoc_
2014
- """,
2060
+ """
2015
2061
  )
2016
2062
  extend_metadata: Optional[Dict[str, Union[str, StringExpression]]] = field(
2017
2063
  description="""\
@@ -2020,7 +2066,7 @@ class TestDocExtraOptions(BaseOptions):
2020
2066
  Set/override metadata of the top level suite.
2021
2067
 
2022
2068
  corresponds to the `-M --metadata name:value *` option of _testdoc_
2023
- """,
2069
+ """
2024
2070
  )
2025
2071
  extend_set_tag: Optional[List[Union[str, StringExpression]]] = field(
2026
2072
  description="""\
@@ -2029,7 +2075,7 @@ class TestDocExtraOptions(BaseOptions):
2029
2075
  Set given tag(s) to all test cases.
2030
2076
 
2031
2077
  corresponds to the `-G --settag tag *` option of _testdoc_
2032
- """,
2078
+ """
2033
2079
  )
2034
2080
  extend_suites: Optional[List[Union[str, StringExpression]]] = field(
2035
2081
  description="""\
@@ -2038,7 +2084,7 @@ class TestDocExtraOptions(BaseOptions):
2038
2084
  Include suites by name.
2039
2085
 
2040
2086
  corresponds to the `-s --suite name *` option of _testdoc_
2041
- """,
2087
+ """
2042
2088
  )
2043
2089
  extend_tests: Optional[List[Union[str, StringExpression]]] = field(
2044
2090
  description="""\
@@ -2047,7 +2093,7 @@ class TestDocExtraOptions(BaseOptions):
2047
2093
  Include tests by name.
2048
2094
 
2049
2095
  corresponds to the `-t --test name *` option of _testdoc_
2050
- """,
2096
+ """
2051
2097
  )
2052
2098
 
2053
2099
 
@@ -2107,7 +2153,7 @@ class RobotBaseProfile(CommonOptions, CommonExtraOptions, RobotOptions, RobotExt
2107
2153
  TEST_VAR = "test"
2108
2154
  SECRET = "password"
2109
2155
  ```
2110
- """,
2156
+ """
2111
2157
  )
2112
2158
 
2113
2159
  rebot: Optional[RebotProfile] = field(
@@ -2141,13 +2187,13 @@ class RobotExtraBaseProfile(RobotBaseProfile):
2141
2187
  extend_args: Optional[List[str]] = field(
2142
2188
  description="""\
2143
2189
  Append extra arguments to be passed to _robot_.
2144
- """,
2190
+ """
2145
2191
  )
2146
2192
 
2147
2193
  extend_env: Optional[Dict[str, str]] = field(
2148
2194
  description="""\
2149
2195
  Append extra environment variables to be set before tests.
2150
- """,
2196
+ """
2151
2197
  )
2152
2198
 
2153
2199
  extend_paths: Union[str, List[str], None] = field(
@@ -2172,7 +2218,7 @@ class RobotProfile(RobotExtraBaseProfile):
2172
2218
  description="""\
2173
2219
  The profile should be detached.
2174
2220
  Detached means it is not inherited from the main profile.
2175
- """,
2221
+ """
2176
2222
  )
2177
2223
 
2178
2224
  enabled: Union[bool, Condition, None] = field(
@@ -2216,22 +2262,18 @@ class RobotConfig(RobotExtraBaseProfile):
2216
2262
  ```toml
2217
2263
  default_profiles = ["default", "Firefox"]
2218
2264
  ```
2219
- """,
2220
- )
2221
- profiles: Optional[Dict[str, RobotProfile]] = field(
2222
- description="Execution profiles.",
2265
+ """
2223
2266
  )
2267
+ profiles: Optional[Dict[str, RobotProfile]] = field(description="Execution profiles.")
2224
2268
 
2225
- extend_profiles: Optional[Dict[str, RobotProfile]] = field(
2226
- description="Extra execution profiles.",
2227
- )
2269
+ extend_profiles: Optional[Dict[str, RobotProfile]] = field(description="Extra execution profiles.")
2228
2270
 
2229
- tool: Any = field(
2230
- description="Tool configurations.",
2231
- )
2271
+ tool: Any = field(description="Tool configurations.")
2232
2272
 
2233
2273
  def select_profiles(
2234
- self, *names: str, verbose_callback: Optional[Callable[..., None]] = None
2274
+ self,
2275
+ *names: str,
2276
+ verbose_callback: Optional[Callable[..., None]] = None,
2235
2277
  ) -> Dict[str, RobotProfile]:
2236
2278
  result: Dict[str, RobotProfile] = {}
2237
2279
 
@@ -2246,7 +2288,7 @@ class RobotConfig(RobotExtraBaseProfile):
2246
2288
  )
2247
2289
 
2248
2290
  if verbose_callback and default_profile:
2249
- verbose_callback(f"Using default profiles: {', '.join( default_profile)}.")
2291
+ verbose_callback(f"Using default profiles: {', '.join(default_profile)}.")
2250
2292
 
2251
2293
  names = (*(default_profile or ()),)
2252
2294
 
@@ -2261,7 +2303,11 @@ class RobotConfig(RobotExtraBaseProfile):
2261
2303
 
2262
2304
  return result
2263
2305
 
2264
- def combine_profiles(self, *names: str, verbose_callback: Optional[Callable[..., None]] = None) -> RobotBaseProfile:
2306
+ def combine_profiles(
2307
+ self,
2308
+ *names: str,
2309
+ verbose_callback: Optional[Callable[..., None]] = None,
2310
+ ) -> RobotBaseProfile:
2265
2311
  type_hints = get_type_hints(RobotBaseProfile)
2266
2312
  base_field_names = [f.name for f in dataclasses.fields(RobotBaseProfile)]
2267
2313
 
@@ -2298,7 +2344,10 @@ class RobotConfig(RobotExtraBaseProfile):
2298
2344
  for f in dataclasses.fields(profile):
2299
2345
  if f.name.startswith("extend_"):
2300
2346
  new = self._verified_value(
2301
- f.name, getattr(profile, f.name), type_hints[f.name[EXTEND_PREFIX_LEN:]], profile
2347
+ f.name,
2348
+ getattr(profile, f.name),
2349
+ type_hints[f.name[EXTEND_PREFIX_LEN:]],
2350
+ profile,
2302
2351
  )
2303
2352
  if new is None:
2304
2353
  continue
@@ -2308,7 +2357,11 @@ class RobotConfig(RobotExtraBaseProfile):
2308
2357
  setattr(result, f.name[EXTEND_PREFIX_LEN:], new)
2309
2358
  else:
2310
2359
  if isinstance(old, dict):
2311
- setattr(result, f.name[EXTEND_PREFIX_LEN:], {**old, **new})
2360
+ setattr(
2361
+ result,
2362
+ f.name[EXTEND_PREFIX_LEN:],
2363
+ {**old, **new},
2364
+ )
2312
2365
  elif isinstance(old, list):
2313
2366
  setattr(result, f.name[EXTEND_PREFIX_LEN:], [*old, *new])
2314
2367
  elif isinstance(old, tuple):
@@ -2323,7 +2376,12 @@ class RobotConfig(RobotExtraBaseProfile):
2323
2376
  if getattr(profile, f"extend_{f.name}", None) is not None:
2324
2377
  continue
2325
2378
 
2326
- new = self._verified_value(f.name, getattr(profile, f.name), type_hints[f.name], profile)
2379
+ new = self._verified_value(
2380
+ f.name,
2381
+ getattr(profile, f.name),
2382
+ type_hints[f.name],
2383
+ profile,
2384
+ )
2327
2385
  if new is not None:
2328
2386
  setattr(result, f.name, new)
2329
2387
 
@@ -3,11 +3,18 @@ from typing import Callable, Optional, Sequence, Tuple, Union
3
3
 
4
4
  import platformdirs
5
5
 
6
- from .loader import ConfigType, DiscoverdBy, find_project_root, get_config_files_from_folder, get_default_config
6
+ from .loader import (
7
+ ConfigType,
8
+ DiscoverdBy,
9
+ find_project_root,
10
+ get_config_files_from_folder,
11
+ get_default_config,
12
+ )
7
13
 
8
14
 
9
15
  def get_user_config_file(
10
- create: bool = True, verbose_callback: Optional[Callable[[str], None]] = None
16
+ create: bool = True,
17
+ verbose_callback: Optional[Callable[[str], None]] = None,
11
18
  ) -> Optional[Path]:
12
19
  result = Path(platformdirs.user_config_dir("robotcode", appauthor=False), "robot.toml")
13
20
  if result.is_file():
@@ -22,8 +29,12 @@ def get_user_config_file(
22
29
 
23
30
  if verbose_callback:
24
31
  verbose_callback(f"User configuration file not found, try to create it at:\n {result}")
25
-
26
- get_default_config().save(result)
32
+ try:
33
+ get_default_config().save(result)
34
+ except OSError as e:
35
+ if verbose_callback:
36
+ verbose_callback(f"Cannot create user configuration file `{result}`:\n {e}")
37
+ return None
27
38
 
28
39
  return result
29
40
 
@@ -54,16 +65,17 @@ def get_config_files(
54
65
 
55
66
  if verbose_callback:
56
67
  if result:
57
- verbose_callback(
58
- "Found configuration files:\n " + "\n ".join(str(f[0]) for f in result),
59
- )
68
+ verbose_callback("Found configuration files:\n " + "\n ".join(str(f[0]) for f in result))
60
69
  else:
61
70
  verbose_callback("No configuration files found.")
62
71
 
63
72
  user_config = get_user_config_file(verbose_callback=verbose_callback)
64
73
 
65
74
  return (
66
- [*([(user_config, ConfigType.USER_DEFAULT_CONFIG_TOML)] if user_config else []), *result],
75
+ [
76
+ *([(user_config, ConfigType.USER_DEFAULT_CONFIG_TOML)] if user_config else []),
77
+ *result,
78
+ ],
67
79
  root_folder,
68
80
  discovered_by,
69
81
  )
File without changes