Coverage for pyTooling/CLIAbstraction/Argument.py: 91%

219 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-25 22:22 +0000

1# ==================================================================================================================== # 

2# _____ _ _ ____ _ ___ _ _ _ _ _ # 

3# _ __ _ |_ _|__ ___ | (_)_ __ __ _ / ___| | |_ _| / \ | |__ ___| |_ _ __ __ _ ___| |_(_) ___ _ __ # 

4# | '_ \| | | || |/ _ \ / _ \| | | '_ \ / _` || | | | | | / _ \ | '_ \/ __| __| '__/ _` |/ __| __| |/ _ \| '_ \ # 

5# | |_) | |_| || | (_) | (_) | | | | | | (_| || |___| |___ | | / ___ \| |_) \__ \ |_| | | (_| | (__| |_| | (_) | | | | # 

6# | .__/ \__, ||_|\___/ \___/|_|_|_| |_|\__, (_)____|_____|___/_/ \_\_.__/|___/\__|_| \__,_|\___|\__|_|\___/|_| |_| # 

7# |_| |___/ |___/ # 

8# ==================================================================================================================== # 

9# Authors: # 

10# Patrick Lehmann # 

11# # 

12# License: # 

13# ==================================================================================================================== # 

14# Copyright 2017-2025 Patrick Lehmann - Bötzingen, Germany # 

15# Copyright 2014-2016 Technische Universität Dresden - Germany, Chair of VLSI-Design, Diagnostics and Architecture # 

16# # 

17# Licensed under the Apache License, Version 2.0 (the "License"); # 

18# you may not use this file except in compliance with the License. # 

19# You may obtain a copy of the License at # 

20# # 

21# http://www.apache.org/licenses/LICENSE-2.0 # 

22# # 

23# Unless required by applicable law or agreed to in writing, software # 

24# distributed under the License is distributed on an "AS IS" BASIS, # 

25# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # 

26# See the License for the specific language governing permissions and # 

27# limitations under the License. # 

28# # 

29# SPDX-License-Identifier: Apache-2.0 # 

30# ==================================================================================================================== # 

31# 

32""" 

33This module implements command line arguments without prefix character(s). 

34 

35 

36""" 

37from abc import abstractmethod 

38from pathlib import Path 

39from sys import version_info # needed for versions before Python 3.11 

40from typing import ClassVar, List, Union, Iterable, TypeVar, Generic, Any, Optional as Nullable 

41 

42try: 

43 from pyTooling.Decorators import export, readonly 

44 from pyTooling.Common import getFullyQualifiedName 

45except (ImportError, ModuleNotFoundError): # pragma: no cover 

46 print("[pyTooling.Versioning] Could not import from 'pyTooling.*'!") 

47 

48 try: 

49 from Decorators import export, readonly 

50 from Common import getFullyQualifiedName 

51 except (ImportError, ModuleNotFoundError) as ex: # pragma: no cover 

52 print("[pyTooling.Versioning] Could not import directly!") 

53 raise ex 

54 

55 

56__all__ = ["ValueT"] 

57 

58 

59ValueT = TypeVar("ValueT") #: The type of value in a valued argument. 

60 

61 

62@export 

63class CommandLineArgument: 

64 """ 

65 Base-class for all *Argument* classes. 

66 

67 An argument instance can be converted via ``AsArgument`` to a single string value or a sequence of string values 

68 (tuple) usable e.g. with :class:`subprocess.Popen`. Each argument class implements at least one ``pattern`` parameter 

69 to specify how argument are formatted. 

70 

71 There are multiple derived formats supporting: 

72 

73 * commands |br| 

74 |rarr| :mod:`~pyTooling.CLIAbstraction.Command` 

75 * simple names (flags) |br| 

76 |rarr| :mod:`~pyTooling.CLIAbstraction.Flag`, :mod:`~pyTooling.CLIAbstraction.BooleanFlag` 

77 * simple values (vlaued flags) |br| 

78 |rarr| :class:`~pyTooling.CLIAbstraction.Argument.StringArgument`, :class:`~pyTooling.CLIAbstraction.Argument.PathArgument` 

79 * names and values |br| 

80 |rarr| :mod:`~pyTooling.CLIAbstraction.ValuedFlag`, :mod:`~pyTooling.CLIAbstraction.OptionalValuedFlag` 

81 * key-value pairs |br| 

82 |rarr| :mod:`~pyTooling.CLIAbstraction.NamedKeyValuePair` 

83 """ 

84 

85 _pattern: ClassVar[str] 

86 

87 def __init_subclass__(cls, *args: Any, pattern: Nullable[str] = None, **kwargs: Any): 

88 """This method is called when a class is derived. 

89 

90 :param args: Any positional arguments. 

91 :param pattern: This pattern is used to format an argument. 

92 :param kwargs: Any keyword argument. 

93 """ 

94 super().__init_subclass__(*args, **kwargs) 

95 cls._pattern = pattern 

96 

97 def __new__(cls, *args: Any, **kwargs: Any): 

98 if cls is CommandLineArgument: 

99 raise TypeError(f"Class '{cls.__name__}' is abstract.") 

100 

101 # TODO: not sure why parameters meant for __init__ do reach this level and distract __new__ from it's work 

102 return super().__new__(cls) 

103 

104 # TODO: Add property to read pattern 

105 

106 @abstractmethod 

107 def AsArgument(self) -> Union[str, Iterable[str]]: # type: ignore[empty-body] 

108 """ 

109 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

110 the internal name and value. 

111 

112 :return: Formatted argument. 

113 :raises NotImplementedError: This is an abstract method and must be overwritten by a subclass. 

114 """ 

115 raise NotImplementedError(f"Method 'AsArgument' is an abstract method and must be implemented by a subclass.") 

116 

117 @abstractmethod 

118 def __str__(self) -> str: # type: ignore[empty-body] 

119 """ 

120 Return a string representation of this argument instance. 

121 

122 :return: Argument formatted and enclosed in double quotes. 

123 :raises NotImplementedError: This is an abstract method and must be overwritten by a subclass. 

124 """ 

125 raise NotImplementedError(f"Method '__str__' is an abstract method and must be implemented by a subclass.") 

126 

127 @abstractmethod 

128 def __repr__(self) -> str: # type: ignore[empty-body] 

129 """ 

130 Return a string representation of this argument instance. 

131 

132 .. note:: By default, this method is identical to :meth:`__str__`. 

133 

134 :return: Argument formatted and enclosed in double quotes. 

135 :raises NotImplementedError: This is an abstract method and must be overwritten by a subclass. 

136 """ 

137 raise NotImplementedError(f"Method '__repr__' is an abstract method and must be implemented by a subclass.") 

138 

139 

140@export 

141class ExecutableArgument(CommandLineArgument): 

142 """ 

143 Represents the executable. 

144 """ 

145 

146 _executable: Path 

147 

148 def __init__(self, executable: Path) -> None: 

149 """ 

150 Initializes a ExecutableArgument instance. 

151 

152 :param executable: Path to the executable. 

153 :raises TypeError: If parameter 'executable' is not of type :class:`~pathlib.Path`. 

154 """ 

155 if not isinstance(executable, Path): 

156 ex = TypeError("Parameter 'executable' is not of type 'Path'.") 

157 if version_info >= (3, 11): # pragma: no cover 

158 ex.add_note(f"Got type '{getFullyQualifiedName(executable)}'.") 

159 raise ex 

160 

161 self._executable = executable 

162 

163 @property 

164 def Executable(self) -> Path: 

165 """ 

166 Get the internal path to the wrapped executable. 

167 

168 :return: Internal path to the executable. 

169 """ 

170 return self._executable 

171 

172 @Executable.setter 

173 def Executable(self, value): 

174 """ 

175 Set the internal path to the wrapped executable. 

176 

177 :param value: Value to path to the executable. 

178 :raises TypeError: If value is not of type :class:`~pathlib.Path`. 

179 """ 

180 if not isinstance(value, Path): 

181 ex = TypeError("Parameter 'value' is not of type 'Path'.") 

182 if version_info >= (3, 11): # pragma: no cover 

183 ex.add_note(f"Got type '{getFullyQualifiedName(value)}'.") 

184 raise ex 

185 

186 self._executable = value 

187 

188 def AsArgument(self) -> Union[str, Iterable[str]]: 

189 """ 

190 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

191 the internal path to the wrapped executable. 

192 

193 :return: Formatted argument. 

194 """ 

195 return f"{self._executable}" 

196 

197 def __str__(self) -> str: 

198 """ 

199 Return a string representation of this argument instance. 

200 

201 :return: Argument formatted and enclosed in double quotes. 

202 """ 

203 return f"\"{self._executable}\"" 

204 

205 __repr__ = __str__ 

206 

207 

208@export 

209class DelimiterArgument(CommandLineArgument, pattern="--"): 

210 """ 

211 Represents a delimiter symbol like ``--``. 

212 """ 

213 

214 def __init_subclass__(cls, *args: Any, pattern: str = "--", **kwargs: Any): 

215 """ 

216 This method is called when a class is derived. 

217 

218 :param args: Any positional arguments. 

219 :param pattern: This pattern is used to format an argument. Default: ``"--"``. 

220 :param kwargs: Any keyword argument. 

221 """ 

222 kwargs["pattern"] = pattern 

223 super().__init_subclass__(*args, **kwargs) 

224 

225 def AsArgument(self) -> Union[str, Iterable[str]]: 

226 """ 

227 Convert this argument instance to a string representation with proper escaping using the matching pattern. 

228 

229 :return: Formatted argument. 

230 """ 

231 return self._pattern 

232 

233 def __str__(self) -> str: 

234 """ 

235 Return a string representation of this argument instance. 

236 

237 :return: Argument formatted and enclosed in double quotes. 

238 """ 

239 return f"\"{self._pattern}\"" 

240 

241 __repr__ = __str__ 

242 

243 

244@export 

245class NamedArgument(CommandLineArgument, pattern="{0}"): 

246 """ 

247 Base-class for all command line arguments with a name. 

248 """ 

249 

250 _name: ClassVar[str] 

251 

252 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "{0}", **kwargs: Any): 

253 """ 

254 This method is called when a class is derived. 

255 

256 :param args: Any positional arguments. 

257 :param name: Name of the argument. 

258 :param pattern: This pattern is used to format an argument. 

259 :param kwargs: Any keyword argument. 

260 """ 

261 kwargs["pattern"] = pattern 

262 super().__init_subclass__(*args, **kwargs) 

263 cls._name = name 

264 

265 def __new__(cls, *args: Any, **kwargs: Any): 

266 if cls is NamedArgument: 

267 raise TypeError(f"Class '{cls.__name__}' is abstract.") 

268 return super().__new__(cls, *args, **kwargs) 

269 

270 @readonly 

271 def Name(self) -> str: 

272 """ 

273 Get the internal name. 

274 

275 :return: Internal name. 

276 """ 

277 return self._name 

278 

279 def AsArgument(self) -> Union[str, Iterable[str]]: 

280 """ 

281 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

282 the internal name. 

283 

284 :return: Formatted argument. 

285 :raises ValueError: If internal name is None. 

286 """ 

287 if self._name is None: 287 ↛ 288line 287 didn't jump to line 288 because the condition on line 287 was never true

288 raise ValueError(f"Internal value '_name' is None.") 

289 

290 return self._pattern.format(self._name) 

291 

292 def __str__(self) -> str: 

293 """ 

294 Return a string representation of this argument instance. 

295 

296 :return: Argument formatted and enclosed in double quotes. 

297 """ 

298 return f"\"{self.AsArgument()}\"" 

299 

300 __repr__ = __str__ 

301 

302 

303@export 

304class ValuedArgument(CommandLineArgument, Generic[ValueT], pattern="{0}"): 

305 """ 

306 Base-class for all command line arguments with a value. 

307 """ 

308 

309 _value: ValueT 

310 

311 def __init_subclass__(cls, *args: Any, pattern: str = "{0}", **kwargs: Any): 

312 """ 

313 This method is called when a class is derived. 

314 

315 :param args: Any positional arguments. 

316 :param pattern: This pattern is used to format an argument. 

317 :param kwargs: Any keyword argument. 

318 """ 

319 kwargs["pattern"] = pattern 

320 super().__init_subclass__(*args, **kwargs) 

321 

322 def __init__(self, value: ValueT) -> None: 

323 """ 

324 Initializes a ValuedArgument instance. 

325 

326 :param value: Value to be stored internally. 

327 :raises TypeError: If parameter 'value' is None. 

328 """ 

329 if value is None: 329 ↛ 330line 329 didn't jump to line 330 because the condition on line 329 was never true

330 raise ValueError("Parameter 'value' is None.") 

331 

332 self._value = value 

333 

334 @property 

335 def Value(self) -> ValueT: 

336 """ 

337 Get the internal value. 

338 

339 :return: Internal value. 

340 """ 

341 return self._value 

342 

343 @Value.setter 

344 def Value(self, value: ValueT) -> None: 

345 """ 

346 Set the internal value. 

347 

348 :param value: Value to set. 

349 :raises ValueError: If value to set is None. 

350 """ 

351 if value is None: 351 ↛ 352line 351 didn't jump to line 352 because the condition on line 351 was never true

352 raise ValueError(f"Value to set is None.") 

353 

354 self._value = value 

355 

356 def AsArgument(self) -> Union[str, Iterable[str]]: 

357 """ 

358 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

359 the internal value. 

360 

361 :return: Formatted argument. 

362 """ 

363 return self._pattern.format(self._value) 

364 

365 def __str__(self) -> str: 

366 """ 

367 Return a string representation of this argument instance. 

368 

369 :return: Argument formatted and enclosed in double quotes. 

370 """ 

371 return f"\"{self.AsArgument()}\"" 

372 

373 __repr__ = __str__ 

374 

375 

376class NamedAndValuedArgument(NamedArgument, ValuedArgument, Generic[ValueT], pattern="{0}={1}"): 

377 """ 

378 Base-class for all command line arguments with a name and a value. 

379 """ 

380 

381 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "{0}={1}", **kwargs: Any): 

382 """ 

383 This method is called when a class is derived. 

384 

385 :param args: Any positional arguments. 

386 :param name: Name of the argument. 

387 :param pattern: This pattern is used to format an argument. 

388 :param kwargs: Any keyword argument. 

389 """ 

390 kwargs["name"] = name 

391 kwargs["pattern"] = pattern 

392 super().__init_subclass__(*args, **kwargs) 

393 del kwargs["name"] 

394 del kwargs["pattern"] 

395 ValuedArgument.__init_subclass__(*args, **kwargs) 

396 

397 def __init__(self, value: ValueT) -> None: 

398 ValuedArgument.__init__(self, value) 

399 

400 def AsArgument(self) -> Union[str, Iterable[str]]: 

401 """ 

402 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

403 the internal name and value. 

404 

405 :return: Formatted argument. 

406 :raises ValueError: If internal name is None. 

407 """ 

408 if self._name is None: 408 ↛ 409line 408 didn't jump to line 409 because the condition on line 408 was never true

409 raise ValueError(f"Internal value '_name' is None.") 

410 

411 return self._pattern.format(self._name, self._value) 

412 

413 def __str__(self) -> str: 

414 """ 

415 Return a string representation of this argument instance. 

416 

417 :return: Argument formatted and enclosed in double quotes. 

418 """ 

419 return f"\"{self.AsArgument()}\"" 

420 

421 __repr__ = __str__ 

422 

423 

424class NamedTupledArgument(NamedArgument, ValuedArgument, Generic[ValueT], pattern="{0}"): 

425 """ 

426 Class and base-class for all TupleFlag classes, which represents an argument with separate value. 

427 

428 A tuple argument is a command line argument followed by a separate value. Name and value are passed as two arguments 

429 to the executable. 

430 

431 **Example: ** 

432 

433 * `width 100`` 

434 """ 

435 

436 _valuePattern: ClassVar[str] 

437 

438 def __init_subclass__(cls, *args: Any, name: Nullable[str] = None, pattern: str = "{0}", valuePattern: str = "{0}", **kwargs: Any): 

439 kwargs["name"] = name 

440 kwargs["pattern"] = pattern 

441 super().__init_subclass__(*args, **kwargs) 

442 cls._valuePattern = valuePattern 

443 

444 def __new__(cls, *args: Any, **kwargs: Any): 

445 if cls is NamedTupledArgument: 

446 raise TypeError(f"Class '{cls.__name__}' is abstract.") 

447 return super().__new__(cls, *args, **kwargs) 

448 

449 def __init__(self, value: ValueT) -> None: 

450 ValuedArgument.__init__(self, value) 

451 

452 # TODO: Add property to read value pattern 

453 

454 # @property 

455 # def ValuePattern(self) -> str: 

456 # if self._valuePattern is None: 

457 # raise ValueError(f"") # XXX: add message 

458 # 

459 # return self._valuePattern 

460 

461 def AsArgument(self) -> Union[str, Iterable[str]]: 

462 """ 

463 Convert this argument instance to a sequence of string representations with proper escaping using the matching 

464 pattern based on the internal name and value. 

465 

466 :return: Formatted argument as tuple of strings. 

467 :raises ValueError: If internal name is None. 

468 """ 

469 if self._name is None: 469 ↛ 470line 469 didn't jump to line 470 because the condition on line 469 was never true

470 raise ValueError(f"Internal value '_name' is None.") 

471 

472 return ( 

473 self._pattern.format(self._name), 

474 self._valuePattern.format(self._value) 

475 ) 

476 

477 def __str__(self) -> str: 

478 """ 

479 Return a string representation of this argument instance. 

480 

481 :return: Space separated sequence of arguments formatted and each enclosed in double quotes. 

482 """ 

483 return " ".join([f"\"{item}\"" for item in self.AsArgument()]) 

484 

485 def __repr__(self) -> str: 

486 """ 

487 Return a string representation of this argument instance. 

488 

489 :return: Comma separated sequence of arguments formatted and each enclosed in double quotes. 

490 """ 

491 return ", ".join([f"\"{item}\"" for item in self.AsArgument()]) 

492 

493 

494@export 

495class StringArgument(ValuedArgument, pattern="{0}"): 

496 """ 

497 Represents a simple string argument. 

498 

499 A list of strings is available as :class:`~pyTooling.CLIAbstraction.Argument.StringListArgument`. 

500 """ 

501 

502 def __init_subclass__(cls, *args: Any, pattern: str = "{0}", **kwargs: Any): 

503 """ 

504 This method is called when a class is derived. 

505 

506 :param args: Any positional arguments. 

507 :param pattern: This pattern is used to format an argument. 

508 :param kwargs: Any keyword argument. 

509 """ 

510 kwargs["pattern"] = pattern 

511 super().__init_subclass__(*args, **kwargs) 

512 

513 

514@export 

515class StringListArgument(ValuedArgument): 

516 """ 

517 Represents a list of string argument (:class:`~pyTooling.CLIAbstraction.Argument.StringArgument`).""" 

518 

519 def __init__(self, values: Iterable[str]) -> None: 

520 """ 

521 Initializes a StringListArgument instance. 

522 

523 :param values: An iterable of str instances. 

524 :raises TypeError: If iterable parameter 'values' contains elements not of type :class:`str`. 

525 """ 

526 self._values = [] 

527 for value in values: 

528 if not isinstance(value, str): 528 ↛ 529line 528 didn't jump to line 529 because the condition on line 528 was never true

529 ex = TypeError(f"Parameter 'values' contains elements which are not of type 'str'.") 

530 if version_info >= (3, 11): # pragma: no cover 

531 ex.add_note(f"Got type '{getFullyQualifiedName(values)}'.") 

532 raise ex 

533 

534 self._values.append(value) 

535 

536 @property 

537 def Value(self) -> List[str]: 

538 """ 

539 Get the internal list of str objects. 

540 

541 :return: Reference to the internal list of str objects. 

542 """ 

543 return self._values 

544 

545 @Value.setter 

546 def Value(self, value: Iterable[str]): 

547 """ 

548 Overwrite all elements in the internal list of str objects. 

549 

550 .. note:: The list object is not replaced, but cleared and then reused by adding the given elements in the iterable. 

551 

552 :param value: List of str objects to set. 

553 :raises TypeError: If value contains elements, which are not of type :class:`str`. 

554 """ 

555 self._values.clear() 

556 for value in value: 

557 if not isinstance(value, str): 

558 ex = TypeError(f"Value contains elements which are not of type 'str'.") 

559 if version_info >= (3, 11): # pragma: no cover 

560 ex.add_note(f"Got type '{getFullyQualifiedName(value)}'.") 

561 raise ex 

562 self._values.append(value) 

563 

564 def AsArgument(self) -> Union[str, Iterable[str]]: 

565 """ 

566 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

567 the internal value. 

568 

569 :return: Sequence of formatted arguments. 

570 """ 

571 return [f"{value}" for value in self._values] 

572 

573 def __str__(self) -> str: 

574 """ 

575 Return a string representation of this argument instance. 

576 

577 :return: Space separated sequence of arguments formatted and each enclosed in double quotes. 

578 """ 

579 return " ".join([f"\"{value}\"" for value in self.AsArgument()]) 

580 

581 def __repr__(self) -> str: 

582 """ 

583 Return a string representation of this argument instance. 

584 

585 :return: Comma separated sequence of arguments formatted and each enclosed in double quotes. 

586 """ 

587 return ", ".join([f"\"{value}\"" for value in self.AsArgument()]) 

588 

589 

590# TODO: Add option to class if path should be checked for existence 

591@export 

592class PathArgument(CommandLineArgument): 

593 """ 

594 Represents a single path argument. 

595 

596 A list of paths is available as :class:`~pyTooling.CLIAbstraction.Argument.PathListArgument`. 

597 """ 

598 # The output format can be forced to the POSIX format with :py:data:`_PosixFormat`. 

599 _path: Path 

600 

601 def __init__(self, path: Path) -> None: 

602 """ 

603 Initializes a PathArgument instance. 

604 

605 :param path: Path to a filesystem object. 

606 :raises TypeError: If parameter 'path' is not of type :class:`~pathlib.Path`. 

607 """ 

608 if not isinstance(path, Path): 608 ↛ 609line 608 didn't jump to line 609 because the condition on line 608 was never true

609 ex = TypeError("Parameter 'path' is not of type 'Path'.") 

610 if version_info >= (3, 11): # pragma: no cover 

611 ex.add_note(f"Got type '{getFullyQualifiedName(path)}'.") 

612 raise ex 

613 self._path = path 

614 

615 @property 

616 def Value(self) -> Path: 

617 """ 

618 Get the internal path object. 

619 

620 :return: Internal path object. 

621 """ 

622 return self._path 

623 

624 @Value.setter 

625 def Value(self, value: Path): 

626 """ 

627 Set the internal path object. 

628 

629 :param value: Value to set. 

630 :raises TypeError: If value is not of type :class:`~pathlib.Path`. 

631 """ 

632 if not isinstance(value, Path): 632 ↛ 633line 632 didn't jump to line 633 because the condition on line 632 was never true

633 ex = TypeError("Value is not of type 'Path'.") 

634 if version_info >= (3, 11): # pragma: no cover 

635 ex.add_note(f"Got type '{getFullyQualifiedName(value)}'.") 

636 raise ex 

637 

638 self._path = value 

639 

640 def AsArgument(self) -> Union[str, Iterable[str]]: 

641 """ 

642 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

643 the internal value. 

644 

645 :return: Formatted argument. 

646 """ 

647 return f"{self._path}" 

648 

649 def __str__(self) -> str: 

650 """ 

651 Return a string representation of this argument instance. 

652 

653 :return: Argument formatted and enclosed in double quotes. 

654 """ 

655 return f"\"{self._path}\"" 

656 

657 __repr__ = __str__ 

658 

659 

660@export 

661class PathListArgument(CommandLineArgument): 

662 """ 

663 Represents a list of path arguments (:class:`~pyTooling.CLIAbstraction.Argument.PathArgument`). 

664 """ 

665 # The output format can be forced to the POSIX format with :py:data:`_PosixFormat`. 

666 _paths: List[Path] 

667 

668 def __init__(self, paths: Iterable[Path]) -> None: 

669 """ 

670 Initializes a PathListArgument instance. 

671 

672 :param paths: An iterable os Path instances. 

673 :raises TypeError: If iterable parameter 'paths' contains elements not of type :class:`~pathlib.Path`. 

674 """ 

675 self._paths = [] 

676 for path in paths: 

677 if not isinstance(path, Path): 677 ↛ 678line 677 didn't jump to line 678 because the condition on line 677 was never true

678 ex = TypeError(f"Parameter 'paths' contains elements which are not of type 'Path'.") 

679 if version_info >= (3, 11): # pragma: no cover 

680 ex.add_note(f"Got type '{getFullyQualifiedName(path)}'.") 

681 raise ex 

682 

683 self._paths.append(path) 

684 

685 @property 

686 def Value(self) -> List[Path]: 

687 """ 

688 Get the internal list of path objects. 

689 

690 :return: Reference to the internal list of path objects. 

691 """ 

692 return self._paths 

693 

694 @Value.setter 

695 def Value(self, value: Iterable[Path]): 

696 """ 

697 Overwrite all elements in the internal list of path objects. 

698 

699 .. note:: The list object is not replaced, but cleared and then reused by adding the given elements in the iterable. 

700 

701 :param value: List of path objects to set. 

702 :raises TypeError: If value contains elements, which are not of type :class:`~pathlib.Path`. 

703 """ 

704 self._paths.clear() 

705 for path in value: 

706 if not isinstance(path, Path): 

707 ex = TypeError(f"Value contains elements which are not of type 'Path'.") 

708 if version_info >= (3, 11): # pragma: no cover 

709 ex.add_note(f"Got type '{getFullyQualifiedName(path)}'.") 

710 raise ex 

711 self._paths.append(path) 

712 

713 def AsArgument(self) -> Union[str, Iterable[str]]: 

714 """ 

715 Convert this argument instance to a string representation with proper escaping using the matching pattern based on 

716 the internal value. 

717 

718 :return: Sequence of formatted arguments. 

719 """ 

720 return [f"{path}" for path in self._paths] 

721 

722 def __str__(self) -> str: 

723 """ 

724 Return a string representation of this argument instance. 

725 

726 :return: Space separated sequence of arguments formatted and each enclosed in double quotes. 

727 """ 

728 return " ".join([f"\"{value}\"" for value in self.AsArgument()]) 

729 

730 def __repr__(self) -> str: 

731 """ 

732 Return a string representation of this argument instance. 

733 

734 :return: Comma separated sequence of arguments formatted and each enclosed in double quotes. 

735 """ 

736 return ", ".join([f"\"{value}\"" for value in self.AsArgument()])